@yansigit/opencodex 2.33.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.
Files changed (62) hide show
  1. package/gui/dist/assets/index-CIDo4y4k.js +102 -0
  2. package/gui/dist/index.html +1 -1
  3. package/package.json +3 -1
  4. package/src/adapters/command-code.ts +101 -20
  5. package/src/adapters/cursor/envelope-echo.ts +162 -0
  6. package/src/adapters/cursor/live-transport.ts +3 -1
  7. package/src/adapters/cursor/native-exec-fs.ts +13 -12
  8. package/src/adapters/cursor/native-exec-network.ts +3 -5
  9. package/src/adapters/cursor/native-exec-policy.ts +47 -0
  10. package/src/adapters/cursor/native-exec-shell.ts +13 -25
  11. package/src/adapters/cursor/native-exec.ts +18 -10
  12. package/src/adapters/cursor/protobuf-events.ts +28 -2
  13. package/src/adapters/cursor/protobuf-request.ts +20 -3
  14. package/src/adapters/cursor/request-builder.ts +7 -0
  15. package/src/adapters/cursor/tool-definitions.ts +22 -1
  16. package/src/adapters/cursor/tool-result-normalize.ts +21 -8
  17. package/src/adapters/cursor/types.ts +7 -0
  18. package/src/adapters/cursor.ts +114 -0
  19. package/src/adapters/google-aistudio-parser.ts +49 -0
  20. package/src/adapters/google.ts +108 -16
  21. package/src/adapters/openai-responses.ts +1 -0
  22. package/src/chat/inbound.ts +15 -0
  23. package/src/cli/index.ts +1 -1
  24. package/src/codex/catalog/provider-fetch.ts +34 -0
  25. package/src/generated/compatibility-version.json +91 -47
  26. package/src/generated/model-metadata.ts +3 -0
  27. package/src/oauth/aistudio-native-daemon.ts +62 -0
  28. package/src/oauth/aistudio-session-sync.ts +95 -0
  29. package/src/oauth/google-aistudio-auth.ts +98 -0
  30. package/src/oauth/key-providers.ts +8 -0
  31. package/src/oauth/login-cli.ts +66 -1
  32. package/src/providers/derive.ts +1 -1
  33. package/src/providers/quota.ts +90 -38
  34. package/src/providers/registry.ts +24 -3
  35. package/src/router.ts +3 -0
  36. package/src/routing/account-pool/cooldown.ts +8 -0
  37. package/src/routing/account-pool/index.ts +1 -0
  38. package/src/server/aistudio-ws-hub.ts +295 -0
  39. package/src/server/auth-cors.ts +1 -0
  40. package/src/server/chat-completions.ts +2 -0
  41. package/src/server/index.ts +94 -0
  42. package/src/server/management/logs-usage-routes.ts +11 -5
  43. package/src/server/management/oauth-account-routes.ts +13 -3
  44. package/src/server/port-reclaim.ts +19 -1
  45. package/src/server/request-log-conversation.ts +12 -0
  46. package/src/server/request-log.ts +2 -1
  47. package/src/server/responses/core.ts +4 -3
  48. package/src/server/responses/policy-fallback.ts +1 -1
  49. package/src/server/ws-bridge.ts +2 -1
  50. package/src/smoke/fingerprint-cache.ts +133 -0
  51. package/src/smoke/live-scenarios.ts +33 -0
  52. package/src/smoke/runner.ts +119 -0
  53. package/src/types/provider.ts +2 -1
  54. package/src/types/request.ts +2 -0
  55. package/src/types/tools.ts +31 -7
  56. package/src/usage/command-code-manifest.ts +116 -0
  57. package/src/usage/cost.ts +2 -2
  58. package/src/usage/expected-prices.ts +83 -0
  59. package/src/usage/log.ts +2 -2
  60. package/src/usage/summary.ts +34 -12
  61. package/src/web-search/index.ts +16 -8
  62. package/gui/dist/assets/index-DKLr4LTE.js +0 -102
@@ -94,6 +94,7 @@ export interface UsageProvider {
94
94
 
95
95
  export interface UsageAccount {
96
96
  accountLogLabel: string;
97
+ provider?: string;
97
98
  ambiguous: boolean;
98
99
  requests: number;
99
100
  attemptCount: number;
@@ -684,12 +685,25 @@ function legacyCodexAccountLabel(provider: string): string | null {
684
685
  return suffix ?? LEGACY_AMBIGUOUS_ACCOUNT_LABEL;
685
686
  }
686
687
 
687
- function accountLabelForAttribution(provider: string, explicit: unknown): string | null {
688
- if (isCodexUsageAccountLogLabel(explicit)) return explicit;
689
- return legacyCodexAccountLabel(provider);
688
+ export function accountLabelForAttribution(
689
+ provider: string,
690
+ explicit: unknown,
691
+ fallbackAccountByProvider?: Record<string, string>,
692
+ ): string | null {
693
+ if (typeof explicit === "string" && explicit.trim().length > 0) return explicit.trim();
694
+ const legacy = legacyCodexAccountLabel(provider);
695
+ if (legacy) return legacy;
696
+ const base = baseProviderLabel(provider);
697
+ if (fallbackAccountByProvider && fallbackAccountByProvider[base]) {
698
+ return fallbackAccountByProvider[base];
699
+ }
700
+ return null;
690
701
  }
691
702
 
692
- function buildAccounts(entries: PersistedUsageEntry[]): UsageAccount[] {
703
+ function buildAccounts(
704
+ entries: PersistedUsageEntry[],
705
+ fallbackAccountByProvider?: Record<string, string>,
706
+ ): UsageAccount[] {
693
707
  const byLabel = new Map<string, UsageAccount>();
694
708
  const requestIds = new Map<string, Set<string>>();
695
709
 
@@ -702,12 +716,13 @@ function buildAccounts(entries: PersistedUsageEntry[]): UsageAccount[] {
702
716
  totalTokens?: number;
703
717
  estimate: ReturnType<typeof estimateRequestCost>;
704
718
  }): void => {
705
- const label = accountLabelForAttribution(input.provider, input.accountLogLabel);
719
+ const label = accountLabelForAttribution(input.provider, input.accountLogLabel, fallbackAccountByProvider);
706
720
  if (!label) return;
707
721
  let row = byLabel.get(label);
708
722
  if (!row) {
709
723
  row = {
710
724
  accountLogLabel: label,
725
+ provider: baseProviderLabel(input.provider),
711
726
  ambiguous: label === LEGACY_AMBIGUOUS_ACCOUNT_LABEL,
712
727
  requests: 0,
713
728
  attemptCount: 0,
@@ -808,6 +823,7 @@ export function summarizeUsage(
808
823
  range: UsageRange,
809
824
  now: number,
810
825
  surface: UsageSurface = "all",
826
+ fallbackAccountByProvider?: Record<string, string>,
811
827
  ): UsageSummary {
812
828
  const { since } = rangeWindow(range, now);
813
829
  const filteredEntries = entries.filter(entry => {
@@ -837,7 +853,7 @@ export function summarizeUsage(
837
853
  days: buildDayGrid(range, since, now, filteredEntries),
838
854
  models: buildModels(filteredEntries, totals.totalTokens),
839
855
  providers: buildProviders(filteredEntries, totals.totalTokens),
840
- accounts: buildAccounts(filteredEntries),
856
+ accounts: buildAccounts(filteredEntries, fallbackAccountByProvider),
841
857
  };
842
858
  }
843
859
 
@@ -869,12 +885,14 @@ function normalizeFilterValue(input: string | null | undefined): string | null {
869
885
  */
870
886
  export function projectUsageSummary<T extends UsageSummary>(
871
887
  summary: T,
872
- filter: { provider?: string | null; model?: string | null },
888
+ filter: { provider?: string | null; model?: string | null; account?: string | null },
873
889
  entries?: PersistedUsageEntry[],
890
+ fallbackAccountByProvider?: Record<string, string>,
874
891
  ): T & { filter?: UsageFilterEcho } {
875
892
  const provider = normalizeFilterValue(filter.provider);
876
893
  const model = normalizeFilterValue(filter.model);
877
- if (provider === null && model === null) return summary;
894
+ const account = normalizeFilterValue(filter.account);
895
+ if (provider === null && model === null && account === null) return summary;
878
896
 
879
897
  // Re-summarise from the entries the summary was built from, rather than
880
898
  // projecting over its rows.
@@ -891,9 +909,13 @@ export function projectUsageSummary<T extends UsageSummary>(
891
909
  //
892
910
  // The entries are already in hand on every path that filters, so the honest
893
911
  // computation is also the simple one.
894
- const matches = (rowProvider: string, rowModel: string): boolean => {
912
+ const matches = (rowProvider: string, rowModel: string, rowAccount?: string | null): boolean => {
895
913
  if (provider !== null && baseProviderLabel(rowProvider).toLowerCase() !== provider) return false;
896
914
  if (model !== null && rowModel.toLowerCase() !== model) return false;
915
+ if (account !== null && rowAccount !== undefined) {
916
+ const effectiveAccount = accountLabelForAttribution(rowProvider, rowAccount, fallbackAccountByProvider);
917
+ if (!effectiveAccount || effectiveAccount.toLowerCase() !== account) return false;
918
+ }
897
919
  return true;
898
920
  };
899
921
 
@@ -909,10 +931,10 @@ export function projectUsageSummary<T extends UsageSummary>(
909
931
  const filtered: PersistedUsageEntry[] = [];
910
932
  for (const entry of source) {
911
933
  if (!entry.attempts?.length) {
912
- if (matches(entry.provider, antigravityUsageModel(entry.provider, entry.model))) filtered.push(entry);
934
+ if (matches(entry.provider, antigravityUsageModel(entry.provider, entry.model), entry.accountLogLabel)) filtered.push(entry);
913
935
  continue;
914
936
  }
915
- const attempts = entry.attempts.filter(a => matches(a.provider, antigravityUsageModel(a.provider, a.model)));
937
+ const attempts = entry.attempts.filter(a => matches(a.provider, antigravityUsageModel(a.provider, a.model), a.accountLogLabel ?? entry.accountLogLabel));
916
938
  if (attempts.length === 0) continue;
917
939
  // A combo is still counted once per participating model, so a filtered
918
940
  // request count can exceed the number of distinct requests. That is the
@@ -921,7 +943,7 @@ export function projectUsageSummary<T extends UsageSummary>(
921
943
  filtered.push({ ...entry, attempts });
922
944
  }
923
945
 
924
- const projected = summarizeUsage(filtered, summary.range, summary.generatedAt, summary.surface);
946
+ const projected = summarizeUsage(filtered, summary.range, summary.generatedAt, summary.surface, fallbackAccountByProvider);
925
947
  // matched reflects usage inside the requested WINDOW, not anywhere in the
926
948
  // log: summarizeUsage applies the range and surface predicates, and the CLI
927
949
  // uses this flag to decide between a table and "no usage recorded".
@@ -9,6 +9,7 @@ import { validateXaiSearchOptions, type XaiSearchOptions } from "./xai-executor"
9
9
  import type { OcxWebSearchSidecarConfig } from "../types";
10
10
  import { DEFAULT_STALL_TIMEOUT_SEC } from "../stall-timeout";
11
11
  import { buildWebSearchTool, extractHostedWebSearch, WEB_SEARCH_TOOL_NAME } from "./synthetic-tool";
12
+ import { estimateInputTokens } from "../server/responses/input-admission";
12
13
 
13
14
  export { runWithWebSearch } from "./loop";
14
15
  export { buildWebSearchTool, extractHostedWebSearch, WEB_SEARCH_TOOL_NAME };
@@ -44,13 +45,19 @@ const STALL_MARGIN_SEC = 30;
44
45
  * deliberately permissive, so malformed values fall back locally without rejecting or rewriting
45
46
  * the caller's config object.
46
47
  */
47
- export function resolveRoutedModelStallTimeoutMs(value: unknown): number {
48
- return typeof value === "number"
48
+ export function resolveRoutedModelStallTimeoutMs(value: unknown, estimatedInputTokens?: number): number {
49
+ if (typeof value === "number"
49
50
  && Number.isInteger(value)
50
51
  && value >= 1
51
- && value <= MAX_ROUTED_MODEL_STALL_TIMEOUT_MS
52
- ? value
53
- : DEFAULT_ROUTED_MODEL_STALL_TIMEOUT_MS;
52
+ && value <= MAX_ROUTED_MODEL_STALL_TIMEOUT_MS) {
53
+ return value;
54
+ }
55
+ const base = DEFAULT_ROUTED_MODEL_STALL_TIMEOUT_MS;
56
+ if (typeof estimatedInputTokens === "number" && Number.isFinite(estimatedInputTokens) && estimatedInputTokens > 100_000) {
57
+ const extraBlocks = Math.ceil((estimatedInputTokens - 100_000) / 100_000);
58
+ return Math.min(MAX_ROUTED_MODEL_STALL_TIMEOUT_MS, base + extraBlocks * 60_000);
59
+ }
60
+ return base;
54
61
  }
55
62
 
56
63
  function finiteCeil(value: number | undefined, fallback: number): number {
@@ -305,9 +312,10 @@ export function planWebSearch(
305
312
  const cfg = config.webSearchSidecar ?? {};
306
313
  if (cfg.enabled === false) return undefined;
307
314
  const timeoutMs = cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS;
308
- const routedModelStallTimeoutMs = resolveRoutedModelStallTimeoutMs(cfg.routedModelStallTimeoutMs);
309
- // Same `?? 200_000` default the server applies when threading connectTimeoutMs into the loop.
310
- const connectTimeoutMs = config.connectTimeoutMs ?? 200_000;
315
+ const safeModelId = typeof modelId === "string" ? modelId : "";
316
+ const estimatedInputTokens = estimateInputTokens(parsed, safeModelId);
317
+ const routedModelStallTimeoutMs = resolveRoutedModelStallTimeoutMs(cfg.routedModelStallTimeoutMs, estimatedInputTokens);
318
+ const connectTimeoutMs = config.connectTimeoutMs ?? Math.max(200_000, routedModelStallTimeoutMs);
311
319
  // Shared auth state (#2188): presence only — backend PREFERENCE stays with
312
320
  // resolveSidecarBackend's explicit-or-openai contract.
313
321
  const auth = resolveSidecarAuth(config);