@yansigit/opencodex 2.32.0 → 2.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/gui/dist/assets/index-CIDo4y4k.js +102 -0
- package/gui/dist/assets/index-DrSQdTRd.css +1 -0
- package/gui/dist/index.html +2 -2
- package/package.json +8 -5
- package/src/adapters/anthropic.ts +20 -6
- package/src/adapters/azure.ts +20 -4
- package/src/adapters/base.ts +3 -1
- package/src/adapters/command-code.ts +131 -17
- package/src/adapters/cursor/envelope-echo.ts +162 -0
- package/src/adapters/cursor/live-transport.ts +4 -2
- package/src/adapters/cursor/native-exec-fs.ts +13 -12
- package/src/adapters/cursor/native-exec-network.ts +3 -5
- package/src/adapters/cursor/native-exec-policy.ts +47 -0
- package/src/adapters/cursor/native-exec-shell.ts +13 -25
- package/src/adapters/cursor/native-exec.ts +18 -10
- package/src/adapters/cursor/protobuf-events.ts +186 -9
- package/src/adapters/cursor/protobuf-request.ts +53 -18
- package/src/adapters/cursor/request-builder.ts +11 -3
- package/src/adapters/cursor/tool-definitions.ts +49 -2
- package/src/adapters/cursor/tool-result-normalize.ts +21 -8
- package/src/adapters/cursor/types.ts +11 -3
- package/src/adapters/cursor.ts +123 -0
- package/src/adapters/google-aistudio-parser.ts +49 -0
- package/src/adapters/google-antigravity-replay.ts +2 -2
- package/src/adapters/google-antigravity-wire.ts +7 -0
- package/src/adapters/google-errors.ts +6 -2
- package/src/adapters/google-http.ts +30 -7
- package/src/adapters/google-truncation.ts +5 -0
- package/src/adapters/google-wire-compiler.ts +38 -6
- package/src/adapters/google.ts +242 -28
- package/src/adapters/kiro-tools.ts +20 -9
- package/src/adapters/openai-chat.ts +9 -0
- package/src/adapters/openai-responses.ts +2 -1
- package/src/bridge.ts +112 -9
- package/src/chat/inbound.ts +15 -0
- package/src/claude/context-windows.ts +16 -9
- package/src/cli/doctor.ts +2 -2
- package/src/cli/index.ts +10 -3
- package/src/cli/provider.ts +6 -0
- package/src/cli/status.ts +23 -0
- package/src/codex/auth-api.ts +4 -2
- package/src/codex/autostart-health.ts +16 -0
- package/src/codex/catalog/aggregation.ts +12 -12
- package/src/codex/catalog/effort.ts +18 -3
- package/src/codex/catalog/metadata.ts +27 -1
- package/src/codex/catalog/model-metadata.ts +39 -12
- package/src/codex/catalog/parsing.ts +38 -27
- package/src/codex/catalog/provider-fetch.ts +232 -133
- package/src/codex/catalog/sync.ts +1 -1
- package/src/codex/convergence.ts +5 -0
- package/src/codex/shim.ts +56 -3
- package/src/config/provider-validation.ts +37 -0
- package/src/config.ts +78 -2
- package/src/generated/compatibility-version.json +187 -119
- package/src/generated/model-metadata.ts +3 -0
- package/src/images/loop.ts +37 -6
- package/src/lib/azure-identity.ts +154 -0
- package/src/lib/debug.ts +42 -0
- package/src/lib/errors.ts +14 -0
- package/src/lib/provider-outbound.ts +45 -33
- package/src/lib/provider-tls-profile.ts +309 -0
- package/src/lib/proxy-env.ts +49 -0
- package/src/lib/redact.ts +10 -1
- package/src/oauth/aistudio-native-daemon.ts +62 -0
- package/src/oauth/aistudio-session-sync.ts +95 -0
- package/src/oauth/antigravity-routing.ts +282 -236
- package/src/oauth/callback-server.ts +22 -2
- package/src/oauth/command-code.ts +5 -16
- package/src/oauth/google-aistudio-auth.ts +98 -0
- package/src/oauth/google-antigravity.ts +42 -5
- package/src/oauth/index.ts +15 -3
- package/src/oauth/key-providers.ts +8 -0
- package/src/oauth/kimi.ts +9 -1
- package/src/oauth/login-cli.ts +66 -1
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +6 -0
- package/src/providers/antigravity-quota.ts +3 -1
- package/src/providers/api-keys.ts +2 -1
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/derive.ts +5 -1
- package/src/providers/key-failover.ts +5 -1
- package/src/providers/openai-tiers.ts +5 -0
- package/src/providers/provider-id-rewrite.ts +1 -0
- package/src/providers/quota.ts +148 -50
- package/src/providers/registry.ts +27 -4
- package/src/providers/request-pacing.ts +33 -6
- package/src/providers/xai-transport.ts +21 -0
- package/src/responses/google-provider-options.ts +36 -0
- package/src/responses/namespace-tool-compat.ts +84 -4
- package/src/responses/parser.ts +11 -0
- package/src/responses/provider-opaque-metadata.ts +3 -3
- package/src/responses/schema.ts +37 -0
- package/src/responses/state.ts +94 -4
- package/src/router.ts +11 -2
- package/src/routing/account-pool/cooldown.ts +8 -0
- package/src/routing/account-pool/index.ts +1 -0
- package/src/server/aistudio-ws-hub.ts +295 -0
- package/src/server/auth-cors.ts +29 -0
- package/src/server/chat-completions.ts +2 -0
- package/src/server/images.ts +19 -35
- package/src/server/index.ts +94 -0
- package/src/server/management/agent-settings-routes.ts +205 -15
- package/src/server/management/combo-routes.ts +6 -0
- package/src/server/management/config-routes.ts +31 -5
- package/src/server/management/logs-usage-routes.ts +11 -5
- package/src/server/management/model-rows.ts +4 -0
- package/src/server/management/oauth-account-routes.ts +38 -7
- package/src/server/management/provider-routes.ts +113 -15
- package/src/server/management/routing-profile-routes.ts +3 -0
- package/src/server/port-reclaim.ts +19 -1
- package/src/server/request-log-conversation.ts +12 -0
- package/src/server/request-log.ts +23 -1
- package/src/server/responses/agent-task-recovery.ts +1 -1
- package/src/server/responses/compact.ts +30 -1
- package/src/server/responses/core.ts +363 -156
- package/src/server/responses/empty-completion-guard.ts +35 -6
- package/src/server/responses/fetch-helpers.ts +18 -5
- package/src/server/responses/policy-fallback.ts +1 -1
- package/src/server/responses/v2-native-parent-override.ts +59 -0
- package/src/server/responses/ws-upstream.ts +75 -2
- package/src/server/responses-undeclared-tool-guard.ts +90 -8
- package/src/server/ws-bridge.ts +2 -1
- package/src/service.ts +1 -1
- package/src/smoke/fingerprint-cache.ts +133 -0
- package/src/smoke/live-scenarios.ts +33 -0
- package/src/smoke/runner.ts +119 -0
- package/src/types/config.ts +16 -1
- package/src/types/provider.ts +18 -1
- package/src/types/request.ts +30 -0
- package/src/types/tools.ts +51 -0
- package/src/types.ts +6 -0
- package/src/usage/command-code-manifest.ts +116 -0
- package/src/usage/cost.ts +2 -2
- package/src/usage/expected-prices.ts +83 -0
- package/src/usage/log.ts +2 -2
- package/src/usage/summary.ts +34 -12
- package/src/web-search/gemini-executor.ts +6 -4
- package/src/web-search/index.ts +16 -8
- package/src/web-search/loop.ts +42 -6
- package/gui/dist/assets/index-BG43zwVe.js +0 -102
- package/gui/dist/assets/index-CiSI-jrP.css +0 -1
package/src/adapters/google.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { AdapterFetchContext, AdapterRequest, ProviderAdapter } from "./base";
|
|
1
|
+
import type { AdapterFetchContext, AdapterRequest, IncomingMeta, ProviderAdapter } from "./base";
|
|
2
2
|
import { debugDroppedFrame } from "../lib/debug";
|
|
3
3
|
import { createToolCallIdAllocator } from "./tool-call-id";
|
|
4
4
|
import { createImageBudget, materializeInlineImage, MAX_ENCODED_BYTES_PER_IMAGE, artifactHttpUrl } from "../images/artifacts";
|
|
5
|
+
import { OcxRequestValidationError } from "../lib/errors";
|
|
5
6
|
import type {
|
|
6
7
|
AdapterEvent,
|
|
7
8
|
OcxAssistantMessage,
|
|
@@ -19,8 +20,9 @@ import { contentPartsToText, parseDataUrl } from "./image";
|
|
|
19
20
|
import { getVertexAccessToken } from "../lib/gcp-adc";
|
|
20
21
|
import { fetchAntigravityWithRetry, fetchVertexWithRetry } from "./google-http";
|
|
21
22
|
import { safeAntigravityHttpErrorMessage, safeVertexHttpErrorMessage } from "./google-errors";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
23
|
+
import { sanitizeUpstreamErrorText } from "./upstream-http-error";
|
|
24
|
+
import { googleTruncationErrorMessage, isVertexTruncatedTurn, vertexTruncationErrorMessage } from "./google-truncation";
|
|
25
|
+
import { ANTIGRAVITY_REQUEST_UA, ANTIGRAVITY_SIGNATURE_BYPASS_SENTINEL, antigravitySessionId, isLikelyRealThoughtSignature, sanitizeAntigravityClaudeSignatures } from "./google-antigravity-wire";
|
|
24
26
|
import { repairGoogleToolPairs, stripTrailingClaudePrefill } from "./google-antigravity-tools";
|
|
25
27
|
import { canonicalAntigravityHttpsHost, isAntigravityHttpsHost } from "./google-antigravity-hosts";
|
|
26
28
|
import { compileGoogleWireBody } from "./google-wire-compiler";
|
|
@@ -45,6 +47,20 @@ import {
|
|
|
45
47
|
} from "../lib/translator-budget";
|
|
46
48
|
import { buildNonOpenAIToolCatalogNudgeForTools } from "./tool-catalog-nudge";
|
|
47
49
|
import { configuredReasoningEfforts, mapReasoningEffort } from "../reasoning-effort";
|
|
50
|
+
import { normalizeAntigravityProviderError } from "../oauth/antigravity-routing";
|
|
51
|
+
import { buildAiStudioHeaders, parseGoogleCookieJar } from "../oauth/google-aistudio-auth";
|
|
52
|
+
import { cookieHeaderFromSession, loadAiStudioSession } from "../oauth/aistudio-session-sync";
|
|
53
|
+
import { parseMakerSuiteChunk } from "./google-aistudio-parser";
|
|
54
|
+
import { globalAiStudioRelayHub } from "../server/aistudio-ws-hub";
|
|
55
|
+
|
|
56
|
+
const INLINE_ERROR_URL_USERINFO = /https?:\/\/[^\s"'<>]*@/gi;
|
|
57
|
+
|
|
58
|
+
function safeAntigravityInlineErrorMessage(value: unknown): string | undefined {
|
|
59
|
+
if (typeof value !== "string") return undefined;
|
|
60
|
+
return sanitizeUpstreamErrorText(value)
|
|
61
|
+
.replace(INLINE_ERROR_URL_USERINFO, "[REDACTED_URL]")
|
|
62
|
+
.slice(0, 500);
|
|
63
|
+
}
|
|
48
64
|
|
|
49
65
|
// Google-family models (Gemini/Vertex/Antigravity) tend to emit long running commentary between
|
|
50
66
|
// tool calls. This steers them to keep the BETWEEN-STEP text to one line and reason internally
|
|
@@ -139,6 +155,19 @@ const GEMINI_EMPTY_PLACEHOLDER = "(empty)";
|
|
|
139
155
|
const GEMINI_EMPTY_TOOL_OUTPUT_PLACEHOLDER = "(empty tool output)";
|
|
140
156
|
const GEMINI_MISSING_TOOL_RESULT = "[missing tool_result for this tool_use in history]";
|
|
141
157
|
|
|
158
|
+
function appendGeminiContent(
|
|
159
|
+
contents: unknown[],
|
|
160
|
+
next: { role: string; parts: unknown[] },
|
|
161
|
+
mergeAdjacentUsers = true,
|
|
162
|
+
): void {
|
|
163
|
+
const previous = contents.at(-1) as { role?: unknown; parts?: unknown[] } | undefined;
|
|
164
|
+
if (mergeAdjacentUsers && previous?.role === "user" && next.role === "user" && Array.isArray(previous.parts)) {
|
|
165
|
+
previous.parts.push(...next.parts);
|
|
166
|
+
} else {
|
|
167
|
+
contents.push(next);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
142
171
|
/** A Gemini text part, or undefined when the value cannot form a valid non-empty text block. */
|
|
143
172
|
function geminiTextPart(text: unknown): { text: string } | undefined {
|
|
144
173
|
return typeof text === "string" && text.length > 0 ? { text } : undefined;
|
|
@@ -208,6 +237,11 @@ function messagesToGeminiFormat(
|
|
|
208
237
|
const systemInstruction = { parts: [{ text: systemText }] };
|
|
209
238
|
|
|
210
239
|
const contents: unknown[] = [];
|
|
240
|
+
let userMergeBarrier = false;
|
|
241
|
+
const appendContent = (next: { role: string; parts: unknown[] }): void => {
|
|
242
|
+
appendGeminiContent(contents, next, !userMergeBarrier);
|
|
243
|
+
userMergeBarrier = false;
|
|
244
|
+
};
|
|
211
245
|
const messages = repairGoogleToolPairs(parsed.context.messages, { dropUnmatchedCalls: repairToolPairs });
|
|
212
246
|
|
|
213
247
|
const callIds = createToolCallIdAllocator();
|
|
@@ -226,7 +260,7 @@ function messagesToGeminiFormat(
|
|
|
226
260
|
case "user":
|
|
227
261
|
case "developer": {
|
|
228
262
|
if (typeof msg.content === "string") {
|
|
229
|
-
|
|
263
|
+
appendContent({ role: "user", parts: [{ text: msg.content || GEMINI_EMPTY_PLACEHOLDER }] });
|
|
230
264
|
} else {
|
|
231
265
|
const parts: unknown[] = [];
|
|
232
266
|
for (const p of msg.content as OcxContentPart[]) {
|
|
@@ -241,7 +275,7 @@ function messagesToGeminiFormat(
|
|
|
241
275
|
const textPart = geminiTextPart(p.text);
|
|
242
276
|
if (textPart) parts.push(textPart);
|
|
243
277
|
}
|
|
244
|
-
|
|
278
|
+
appendContent({ role: "user", parts: parts.length > 0 ? parts : [{ text: GEMINI_EMPTY_PLACEHOLDER }] });
|
|
245
279
|
}
|
|
246
280
|
break;
|
|
247
281
|
}
|
|
@@ -291,8 +325,11 @@ function messagesToGeminiFormat(
|
|
|
291
325
|
// A turn with nothing Gemini can represent (e.g. thinking-only) would serialize as
|
|
292
326
|
// `parts: []`, which the Anthropic translation rejects. Skip it, as the Anthropic
|
|
293
327
|
// adapter does for its own empty assistant content.
|
|
294
|
-
if (parts.length === 0)
|
|
295
|
-
|
|
328
|
+
if (parts.length === 0) {
|
|
329
|
+
userMergeBarrier = true;
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
appendContent({ role: "model", parts });
|
|
296
333
|
if (toolCalls.length > 0) {
|
|
297
334
|
// Gemini/Claude-on-Antigravity requires one adjacent response batch for the whole
|
|
298
335
|
// function-call turn. Replayed histories can be interrupted, reversed, duplicated, or
|
|
@@ -321,7 +358,7 @@ function messagesToGeminiFormat(
|
|
|
321
358
|
for (const orphan of orphanResults) {
|
|
322
359
|
responseParts.push(...geminiOrphanToolResultParts(orphan));
|
|
323
360
|
}
|
|
324
|
-
|
|
361
|
+
appendContent({ role: "user", parts: responseParts });
|
|
325
362
|
i = j - 1;
|
|
326
363
|
}
|
|
327
364
|
break;
|
|
@@ -332,7 +369,7 @@ function messagesToGeminiFormat(
|
|
|
332
369
|
// batch never reach here (the assistant branch consumes them). Standalone or
|
|
333
370
|
// barrier-delayed results still have to stay visible — especially image-bearing
|
|
334
371
|
// screenshots — as explicit user text rather than vanishing or 400ing CCA.
|
|
335
|
-
|
|
372
|
+
appendContent({ role: "user", parts: geminiOrphanToolResultParts(msg as OcxToolResultMessage) });
|
|
336
373
|
break;
|
|
337
374
|
}
|
|
338
375
|
}
|
|
@@ -395,6 +432,13 @@ function usageFromGemini(usage: Record<string, number> | undefined): OcxUsage |
|
|
|
395
432
|
};
|
|
396
433
|
}
|
|
397
434
|
|
|
435
|
+
function googlePromptFeedbackError(root: Record<string, unknown>): Extract<AdapterEvent, { type: "error" }> | undefined {
|
|
436
|
+
const feedback = root.promptFeedback;
|
|
437
|
+
if (!isGoogleRecord(feedback) || typeof feedback.blockReason !== "string" || !feedback.blockReason.trim()) return undefined;
|
|
438
|
+
const reason = sanitizeUpstreamErrorText(feedback.blockReason).slice(0, 160);
|
|
439
|
+
return { type: "error", message: `google response blocked by prompt feedback: ${reason}` };
|
|
440
|
+
}
|
|
441
|
+
|
|
398
442
|
/**
|
|
399
443
|
* Cap on the buffered non-streaming response body (100 MiB), matching
|
|
400
444
|
* IMAGES_RESPONSE_MAX_BYTES in src/server/images.ts. Enforced by streaming the
|
|
@@ -500,6 +544,21 @@ function googlePartThoughtSignature(part: GoogleResponsePart): string | undefine
|
|
|
500
544
|
return typeof nested === "string" && nested.length > 0 ? nested : undefined;
|
|
501
545
|
}
|
|
502
546
|
|
|
547
|
+
function ensureThoughtSignatureBypassSentinel(contents: unknown[], modelId?: string): void {
|
|
548
|
+
if (modelId && !/gemini-(?:3.7|2.5)|thinking/i.test(modelId)) return;
|
|
549
|
+
for (const c of contents as { role?: string; parts?: unknown[] }[]) {
|
|
550
|
+
if (c?.role !== "model" || !Array.isArray(c.parts)) continue;
|
|
551
|
+
for (const p of c.parts) {
|
|
552
|
+
if (p && typeof p === "object") {
|
|
553
|
+
const partObj = p as Record<string, unknown>;
|
|
554
|
+
if (partObj.functionCall && !partObj.thoughtSignature && !partObj.thought_signature) {
|
|
555
|
+
partObj.thoughtSignature = ANTIGRAVITY_SIGNATURE_BYPASS_SENTINEL;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
503
562
|
/**
|
|
504
563
|
* Carry a Gemini thought signature with the exact function-call part that produced it. Google
|
|
505
564
|
* validates the signature against that specific part, so it must ride the individual tool call
|
|
@@ -672,6 +731,7 @@ function invalidGoogleShapeEvent(
|
|
|
672
731
|
export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapter {
|
|
673
732
|
// Per-request closure: resolveAdapter builds a fresh adapter per request (server.ts), so buildRequest
|
|
674
733
|
// can stash the CCA model/session for parseStream's reasoning-replay observation.
|
|
734
|
+
let observeProviderError: IncomingMeta["onProviderError"];
|
|
675
735
|
let antigravityModel: string | undefined;
|
|
676
736
|
let antigravitySession: string | undefined;
|
|
677
737
|
// Vertex returns the same opaque Gemini thought signatures as CCA, but its replay namespace
|
|
@@ -681,14 +741,68 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
681
741
|
let vertexReplaySession: string | undefined;
|
|
682
742
|
let restoreGoogleToolName = (name: string): string => name;
|
|
683
743
|
const emitInTurnGroundingSourcesQueue: boolean[] = [];
|
|
744
|
+
const truncationErrorMessage = provider.googleMode === "vertex" || provider.googleMode === "cloud-code-assist"
|
|
745
|
+
? vertexTruncationErrorMessage
|
|
746
|
+
: googleTruncationErrorMessage;
|
|
684
747
|
return {
|
|
685
748
|
name: "google",
|
|
749
|
+
validateRequest(parsed: OcxParsedRequest) {
|
|
750
|
+
if (provider.googleMode === "cloud-code-assist" && parsed.options.providerOptions?.google) {
|
|
751
|
+
throw new OcxRequestValidationError("provider_options.google is not supported on Google Cloud Code Assist routes");
|
|
752
|
+
}
|
|
753
|
+
const googleOptions = parsed.options.providerOptions?.google;
|
|
754
|
+
if (isImageCapableModel(parsed.modelId)
|
|
755
|
+
&& (googleOptions?.thinkingBudget !== undefined || googleOptions?.includeThoughts !== undefined)) {
|
|
756
|
+
throw new OcxRequestValidationError(
|
|
757
|
+
"provider_options.google thinking_budget and include_thoughts are not supported for image-capable Gemini models",
|
|
758
|
+
);
|
|
759
|
+
}
|
|
760
|
+
},
|
|
686
761
|
|
|
687
762
|
// Vertex + Antigravity get Kiro-style retry/timeout + classified, redacted errors.
|
|
688
763
|
// Direct AI-Studio uses the canonical server transport (fetchWithTransientRetry), which
|
|
689
764
|
// retries transient 5xx responses through providerFetch while preserving multi-key pool
|
|
690
765
|
// 429 rotation and raw error formatting.
|
|
691
|
-
...(provider.googleMode === "
|
|
766
|
+
...(provider.googleMode === "ai-studio-web"
|
|
767
|
+
? {
|
|
768
|
+
fetchResponse: async (request: AdapterRequest, ctx?: AdapterFetchContext): Promise<Response> => {
|
|
769
|
+
if (globalAiStudioRelayHub.hasActiveSessions()) {
|
|
770
|
+
const streamRes = await globalAiStudioRelayHub.dispatchStream(
|
|
771
|
+
{
|
|
772
|
+
url: request.url,
|
|
773
|
+
method: request.method,
|
|
774
|
+
headers: request.headers,
|
|
775
|
+
body: request.body,
|
|
776
|
+
},
|
|
777
|
+
ctx?.abortSignal,
|
|
778
|
+
);
|
|
779
|
+
const encoder = new TextEncoder();
|
|
780
|
+
const bodyStream = new ReadableStream({
|
|
781
|
+
async start(controller) {
|
|
782
|
+
try {
|
|
783
|
+
for await (const chunk of streamRes.chunks) {
|
|
784
|
+
controller.enqueue(encoder.encode(chunk));
|
|
785
|
+
}
|
|
786
|
+
controller.close();
|
|
787
|
+
} catch (err) {
|
|
788
|
+
controller.error(err);
|
|
789
|
+
}
|
|
790
|
+
},
|
|
791
|
+
});
|
|
792
|
+
return new Response(bodyStream, {
|
|
793
|
+
status: 200,
|
|
794
|
+
headers: { "Content-Type": "text/event-stream" },
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
return fetch(request.url, {
|
|
798
|
+
method: request.method,
|
|
799
|
+
headers: request.headers,
|
|
800
|
+
body: request.body,
|
|
801
|
+
signal: ctx?.abortSignal,
|
|
802
|
+
});
|
|
803
|
+
},
|
|
804
|
+
}
|
|
805
|
+
: provider.googleMode === "vertex" || provider.googleMode === "cloud-code-assist"
|
|
692
806
|
? {
|
|
693
807
|
fetchResponse: (request: AdapterRequest, ctx?: AdapterFetchContext): Promise<Response> =>
|
|
694
808
|
(provider.googleMode === "cloud-code-assist" ? fetchAntigravityWithRetry : fetchVertexWithRetry)(request, ctx),
|
|
@@ -697,7 +811,8 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
697
811
|
}
|
|
698
812
|
: {}),
|
|
699
813
|
|
|
700
|
-
async buildRequest(parsed: OcxParsedRequest) {
|
|
814
|
+
async buildRequest(parsed: OcxParsedRequest, options?: IncomingMeta) {
|
|
815
|
+
observeProviderError = options?.onProviderError;
|
|
701
816
|
const routedModelId = provider.googleMode === "cloud-code-assist"
|
|
702
817
|
? resolveAntigravityEffortWireModel(
|
|
703
818
|
parsed.modelId,
|
|
@@ -723,6 +838,9 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
723
838
|
// catalog is a guaranteed upstream 400.
|
|
724
839
|
const toolConfig = tools ? toolChoiceToGeminiToolConfig(parsed) : undefined;
|
|
725
840
|
if (toolConfig) body.toolConfig = toolConfig;
|
|
841
|
+
const googleOptions = parsed.options.providerOptions?.google;
|
|
842
|
+
if (googleOptions?.safetySettings) body.safetySettings = googleOptions.safetySettings;
|
|
843
|
+
if (googleOptions?.cachedContent) body.cachedContent = googleOptions.cachedContent;
|
|
726
844
|
|
|
727
845
|
const generationConfig: Record<string, unknown> = {};
|
|
728
846
|
if (parsed.options.maxOutputTokens) generationConfig.maxOutputTokens = parsed.options.maxOutputTokens;
|
|
@@ -744,7 +862,13 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
744
862
|
const thinkingLevel = thinkingEligible
|
|
745
863
|
? mapReasoningEffort(provider, parsed.modelId, parsed.options.reasoning)
|
|
746
864
|
: undefined;
|
|
747
|
-
if (
|
|
865
|
+
if (!isImageCapableModel(parsed.modelId)) {
|
|
866
|
+
const thinkingConfig: Record<string, unknown> = {};
|
|
867
|
+
if (googleOptions?.thinkingBudget !== undefined) thinkingConfig.thinkingBudget = googleOptions.thinkingBudget;
|
|
868
|
+
else if (thinkingLevel) thinkingConfig.thinkingLevel = thinkingLevel;
|
|
869
|
+
if (googleOptions?.includeThoughts !== undefined) thinkingConfig.includeThoughts = googleOptions.includeThoughts;
|
|
870
|
+
if (Object.keys(thinkingConfig).length > 0) generationConfig.thinkingConfig = thinkingConfig;
|
|
871
|
+
}
|
|
748
872
|
if (!generationConfig.thinkingConfig && isImageCapableModel(parsed.modelId)) {
|
|
749
873
|
generationConfig.responseModalities = ["TEXT", "IMAGE"];
|
|
750
874
|
}
|
|
@@ -816,6 +940,7 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
816
940
|
const strippedModelTail = /claude/i.test(wireModelId) ? stripTrailingClaudePrefill(contents) : false;
|
|
817
941
|
if (antigravityUsesReplayCache(wireModelId)) {
|
|
818
942
|
applyAntigravityReplay(wireModelId, sessionId, contents);
|
|
943
|
+
ensureThoughtSignatureBypassSentinel(contents);
|
|
819
944
|
} else {
|
|
820
945
|
sanitizeAntigravityClaudeSignatures(contents);
|
|
821
946
|
}
|
|
@@ -891,6 +1016,22 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
891
1016
|
return { url, method: "POST", headers, body: JSON.stringify(compiled.body) };
|
|
892
1017
|
}
|
|
893
1018
|
|
|
1019
|
+
if (provider.googleMode === "ai-studio-web") {
|
|
1020
|
+
const base = (provider.baseUrl || "https://alkalimakersuite-pa.clients6.google.com").replace(/\/+$/, "");
|
|
1021
|
+
const url = `${base}/v1internal:${method}${streamParam}`;
|
|
1022
|
+
const cookieInput = provider.apiKey || provider.headers?.["Cookie"] || cookieHeaderFromSession(loadAiStudioSession()) || "";
|
|
1023
|
+
const jar = parseGoogleCookieJar(cookieInput);
|
|
1024
|
+
const aiStudioHeaders = await buildAiStudioHeaders(jar, "https://aistudio.google.com");
|
|
1025
|
+
Object.assign(headers, aiStudioHeaders);
|
|
1026
|
+
const compiled = compileGoogleWireBody({ ...body, model: routedModelId });
|
|
1027
|
+
restoreGoogleToolName = compiled.restoreToolName;
|
|
1028
|
+
if (Array.isArray((compiled.body as { contents?: unknown[] }).contents)) {
|
|
1029
|
+
ensureThoughtSignatureBypassSentinel((compiled.body as { contents: unknown[] }).contents, routedModelId);
|
|
1030
|
+
}
|
|
1031
|
+
emitInTurnGroundingSourcesQueue.push(!!parsed._ccaInTurnGrounding);
|
|
1032
|
+
return { url, method: "POST", headers, body: JSON.stringify(compiled.body) };
|
|
1033
|
+
}
|
|
1034
|
+
|
|
894
1035
|
// ai-studio (default): Generative Language API + x-goog-api-key.
|
|
895
1036
|
const url = `${provider.baseUrl}/v1beta/models/${routedModelId}:${method}${streamParam}`;
|
|
896
1037
|
const apiKey = provider.apiKey?.trim();
|
|
@@ -899,6 +1040,9 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
899
1040
|
|
|
900
1041
|
const compiled = compileGoogleWireBody(body);
|
|
901
1042
|
restoreGoogleToolName = compiled.restoreToolName;
|
|
1043
|
+
if (Array.isArray((compiled.body as { contents?: unknown[] }).contents)) {
|
|
1044
|
+
ensureThoughtSignatureBypassSentinel((compiled.body as { contents: unknown[] }).contents, routedModelId);
|
|
1045
|
+
}
|
|
902
1046
|
emitInTurnGroundingSourcesQueue.push(!!parsed._ccaInTurnGrounding);
|
|
903
1047
|
return { url, method: "POST", headers, body: JSON.stringify(compiled.body) };
|
|
904
1048
|
},
|
|
@@ -970,17 +1114,31 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
970
1114
|
|
|
971
1115
|
// Inline provider error inside a 200 stream → terminal error (see openai-chat.ts).
|
|
972
1116
|
if (chunk.error) {
|
|
973
|
-
const
|
|
1117
|
+
const rawError = chunk.error as { code?: unknown; status?: unknown; message?: unknown };
|
|
1118
|
+
const safeMessage = safeAntigravityInlineErrorMessage(rawError.message);
|
|
1119
|
+
const error = normalizeAntigravityProviderError({
|
|
1120
|
+
code: rawError.code,
|
|
1121
|
+
status: rawError.status,
|
|
1122
|
+
message: safeMessage,
|
|
1123
|
+
});
|
|
1124
|
+
if (provider.googleMode === "cloud-code-assist" && error) observeProviderError?.(error);
|
|
1125
|
+
const err = { ...(error ?? {}), message: error?.message ?? safeMessage ?? "upstream error" };
|
|
974
1126
|
// Clear-on-invalid: a signature rejection means our replayed thoughtSignatures are stale.
|
|
975
1127
|
// Drop the cache entry so the next turn starts clean instead of re-injecting a bad sig.
|
|
976
1128
|
const replayModel = provider.googleMode === "cloud-code-assist" ? antigravityModel : vertexReplayModel;
|
|
977
1129
|
const replaySession = provider.googleMode === "cloud-code-assist" ? antigravitySession : vertexReplaySession;
|
|
978
1130
|
if ((provider.googleMode === "cloud-code-assist" || provider.googleMode === "vertex")
|
|
979
1131
|
&& replayModel && replaySession
|
|
1132
|
+
&& !/missing.*thought_signature/i.test(err?.message ?? "")
|
|
980
1133
|
&& /signature|invalid_argument|invalid argument/i.test(err?.message ?? "")) {
|
|
981
1134
|
clearAntigravityReplay(replayModel, replaySession);
|
|
982
1135
|
}
|
|
983
|
-
yield {
|
|
1136
|
+
yield {
|
|
1137
|
+
type: "error",
|
|
1138
|
+
...(error?.status !== undefined ? { status: error.status } : {}),
|
|
1139
|
+
...(error?.code ? { code: error.code } : {}),
|
|
1140
|
+
message: err.message ?? "upstream error",
|
|
1141
|
+
};
|
|
984
1142
|
return "terminate";
|
|
985
1143
|
}
|
|
986
1144
|
|
|
@@ -1010,7 +1168,14 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1010
1168
|
// absent key and an empty array are already skipped here; `null` joins them. A non-null
|
|
1011
1169
|
// non-array container is still claimed structure the parser cannot read, and stays
|
|
1012
1170
|
// terminal.
|
|
1013
|
-
if (rawCandidates === undefined || rawCandidates === null)
|
|
1171
|
+
if (rawCandidates === undefined || rawCandidates === null) {
|
|
1172
|
+
const feedbackError = googlePromptFeedbackError(root);
|
|
1173
|
+
if (feedbackError) {
|
|
1174
|
+
yield feedbackError;
|
|
1175
|
+
return "terminate";
|
|
1176
|
+
}
|
|
1177
|
+
return "continue";
|
|
1178
|
+
}
|
|
1014
1179
|
if (!Array.isArray(rawCandidates)) {
|
|
1015
1180
|
yield invalidGoogleShapeEvent({
|
|
1016
1181
|
reason: "candidates_not_array",
|
|
@@ -1018,7 +1183,14 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1018
1183
|
});
|
|
1019
1184
|
return "terminate";
|
|
1020
1185
|
}
|
|
1021
|
-
if (rawCandidates.length === 0)
|
|
1186
|
+
if (rawCandidates.length === 0) {
|
|
1187
|
+
const feedbackError = googlePromptFeedbackError(root);
|
|
1188
|
+
if (feedbackError) {
|
|
1189
|
+
yield feedbackError;
|
|
1190
|
+
return "terminate";
|
|
1191
|
+
}
|
|
1192
|
+
return "continue";
|
|
1193
|
+
}
|
|
1022
1194
|
const rawCandidate = rawCandidates[0];
|
|
1023
1195
|
if (!isGoogleRecord(rawCandidate)) {
|
|
1024
1196
|
// Unlike a root `data: null` keepalive, this is a claimed response candidate. Treat it
|
|
@@ -1086,7 +1258,7 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1086
1258
|
if (parts) {
|
|
1087
1259
|
for (const part of parts) {
|
|
1088
1260
|
const sig = googlePartThoughtSignature(part);
|
|
1089
|
-
if (part.thought === true
|
|
1261
|
+
if (sig && isLikelyRealThoughtSignature(sig) && (part.thought === true || !part.functionCall)) {
|
|
1090
1262
|
pendingStreamThoughtSig = sig;
|
|
1091
1263
|
}
|
|
1092
1264
|
const textEvent = googlePartTextEvent(part, filterCcaSearchSuggestionHtml);
|
|
@@ -1173,6 +1345,16 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1173
1345
|
if (result === "content") sawContentEvent = true;
|
|
1174
1346
|
continue;
|
|
1175
1347
|
}
|
|
1348
|
+
if (provider.googleMode === "ai-studio-web") {
|
|
1349
|
+
const parsed = parseMakerSuiteChunk(line);
|
|
1350
|
+
if (parsed.text) {
|
|
1351
|
+
sawAnyFrame = true;
|
|
1352
|
+
sawTerminalSignal = true;
|
|
1353
|
+
sawContentEvent = true;
|
|
1354
|
+
yield { type: "text_delta", text: parsed.text };
|
|
1355
|
+
continue;
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1176
1358
|
sawLiveness = true;
|
|
1177
1359
|
if (line.startsWith(":") || !line.trim()) continue;
|
|
1178
1360
|
debugDroppedFrame("google", line);
|
|
@@ -1185,15 +1367,31 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1185
1367
|
if (residual.startsWith(":")) {
|
|
1186
1368
|
yield { type: "heartbeat" };
|
|
1187
1369
|
} else if (!residual.startsWith("data:")) {
|
|
1188
|
-
|
|
1370
|
+
try {
|
|
1371
|
+
const parsedErr = JSON.parse(residual);
|
|
1372
|
+
if (parsedErr.error?.message) {
|
|
1373
|
+
yield { type: "error", message: parsedErr.error.message };
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
} catch (err) {
|
|
1377
|
+
void err;
|
|
1378
|
+
}
|
|
1379
|
+
if (provider.googleMode === "ai-studio-web") {
|
|
1380
|
+
const parsed = parseMakerSuiteChunk(residual);
|
|
1381
|
+
if (parsed.text) {
|
|
1382
|
+
yield { type: "text_delta", text: parsed.text };
|
|
1383
|
+
yield { type: "done" };
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
yield { type: "error", message: `upstream non-SSE response: ${residual.slice(0, 300)}` };
|
|
1189
1388
|
return;
|
|
1190
1389
|
} else if ((yield* handleDataLine(residual)) === "terminate") return;
|
|
1191
1390
|
}
|
|
1192
1391
|
// Fail-closed: a turn cut off mid tool call (MAX_TOKENS / MALFORMED_FUNCTION_CALL) surfaces
|
|
1193
1392
|
// an error instead of a silently-incomplete done. Mirrors kiro-truncation.
|
|
1194
|
-
if ((
|
|
1195
|
-
|
|
1196
|
-
yield { type: "error", message: vertexTruncationErrorMessage(lastFinishReason) };
|
|
1393
|
+
if (isVertexTruncatedTurn(lastFinishReason, toolCallsStarted)) {
|
|
1394
|
+
yield { type: "error", message: truncationErrorMessage(lastFinishReason) };
|
|
1197
1395
|
return;
|
|
1198
1396
|
}
|
|
1199
1397
|
if (!sawAnyFrame || !sawTerminalSignal) {
|
|
@@ -1237,7 +1435,8 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1237
1435
|
// Cloud Code Assist exposes only the SSE transport. Unary callers still use this
|
|
1238
1436
|
// buffered adapter entry point, so collect the exact same events parseStream emits
|
|
1239
1437
|
// instead of maintaining a second CCA JSON parser.
|
|
1240
|
-
|
|
1438
|
+
const isSse = response.headers.get("content-type")?.includes("text/event-stream") ?? false;
|
|
1439
|
+
if ((provider.googleMode === "cloud-code-assist" && isSse) || provider.googleMode === "ai-studio-web") {
|
|
1241
1440
|
const events: AdapterEvent[] = [];
|
|
1242
1441
|
let previousTail: AdapterEvent | undefined;
|
|
1243
1442
|
try {
|
|
@@ -1326,10 +1525,24 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1326
1525
|
return events;
|
|
1327
1526
|
};
|
|
1328
1527
|
if (raw.error) {
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1528
|
+
const rawError = raw.error as { code?: unknown; status?: unknown; message?: unknown };
|
|
1529
|
+
const safeMessage = safeAntigravityInlineErrorMessage(rawError.message);
|
|
1530
|
+
const error = normalizeAntigravityProviderError({
|
|
1531
|
+
code: rawError.code,
|
|
1532
|
+
status: rawError.status,
|
|
1533
|
+
message: safeMessage,
|
|
1534
|
+
});
|
|
1535
|
+
if (error) observeProviderError?.(error);
|
|
1536
|
+
return finish([{
|
|
1537
|
+
type: "error",
|
|
1538
|
+
...(error?.status !== undefined ? { status: error.status } : {}),
|
|
1539
|
+
...(error?.code ? { code: error.code } : {}),
|
|
1540
|
+
message: error?.message ?? safeMessage ?? "upstream error",
|
|
1541
|
+
}]);
|
|
1331
1542
|
}
|
|
1332
|
-
const json = raw
|
|
1543
|
+
const json = (provider.googleMode === "cloud-code-assist" && raw.response && typeof raw.response === "object" && !Array.isArray(raw.response))
|
|
1544
|
+
? (raw.response as Record<string, unknown>)
|
|
1545
|
+
: raw;
|
|
1333
1546
|
const events: AdapterEvent[] = [];
|
|
1334
1547
|
|
|
1335
1548
|
const rawCandidates: unknown = json.candidates;
|
|
@@ -1345,6 +1558,8 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1345
1558
|
}
|
|
1346
1559
|
const candidates = rawCandidates as { finishReason?: string }[] | undefined;
|
|
1347
1560
|
if (!candidates?.length) {
|
|
1561
|
+
const feedbackError = googlePromptFeedbackError(json);
|
|
1562
|
+
if (feedbackError) return finish([feedbackError]);
|
|
1348
1563
|
return finish([{ type: "error", message: "google response contained no candidates" }]);
|
|
1349
1564
|
}
|
|
1350
1565
|
const rawCandidate: unknown = candidates[0];
|
|
@@ -1417,9 +1632,8 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1417
1632
|
|
|
1418
1633
|
// Fail-closed truncation, same as the stream path: a non-stream turn cut off mid tool call
|
|
1419
1634
|
// (MAX_TOKENS / MALFORMED_FUNCTION_CALL) surfaces an error instead of a silent done.
|
|
1420
|
-
if (
|
|
1421
|
-
|
|
1422
|
-
return finish([{ type: "error", message: vertexTruncationErrorMessage(candidate.finishReason) }]);
|
|
1635
|
+
if (isVertexTruncatedTurn(candidate.finishReason, toolCallsStarted)) {
|
|
1636
|
+
return finish([{ type: "error", message: truncationErrorMessage(candidate.finishReason) }]);
|
|
1423
1637
|
}
|
|
1424
1638
|
|
|
1425
1639
|
const usage = json.usageMetadata as Record<string, number> | undefined;
|
|
@@ -172,6 +172,12 @@ function omittedToolCatalogNotice(kept: number, omitted: readonly OcxTool[], reg
|
|
|
172
172
|
return `[opencodex] Kiro's outbound catalog budget allows ${kept} of ${kept + omitted.length} client tools this turn. Omitted and unavailable this turn: ${summary}.`;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
function boundedCatalogPriority(tool: OcxTool): number {
|
|
176
|
+
if (tool.loadedFromToolSearch) return 0;
|
|
177
|
+
if (tool.toolSearch) return 1;
|
|
178
|
+
return 2;
|
|
179
|
+
}
|
|
180
|
+
|
|
175
181
|
export function convertKiroToolContext(
|
|
176
182
|
parsed: OcxParsedRequest,
|
|
177
183
|
registry: KiroToolNameRegistry = createKiroToolNameRegistry(),
|
|
@@ -181,9 +187,7 @@ export function convertKiroToolContext(
|
|
|
181
187
|
// Validate every listed name even when tool_choice:none emulates a tool-free turn.
|
|
182
188
|
for (const tool of tools) registry.alias(namespacedToolName(tool.namespace, tool.name));
|
|
183
189
|
const effectiveTools = parsed.options.toolChoice === "none" ? [] : tools;
|
|
184
|
-
const
|
|
185
|
-
let omittedAt = effectiveTools.length;
|
|
186
|
-
for (const [index, tool] of effectiveTools.entries()) {
|
|
190
|
+
const convertedEntries = effectiveTools.map((tool, index) => {
|
|
187
191
|
const description = tool.description || `Tool: ${tool.name}`;
|
|
188
192
|
// Send the full namespaced wire name (e.g. mcp__chrome-devtools__navigate_page) so Kiro echoes
|
|
189
193
|
// it back; the bridge's toolNsMap is keyed by this name and restores the MCP namespace Codex
|
|
@@ -198,19 +202,26 @@ export function convertKiroToolContext(
|
|
|
198
202
|
inputSchema: { json: ensureRootObjectType(sanitizeKiroSchema(tool.parameters ?? {})) },
|
|
199
203
|
},
|
|
200
204
|
};
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
205
|
+
return { tool, index, converted };
|
|
206
|
+
});
|
|
207
|
+
const exceedsBudget = convertedEntries.length > MAX_KIRO_TOOL_COUNT
|
|
208
|
+
|| serializedToolCatalogBytes(convertedEntries.map(entry => entry.converted)) > MAX_KIRO_TOOL_CATALOG_BYTES;
|
|
209
|
+
const candidates = exceedsBudget
|
|
210
|
+
? convertedEntries.toSorted((a, b) => boundedCatalogPriority(a.tool) - boundedCatalogPriority(b.tool) || a.index - b.index)
|
|
211
|
+
: convertedEntries;
|
|
212
|
+
const convertedTools: unknown[] = [];
|
|
213
|
+
let omittedAt = candidates.length;
|
|
214
|
+
for (const [index, entry] of candidates.entries()) {
|
|
204
215
|
if (
|
|
205
216
|
convertedTools.length >= MAX_KIRO_TOOL_COUNT
|
|
206
|
-
|| serializedToolCatalogBytes([...convertedTools, converted]) > MAX_KIRO_TOOL_CATALOG_BYTES
|
|
217
|
+
|| serializedToolCatalogBytes([...convertedTools, entry.converted]) > MAX_KIRO_TOOL_CATALOG_BYTES
|
|
207
218
|
) {
|
|
208
219
|
omittedAt = index;
|
|
209
220
|
break;
|
|
210
221
|
}
|
|
211
|
-
convertedTools.push(converted);
|
|
222
|
+
convertedTools.push(entry.converted);
|
|
212
223
|
}
|
|
213
|
-
const omittedTools =
|
|
224
|
+
const omittedTools = candidates.slice(omittedAt).map(entry => entry.tool);
|
|
214
225
|
return {
|
|
215
226
|
tools: convertedTools,
|
|
216
227
|
systemAdditions: omittedTools.length > 0 ? [omittedToolCatalogNotice(convertedTools.length, omittedTools, registry)] : [],
|
|
@@ -1244,6 +1244,15 @@ function toolsToChatFormat(parsed: OcxParsedRequest, provider: OcxProviderConfig
|
|
|
1244
1244
|
},
|
|
1245
1245
|
}];
|
|
1246
1246
|
});
|
|
1247
|
+
if (xaiTarget) {
|
|
1248
|
+
const omitted = tools.length - formatted.length;
|
|
1249
|
+
debugProviderDiagnostic("openai-chat", "tool-catalog", {
|
|
1250
|
+
declared: tools.length,
|
|
1251
|
+
emitted: formatted.length,
|
|
1252
|
+
omitted,
|
|
1253
|
+
...(omitted > 0 ? { omissionCause: "xai_schema_not_lossless" } : {}),
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1247
1256
|
return formatted.length > 0 ? formatted : undefined;
|
|
1248
1257
|
}
|
|
1249
1258
|
|
|
@@ -38,6 +38,7 @@ export const FORWARD_HEADERS = [
|
|
|
38
38
|
"x-codex-beta-features",
|
|
39
39
|
"x-codex-installation-id",
|
|
40
40
|
"x-codex-parent-thread-id",
|
|
41
|
+
"x-session-id",
|
|
41
42
|
"x-codex-turn-metadata",
|
|
42
43
|
"x-codex-turn-state",
|
|
43
44
|
"x-codex-window-id",
|
|
@@ -1686,7 +1687,7 @@ export function createResponsesPassthroughAdapter(provider: OcxProviderConfig):
|
|
|
1686
1687
|
let convertedRoutedCustomToolNames: Set<string> | undefined;
|
|
1687
1688
|
let routedCustomToolRepairNames: Set<string> | undefined;
|
|
1688
1689
|
let convertedRoutedToolSearchNames: Set<string> | undefined;
|
|
1689
|
-
let convertedRoutedNamespaceToolAliases: Map<string, { namespace: string; name: string }> | undefined;
|
|
1690
|
+
let convertedRoutedNamespaceToolAliases: Map<string, { namespace: string; name: string; kind: "function" | "custom" }> | undefined;
|
|
1690
1691
|
const unexpandedMiss = !!parsed.previousResponseId && parsed._previousResponseInputExpanded !== true;
|
|
1691
1692
|
let outBody = stripPreviousResponseId(
|
|
1692
1693
|
parsed._rawBody,
|