


























@@ -2,6 +2,7 @@
22import fs from "node:fs/promises";
33import os from "node:os";
44import path from "node:path";
5+import { RequestedModelUnsupportedError } from "acpx/runtime";
56import { beforeEach, describe, expect, it, vi } from "vitest";
67import {
78AcpRuntimeError,
@@ -708,6 +709,100 @@ describe("AcpxRuntime fresh reset wrapper", () => {
708709});
709710});
710711712+it("retries without a model when ACPX reports missing model capability", async () => {
713+const baseStore: TestSessionStore = {
714+load: vi.fn(async () => undefined),
715+save: vi.fn(async () => {}),
716+};
717+const { runtime, delegate } = makeRuntime(baseStore, {
718+agentRegistry: {
719+resolve: (agentName: string) => (agentName === "opencode" ? "opencode acp" : agentName),
720+list: () => ["opencode"],
721+},
722+});
723+const ensure = vi
724+.spyOn(delegate, "ensureSession")
725+.mockRejectedValueOnce(
726+new RequestedModelUnsupportedError(
727+"Cannot apply --model: the ACP agent did not advertise model support",
728+"missing-capability",
729+),
730+)
731+.mockResolvedValueOnce({
732+sessionKey: "agent:opencode:acp:test",
733+backend: "acpx",
734+runtimeSessionName: "opencode",
735+});
736+737+await runtime.ensureSession({
738+sessionKey: "agent:opencode:acp:test",
739+agent: "opencode",
740+mode: "persistent",
741+model: "openrouter/owl-alpha",
742+});
743+744+expect(ensure).toHaveBeenCalledTimes(2);
745+expect(readFirstEnsureSessionInput(ensure)).toMatchObject({
746+model: "openrouter/owl-alpha",
747+sessionOptions: { model: "openrouter/owl-alpha" },
748+});
749+const [, secondCall] = ensure.mock.calls;
750+expect(secondCall?.[0]).not.toHaveProperty("sessionOptions");
751+expect((secondCall?.[0] as { model?: string } | undefined)?.model).toBeUndefined();
752+});
753+754+it("does not retry when ACPX rejects an explicitly unsupported model id", async () => {
755+const baseStore: TestSessionStore = {
756+load: vi.fn(async () => undefined),
757+save: vi.fn(async () => {}),
758+};
759+const { runtime, delegate } = makeRuntime(baseStore, {
760+agentRegistry: {
761+resolve: (agentName: string) => (agentName === "opencode" ? "opencode acp" : agentName),
762+list: () => ["opencode"],
763+},
764+});
765+const ensure = vi
766+.spyOn(delegate, "ensureSession")
767+.mockRejectedValueOnce(
768+new RequestedModelUnsupportedError(
769+"Cannot apply --model: the ACP agent did not advertise that model",
770+"unadvertised-model",
771+),
772+);
773+774+await expect(
775+runtime.ensureSession({
776+sessionKey: "agent:opencode:acp:test",
777+agent: "opencode",
778+mode: "persistent",
779+model: "unknown/model",
780+}),
781+).rejects.toThrow("did not advertise that model");
782+expect(ensure).toHaveBeenCalledTimes(1);
783+});
784+785+it("does not retry an unrelated error with similar wording", async () => {
786+const baseStore: TestSessionStore = {
787+load: vi.fn(async () => undefined),
788+save: vi.fn(async () => {}),
789+};
790+const { runtime, delegate } = makeRuntime(baseStore);
791+const ensure = vi
792+.spyOn(delegate, "ensureSession")
793+.mockRejectedValueOnce(new Error("the ACP agent did not advertise model support"));
794+795+await expect(
796+runtime.ensureSession({
797+sessionKey: "agent:main:acp:test",
798+agent: "main",
799+mode: "persistent",
800+model: "openrouter/owl-alpha",
801+}),
802+).rejects.toThrow("did not advertise model support");
803+expect(ensure).toHaveBeenCalledTimes(1);
804+});
805+711806it("injects Codex ACP startup config into the scoped registry", () => {
712807expect(testing.isCodexAcpCommand(CODEX_ACP_COMMAND)).toBe(true);
713808expect(testing.isCodexAcpCommand(CODEX_ACP_WRAPPER_COMMAND)).toBe(true);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。