Help us shape the future of Go! Take the 2026 Go Developer Survey

header

package
v0.36.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: Apache-2.0, MIT Imports: 3 Imported by: 0

Documentation

Overview

Package header provides header filtering for the tapes proxy.

This proxy sits between a client and an upstream LLM provider like so:

Client <--> Proxy <--> Upstream LLM Provider

and headers are handled accordingly as each leg negotiates compression, hops, encoding, etc. independently.

Index

Constants

View Source
const (
	// CodexSessionID is the Codex harness's root session id, present on
	// every Codex call.
	CodexSessionID = "session-id"

	// CodexThreadID is the Codex harness's thread id for this call: equal to
	// session-id on root turns, a distinct id on sub-thread (spawned agent)
	// turns.
	CodexThreadID = "thread-id"
)

Codex's native identity headers. Unlike Claude Code, Codex stamps thread-id on EVERY call — root turns carry thread-id == session-id, and only spawned sub-thread (child) turns carry a distinct thread-id. So presence alone doesn't mean "subagent"; the root guard in ThreadID compares the pair and resolves root turns to "". Getting this wrong is not cosmetic: a non-empty thread_id on a root turn misroutes the root spine into tapes derive's threadCall path and silently degrades the session's derived status (terminalMainSpan requires ThreadID=="").

Canonical home: tapes-harnesses src/envelope.rs (CODEX_THREAD_ID_HEADER / CODEX_SESSION_ID_HEADER); the lifecycle counterpart of the same identities is src/attribution/codex_app (session_id = the root session, agent_id = the child thread). Pinned cross-language by fixtures/thread/.

View Source
const AgentNameHeader = "X-Tapes-Agent-Name"

AgentNameHeader is the optional header used to tag agent requests.

Variables

View Source
var ThreadIDHeaders = []string{
	"x-claude-code-agent-id",
}

ThreadIDHeaders maps each harness's native sub-thread header onto the capture-side thread id. A harness that runs subagents fires their API calls with a per-thread identifier — Claude Code stamps x-claude-code-agent-id on every call made from a subagent context (including its security-monitor checks) and omits it on the main thread. Capturing it makes thread attribution deterministic at capture time instead of recovered by content joins downstream.

The list is ordered; first present header wins. Add other harnesses' equivalents here as they are identified — the rest of the pipeline is harness-neutral and only sees the resolved thread id. Codex is NOT a member of this list: its sub-thread signal is a header *pair* (see the Codex constants below), resolved separately in ThreadID.

This must stay in step with extproc/headers' harnessThreadIDHeaders: the two are independent capture paths for the same traffic, and a header one records and the other doesn't is a fidelity gap that only shows up as subagent turns mis-attributed to the main thread. They stayed separate through the extproc fold because they read from different transports — a fiber.Ctx here, an ext_proc HeaderMap there — so only the list itself could ever be shared.

These headers are NOT stripped on the way upstream. They are the harness's own, addressed to the model provider; tapes only observes them.

Canonical home: tapes-harnesses src/envelope.rs (CLAUDE_THREAD_ID_HEADERS, and HARNESS_THREAD_ID_RULES for the rule shape). The shared corpus at fixtures/thread/ pins the spelling and resolution across every reader (thread_corpus_test.go here; the authored-home gate lives in extproc/headers).

Functions

func ThreadID added in v0.30.0

func ThreadID(c *fiber.Ctx) string

ThreadID resolves the harness-native sub-thread id for this request, or "" for a main-thread call (or a harness with no known mapping). Fiber's Get is case-insensitive, so the constants are written in the lowercase HTTP/2 form that matches a packet capture.

Types

type Handler

type Handler struct{}

Handler manages headers between proxy connections.

func NewHandler

func NewHandler() *Handler

NewHandler creates a new header Handler.

func (*Handler) SetClientResponseHeaders

func (h *Handler) SetClientResponseHeaders(c *fiber.Ctx, resp *http.Response)

SetClientResponseHeaders copies response headers from the upstream API http.Response to the Fiber context, filtering headers that the proxy should not forward back down to the client.

func (*Handler) SetUpstreamRequestHeaders

func (h *Handler) SetUpstreamRequestHeaders(c *fiber.Ctx, req *http.Request)

SetUpstreamRequestHeaders copies request headers from the Fiber context to the outgoing http.Request, filtering headers that the proxy should not forward to the upstream API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL