@@ -6319,3 +6319,100 @@ func TestClaudeExecutor_CacheTTLIsPairedWithExtendedCacheTTLBeta(t *testing.T) {
63196319 })
63206320 }
63216321}
6322+
6323+ func TestClaudeExecutor_PreservesNativeAgentAndEnvironmentHeaders (t * testing.T ) {
6324+ tests := []struct {
6325+ name string
6326+ incomingHeaders http.Header
6327+ wantHeaders map [string ]string
6328+ wantAbsent []string
6329+ }{
6330+ {
6331+ name : "preserves canonical agent and parent agent headers" ,
6332+ incomingHeaders : http.Header {
6333+ "X-Claude-Code-Agent-Id" : {"subagent-001" },
6334+ "X-Claude-Code-Parent-Agent-Id" : {"parent-agent-root" },
6335+ },
6336+ wantHeaders : map [string ]string {
6337+ "X-Claude-Code-Agent-Id" : "subagent-001" ,
6338+ "X-Claude-Code-Parent-Agent-Id" : "parent-agent-root" ,
6339+ },
6340+ },
6341+ {
6342+ name : "preserves lowercased agent and environment headers" ,
6343+ incomingHeaders : http.Header {
6344+ "x-claude-code-agent-id" : {"agent-xyz" },
6345+ "x-claude-remote-container-id" : {"container-123" },
6346+ "x-claude-remote-session-id" : {"remote-sess-456" },
6347+ "x-client-app" : {"custom-sdk" },
6348+ "x-anthropic-additional-protection" : {"true" },
6349+ },
6350+ wantHeaders : map [string ]string {
6351+ "X-Claude-Code-Agent-Id" : "agent-xyz" ,
6352+ "X-Claude-Remote-Container-Id" : "container-123" ,
6353+ "X-Claude-Remote-Session-Id" : "remote-sess-456" ,
6354+ "X-Client-App" : "custom-sdk" ,
6355+ "X-Anthropic-Additional-Protection" : "true" ,
6356+ },
6357+ },
6358+ {
6359+ name : "does not fabricate agent header when absent" ,
6360+ incomingHeaders : http.Header {
6361+ "User-Agent" : {"test-client" },
6362+ },
6363+ wantAbsent : []string {
6364+ "X-Claude-Code-Agent-Id" ,
6365+ "X-Claude-Code-Parent-Agent-Id" ,
6366+ "X-Claude-Remote-Container-Id" ,
6367+ "X-Claude-Remote-Session-Id" ,
6368+ "X-Client-App" ,
6369+ "X-Anthropic-Additional-Protection" ,
6370+ },
6371+ },
6372+ }
6373+
6374+ for _ , tt := range tests {
6375+ t .Run (tt .name , func (t * testing.T ) {
6376+ var seenHeaders http.Header
6377+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
6378+ seenHeaders = r .Header .Clone ()
6379+ w .Header ().Set ("Content-Type" , "application/json" )
6380+ _ , _ = w .Write ([]byte (`{"id":"msg_agent","type":"message","model":"claude-opus-4-6","role":"assistant","content":[{"type":"text","text":"ok"}],"usage":{"input_tokens":1,"output_tokens":1}}` ))
6381+ }))
6382+ defer server .Close ()
6383+
6384+ executor := NewClaudeExecutor (& config.Config {})
6385+ auth := & cliproxyauth.Auth {
6386+ ID : "agent-header-test" ,
6387+ Attributes : map [string ]string {
6388+ "api_key" : "sk-ant-test-key" ,
6389+ "base_url" : server .URL ,
6390+ "cloak_mode" : "always" ,
6391+ },
6392+ Metadata : claudeOAuthTestMetadata (),
6393+ }
6394+
6395+ _ , errExecute := executor .Execute (context .Background (), auth , cliproxyexecutor.Request {
6396+ Model : "claude-opus-4-6" ,
6397+ Payload : []byte (`{"model":"claude-opus-4-6","messages":[{"role":"user","content":[{"type":"text","text":"hi"}]}]}` ),
6398+ }, cliproxyexecutor.Options {
6399+ SourceFormat : sdktranslator .FormatClaude ,
6400+ Headers : tt .incomingHeaders ,
6401+ })
6402+ if errExecute != nil {
6403+ t .Fatalf ("Execute() error = %v" , errExecute )
6404+ }
6405+
6406+ for wantKey , wantVal := range tt .wantHeaders {
6407+ if got := seenHeaders .Get (wantKey ); got != wantVal {
6408+ t .Errorf ("header %s = %q, want %q" , wantKey , got , wantVal )
6409+ }
6410+ }
6411+ for _ , absentKey := range tt .wantAbsent {
6412+ if got := seenHeaders .Get (absentKey ); got != "" {
6413+ t .Errorf ("header %s = %q, want absent" , absentKey , got )
6414+ }
6415+ }
6416+ })
6417+ }
6418+ }
0 commit comments