History

fix: filter synthetic 'default' service tier and close registry sync probe race

Bug 1: getCodexServiceTierOptionValue now returns undefined when the persisted serviceTier value is the synthetic 'default' id used only as a UI select option. Previously this forwarded 'default' to the API, which overrides project-level routing settings. Standard routing should omit the tier entirely (matching pre-change behavior). Bug 2: Add a deferred re-read of instance snapshots after the forked stream consumers have had time to subscribe. The managed provider updates its snapshot ref before publishing to its PubSub, so re-reading after a yield captures any probe result that landed between the initial getSnapshot and the subscriber becoming active.

Cursor Agent committed 5 months ago

Commit cb4e8f41 parent 34629c22 files · +24 −3Browse files

Unified · Split

2 files
  1. apps/server/src/codexModelOptions.ts +4 −3
  2. apps/server/src/provider/Layers/ProviderRegistry.ts +20 −0
apps/server/src/codexModelOptions.ts+4−3
@@ -7,8 +7,9 @@ import { · 6 unmodified lines
77 export function getCodexServiceTierOptionValue(
88 modelSelection: ModelSelection | null | undefined,
99 ): string | undefined {
10− return (
10+ const tier =
1111 getModelSelectionStringOptionValue(modelSelection, "serviceTier") ??
12− (getModelSelectionBooleanOptionValue(modelSelection, "fastMode") === true ? "fast" : undefined)
13− );
12+ (getModelSelectionBooleanOptionValue(modelSelection, "fastMode") === true ? "fast" : undefined);
13+ if (tier === "default") return undefined;
14+ return tier;
1415 }
apps/server/src/provider/Layers/ProviderRegistry.ts+20−0
@@ -569,6 +569,26 @@ export const ProviderRegistryLive = Layer.effect( · 568 unmodified lines
569569 }).pipe(Effect.ignoreCause({ log: true })),
570570 { concurrency: "unbounded", discard: true },
571571 );
572+
573+ // Re-read snapshots after yielding to close the race between
574+ // subscription establishment and the initial read. The managed
575+ // provider updates its snapshot ref before publishing to the
576+ // PubSub, so this second read captures any probe that landed
577+ // after the first getSnapshot but before the forked subscriber
578+ // became active. The subscriber then handles all future updates.
579+ yield* Effect.yieldNow;
580+ yield* Effect.forEach(
581+ newlyAdded,
582+ ([, instance]) =>
583+ Effect.gen(function* () {
584+ const source = buildSnapshotSource(instance);
585+ const provider = yield* source.getSnapshot;
586+ yield* correlateSnapshotWithSource(source, provider).pipe(
587+ Effect.flatMap(syncProvider),
588+ );
589+ }).pipe(Effect.ignoreCause({ log: true })),
590+ { concurrency: "unbounded", discard: true },
591+ );
572592 yield* upsertProviders(unavailableProviders, {
573593 persist: false,
574594 replace: true,