From e785bfcd127d864136b204211b9609949668c952 Mon Sep 17 00:00:00 2001 From: Ben Vargas Date: Fri, 9 Jan 2026 00:54:35 -0700 Subject: [PATCH] Use unprefixed Claude request for translation Keep the upstream payload prefixed for OAuth while passing the unprefixed request body into response translators. This avoids proxy_ leaking into OpenAI Responses echoed tool metadata while preserving the Claude OAuth workaround. --- internal/runtime/executor/claude_executor.go | 38 +++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/internal/runtime/executor/claude_executor.go b/internal/runtime/executor/claude_executor.go index e385b41e..d426326f 100644 --- a/internal/runtime/executor/claude_executor.go +++ b/internal/runtime/executor/claude_executor.go @@ -83,12 +83,14 @@ func (e *ClaudeExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, r // Extract betas from body and convert to header var extraBetas []string extraBetas, body = extractAndRemoveBetas(body) + bodyForTranslation := body + bodyForUpstream := body if isClaudeOAuthToken(apiKey) { - body = applyClaudeToolPrefix(body, claudeToolPrefix) + bodyForUpstream = applyClaudeToolPrefix(body, claudeToolPrefix) } url := fmt.Sprintf("%s/v1/messages?beta=true", baseURL) - httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body)) + httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(bodyForUpstream)) if err != nil { return resp, err } @@ -103,7 +105,7 @@ func (e *ClaudeExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, r URL: url, Method: http.MethodPost, Headers: httpReq.Header.Clone(), - Body: body, + Body: bodyForUpstream, Provider: e.Identifier(), AuthID: authID, AuthLabel: authLabel, @@ -161,7 +163,16 @@ func (e *ClaudeExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, r data = stripClaudeToolPrefixFromResponse(data, claudeToolPrefix) } var param any - out := sdktranslator.TranslateNonStream(ctx, to, from, req.Model, bytes.Clone(opts.OriginalRequest), body, data, ¶m) + out := sdktranslator.TranslateNonStream( + ctx, + to, + from, + req.Model, + bytes.Clone(opts.OriginalRequest), + bodyForTranslation, + data, + ¶m, + ) resp = cliproxyexecutor.Response{Payload: []byte(out)} return resp, nil } @@ -201,12 +212,14 @@ func (e *ClaudeExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.A // Extract betas from body and convert to header var extraBetas []string extraBetas, body = extractAndRemoveBetas(body) + bodyForTranslation := body + bodyForUpstream := body if isClaudeOAuthToken(apiKey) { - body = applyClaudeToolPrefix(body, claudeToolPrefix) + bodyForUpstream = applyClaudeToolPrefix(body, claudeToolPrefix) } url := fmt.Sprintf("%s/v1/messages?beta=true", baseURL) - httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body)) + httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(bodyForUpstream)) if err != nil { return nil, err } @@ -221,7 +234,7 @@ func (e *ClaudeExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.A URL: url, Method: http.MethodPost, Headers: httpReq.Header.Clone(), - Body: body, + Body: bodyForUpstream, Provider: e.Identifier(), AuthID: authID, AuthLabel: authLabel, @@ -304,7 +317,16 @@ func (e *ClaudeExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.A if isClaudeOAuthToken(apiKey) { line = stripClaudeToolPrefixFromStreamLine(line, claudeToolPrefix) } - chunks := sdktranslator.TranslateStream(ctx, to, from, req.Model, bytes.Clone(opts.OriginalRequest), body, bytes.Clone(line), ¶m) + chunks := sdktranslator.TranslateStream( + ctx, + to, + from, + req.Model, + bytes.Clone(opts.OriginalRequest), + bodyForTranslation, + bytes.Clone(line), + ¶m, + ) for i := range chunks { out <- cliproxyexecutor.StreamChunk{Payload: []byte(chunks[i])} }