header

package
v0.36.0 Latest Latest
Warning

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

Go to latest
Published: Aug 14, 2026 License: AGPL-3.0 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