

























1+// Coverage for handing replay-safe plugin-harness prompt timeouts to model fallback.
2+import { beforeAll, beforeEach, describe, expect, it } from "vitest";
3+import { makeModelFallbackCfg } from "../test-helpers/model-fallback-config-fixture.js";
4+import { makeAttemptResult } from "./run.overflow-compaction.fixture.js";
5+import {
6+loadRunOverflowCompactionHarness,
7+MockedFailoverError,
8+mockedClassifyFailoverReason,
9+mockedRunEmbeddedAttempt,
10+overflowBaseRunParams,
11+resetRunOverflowCompactionHarnessMocks,
12+} from "./run.overflow-compaction.harness.js";
13+14+let runEmbeddedAgent: typeof import("./run.js").runEmbeddedAgent;
15+16+describe("runEmbeddedAgent prompt timeout fallback handoff", () => {
17+beforeAll(async () => {
18+({ runEmbeddedAgent } = await loadRunOverflowCompactionHarness());
19+});
20+21+beforeEach(() => {
22+resetRunOverflowCompactionHarnessMocks();
23+});
24+25+it("throws FailoverError for replay-safe harness-owned prompt timeouts when model fallbacks are configured", async () => {
26+mockedClassifyFailoverReason.mockReturnValue("timeout");
27+mockedRunEmbeddedAttempt.mockResolvedValueOnce(
28+makeAttemptResult({
29+assistantTexts: [],
30+promptError: new Error("LLM request timed out."),
31+promptErrorSource: "prompt",
32+}),
33+);
34+35+const promise = runEmbeddedAgent({
36+ ...overflowBaseRunParams,
37+provider: "openai",
38+model: "gpt-5.4",
39+runId: "run-prompt-timeout-fallback",
40+config: makeModelFallbackCfg({
41+agents: {
42+defaults: {
43+model: {
44+primary: "openai/gpt-5.4",
45+fallbacks: ["anthropic/claude-opus-4-6"],
46+},
47+},
48+},
49+}),
50+});
51+52+await expect(promise).rejects.toBeInstanceOf(MockedFailoverError);
53+await expect(promise).rejects.toThrow("LLM request timed out.");
54+expect(mockedRunEmbeddedAttempt).toHaveBeenCalledTimes(1);
55+});
56+57+it("surfaces replay-invalid prompt timeouts instead of handing them to model fallback", async () => {
58+mockedClassifyFailoverReason.mockReturnValue("timeout");
59+mockedRunEmbeddedAttempt.mockResolvedValueOnce(
60+makeAttemptResult({
61+assistantTexts: [],
62+promptError: new Error("LLM request timed out."),
63+promptErrorSource: "prompt",
64+promptTimeoutOutcome: {
65+message: "Harness abandoned the timed-out turn after provider activity.",
66+replayInvalid: true,
67+livenessState: "abandoned",
68+},
69+}),
70+);
71+72+let thrown: unknown;
73+try {
74+await runEmbeddedAgent({
75+ ...overflowBaseRunParams,
76+provider: "openai",
77+model: "gpt-5.4",
78+runId: "run-prompt-timeout-replay-invalid",
79+config: makeModelFallbackCfg({
80+agents: {
81+defaults: {
82+model: {
83+primary: "openai/gpt-5.4",
84+fallbacks: ["anthropic/claude-opus-4-6"],
85+},
86+},
87+},
88+}),
89+});
90+} catch (err) {
91+thrown = err;
92+}
93+94+expect(thrown).toBeInstanceOf(Error);
95+expect(thrown).not.toBeInstanceOf(MockedFailoverError);
96+expect(String((thrown as Error | undefined)?.message)).toContain("LLM request timed out.");
97+expect(mockedRunEmbeddedAttempt).toHaveBeenCalledTimes(1);
98+});
99+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。