@yansigit/opencodex 2.32.0 → 2.33.0

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.
Files changed (108) hide show
  1. package/README.md +2 -2
  2. package/gui/dist/assets/index-DKLr4LTE.js +102 -0
  3. package/gui/dist/assets/index-DrSQdTRd.css +1 -0
  4. package/gui/dist/index.html +2 -2
  5. package/package.json +6 -5
  6. package/src/adapters/anthropic.ts +20 -6
  7. package/src/adapters/azure.ts +20 -4
  8. package/src/adapters/base.ts +3 -1
  9. package/src/adapters/command-code.ts +40 -7
  10. package/src/adapters/cursor/live-transport.ts +1 -1
  11. package/src/adapters/cursor/protobuf-events.ts +158 -7
  12. package/src/adapters/cursor/protobuf-request.ts +33 -15
  13. package/src/adapters/cursor/request-builder.ts +4 -3
  14. package/src/adapters/cursor/tool-definitions.ts +27 -1
  15. package/src/adapters/cursor/types.ts +4 -3
  16. package/src/adapters/cursor.ts +9 -0
  17. package/src/adapters/google-antigravity-replay.ts +2 -2
  18. package/src/adapters/google-antigravity-wire.ts +7 -0
  19. package/src/adapters/google-errors.ts +6 -2
  20. package/src/adapters/google-http.ts +30 -7
  21. package/src/adapters/google-truncation.ts +5 -0
  22. package/src/adapters/google-wire-compiler.ts +38 -6
  23. package/src/adapters/google.ts +148 -26
  24. package/src/adapters/kiro-tools.ts +20 -9
  25. package/src/adapters/openai-chat.ts +9 -0
  26. package/src/adapters/openai-responses.ts +1 -1
  27. package/src/bridge.ts +112 -9
  28. package/src/claude/context-windows.ts +16 -9
  29. package/src/cli/doctor.ts +2 -2
  30. package/src/cli/index.ts +9 -2
  31. package/src/cli/provider.ts +6 -0
  32. package/src/cli/status.ts +23 -0
  33. package/src/codex/auth-api.ts +4 -2
  34. package/src/codex/autostart-health.ts +16 -0
  35. package/src/codex/catalog/aggregation.ts +12 -12
  36. package/src/codex/catalog/effort.ts +18 -3
  37. package/src/codex/catalog/metadata.ts +27 -1
  38. package/src/codex/catalog/model-metadata.ts +39 -12
  39. package/src/codex/catalog/parsing.ts +38 -27
  40. package/src/codex/catalog/provider-fetch.ts +198 -133
  41. package/src/codex/catalog/sync.ts +1 -1
  42. package/src/codex/convergence.ts +5 -0
  43. package/src/codex/shim.ts +56 -3
  44. package/src/config/provider-validation.ts +37 -0
  45. package/src/config.ts +78 -2
  46. package/src/generated/compatibility-version.json +120 -96
  47. package/src/images/loop.ts +37 -6
  48. package/src/lib/azure-identity.ts +154 -0
  49. package/src/lib/debug.ts +42 -0
  50. package/src/lib/errors.ts +14 -0
  51. package/src/lib/provider-outbound.ts +45 -33
  52. package/src/lib/provider-tls-profile.ts +309 -0
  53. package/src/lib/proxy-env.ts +49 -0
  54. package/src/lib/redact.ts +10 -1
  55. package/src/oauth/antigravity-routing.ts +282 -236
  56. package/src/oauth/callback-server.ts +22 -2
  57. package/src/oauth/command-code.ts +5 -16
  58. package/src/oauth/google-antigravity.ts +42 -5
  59. package/src/oauth/index.ts +15 -3
  60. package/src/oauth/kimi.ts +9 -1
  61. package/src/oauth/open-browser-choice.ts +26 -0
  62. package/src/oauth/store.ts +6 -0
  63. package/src/providers/antigravity-quota.ts +3 -1
  64. package/src/providers/api-keys.ts +2 -1
  65. package/src/providers/auto-compact-budget.ts +65 -0
  66. package/src/providers/derive.ts +4 -0
  67. package/src/providers/key-failover.ts +5 -1
  68. package/src/providers/openai-tiers.ts +5 -0
  69. package/src/providers/provider-id-rewrite.ts +1 -0
  70. package/src/providers/quota.ts +59 -13
  71. package/src/providers/registry.ts +3 -1
  72. package/src/providers/request-pacing.ts +33 -6
  73. package/src/providers/xai-transport.ts +21 -0
  74. package/src/responses/google-provider-options.ts +36 -0
  75. package/src/responses/namespace-tool-compat.ts +84 -4
  76. package/src/responses/parser.ts +11 -0
  77. package/src/responses/provider-opaque-metadata.ts +3 -3
  78. package/src/responses/schema.ts +37 -0
  79. package/src/responses/state.ts +94 -4
  80. package/src/router.ts +8 -2
  81. package/src/server/auth-cors.ts +28 -0
  82. package/src/server/images.ts +19 -35
  83. package/src/server/management/agent-settings-routes.ts +205 -15
  84. package/src/server/management/combo-routes.ts +6 -0
  85. package/src/server/management/config-routes.ts +31 -5
  86. package/src/server/management/model-rows.ts +4 -0
  87. package/src/server/management/oauth-account-routes.ts +25 -4
  88. package/src/server/management/provider-routes.ts +113 -15
  89. package/src/server/management/routing-profile-routes.ts +3 -0
  90. package/src/server/request-log.ts +21 -0
  91. package/src/server/responses/agent-task-recovery.ts +1 -1
  92. package/src/server/responses/compact.ts +30 -1
  93. package/src/server/responses/core.ts +359 -153
  94. package/src/server/responses/empty-completion-guard.ts +35 -6
  95. package/src/server/responses/fetch-helpers.ts +18 -5
  96. package/src/server/responses/v2-native-parent-override.ts +59 -0
  97. package/src/server/responses/ws-upstream.ts +75 -2
  98. package/src/server/responses-undeclared-tool-guard.ts +90 -8
  99. package/src/service.ts +1 -1
  100. package/src/types/config.ts +16 -1
  101. package/src/types/provider.ts +16 -0
  102. package/src/types/request.ts +28 -0
  103. package/src/types/tools.ts +27 -0
  104. package/src/types.ts +6 -0
  105. package/src/web-search/gemini-executor.ts +6 -4
  106. package/src/web-search/loop.ts +42 -6
  107. package/gui/dist/assets/index-BG43zwVe.js +0 -102
  108. package/gui/dist/assets/index-CiSI-jrP.css +0 -1
@@ -14,13 +14,14 @@ import { fetchWithResetRetry } from "../lib/upstream-retry";
14
14
  import { cancelBodyOnAbort, signalWithTimeout } from "../lib/abort";
15
15
  import { readBoundedResponseBytes } from "../lib/bounded-body";
16
16
  import { sidecarEnter } from "../lib/sidecar-tracker";
17
- import { redactSecretString } from "../lib/redact";
17
+ import { redactErrorMessage, redactSecretString } from "../lib/redact";
18
18
  import { ANTIGRAVITY_REQUEST_UA } from "../adapters/google-antigravity-wire";
19
19
  import { resolveAntigravityEffortWireModel } from "../providers/antigravity-models";
20
20
  import { getProviderRegistryEntry } from "../providers/registry";
21
21
  import { MAX_SIDECAR_RESPONSE_BYTES, type WebSearchSource } from "./parse";
22
22
  import { appendSafeWebSearchSource } from "./sources";
23
23
  import { BASE_INSTRUCTION, IMAGE_INSTRUCTION, type SidecarOutcome, type SidecarSettings } from "./executor";
24
+ import { providerFetch } from "../server/responses/fetch-helpers";
24
25
 
25
26
  const CCA_FALLBACK_BASE = "https://daily-cloudcode-pa.googleapis.com";
26
27
 
@@ -31,7 +32,7 @@ function isRec(v: unknown): v is Record<string, unknown> {
31
32
  export async function runGeminiWebSearch(
32
33
  query: string,
33
34
  providerName: string,
34
- _provider: OcxProviderConfig,
35
+ provider: OcxProviderConfig,
35
36
  settings: SidecarSettings,
36
37
  abortSignal?: AbortSignal,
37
38
  ): Promise<SidecarOutcome> {
@@ -68,9 +69,10 @@ export async function runGeminiWebSearch(
68
69
  const linkedSignal = signalWithTimeout(settings.timeoutMs, abortSignal);
69
70
  const sidecarExit = sidecarEnter("web-search");
70
71
  const t0 = Date.now();
72
+ const executor = providerFetch(provider, undefined, { providerName, modelId: settings.model });
71
73
  try {
72
74
  const res = await fetchWithResetRetry(
73
- () => fetch(`${base}/v1internal:generateContent`, {
75
+ () => executor(`${base}/v1internal:generateContent`, {
74
76
  method: "POST",
75
77
  headers: {
76
78
  "Content-Type": "application/json",
@@ -110,7 +112,7 @@ export async function runGeminiWebSearch(
110
112
  } catch (e) {
111
113
  const kind = e instanceof Error && e.name === "TimeoutError" ? "timeout" : "connect_error";
112
114
  console.warn(`[web-search] gemini sidecar ${kind} (${Date.now() - t0}ms)`);
113
- return { text: "", sources: [], error: redactSecretString(e instanceof Error ? e.message : String(e)) };
115
+ return { text: "", sources: [], error: redactErrorMessage(e instanceof Error ? e.message : String(e)) };
114
116
  } finally {
115
117
  sidecarExit();
116
118
  linkedSignal.cleanup();
@@ -3,7 +3,7 @@ import type { AdapterEvent, OcxMessage, OcxParsedRequest, OcxProviderConfig, Ocx
3
3
  import { namespacedToolName, toolChoiceToolPredicate } from "../types";
4
4
  import { cloneProviderOpaqueToolCallMetadata } from "../responses/provider-opaque-metadata";
5
5
  import type { AttemptRecoveryKind } from "../usage/log";
6
- import { bridgeToResponsesSSE } from "../bridge";
6
+ import { bridgeToResponsesSSE, diagnoseAdapterEvent, type BridgeDiagnosticContext } from "../bridge";
7
7
  import { runWebSearch, type SidecarOutcome, type SidecarOutcomeRecorder, type SidecarSettings } from "./executor";
8
8
  import { runAnthropicWebSearch } from "./anthropic-executor";
9
9
  import { runXaiWebSearch, type XaiSearchOptions } from "./xai-executor";
@@ -23,6 +23,7 @@ import {
23
23
  import { formatWebSearchResults } from "./format-result";
24
24
  import { parseStreamWithProgress, RoutedModelInactivityError, WebSearchStreamProtocolError } from "./progress-stream";
25
25
  import { WEB_SEARCH_TOOL_NAME } from "./synthetic-tool";
26
+ import { OcxRequestValidationError } from "../lib/errors";
26
27
 
27
28
  const SSE_HEADERS = {
28
29
  "Content-Type": "text/event-stream",
@@ -230,8 +231,14 @@ function forcedAnswerNudge(): OcxMessage {
230
231
  };
231
232
  }
232
233
 
233
- function jsonError(status: number, message: string): Response {
234
- return new Response(JSON.stringify({ error: { message, type: "upstream_error", code: null } }), {
234
+ function jsonError(status: number, message: string, errorType = "upstream_error", code: string | null = null): Response {
235
+ return new Response(JSON.stringify({
236
+ error: {
237
+ message,
238
+ type: errorType,
239
+ code,
240
+ },
241
+ }), {
235
242
  status,
236
243
  headers: { "Content-Type": "application/json" },
237
244
  });
@@ -240,7 +247,12 @@ function jsonError(status: number, message: string): Response {
240
247
  /** Hard provider/parse failure inside an iteration. The eager first iteration converts it to a
241
248
  * non-200 jsonError; later (already-streaming) iterations surface it as an in-stream error event. */
242
249
  class LoopError extends Error {
243
- constructor(readonly status: number, message: string) {
250
+ constructor(
251
+ readonly status: number,
252
+ message: string,
253
+ readonly errorType?: string,
254
+ readonly code?: string,
255
+ ) {
244
256
  super(message);
245
257
  this.name = "LoopError";
246
258
  }
@@ -301,6 +313,8 @@ export interface WebSearchLoopDeps {
301
313
  onUsage?: (usage: OcxUsage | undefined) => void;
302
314
  /** Observe the exact adapter request selected for each routed-model iteration. */
303
315
  onRequestBuilt?: (request: AdapterRequest) => void;
316
+ /** Validate the final adapter before every cached replay or request build. */
317
+ validateAdapter?: (parsed: OcxParsedRequest, adapter: ProviderAdapter) => void;
304
318
  /** Called before each routed-model dispatch in the loop, for attempt telemetry. Same-target 429 replays pass the `rate-limit-429` recovery kind. */
305
319
  onAttemptSend?: (recovery?: AttemptRecoveryKind) => void;
306
320
  /**
@@ -314,6 +328,8 @@ export interface WebSearchLoopDeps {
314
328
  onCompletedResponse?: (response: Record<string, unknown>) => void;
315
329
  /** OAuth account identity forwarded to AdapterFetchContext for provider-local cooldown bookkeeping. */
316
330
  accountId?: string;
331
+ /** Internal, opt-in structural stream diagnostics shared with the final bridge. */
332
+ diagnostic?: BridgeDiagnosticContext;
317
333
  }
318
334
 
319
335
  /**
@@ -422,6 +438,7 @@ export async function runWithWebSearch(deps: WebSearchLoopDeps): Promise<Respons
422
438
  * header deadline. The caller owns same-target 429 replays and key rotation around it.
423
439
  */
424
440
  const fetchOnce = async (requestAdapter: ProviderAdapter, recovery?: AttemptRecoveryKind): Promise<IterationResponse> => {
441
+ deps.validateAdapter?.(iterParsed, requestAdapter);
425
442
  let request: AdapterRequest;
426
443
  if (cachedRequest !== undefined && cachedAdapter === requestAdapter) {
427
444
  request = cachedRequest;
@@ -553,6 +570,9 @@ export async function runWithWebSearch(deps: WebSearchLoopDeps): Promise<Respons
553
570
  return prepared;
554
571
  } catch (error) {
555
572
  if (isTranslatorBudgetExceededError(error)) throw error;
573
+ if (error instanceof OcxRequestValidationError) {
574
+ throw new LoopError(error.status, error.message, "invalid_request_error", "invalid_request_error");
575
+ }
556
576
  if (headerDeadline.didExpire()) {
557
577
  throw new LoopError(504, `Provider response-header timeout after ${connectTimeoutMs}ms during web-search`);
558
578
  }
@@ -595,6 +615,10 @@ export async function runWithWebSearch(deps: WebSearchLoopDeps): Promise<Respons
595
615
  inactivityTimeoutMs: routedModelStallTimeoutMs,
596
616
  translatorBudget,
597
617
  })) {
618
+ if (deps.diagnostic) {
619
+ deps.diagnostic.adapterName = prepared.responseAdapter.name;
620
+ diagnoseAdapterEvent(deps.diagnostic, event);
621
+ }
598
622
  if (event.type === "heartbeat") yield event;
599
623
  // Kiro's explicit-completion protocol marks ordinary assistant text as commentary while
600
624
  // it performs a bounded final-answer retry. That text is safe to surface immediately and
@@ -779,7 +803,7 @@ export async function runWithWebSearch(deps: WebSearchLoopDeps): Promise<Respons
779
803
  firstPrepared = await prepareIterationDrained(false);
780
804
  } catch (e) {
781
805
  if (abortSignal) abortSignal.removeEventListener("abort", linkAbort);
782
- if (e instanceof LoopError) return jsonError(e.status, e.message);
806
+ if (e instanceof LoopError) return jsonError(e.status, e.message, e.errorType, e.code ?? null);
783
807
  throw e;
784
808
  }
785
809
 
@@ -863,7 +887,18 @@ export async function runWithWebSearch(deps: WebSearchLoopDeps): Promise<Respons
863
887
  message: "upstream translation buffer exceeded the safe limit",
864
888
  };
865
889
  } else {
866
- yield { type: "error", message: e instanceof LoopError ? e.message : (e instanceof Error ? e.message : String(e)) };
890
+ const message = e instanceof LoopError ? e.message : (e instanceof Error ? e.message : String(e));
891
+ yield {
892
+ type: "error",
893
+ ...(e instanceof LoopError ? {
894
+ status: e.status,
895
+ ...(e.errorType !== undefined || e.status === 400
896
+ ? { errorType: e.errorType ?? "upstream_error" }
897
+ : {}),
898
+ ...(e.code !== undefined ? { code: e.code } : {}),
899
+ } : {}),
900
+ message,
901
+ };
867
902
  }
868
903
  return;
869
904
  }
@@ -890,6 +925,7 @@ export async function runWithWebSearch(deps: WebSearchLoopDeps): Promise<Respons
890
925
  ...(deps.onFirstOutput ? { onFirstOutput: deps.onFirstOutput } : {}),
891
926
  ...(deps.onUsage ? { onUsage: deps.onUsage } : {}),
892
927
  ...(deps.onCompletedResponse ? { onCompletedResponse: deps.onCompletedResponse } : {}),
928
+ ...(deps.diagnostic ? { diagnostic: deps.diagnostic } : {}),
893
929
  },
894
930
  );
895
931
  return new Response(sse, { headers: SSE_HEADERS });