@bitkyc08/opencodex 2.26.0 → 2.28.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 (83) hide show
  1. package/gui/dist/assets/{index-RL6b1bTV.js → index-D2sP-biU.js} +14 -14
  2. package/gui/dist/index.html +1 -1
  3. package/package.json +1 -1
  4. package/src/adapters/anthropic.ts +60 -1
  5. package/src/adapters/base.ts +16 -2
  6. package/src/adapters/command-code.ts +4 -3
  7. package/src/adapters/cursor/cursor-errors.ts +15 -0
  8. package/src/adapters/cursor/live-transport.ts +14 -1
  9. package/src/adapters/google-antigravity-replay.ts +16 -8
  10. package/src/adapters/google.ts +22 -5
  11. package/src/adapters/openai-chat.ts +189 -60
  12. package/src/adapters/openai-responses.ts +37 -0
  13. package/src/adapters/tool-catalog-nudge.ts +1 -1
  14. package/src/bridge.ts +11 -5
  15. package/src/cli/doctor.ts +76 -0
  16. package/src/cli/help.ts +2 -0
  17. package/src/cli/index.ts +19 -6
  18. package/src/cli/models.ts +13 -6
  19. package/src/codex/account-usability.ts +3 -0
  20. package/src/codex/app-server-processes.ts +269 -37
  21. package/src/codex/auth-api.ts +22 -5
  22. package/src/codex/auth-context.ts +108 -3
  23. package/src/codex/catalog/aggregation.ts +3 -0
  24. package/src/codex/catalog/metadata.ts +17 -3
  25. package/src/codex/catalog/native-models.ts +22 -14
  26. package/src/codex/catalog/parsing.ts +20 -3
  27. package/src/codex/catalog/provider-fetch.ts +8 -0
  28. package/src/codex/catalog/sync.ts +63 -15
  29. package/src/codex/convergence.ts +61 -13
  30. package/src/codex/log-guard/path-safety.ts +52 -3
  31. package/src/codex/model-entitlements.ts +353 -0
  32. package/src/codex/native-profile-startup.ts +100 -2
  33. package/src/codex/quota.ts +28 -3
  34. package/src/codex/routing.ts +14 -8
  35. package/src/codex/user-identity.ts +21 -1
  36. package/src/config/provider-name.ts +24 -0
  37. package/src/config.ts +11 -24
  38. package/src/generated/compatibility-version.json +110 -70
  39. package/src/images/loop.ts +11 -4
  40. package/src/lib/destination-policy.ts +47 -0
  41. package/src/lib/shadow-call.ts +15 -0
  42. package/src/lib/state-store-registrations.ts +8 -2
  43. package/src/oauth/index.ts +33 -5
  44. package/src/oauth/store.ts +11 -5
  45. package/src/providers/antigravity-models.ts +70 -5
  46. package/src/providers/derive.ts +12 -2
  47. package/src/providers/fastwire.ts +39 -8
  48. package/src/providers/quota.ts +9 -2
  49. package/src/providers/registry.ts +120 -6
  50. package/src/providers/service-tier.ts +50 -15
  51. package/src/responses/parser.ts +59 -11
  52. package/src/responses/state.ts +162 -5
  53. package/src/responses/tool-search-compat.ts +301 -0
  54. package/src/router.ts +17 -3
  55. package/src/routing/capability.ts +26 -9
  56. package/src/routing/compatibility/behavior.ts +44 -6
  57. package/src/routing/profile.ts +1 -1
  58. package/src/server/chat-native.ts +11 -2
  59. package/src/server/index.ts +59 -8
  60. package/src/server/management/agent-settings-routes.ts +16 -2
  61. package/src/server/management/shared.ts +3 -1
  62. package/src/server/request-log.ts +31 -0
  63. package/src/server/responses/collaboration.ts +34 -9
  64. package/src/server/responses/compact.ts +54 -7
  65. package/src/server/responses/core.ts +259 -43
  66. package/src/server/responses/input-admission.ts +7 -2
  67. package/src/server/responses/responses-field-backfill.ts +88 -6
  68. package/src/server/responses/terminal-guard.ts +10 -0
  69. package/src/server/responses-tool-search-repair.ts +217 -0
  70. package/src/server/system-env.ts +74 -5
  71. package/src/service-manager-probe.ts +99 -0
  72. package/src/service.ts +86 -6
  73. package/src/tray/windows.ts +25 -5
  74. package/src/types/accounts.ts +37 -0
  75. package/src/types/config.ts +818 -0
  76. package/src/types/provider.ts +521 -0
  77. package/src/types/request.ts +358 -0
  78. package/src/types/tools.ts +131 -0
  79. package/src/types/wire.ts +80 -0
  80. package/src/types.ts +103 -1883
  81. package/src/usage/cost.ts +37 -1
  82. package/src/usage/log.ts +4 -0
  83. package/src/web-search/loop.ts +11 -4
package/src/usage/cost.ts CHANGED
@@ -83,6 +83,8 @@ export interface AttemptCostEstimate {
83
83
  estimated: boolean;
84
84
  /** Applied OpenAI priority-tier multiplier (undefined or 1 = standard). */
85
85
  priorityMultiplier?: number;
86
+ /** Standard-price estimate is a known floor for a confirmed, unpriced priority endpoint. */
87
+ priorityLowerBound?: boolean;
86
88
  /** Set when the published long-context rate was applied (#908). */
87
89
  contextTier?: ContextTierName;
88
90
  }
@@ -95,6 +97,8 @@ export interface CostEstimate {
95
97
  price?: MatchedPrice;
96
98
  /** Applied OpenAI priority-tier multiplier (undefined or 1 = standard). */
97
99
  priorityMultiplier?: number;
100
+ /** Standard-price estimate is a known floor for a confirmed, unpriced priority endpoint. */
101
+ priorityLowerBound?: boolean;
98
102
  /** Set when any priced attempt used the published long-context rate (#908). */
99
103
  contextTier?: ContextTierName;
100
104
  }
@@ -350,7 +354,9 @@ export type ServiceTierInput = string | ServiceTierContext;
350
354
  * and long-context exclusivity depends on that distinction.
351
355
  */
352
356
  export function serviceTierContext(entry: ServiceTierContext): ServiceTierContext {
353
- if (entry.tierOutcome) return serviceTierContextFromOutcome(entry.tierOutcome);
357
+ if (entry.tierOutcome) {
358
+ return { ...serviceTierContextFromOutcome(entry.tierOutcome), tierOutcome: entry.tierOutcome };
359
+ }
354
360
  return {
355
361
  responseServiceTier: entry.responseServiceTier,
356
362
  requestedServiceTier: entry.requestedServiceTier,
@@ -448,6 +454,28 @@ function applyPriorityMultiplier(
448
454
  }, multiplier];
449
455
  }
450
456
 
457
+ /**
458
+ * OpenRouter confirms the actual endpoint tier and documents priority as higher cost, but this
459
+ * branch does not bundle its provider-specific priority endpoint prices. A confirmed canonical
460
+ * priority result can therefore use the standard price only as a provable lower bound. Do not
461
+ * extend this to flex (cheaper) or to other providers without the same pricing contract.
462
+ *
463
+ * An ASSUMED priority attempt needs the same marker for a different reason. There the provider
464
+ * never echoed a tier at all, so the standard price is not merely a lower bound on a known
465
+ * premium — it is a floor under an outcome we did not observe. Returning it unmarked reports a
466
+ * definite standard cost for a request that may well have been billed as priority, which is the
467
+ * one thing a cost estimate must never do.
468
+ */
469
+ function isOpenRouterPriorityLowerBound(
470
+ provider: string,
471
+ outcome: AttemptTierOutcome | undefined,
472
+ ): boolean {
473
+ return baseProviderLabel(provider) === "openrouter"
474
+ && outcome?.canonical === "priority"
475
+ && outcome.fastOutcome === "applied"
476
+ && (outcome.confirmation === "confirmed" || outcome.confirmation === "assumed");
477
+ }
478
+
451
479
  /**
452
480
  * Per-attempt cost estimate: tokens normalized, price resolved (user overlay →
453
481
  * catalogs), priority/long-context tiers applied. Null when usage or price is
@@ -476,6 +504,7 @@ export function estimateAttemptCost(
476
504
  const [effectiveCost4, multiplier] = contextTier
477
505
  ? [tieredCost4, 1] as const
478
506
  : applyPriorityMultiplier(tieredCost4, attempt.provider, attempt.model, attemptServiceTier);
507
+ const priorityLowerBound = isOpenRouterPriorityLowerBound(attempt.provider, attempt.tierOutcome);
479
508
  return {
480
509
  ordinal: attempt.ordinal,
481
510
  provider: attempt.provider,
@@ -485,6 +514,7 @@ export function estimateAttemptCost(
485
514
  cost: calculateCost(tokens, effectiveCost4),
486
515
  estimated: isEstimated(attempt.usage, attempt.usageStatus, price.status),
487
516
  ...(multiplier !== 1 ? { priorityMultiplier: multiplier } : {}),
517
+ ...(priorityLowerBound ? { priorityLowerBound: true } : {}),
488
518
  ...(contextTier ? { contextTier } : {}),
489
519
  };
490
520
  }
@@ -527,6 +557,7 @@ export function estimateComboCost(
527
557
  ...(estimates.some(est => est.priorityMultiplier && est.priorityMultiplier !== 1)
528
558
  ? { priorityMultiplier: estimates.find(est => est.priorityMultiplier)?.priorityMultiplier }
529
559
  : {}),
560
+ ...(estimates.some(est => est.priorityLowerBound) ? { priorityLowerBound: true } : {}),
530
561
  ...(estimates.some(est => est.contextTier) ? { contextTier: "long" as const } : {}),
531
562
  };
532
563
  }
@@ -554,12 +585,17 @@ export function estimateRequestCost(
554
585
  const [effectiveCost4, multiplier] = contextTier
555
586
  ? [tieredCost4, 1] as const
556
587
  : applyPriorityMultiplier(tieredCost4, input.provider, input.model, input.serviceTier);
588
+ const priorityLowerBound = isOpenRouterPriorityLowerBound(
589
+ input.provider,
590
+ typeof input.serviceTier === "object" ? input.serviceTier.tierOutcome : undefined,
591
+ );
557
592
  return {
558
593
  tokens,
559
594
  price,
560
595
  cost: calculateCost(tokens, effectiveCost4),
561
596
  estimated: isEstimated(input.usage, input.usageStatus, price.status),
562
597
  ...(multiplier !== 1 ? { priorityMultiplier: multiplier } : {}),
598
+ ...(priorityLowerBound ? { priorityLowerBound: true } : {}),
563
599
  ...(contextTier ? { contextTier } : {}),
564
600
  };
565
601
  }
package/src/usage/log.ts CHANGED
@@ -84,6 +84,8 @@ export interface PersistedUsageEntry {
84
84
  conversationId?: string;
85
85
  resolvedModel?: string;
86
86
  requestedModel?: string;
87
+ /** Original bare helper model when the opt-in shadow-call route rewrote this request. */
88
+ shadowCallRewrittenFrom?: string;
87
89
  /** Reasoning effort / service-tier metadata for GUI Logs after restart. */
88
90
  requestedEffort?: string;
89
91
  /** Adapter-normalized tier and exact upstream parameter emitted for this request. */
@@ -427,6 +429,7 @@ function normalizeUsageEntry(entry: PersistedUsageEntry): PersistedUsageEntry {
427
429
  const tierOutcome = entry.tierOutcome ? normalizeAttemptTierOutcome(entry.tierOutcome) : undefined;
428
430
  const callerServiceTier = sanitizeLogMetadataString(entry.callerServiceTier);
429
431
  const responseServiceTier = sanitizeLogMetadataString(entry.responseServiceTier);
432
+ const shadowCallRewrittenFrom = sanitizeLogMetadataString(entry.shadowCallRewrittenFrom);
430
433
  const routeDecision = entry.routeDecision
431
434
  ? normalizeRouteDecisionTrace(entry.routeDecision)
432
435
  : undefined;
@@ -453,6 +456,7 @@ function normalizeUsageEntry(entry: PersistedUsageEntry): PersistedUsageEntry {
453
456
  : {}),
454
457
  ...(entry.resolvedModel ? { resolvedModel: entry.resolvedModel } : {}),
455
458
  ...(entry.requestedModel ? { requestedModel: entry.requestedModel } : {}),
459
+ ...(shadowCallRewrittenFrom ? { shadowCallRewrittenFrom } : {}),
456
460
  ...(typeof entry.requestedEffort === "string" && entry.requestedEffort
457
461
  ? { requestedEffort: capMetadataString(entry.requestedEffort) }
458
462
  : {}),
@@ -741,13 +741,20 @@ export async function runWithWebSearch(deps: WebSearchLoopDeps): Promise<Respons
741
741
  throw e;
742
742
  }
743
743
 
744
- const toolNsMap = new Map<string, { namespace: string; name: string }>();
744
+ const toolNsMap = new Map<string, { namespace: string; name: string; freeform?: true }>();
745
745
  const freeform = new Set<string>();
746
746
  const toolSearch = new Set<string>();
747
- const toolAllowed = toolChoiceToolPredicate(parsed.options.toolChoice);
748
- for (const t of parsed.context.tools ?? []) {
747
+ const requestedTools = parsed.context.tools ?? [];
748
+ const toolAllowed = toolChoiceToolPredicate(parsed.options.toolChoice, requestedTools);
749
+ for (const t of requestedTools) {
749
750
  if (!toolAllowed(t)) continue;
750
- if (t.namespace) toolNsMap.set(namespacedToolName(t.namespace, t.name), { namespace: t.namespace, name: t.name });
751
+ if (t.namespace) {
752
+ toolNsMap.set(namespacedToolName(t.namespace, t.name), {
753
+ namespace: t.namespace,
754
+ name: t.name,
755
+ ...(t.freeform ? { freeform: true } : {}),
756
+ });
757
+ }
751
758
  if (t.freeform) freeform.add(t.name);
752
759
  if (t.toolSearch) toolSearch.add(t.name);
753
760
  }