Skip to content

Commit b84bfe9

Browse files
committed
fix: resolve instance IDs to driver kinds in ProviderCommandReactor
- Use the actual unknown provider slug in ProviderAdapterRequestError instead of hardcoding 'codex', so error messages and tracking correctly identify which driver caused the failure. - Resolve instance IDs to their underlying driver kind via ServerSettings.providerInstances, so custom instances (e.g. 'codex_personal') properly map to their driver and are not rejected at the ProviderKind narrowing check. - Compare driver kinds (not instance IDs) when checking for provider switches, so two instances of the same driver are correctly treated as compatible.
1 parent fb6a229 commit b84bfe9

1 file changed

Lines changed: 34 additions & 19 deletions

File tree

apps/server/src/orchestration/Layers/ProviderCommandReactor.ts

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,22 @@ const make = Effect.gen(function* () {
170170
),
171171
);
172172

173+
const resolveDriverKindForInstanceId = (
174+
instanceId: string,
175+
): Effect.Effect<ProviderKind | undefined> => {
176+
if (Schema.is(ProviderKind)(instanceId)) {
177+
return Effect.succeed(instanceId);
178+
}
179+
return serverSettingsService.getSettings.pipe(
180+
Effect.map((settings) => {
181+
const instances = settings.providerInstances as Record<string, { driver?: string }>;
182+
const driver = instances[instanceId]?.driver;
183+
return driver !== undefined && Schema.is(ProviderKind)(driver) ? driver : undefined;
184+
}),
185+
Effect.orElseSucceed(() => undefined),
186+
);
187+
};
188+
173189
const threadModelSelections = new Map<string, ModelSelection>();
174190

175191
const appendProviderFailureActivity = (input: {
@@ -277,29 +293,28 @@ const make = Effect.gen(function* () {
277293
? thread.session.providerName
278294
: undefined;
279295
const requestedModelSelection = options?.modelSelection;
280-
// The thread's model selection is keyed by `instanceId` (an open slug);
281-
// for built-in drivers the default instance id equals the driver id, so
282-
// narrow back to the closed `ProviderKind` here. Threads persisted
283-
// against a fork/unknown driver are surfaced via a structured error
284-
// rather than silently routed to the wrong provider.
285-
const threadProviderCandidate: string = currentProvider ?? thread.modelSelection.instanceId;
286-
if (!Schema.is(ProviderKind)(threadProviderCandidate)) {
296+
const threadInstanceId: string = currentProvider ?? thread.modelSelection.instanceId;
297+
const resolvedThreadDriver: ProviderKind | undefined =
298+
yield* resolveDriverKindForInstanceId(threadInstanceId);
299+
if (resolvedThreadDriver === undefined) {
287300
return yield* new ProviderAdapterRequestError({
288-
provider: "codex",
301+
provider: threadInstanceId,
289302
method: "thread.turn.start",
290-
detail: `Thread '${threadId}' references unknown provider driver '${threadProviderCandidate}'. The driver is not installed in this build (rolled-back / fork mismatch).`,
303+
detail: `Thread '${threadId}' references unknown provider driver '${threadInstanceId}'. The driver is not installed in this build (rolled-back / fork mismatch).`,
291304
});
292305
}
293-
const threadProvider: ProviderKind = threadProviderCandidate;
294-
if (
295-
requestedModelSelection !== undefined &&
296-
requestedModelSelection.instanceId !== threadProvider
297-
) {
298-
return yield* new ProviderAdapterRequestError({
299-
provider: threadProvider,
300-
method: "thread.turn.start",
301-
detail: `Thread '${threadId}' is bound to provider '${threadProvider}' and cannot switch to '${requestedModelSelection.instanceId}'.`,
302-
});
306+
const threadProvider: ProviderKind = resolvedThreadDriver;
307+
if (requestedModelSelection !== undefined) {
308+
const requestedDriver: ProviderKind | undefined = yield* resolveDriverKindForInstanceId(
309+
requestedModelSelection.instanceId,
310+
);
311+
if (requestedDriver !== threadProvider) {
312+
return yield* new ProviderAdapterRequestError({
313+
provider: threadProvider,
314+
method: "thread.turn.start",
315+
detail: `Thread '${threadId}' is bound to provider '${threadProvider}' and cannot switch to '${requestedModelSelection.instanceId}'.`,
316+
});
317+
}
303318
}
304319
const preferredProvider: ProviderKind = threadProvider;
305320
const desiredModelSelection = requestedModelSelection ?? thread.modelSelection;

0 commit comments

Comments
 (0)