Skip to content

Commit afcd9f3

Browse files
blazejpawlakclaude
andcommitted
test(orchestrator): verify agent is preserved across fallback replay
Add two cases to the orchestrator test suite: - agent name from the failing message is passed to session.prompt - agent is omitted (undefined) when it could not be resolved Also extend MockClientCalls.prompt to capture the agent field. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent dca6ff1 commit afcd9f3

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

test/helpers/mock-client.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface MockMessageEntry {
1111
export interface MockClientCalls {
1212
abort: string[];
1313
revert: Array<{ sessionId: string; messageID: string }>;
14-
prompt: Array<{ sessionId: string; providerID: string; modelID: string; parts: unknown[] }>;
14+
prompt: Array<{ sessionId: string; providerID: string; modelID: string; agent?: string; parts: unknown[] }>;
1515
toasts: Array<{ title?: string; message: string; variant: string }>;
1616
logs: Array<{ level: string; message: string }>;
1717
}
@@ -52,13 +52,14 @@ export function makeMockClient(opts: MockClientOptions = {}): {
5252
},
5353
prompt: async (options: {
5454
path: { id: string };
55-
body?: { model?: { providerID: string; modelID: string }; parts?: unknown[] };
55+
body?: { model?: { providerID: string; modelID: string }; agent?: string; parts?: unknown[] };
5656
}) => {
5757
if (opts.promptError) throw opts.promptError;
5858
calls.prompt.push({
5959
sessionId: options.path.id,
6060
providerID: options.body?.model?.providerID ?? "",
6161
modelID: options.body?.model?.modelID ?? "",
62+
agent: options.body?.agent,
6263
parts: options.body?.parts ?? [],
6364
});
6465
return { data: {} };

test/orchestrator.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,41 @@ describe("attemptFallback — concurrency", () => {
453453
});
454454
});
455455

456+
// ─── Agent preservation ───────────────────────────────────────────────────────
457+
458+
describe("attemptFallback — agent preservation", () => {
459+
it("passes the agent name to the prompt call so the fallback model runs under the same agent", async () => {
460+
const { client, calls } = makeMockClient({
461+
messages: [makeUserMessage("s1", "m1", "openai", "gpt-5.3-codex", "OpenCoder")],
462+
});
463+
const store = makeStore();
464+
store.sessions.setOriginalModel("s1", "openai/gpt-5.3-codex");
465+
const logger = new Logger(client, "/tmp/test.log", false);
466+
467+
await attemptFallback("s1", "rate_limit", client, store, BASE_CONFIG, logger, "/tmp");
468+
469+
expect(calls.prompt).toHaveLength(1);
470+
expect(calls.prompt[0].agent).toBe("OpenCoder");
471+
});
472+
473+
it("omits agent from prompt when it could not be resolved", async () => {
474+
// No agent field in the message → agentName resolves to null
475+
const msg = makeUserMessage("s1", "m1", "openai", "gpt-5.3-codex");
476+
// Strip the agent field so resolveAgentName has nothing to work with
477+
(msg.info as any).agent = undefined;
478+
479+
const { client, calls } = makeMockClient({ messages: [msg] });
480+
const store = makeStore();
481+
store.sessions.setOriginalModel("s1", "openai/gpt-5.3-codex");
482+
const logger = new Logger(client, "/tmp/test.log", false);
483+
484+
await attemptFallback("s1", "rate_limit", client, store, BASE_CONFIG, logger, "/tmp");
485+
486+
expect(calls.prompt).toHaveLength(1);
487+
expect(calls.prompt[0].agent).toBeUndefined();
488+
});
489+
});
490+
456491
// ─── Replay step failures ─────────────────────────────────────────────────────
457492

458493
describe("attemptFallback — replay step failures", () => {

0 commit comments

Comments
 (0)