revert(executor): re-apply PR #1735 antigravity changes with cleanup
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"crypto/tls"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -45,10 +46,10 @@ const (
|
|||||||
antigravityModelsPath = "/v1internal:fetchAvailableModels"
|
antigravityModelsPath = "/v1internal:fetchAvailableModels"
|
||||||
antigravityClientID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com"
|
antigravityClientID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com"
|
||||||
antigravityClientSecret = "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"
|
antigravityClientSecret = "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"
|
||||||
defaultAntigravityAgent = "antigravity/1.104.0 darwin/arm64"
|
defaultAntigravityAgent = "antigravity/1.19.6 darwin/arm64"
|
||||||
antigravityAuthType = "antigravity"
|
antigravityAuthType = "antigravity"
|
||||||
refreshSkew = 3000 * time.Second
|
refreshSkew = 3000 * time.Second
|
||||||
systemInstruction = "You are Antigravity, a powerful agentic AI coding assistant designed by the Google Deepmind team working on Advanced Agentic Coding.You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.**Absolute paths only****Proactiveness**"
|
// systemInstruction = "You are Antigravity, a powerful agentic AI coding assistant designed by the Google Deepmind team working on Advanced Agentic Coding.You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.**Absolute paths only****Proactiveness**"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -142,6 +143,62 @@ func NewAntigravityExecutor(cfg *config.Config) *AntigravityExecutor {
|
|||||||
return &AntigravityExecutor{cfg: cfg}
|
return &AntigravityExecutor{cfg: cfg}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// antigravityTransport is a singleton HTTP/1.1 transport shared by all Antigravity requests.
|
||||||
|
// It is initialized once via antigravityTransportOnce to avoid leaking a new connection pool
|
||||||
|
// (and the goroutines managing it) on every request.
|
||||||
|
var (
|
||||||
|
antigravityTransport *http.Transport
|
||||||
|
antigravityTransportOnce sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
|
func cloneTransportWithHTTP11(base *http.Transport) *http.Transport {
|
||||||
|
if base == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
clone := base.Clone()
|
||||||
|
clone.ForceAttemptHTTP2 = false
|
||||||
|
// Wipe TLSNextProto to prevent implicit HTTP/2 upgrade.
|
||||||
|
clone.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) http.RoundTripper)
|
||||||
|
if clone.TLSClientConfig == nil {
|
||||||
|
clone.TLSClientConfig = &tls.Config{}
|
||||||
|
} else {
|
||||||
|
clone.TLSClientConfig = clone.TLSClientConfig.Clone()
|
||||||
|
}
|
||||||
|
// Actively advertise only HTTP/1.1 in the ALPN handshake.
|
||||||
|
clone.TLSClientConfig.NextProtos = []string{"http/1.1"}
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
|
// initAntigravityTransport creates the shared HTTP/1.1 transport exactly once.
|
||||||
|
func initAntigravityTransport() {
|
||||||
|
base, ok := http.DefaultTransport.(*http.Transport)
|
||||||
|
if !ok {
|
||||||
|
base = &http.Transport{}
|
||||||
|
}
|
||||||
|
antigravityTransport = cloneTransportWithHTTP11(base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// newAntigravityHTTPClient creates an HTTP client specifically for Antigravity,
|
||||||
|
// enforcing HTTP/1.1 by disabling HTTP/2 to perfectly mimic Node.js https defaults.
|
||||||
|
// The underlying Transport is a singleton to avoid leaking connection pools.
|
||||||
|
func newAntigravityHTTPClient(ctx context.Context, cfg *config.Config, auth *cliproxyauth.Auth, timeout time.Duration) *http.Client {
|
||||||
|
antigravityTransportOnce.Do(initAntigravityTransport)
|
||||||
|
|
||||||
|
client := newProxyAwareHTTPClient(ctx, cfg, auth, timeout)
|
||||||
|
// If no transport is set, use the shared HTTP/1.1 transport.
|
||||||
|
if client.Transport == nil {
|
||||||
|
client.Transport = antigravityTransport
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preserve proxy settings from proxy-aware transports while forcing HTTP/1.1.
|
||||||
|
if transport, ok := client.Transport.(*http.Transport); ok {
|
||||||
|
client.Transport = cloneTransportWithHTTP11(transport)
|
||||||
|
}
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
// Identifier returns the executor identifier.
|
// Identifier returns the executor identifier.
|
||||||
func (e *AntigravityExecutor) Identifier() string { return antigravityAuthType }
|
func (e *AntigravityExecutor) Identifier() string { return antigravityAuthType }
|
||||||
|
|
||||||
@@ -162,6 +219,8 @@ func (e *AntigravityExecutor) PrepareRequest(req *http.Request, auth *cliproxyau
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HttpRequest injects Antigravity credentials into the request and executes it.
|
// HttpRequest injects Antigravity credentials into the request and executes it.
|
||||||
|
// It uses a whitelist approach: all incoming headers are stripped and only
|
||||||
|
// the minimum set required by the Antigravity protocol is explicitly set.
|
||||||
func (e *AntigravityExecutor) HttpRequest(ctx context.Context, auth *cliproxyauth.Auth, req *http.Request) (*http.Response, error) {
|
func (e *AntigravityExecutor) HttpRequest(ctx context.Context, auth *cliproxyauth.Auth, req *http.Request) (*http.Response, error) {
|
||||||
if req == nil {
|
if req == nil {
|
||||||
return nil, fmt.Errorf("antigravity executor: request is nil")
|
return nil, fmt.Errorf("antigravity executor: request is nil")
|
||||||
@@ -170,10 +229,29 @@ func (e *AntigravityExecutor) HttpRequest(ctx context.Context, auth *cliproxyaut
|
|||||||
ctx = req.Context()
|
ctx = req.Context()
|
||||||
}
|
}
|
||||||
httpReq := req.WithContext(ctx)
|
httpReq := req.WithContext(ctx)
|
||||||
|
|
||||||
|
// --- Whitelist: save only the headers we need from the original request ---
|
||||||
|
contentType := httpReq.Header.Get("Content-Type")
|
||||||
|
|
||||||
|
// Wipe ALL incoming headers
|
||||||
|
for k := range httpReq.Header {
|
||||||
|
delete(httpReq.Header, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Set only the headers Antigravity actually sends ---
|
||||||
|
if contentType != "" {
|
||||||
|
httpReq.Header.Set("Content-Type", contentType)
|
||||||
|
}
|
||||||
|
// Content-Length is managed automatically by Go's http.Client from the Body
|
||||||
|
httpReq.Header.Set("User-Agent", resolveUserAgent(auth))
|
||||||
|
httpReq.Close = true // sends Connection: close
|
||||||
|
|
||||||
|
// Inject Authorization: Bearer <token>
|
||||||
if err := e.PrepareRequest(httpReq, auth); err != nil {
|
if err := e.PrepareRequest(httpReq, auth); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
httpClient := newProxyAwareHTTPClient(ctx, e.cfg, auth, 0)
|
|
||||||
|
httpClient := newAntigravityHTTPClient(ctx, e.cfg, auth, 0)
|
||||||
return httpClient.Do(httpReq)
|
return httpClient.Do(httpReq)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +263,7 @@ func (e *AntigravityExecutor) Execute(ctx context.Context, auth *cliproxyauth.Au
|
|||||||
baseModel := thinking.ParseSuffix(req.Model).ModelName
|
baseModel := thinking.ParseSuffix(req.Model).ModelName
|
||||||
isClaude := strings.Contains(strings.ToLower(baseModel), "claude")
|
isClaude := strings.Contains(strings.ToLower(baseModel), "claude")
|
||||||
|
|
||||||
if isClaude || strings.Contains(baseModel, "gemini-3-pro") {
|
if isClaude || strings.Contains(baseModel, "gemini-3-pro") || strings.Contains(baseModel, "gemini-3.1-flash-image") {
|
||||||
return e.executeClaudeNonStream(ctx, auth, req, opts)
|
return e.executeClaudeNonStream(ctx, auth, req, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +298,7 @@ func (e *AntigravityExecutor) Execute(ctx context.Context, auth *cliproxyauth.Au
|
|||||||
translated = applyPayloadConfigWithRoot(e.cfg, baseModel, "antigravity", "request", translated, originalTranslated, requestedModel)
|
translated = applyPayloadConfigWithRoot(e.cfg, baseModel, "antigravity", "request", translated, originalTranslated, requestedModel)
|
||||||
|
|
||||||
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
||||||
httpClient := newProxyAwareHTTPClient(ctx, e.cfg, auth, 0)
|
httpClient := newAntigravityHTTPClient(ctx, e.cfg, auth, 0)
|
||||||
|
|
||||||
attempts := antigravityRetryAttempts(auth, e.cfg)
|
attempts := antigravityRetryAttempts(auth, e.cfg)
|
||||||
|
|
||||||
@@ -362,7 +440,7 @@ func (e *AntigravityExecutor) executeClaudeNonStream(ctx context.Context, auth *
|
|||||||
translated = applyPayloadConfigWithRoot(e.cfg, baseModel, "antigravity", "request", translated, originalTranslated, requestedModel)
|
translated = applyPayloadConfigWithRoot(e.cfg, baseModel, "antigravity", "request", translated, originalTranslated, requestedModel)
|
||||||
|
|
||||||
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
||||||
httpClient := newProxyAwareHTTPClient(ctx, e.cfg, auth, 0)
|
httpClient := newAntigravityHTTPClient(ctx, e.cfg, auth, 0)
|
||||||
|
|
||||||
attempts := antigravityRetryAttempts(auth, e.cfg)
|
attempts := antigravityRetryAttempts(auth, e.cfg)
|
||||||
|
|
||||||
@@ -754,7 +832,7 @@ func (e *AntigravityExecutor) ExecuteStream(ctx context.Context, auth *cliproxya
|
|||||||
translated = applyPayloadConfigWithRoot(e.cfg, baseModel, "antigravity", "request", translated, originalTranslated, requestedModel)
|
translated = applyPayloadConfigWithRoot(e.cfg, baseModel, "antigravity", "request", translated, originalTranslated, requestedModel)
|
||||||
|
|
||||||
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
||||||
httpClient := newProxyAwareHTTPClient(ctx, e.cfg, auth, 0)
|
httpClient := newAntigravityHTTPClient(ctx, e.cfg, auth, 0)
|
||||||
|
|
||||||
attempts := antigravityRetryAttempts(auth, e.cfg)
|
attempts := antigravityRetryAttempts(auth, e.cfg)
|
||||||
|
|
||||||
@@ -956,7 +1034,7 @@ func (e *AntigravityExecutor) CountTokens(ctx context.Context, auth *cliproxyaut
|
|||||||
payload = deleteJSONField(payload, "request.safetySettings")
|
payload = deleteJSONField(payload, "request.safetySettings")
|
||||||
|
|
||||||
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
||||||
httpClient := newProxyAwareHTTPClient(ctx, e.cfg, auth, 0)
|
httpClient := newAntigravityHTTPClient(ctx, e.cfg, auth, 0)
|
||||||
|
|
||||||
var authID, authLabel, authType, authValue string
|
var authID, authLabel, authType, authValue string
|
||||||
if auth != nil {
|
if auth != nil {
|
||||||
@@ -987,10 +1065,10 @@ func (e *AntigravityExecutor) CountTokens(ctx context.Context, auth *cliproxyaut
|
|||||||
if errReq != nil {
|
if errReq != nil {
|
||||||
return cliproxyexecutor.Response{}, errReq
|
return cliproxyexecutor.Response{}, errReq
|
||||||
}
|
}
|
||||||
|
httpReq.Close = true
|
||||||
httpReq.Header.Set("Content-Type", "application/json")
|
httpReq.Header.Set("Content-Type", "application/json")
|
||||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||||
httpReq.Header.Set("User-Agent", resolveUserAgent(auth))
|
httpReq.Header.Set("User-Agent", resolveUserAgent(auth))
|
||||||
httpReq.Header.Set("Accept", "application/json")
|
|
||||||
if host := resolveHost(base); host != "" {
|
if host := resolveHost(base); host != "" {
|
||||||
httpReq.Host = host
|
httpReq.Host = host
|
||||||
}
|
}
|
||||||
@@ -1084,14 +1162,26 @@ func FetchAntigravityModels(ctx context.Context, auth *cliproxyauth.Auth, cfg *c
|
|||||||
}
|
}
|
||||||
|
|
||||||
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
baseURLs := antigravityBaseURLFallbackOrder(auth)
|
||||||
httpClient := newProxyAwareHTTPClient(ctx, cfg, auth, 0)
|
httpClient := newAntigravityHTTPClient(ctx, cfg, auth, 0)
|
||||||
|
|
||||||
for idx, baseURL := range baseURLs {
|
for idx, baseURL := range baseURLs {
|
||||||
modelsURL := baseURL + antigravityModelsPath
|
modelsURL := baseURL + antigravityModelsPath
|
||||||
httpReq, errReq := http.NewRequestWithContext(ctx, http.MethodPost, modelsURL, bytes.NewReader([]byte(`{}`)))
|
|
||||||
|
var payload []byte
|
||||||
|
if auth != nil && auth.Metadata != nil {
|
||||||
|
if pid, ok := auth.Metadata["project_id"].(string); ok && strings.TrimSpace(pid) != "" {
|
||||||
|
payload = []byte(fmt.Sprintf(`{"project": "%s"}`, strings.TrimSpace(pid)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(payload) == 0 {
|
||||||
|
payload = []byte(`{}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
httpReq, errReq := http.NewRequestWithContext(ctx, http.MethodPost, modelsURL, bytes.NewReader(payload))
|
||||||
if errReq != nil {
|
if errReq != nil {
|
||||||
return fallbackAntigravityPrimaryModels()
|
return fallbackAntigravityPrimaryModels()
|
||||||
}
|
}
|
||||||
|
httpReq.Close = true
|
||||||
httpReq.Header.Set("Content-Type", "application/json")
|
httpReq.Header.Set("Content-Type", "application/json")
|
||||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||||
httpReq.Header.Set("User-Agent", resolveUserAgent(auth))
|
httpReq.Header.Set("User-Agent", resolveUserAgent(auth))
|
||||||
@@ -1174,6 +1264,29 @@ func FetchAntigravityModels(ctx context.Context, auth *cliproxyauth.Auth, cfg *c
|
|||||||
OwnedBy: antigravityAuthType,
|
OwnedBy: antigravityAuthType,
|
||||||
Type: antigravityAuthType,
|
Type: antigravityAuthType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build input modalities from upstream capability flags.
|
||||||
|
inputModalities := []string{"TEXT"}
|
||||||
|
if modelData.Get("supportsImages").Bool() {
|
||||||
|
inputModalities = append(inputModalities, "IMAGE")
|
||||||
|
}
|
||||||
|
if modelData.Get("supportsVideo").Bool() {
|
||||||
|
inputModalities = append(inputModalities, "VIDEO")
|
||||||
|
}
|
||||||
|
modelInfo.SupportedInputModalities = inputModalities
|
||||||
|
modelInfo.SupportedOutputModalities = []string{"TEXT"}
|
||||||
|
|
||||||
|
// Token limits from upstream.
|
||||||
|
if maxTok := modelData.Get("maxTokens").Int(); maxTok > 0 {
|
||||||
|
modelInfo.InputTokenLimit = int(maxTok)
|
||||||
|
}
|
||||||
|
if maxOut := modelData.Get("maxOutputTokens").Int(); maxOut > 0 {
|
||||||
|
modelInfo.OutputTokenLimit = int(maxOut)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supported generation methods (Gemini v1beta convention).
|
||||||
|
modelInfo.SupportedGenerationMethods = []string{"generateContent", "countTokens"}
|
||||||
|
|
||||||
// Look up Thinking support from static config using upstream model name.
|
// Look up Thinking support from static config using upstream model name.
|
||||||
if modelCfg != nil {
|
if modelCfg != nil {
|
||||||
if modelCfg.Thinking != nil {
|
if modelCfg.Thinking != nil {
|
||||||
@@ -1241,10 +1354,11 @@ func (e *AntigravityExecutor) refreshToken(ctx context.Context, auth *cliproxyau
|
|||||||
return auth, errReq
|
return auth, errReq
|
||||||
}
|
}
|
||||||
httpReq.Header.Set("Host", "oauth2.googleapis.com")
|
httpReq.Header.Set("Host", "oauth2.googleapis.com")
|
||||||
httpReq.Header.Set("User-Agent", defaultAntigravityAgent)
|
|
||||||
httpReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
httpReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
// Real Antigravity uses Go's default User-Agent for OAuth token refresh
|
||||||
|
httpReq.Header.Set("User-Agent", "Go-http-client/2.0")
|
||||||
|
|
||||||
httpClient := newProxyAwareHTTPClient(ctx, e.cfg, auth, 0)
|
httpClient := newAntigravityHTTPClient(ctx, e.cfg, auth, 0)
|
||||||
httpResp, errDo := httpClient.Do(httpReq)
|
httpResp, errDo := httpClient.Do(httpReq)
|
||||||
if errDo != nil {
|
if errDo != nil {
|
||||||
return auth, errDo
|
return auth, errDo
|
||||||
@@ -1315,7 +1429,7 @@ func (e *AntigravityExecutor) ensureAntigravityProjectID(ctx context.Context, au
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := newProxyAwareHTTPClient(ctx, e.cfg, auth, 0)
|
httpClient := newAntigravityHTTPClient(ctx, e.cfg, auth, 0)
|
||||||
projectID, errFetch := sdkAuth.FetchAntigravityProjectID(ctx, token, httpClient)
|
projectID, errFetch := sdkAuth.FetchAntigravityProjectID(ctx, token, httpClient)
|
||||||
if errFetch != nil {
|
if errFetch != nil {
|
||||||
return errFetch
|
return errFetch
|
||||||
@@ -1369,7 +1483,7 @@ func (e *AntigravityExecutor) buildRequest(ctx context.Context, auth *cliproxyau
|
|||||||
payload = geminiToAntigravity(modelName, payload, projectID)
|
payload = geminiToAntigravity(modelName, payload, projectID)
|
||||||
payload, _ = sjson.SetBytes(payload, "model", modelName)
|
payload, _ = sjson.SetBytes(payload, "model", modelName)
|
||||||
|
|
||||||
useAntigravitySchema := strings.Contains(modelName, "claude") || strings.Contains(modelName, "gemini-3-pro-high")
|
useAntigravitySchema := strings.Contains(modelName, "claude") || strings.Contains(modelName, "gemini-3-pro") || strings.Contains(modelName, "gemini-3.1-pro")
|
||||||
payloadStr := string(payload)
|
payloadStr := string(payload)
|
||||||
paths := make([]string, 0)
|
paths := make([]string, 0)
|
||||||
util.Walk(gjson.Parse(payloadStr), "", "parametersJsonSchema", &paths)
|
util.Walk(gjson.Parse(payloadStr), "", "parametersJsonSchema", &paths)
|
||||||
@@ -1383,18 +1497,18 @@ func (e *AntigravityExecutor) buildRequest(ctx context.Context, auth *cliproxyau
|
|||||||
payloadStr = util.CleanJSONSchemaForGemini(payloadStr)
|
payloadStr = util.CleanJSONSchemaForGemini(payloadStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if useAntigravitySchema {
|
// if useAntigravitySchema {
|
||||||
systemInstructionPartsResult := gjson.Get(payloadStr, "request.systemInstruction.parts")
|
// systemInstructionPartsResult := gjson.Get(payloadStr, "request.systemInstruction.parts")
|
||||||
payloadStr, _ = sjson.Set(payloadStr, "request.systemInstruction.role", "user")
|
// payloadStr, _ = sjson.Set(payloadStr, "request.systemInstruction.role", "user")
|
||||||
payloadStr, _ = sjson.Set(payloadStr, "request.systemInstruction.parts.0.text", systemInstruction)
|
// payloadStr, _ = sjson.Set(payloadStr, "request.systemInstruction.parts.0.text", systemInstruction)
|
||||||
payloadStr, _ = sjson.Set(payloadStr, "request.systemInstruction.parts.1.text", fmt.Sprintf("Please ignore following [ignore]%s[/ignore]", systemInstruction))
|
// payloadStr, _ = sjson.Set(payloadStr, "request.systemInstruction.parts.1.text", fmt.Sprintf("Please ignore following [ignore]%s[/ignore]", systemInstruction))
|
||||||
|
|
||||||
if systemInstructionPartsResult.Exists() && systemInstructionPartsResult.IsArray() {
|
// if systemInstructionPartsResult.Exists() && systemInstructionPartsResult.IsArray() {
|
||||||
for _, partResult := range systemInstructionPartsResult.Array() {
|
// for _, partResult := range systemInstructionPartsResult.Array() {
|
||||||
payloadStr, _ = sjson.SetRaw(payloadStr, "request.systemInstruction.parts.-1", partResult.Raw)
|
// payloadStr, _ = sjson.SetRaw(payloadStr, "request.systemInstruction.parts.-1", partResult.Raw)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if strings.Contains(modelName, "claude") {
|
if strings.Contains(modelName, "claude") {
|
||||||
payloadStr, _ = sjson.Set(payloadStr, "request.toolConfig.functionCallingConfig.mode", "VALIDATED")
|
payloadStr, _ = sjson.Set(payloadStr, "request.toolConfig.functionCallingConfig.mode", "VALIDATED")
|
||||||
@@ -1406,14 +1520,10 @@ func (e *AntigravityExecutor) buildRequest(ctx context.Context, auth *cliproxyau
|
|||||||
if errReq != nil {
|
if errReq != nil {
|
||||||
return nil, errReq
|
return nil, errReq
|
||||||
}
|
}
|
||||||
|
httpReq.Close = true
|
||||||
httpReq.Header.Set("Content-Type", "application/json")
|
httpReq.Header.Set("Content-Type", "application/json")
|
||||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||||
httpReq.Header.Set("User-Agent", resolveUserAgent(auth))
|
httpReq.Header.Set("User-Agent", resolveUserAgent(auth))
|
||||||
if stream {
|
|
||||||
httpReq.Header.Set("Accept", "text/event-stream")
|
|
||||||
} else {
|
|
||||||
httpReq.Header.Set("Accept", "application/json")
|
|
||||||
}
|
|
||||||
if host := resolveHost(base); host != "" {
|
if host := resolveHost(base); host != "" {
|
||||||
httpReq.Host = host
|
httpReq.Host = host
|
||||||
}
|
}
|
||||||
@@ -1625,7 +1735,16 @@ func resolveCustomAntigravityBaseURL(auth *cliproxyauth.Auth) string {
|
|||||||
func geminiToAntigravity(modelName string, payload []byte, projectID string) []byte {
|
func geminiToAntigravity(modelName string, payload []byte, projectID string) []byte {
|
||||||
template, _ := sjson.Set(string(payload), "model", modelName)
|
template, _ := sjson.Set(string(payload), "model", modelName)
|
||||||
template, _ = sjson.Set(template, "userAgent", "antigravity")
|
template, _ = sjson.Set(template, "userAgent", "antigravity")
|
||||||
template, _ = sjson.Set(template, "requestType", "agent")
|
|
||||||
|
isImageModel := strings.Contains(modelName, "image")
|
||||||
|
|
||||||
|
var reqType string
|
||||||
|
if isImageModel {
|
||||||
|
reqType = "image_gen"
|
||||||
|
} else {
|
||||||
|
reqType = "agent"
|
||||||
|
}
|
||||||
|
template, _ = sjson.Set(template, "requestType", reqType)
|
||||||
|
|
||||||
// Use real project ID from auth if available, otherwise generate random (legacy fallback)
|
// Use real project ID from auth if available, otherwise generate random (legacy fallback)
|
||||||
if projectID != "" {
|
if projectID != "" {
|
||||||
@@ -1633,8 +1752,13 @@ func geminiToAntigravity(modelName string, payload []byte, projectID string) []b
|
|||||||
} else {
|
} else {
|
||||||
template, _ = sjson.Set(template, "project", generateProjectID())
|
template, _ = sjson.Set(template, "project", generateProjectID())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isImageModel {
|
||||||
|
template, _ = sjson.Set(template, "requestId", generateImageGenRequestID())
|
||||||
|
} else {
|
||||||
template, _ = sjson.Set(template, "requestId", generateRequestID())
|
template, _ = sjson.Set(template, "requestId", generateRequestID())
|
||||||
template, _ = sjson.Set(template, "request.sessionId", generateStableSessionID(payload))
|
template, _ = sjson.Set(template, "request.sessionId", generateStableSessionID(payload))
|
||||||
|
}
|
||||||
|
|
||||||
template, _ = sjson.Delete(template, "request.safetySettings")
|
template, _ = sjson.Delete(template, "request.safetySettings")
|
||||||
if toolConfig := gjson.Get(template, "toolConfig"); toolConfig.Exists() && !gjson.Get(template, "request.toolConfig").Exists() {
|
if toolConfig := gjson.Get(template, "toolConfig"); toolConfig.Exists() && !gjson.Get(template, "request.toolConfig").Exists() {
|
||||||
@@ -1648,6 +1772,10 @@ func generateRequestID() string {
|
|||||||
return "agent-" + uuid.NewString()
|
return "agent-" + uuid.NewString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateImageGenRequestID() string {
|
||||||
|
return fmt.Sprintf("image_gen/%d/%s/12", time.Now().UnixMilli(), uuid.NewString())
|
||||||
|
}
|
||||||
|
|
||||||
func generateSessionID() string {
|
func generateSessionID() string {
|
||||||
randSourceMutex.Lock()
|
randSourceMutex.Lock()
|
||||||
n := randSource.Int63n(9_000_000_000_000_000_000)
|
n := randSource.Int63n(9_000_000_000_000_000_000)
|
||||||
|
|||||||
Reference in New Issue
Block a user