




















@@ -26,33 +26,27 @@ function normalizeObservation(
26262727describe("normalizeFailoverDecisionObservationBase", () => {
2828it("fills timeout observation reasons for deadline timeouts without provider error text", () => {
29-expect(
30-normalizeObservation({
31-runId: "run:timeout",
32-timedOut: true,
33-}),
34-).toMatchObject({
35-failoverReason: "timeout",
36-profileFailureReason: "timeout",
29+const observation = normalizeObservation({
30+runId: "run:timeout",
3731timedOut: true,
3832});
33+expect(observation.failoverReason).toBe("timeout");
34+expect(observation.profileFailureReason).toBe("timeout");
35+expect(observation.timedOut).toBe(true);
3936});
40374138it("preserves explicit failover reasons", () => {
42-expect(
43-normalizeObservation({
44-runId: "run:overloaded",
45-rawError: '{"error":{"type":"overloaded_error"}}',
46-failoverReason: "overloaded",
47-profileFailureReason: "overloaded",
48-fallbackConfigured: true,
49-timedOut: true,
50-}),
51-).toMatchObject({
39+const observation = normalizeObservation({
40+runId: "run:overloaded",
41+rawError: '{"error":{"type":"overloaded_error"}}',
5242failoverReason: "overloaded",
5343profileFailureReason: "overloaded",
44+fallbackConfigured: true,
5445timedOut: true,
5546});
47+expect(observation.failoverReason).toBe("overloaded");
48+expect(observation.profileFailureReason).toBe("overloaded");
49+expect(observation.timedOut).toBe(true);
5650});
5751});
5852@@ -81,19 +75,23 @@ describe("createFailoverDecisionLogger", () => {
81758276logDecision("fallback_model");
837784-expect(warnSpy).toHaveBeenCalledWith(
85-"embedded run failover decision",
86-expect.objectContaining({
87-sourceProvider: "github-copilot",
88-sourceModel: "gpt-5.4-mini",
89-provider: "openai",
90-model: "gpt-5.4",
91-consoleMessage: expect.stringContaining("from=github-copilot/gpt-5.4-mini"),
92-}),
93-);
94-expect(
95-(warnSpy.mock.calls[0]?.[1] as { consoleMessage?: string } | undefined)?.consoleMessage,
96-).toContain("to=openai/gpt-5.4");
78+const [message, details] = warnSpy.mock.calls[0] ?? [];
79+expect(message).toBe("embedded run failover decision");
80+const observation = details as
81+| {
82+sourceProvider?: string;
83+sourceModel?: string;
84+provider?: string;
85+model?: string;
86+consoleMessage?: string;
87+}
88+| undefined;
89+expect(observation?.sourceProvider).toBe("github-copilot");
90+expect(observation?.sourceModel).toBe("gpt-5.4-mini");
91+expect(observation?.provider).toBe("openai");
92+expect(observation?.model).toBe("gpt-5.4");
93+expect(observation?.consoleMessage).toContain("from=github-copilot/gpt-5.4-mini");
94+expect(observation?.consoleMessage).toContain("to=openai/gpt-5.4");
9795});
98969997it("omits to model refs when the source matches the selected target", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。