perf(antigravity): translate each upstream request once

Execute, executeClaudeNonStream and ExecuteStream all assign the validated
original payload to the request and then translate both values. Since both
translations saw the same bytes, every Antigravity request paid for a second
full scan of the client payload. On a captured 24MB tool-history request that
second pass cost roughly 0.9s of CPU and 651MB of allocations.

Translate once when both inputs share a backing array and hand the caller an
independent duplicate, because later stages edit the working copy in place.
Payloads that genuinely differ still get two translations.
This commit is contained in:
sususu
2026-08-11 12:54:42 +08:00
committed by sususu98
parent d5f68856f6
commit cf8c27fe90
4 changed files with 157 additions and 6 deletions

View File

@@ -66,8 +66,7 @@ func (e *AntigravityExecutor) Execute(ctx context.Context, auth *cliproxyauth.Au
auth = updatedAuth
reporter.UpdateAccessTokenFingerprint(auth)
}
originalTranslated := helps.TranslateRequestWithCodexMultiAgentV2(ctx, opts.Headers, e.cfg, from, to, baseModel, originalPayload, false)
translated := helps.TranslateRequestWithCodexMultiAgentV2(ctx, opts.Headers, e.cfg, from, to, baseModel, req.Payload, false)
originalTranslated, translated := helps.TranslateRequestPairWithCodexMultiAgentV2(ctx, opts.Headers, e.cfg, from, to, baseModel, originalPayload, req.Payload, false)
translated, err = helps.ApplyThinkingWithSourcePayload(translated, req.Payload, originalPayloadSource, req.Model, from.String(), to.String(), e.Identifier())
if err != nil {
@@ -290,8 +289,7 @@ func (e *AntigravityExecutor) executeClaudeNonStream(ctx context.Context, auth *
auth = updatedAuth
reporter.UpdateAccessTokenFingerprint(auth)
}
originalTranslated := helps.TranslateRequestWithCodexMultiAgentV2(ctx, opts.Headers, e.cfg, from, to, baseModel, originalPayload, true)
translated := helps.TranslateRequestWithCodexMultiAgentV2(ctx, opts.Headers, e.cfg, from, to, baseModel, req.Payload, true)
originalTranslated, translated := helps.TranslateRequestPairWithCodexMultiAgentV2(ctx, opts.Headers, e.cfg, from, to, baseModel, originalPayload, req.Payload, true)
translated, err = helps.ApplyThinkingWithSourcePayload(translated, req.Payload, originalPayloadSource, req.Model, from.String(), to.String(), e.Identifier())
if err != nil {

View File

@@ -61,8 +61,7 @@ func (e *AntigravityExecutor) ExecuteStream(ctx context.Context, auth *cliproxya
reporter.UpdateAccessTokenFingerprint(auth)
}
originalTranslated := helps.TranslateRequestWithCodexMultiAgentV2(ctx, opts.Headers, e.cfg, from, to, baseModel, originalPayload, true)
translated := helps.TranslateRequestWithCodexMultiAgentV2(ctx, opts.Headers, e.cfg, from, to, baseModel, req.Payload, true)
originalTranslated, translated := helps.TranslateRequestPairWithCodexMultiAgentV2(ctx, opts.Headers, e.cfg, from, to, baseModel, originalPayload, req.Payload, true)
translated, err = helps.ApplyThinkingWithSourcePayload(translated, req.Payload, originalPayloadSource, req.Model, from.String(), to.String(), e.Identifier())
if err != nil {

View File

@@ -35,6 +35,35 @@ func TranslateRequestWithCodexMultiAgentV2(ctx context.Context, headers http.Hea
return multiagentv2.TranslateRequestWithCodexMultiAgentV2(ctx, headers, cfg, from, to, model, payload, stream)
}
// TranslateRequestPairWithCodexMultiAgentV2 translates the untouched baseline
// payload and the working payload that later stages mutate in place. Executors
// normally assign the original payload to the request before translating, so both
// translations would rescan the same bytes and produce the same result. Request
// translation is deterministic and never aliases its input, so that case is
// translated once and duplicated, which removes a full extra pass over payloads
// that can reach tens of megabytes.
func TranslateRequestPairWithCodexMultiAgentV2(ctx context.Context, headers http.Header, cfg *config.Config, from, to sdktranslator.Format, model string, originalPayload, requestPayload []byte, stream bool) (original, working []byte) {
original = TranslateRequestWithCodexMultiAgentV2(ctx, headers, cfg, from, to, model, originalPayload, stream)
if sameByteSlice(originalPayload, requestPayload) {
// The caller mutates the working copy, so it must not share the baseline array.
return original, append([]byte(nil), original...)
}
return original, TranslateRequestWithCodexMultiAgentV2(ctx, headers, cfg, from, to, model, requestPayload, stream)
}
// sameByteSlice reports whether both slices describe the same bytes of the same
// backing array. It compares identity rather than content so the check stays
// constant time on large payloads.
func sameByteSlice(a, b []byte) bool {
if len(a) != len(b) {
return false
}
if len(a) == 0 {
return true
}
return &a[0] == &b[0]
}
// TranslateRequestWithAPIKeyModelCompatibility applies compatibility-aware
// request translators when a configured API-key model enables compatibility mode.
func TranslateRequestWithAPIKeyModelCompatibility(ctx context.Context, headers http.Header, cfg *config.Config, from, to sdktranslator.Format, model string, payload []byte, stream, isCompat bool) []byte {

View File

@@ -0,0 +1,125 @@
package helps
import (
"bytes"
"context"
"fmt"
"net/http"
"strings"
"testing"
"github.com/router-for-me/CLIProxyAPI/v7/internal/config"
_ "github.com/router-for-me/CLIProxyAPI/v7/internal/translator"
sdktranslator "github.com/router-for-me/CLIProxyAPI/v7/sdk/translator"
)
func geminiToolHistoryPayload(turns int) []byte {
contents := []string{`{"role":"user","parts":[{"text":"start"}]}`}
for i := 0; i < turns; i++ {
contents = append(contents,
fmt.Sprintf(`{"role":"user","parts":[{"text":"ask %d"}]}`, i),
fmt.Sprintf(`{"role":"model","parts":[{"text":"think %d"},{"thoughtSignature":"sig-%d","functionCall":{"id":"c%d","name":"read_file","args":{"path":"a%d.go"}}}]}`, i, i, i, i),
fmt.Sprintf(`{"role":"user","parts":[{"functionResponse":{"id":"c%d","name":"read_file","response":{"content":"data %d"}}}]}`, i, i),
fmt.Sprintf(`{"role":"model","parts":[{"text":"answer %d"}]}`, i))
}
return []byte(fmt.Sprintf(
`{"contents":[%s],"tools":[{"functionDeclarations":[{"name":"read_file","description":"read a file","parameters":{"type":"object","properties":{"path":{"type":"string"}},"required":["path"]}}]}],"generationConfig":{"temperature":1}}`,
strings.Join(contents, ",")))
}
// TestTranslateRequestPairMatchesSeparateTranslations pins the reuse fast path to
// the behavior of translating both payloads independently.
func TestTranslateRequestPairMatchesSeparateTranslations(t *testing.T) {
from := sdktranslator.FormatGemini
to := sdktranslator.FromString("antigravity")
cfg := &config.Config{}
const model = "gemini-3.6-flash-high"
for _, turns := range []int{0, 1, 5, 20} {
payload := geminiToolHistoryPayload(turns)
// Same bytes in a different backing array forces the translate-twice branch.
detached := append([]byte(nil), payload...)
want := TranslateRequestWithCodexMultiAgentV2(context.Background(), http.Header{}, cfg, from, to, model, payload, true)
reuseBase, reuseWork := TranslateRequestPairWithCodexMultiAgentV2(
context.Background(), http.Header{}, cfg, from, to, model, payload, payload, true)
twiceBase, twiceWork := TranslateRequestPairWithCodexMultiAgentV2(
context.Background(), http.Header{}, cfg, from, to, model, payload, detached, true)
for name, got := range map[string][]byte{
"reuse baseline": reuseBase,
"reuse working": reuseWork,
"twice baseline": twiceBase,
"twice working": twiceWork,
} {
if !bytes.Equal(want, got) {
t.Fatalf("turns=%d: %s translation differs from a standalone translation", turns, name)
}
}
if len(reuseBase) > 0 && &reuseBase[0] == &reuseWork[0] {
t.Fatalf("turns=%d: working copy aliases the baseline; later in-place edits would corrupt it", turns)
}
// The caller mutates the working copy, so the baseline must stay intact.
baselineBefore := append([]byte(nil), reuseBase...)
reuseWork[0] = 'X'
if !bytes.Equal(baselineBefore, reuseBase) {
t.Fatalf("turns=%d: mutating the working copy changed the baseline", turns)
}
}
}
// TestTranslateRequestPairTranslatesDistinctPayloads guards the case where the
// executor really does hand over two different requests.
func TestTranslateRequestPairTranslatesDistinctPayloads(t *testing.T) {
from := sdktranslator.FormatGemini
to := sdktranslator.FromString("antigravity")
cfg := &config.Config{}
const model = "gemini-3.6-flash-high"
original := geminiToolHistoryPayload(2)
request := geminiToolHistoryPayload(4)
base, work := TranslateRequestPairWithCodexMultiAgentV2(
context.Background(), http.Header{}, cfg, from, to, model, original, request, true)
wantBase := TranslateRequestWithCodexMultiAgentV2(context.Background(), http.Header{}, cfg, from, to, model, original, true)
wantWork := TranslateRequestWithCodexMultiAgentV2(context.Background(), http.Header{}, cfg, from, to, model, request, true)
if !bytes.Equal(wantBase, base) {
t.Fatal("baseline translation differs for distinct payloads")
}
if !bytes.Equal(wantWork, work) {
t.Fatal("working translation differs for distinct payloads")
}
if bytes.Equal(base, work) {
t.Fatal("distinct payloads produced identical translations; the reuse path was taken by mistake")
}
}
func TestSameByteSlice(t *testing.T) {
buf := []byte("payload")
cases := []struct {
name string
a, b []byte
want bool
}{
{"identical slice", buf, buf, true},
{"same array same length", buf[:3], buf[:3], true},
{"equal bytes different array", buf, append([]byte(nil), buf...), false},
{"different length", buf, buf[:3], false},
{"both nil", nil, nil, true},
{"nil and empty", nil, []byte{}, true},
{"nil and non-empty", nil, buf, false},
{"offset alias", buf, buf[1:], false},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if got := sameByteSlice(tc.a, tc.b); got != tc.want {
t.Fatalf("sameByteSlice() = %v, want %v", got, tc.want)
}
})
}
}