**feat(translator): add Antigravity translation logic**

- Introduced request and response translation functions to enable compatibility between OpenAI Chat Completions API and Antigravity.
- Registered translation utilities for both streaming and non-streaming scenarios.
- Added support for reasoning content, tool calls, and metadata handling.
- Established request normalization and embedding for Antigravity-compatible payloads.
- Added new fields to `Params` struct for better tracking of finish reasons, usage metadata, and tool usage.
- Refactored handling of response transitions, final events, and state-driven logic in `ConvertAntigravityResponseToClaude`.
- Introduced `appendFinalEvents` and `resolveStopReason` helper functions for cleaner separation of concerns.
- Added `TotalTokenCount` field to `Params` struct for enhanced token tracking.
- Updated token count calculations to fallback on `TotalTokenCount` when specific counts are missing.
- Introduced `hasNonZeroUsageMetadata` function to validate presence of token data in `usage_metadata`.
This commit is contained in:
Luis Pater
2025-11-21 22:52:26 +08:00
parent 327cc7039e
commit c1031e2d3f
16 changed files with 1730 additions and 2 deletions

View File

@@ -70,7 +70,7 @@ func (e *AntigravityExecutor) Execute(ctx context.Context, auth *cliproxyauth.Au
defer reporter.trackFailure(ctx, &err)
from := opts.SourceFormat
to := sdktranslator.FromString("gemini-cli")
to := sdktranslator.FromString("antigravity")
translated := sdktranslator.TranslateRequest(from, to, req.Model, bytes.Clone(req.Payload), false)
httpReq, errReq := e.buildRequest(ctx, auth, token, req.Model, translated, false, opts.Alt)
@@ -127,7 +127,7 @@ func (e *AntigravityExecutor) ExecuteStream(ctx context.Context, auth *cliproxya
defer reporter.trackFailure(ctx, &err)
from := opts.SourceFormat
to := sdktranslator.FromString("gemini-cli")
to := sdktranslator.FromString("antigravity")
translated := sdktranslator.TranslateRequest(from, to, req.Model, bytes.Clone(req.Payload), true)
httpReq, errReq := e.buildRequest(ctx, auth, token, req.Model, translated, true, opts.Alt)

View File

@@ -453,6 +453,10 @@ func StripUsageMetadataFromJSON(rawJSON []byte) ([]byte, bool) {
usageMetadata = gjson.GetBytes(jsonBytes, "response.usageMetadata")
}
if hasNonZeroUsageMetadata(usageMetadata) {
return rawJSON, false
}
if !usageMetadata.Exists() {
return rawJSON, false
}
@@ -475,3 +479,14 @@ func StripUsageMetadataFromJSON(rawJSON []byte) ([]byte, bool) {
return cleaned, changed
}
// hasNonZeroUsageMetadata checks if any usage token counts are present.
func hasNonZeroUsageMetadata(node gjson.Result) bool {
if !node.Exists() {
return false
}
return node.Get("totalTokenCount").Int() > 0 ||
node.Get("promptTokenCount").Int() > 0 ||
node.Get("candidatesTokenCount").Int() > 0 ||
node.Get("thoughtsTokenCount").Int() > 0
}