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.
This commit is contained in:
Ben Vargas
2026-01-09 00:54:35 -07:00
parent dcac3407ab
commit e785bfcd12

View File

@@ -83,12 +83,14 @@ func (e *ClaudeExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, r
// Extract betas from body and convert to header // Extract betas from body and convert to header
var extraBetas []string var extraBetas []string
extraBetas, body = extractAndRemoveBetas(body) extraBetas, body = extractAndRemoveBetas(body)
bodyForTranslation := body
bodyForUpstream := body
if isClaudeOAuthToken(apiKey) { if isClaudeOAuthToken(apiKey) {
body = applyClaudeToolPrefix(body, claudeToolPrefix) bodyForUpstream = applyClaudeToolPrefix(body, claudeToolPrefix)
} }
url := fmt.Sprintf("%s/v1/messages?beta=true", baseURL) 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 { if err != nil {
return resp, err return resp, err
} }
@@ -103,7 +105,7 @@ func (e *ClaudeExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, r
URL: url, URL: url,
Method: http.MethodPost, Method: http.MethodPost,
Headers: httpReq.Header.Clone(), Headers: httpReq.Header.Clone(),
Body: body, Body: bodyForUpstream,
Provider: e.Identifier(), Provider: e.Identifier(),
AuthID: authID, AuthID: authID,
AuthLabel: authLabel, AuthLabel: authLabel,
@@ -161,7 +163,16 @@ func (e *ClaudeExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, r
data = stripClaudeToolPrefixFromResponse(data, claudeToolPrefix) data = stripClaudeToolPrefixFromResponse(data, claudeToolPrefix)
} }
var param any var param any
out := sdktranslator.TranslateNonStream(ctx, to, from, req.Model, bytes.Clone(opts.OriginalRequest), body, data, &param) out := sdktranslator.TranslateNonStream(
ctx,
to,
from,
req.Model,
bytes.Clone(opts.OriginalRequest),
bodyForTranslation,
data,
&param,
)
resp = cliproxyexecutor.Response{Payload: []byte(out)} resp = cliproxyexecutor.Response{Payload: []byte(out)}
return resp, nil 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 // Extract betas from body and convert to header
var extraBetas []string var extraBetas []string
extraBetas, body = extractAndRemoveBetas(body) extraBetas, body = extractAndRemoveBetas(body)
bodyForTranslation := body
bodyForUpstream := body
if isClaudeOAuthToken(apiKey) { if isClaudeOAuthToken(apiKey) {
body = applyClaudeToolPrefix(body, claudeToolPrefix) bodyForUpstream = applyClaudeToolPrefix(body, claudeToolPrefix)
} }
url := fmt.Sprintf("%s/v1/messages?beta=true", baseURL) 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 { if err != nil {
return nil, err return nil, err
} }
@@ -221,7 +234,7 @@ func (e *ClaudeExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.A
URL: url, URL: url,
Method: http.MethodPost, Method: http.MethodPost,
Headers: httpReq.Header.Clone(), Headers: httpReq.Header.Clone(),
Body: body, Body: bodyForUpstream,
Provider: e.Identifier(), Provider: e.Identifier(),
AuthID: authID, AuthID: authID,
AuthLabel: authLabel, AuthLabel: authLabel,
@@ -304,7 +317,16 @@ func (e *ClaudeExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.A
if isClaudeOAuthToken(apiKey) { if isClaudeOAuthToken(apiKey) {
line = stripClaudeToolPrefixFromStreamLine(line, claudeToolPrefix) line = stripClaudeToolPrefixFromStreamLine(line, claudeToolPrefix)
} }
chunks := sdktranslator.TranslateStream(ctx, to, from, req.Model, bytes.Clone(opts.OriginalRequest), body, bytes.Clone(line), &param) chunks := sdktranslator.TranslateStream(
ctx,
to,
from,
req.Model,
bytes.Clone(opts.OriginalRequest),
bodyForTranslation,
bytes.Clone(line),
&param,
)
for i := range chunks { for i := range chunks {
out <- cliproxyexecutor.StreamChunk{Payload: []byte(chunks[i])} out <- cliproxyexecutor.StreamChunk{Payload: []byte(chunks[i])}
} }