



























@@ -100,15 +100,36 @@ function registerFailingCodexHarness(): void {
100100}
101101102102describe("runAgentHarnessAttemptWithFallback", () => {
103-it("falls back to the PI harness when a forced plugin harness is unavailable", async () => {
103+it("fails when a forced plugin harness is unavailable and fallback is omitted", async () => {
104104process.env.OPENCLAW_AGENT_RUNTIME = "codex";
105105106+await expect(runAgentHarnessAttemptWithFallback(createAttemptParams())).rejects.toThrow(
107+'Requested agent harness "codex" is not registered and PI fallback is disabled.',
108+);
109+expect(piRunAttempt).not.toHaveBeenCalled();
110+});
111+112+it("falls back to the PI harness for a forced plugin harness only when explicitly configured", async () => {
113+process.env.OPENCLAW_AGENT_RUNTIME = "codex";
114+process.env.OPENCLAW_AGENT_HARNESS_FALLBACK = "pi";
115+106116const result = await runAgentHarnessAttemptWithFallback(createAttemptParams());
107117108118expect(result.sessionIdUsed).toBe("pi");
109119expect(piRunAttempt).toHaveBeenCalledTimes(1);
110120});
111121122+it("does not inherit config fallback when env forces a plugin harness", async () => {
123+process.env.OPENCLAW_AGENT_RUNTIME = "codex";
124+125+await expect(
126+runAgentHarnessAttemptWithFallback(
127+createAttemptParams({ agents: { defaults: { embeddedHarness: { fallback: "pi" } } } }),
128+),
129+).rejects.toThrow('Requested agent harness "codex" is not registered');
130+expect(piRunAttempt).not.toHaveBeenCalled();
131+});
132+112133it("falls back to the PI harness in auto mode when no plugin harness matches", async () => {
113134process.env.OPENCLAW_AGENT_RUNTIME = "auto";
114135@@ -177,6 +198,56 @@ describe("runAgentHarnessAttemptWithFallback", () => {
177198).rejects.toThrow("PI fallback is disabled");
178199expect(piRunAttempt).not.toHaveBeenCalled();
179200});
201+202+it("fails for config-forced plugin harnesses when fallback is omitted", async () => {
203+await expect(
204+runAgentHarnessAttemptWithFallback(
205+createAttemptParams({ agents: { defaults: { embeddedHarness: { runtime: "codex" } } } }),
206+),
207+).rejects.toThrow('Requested agent harness "codex" is not registered');
208+expect(piRunAttempt).not.toHaveBeenCalled();
209+});
210+211+it("allows config-forced plugin harnesses to opt into PI fallback", async () => {
212+const result = await runAgentHarnessAttemptWithFallback(
213+createAttemptParams({
214+agents: { defaults: { embeddedHarness: { runtime: "codex", fallback: "pi" } } },
215+}),
216+);
217+218+expect(result.sessionIdUsed).toBe("pi");
219+expect(piRunAttempt).toHaveBeenCalledTimes(1);
220+});
221+222+it("does not inherit default fallback when an agent forces a plugin harness", async () => {
223+await expect(
224+runAgentHarnessAttemptWithFallback({
225+ ...createAttemptParams({
226+agents: {
227+defaults: { embeddedHarness: { fallback: "pi" } },
228+list: [{ id: "strict", embeddedHarness: { runtime: "codex" } }],
229+},
230+}),
231+sessionKey: "agent:strict:session-1",
232+}),
233+).rejects.toThrow('Requested agent harness "codex" is not registered');
234+expect(piRunAttempt).not.toHaveBeenCalled();
235+});
236+237+it("lets an agent-forced plugin harness opt into PI fallback", async () => {
238+const result = await runAgentHarnessAttemptWithFallback({
239+ ...createAttemptParams({
240+agents: {
241+defaults: { embeddedHarness: { fallback: "none" } },
242+list: [{ id: "strict", embeddedHarness: { runtime: "codex", fallback: "pi" } }],
243+},
244+}),
245+sessionKey: "agent:strict:session-1",
246+});
247+248+expect(result.sessionIdUsed).toBe("pi");
249+expect(piRunAttempt).toHaveBeenCalledTimes(1);
250+});
180251});
181252182253describe("selectAgentHarness", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。