Revert "fix(runner): name an ACP agent's rejection of an unadvertised model"

This reverts commit 35aff22dd3.
This commit is contained in:
Dotta committed 2026-11-10 03:50:33 -06:00
1 parent 35aff22dd3
commit 6b2142eb00
2 files changed
+1 -52

No files matched your search

@@ -2,7 +2,6 @@ import { describe, expect, it, vi } from "vitest";
import { resolveQualifiedAcpxProfile } from "./qualified-profiles.js";
import { requireVerifiedAcpxModel } from "./model-verification.js";
import { acpxSidecarErrorCode } from "../../cli/acpx-sidecar-input.js";
describe("ACPX requested model verification", () => {
it.each(["claude", "codex", "pi", "grok", "cursor", "copilot"] as const)("selects and verifies an unlisted model unchanged with %s", async agent => {
@@ -30,33 +29,6 @@ describe("ACPX requested model verification", () => {
expect(getStatus).toHaveBeenCalledTimes(1);
});
it.each(["claude", "codex", "pi", "grok", "cursor", "copilot"] as const)("names an ACP rejection of an unadvertised model as an unsupported model with %s", async agent => {
const model = "chaos-missing-model-abc12345";
// claude-agent-acp 0.73.0 answers session/set_config_option for an unknown model with this
// JSON-RPC error; ACPX wraps it as below (live probe, 2026-11-10).
const acp = Object.assign(new Error("Internal error"), {
code: -32603, data: { details: `Invalid value for config option model: ${model}` },
});
const wrapped = new Error(`Failed session/set_config_option for model "${model}": Invalid value for config option model: ${model} (ACP -32603, adapter reported "Internal error")`, { cause: acp });
const getStatus = vi.fn(async () => ({ models: { currentModelId: "default", availableModelIds: ["default", "opus", "sonnet"] } }));
const setModel = vi.fn(async () => { throw wrapped; });
const failure = await requireVerifiedAcpxModel({ getStatus, setModel }, resolveQualifiedAcpxProfile(agent, model))
.then(() => null, (error: unknown) => error as Error & { code?: unknown; retryable?: unknown });
expect(failure).toMatchObject({ code: "ACP_MODEL_UNSUPPORTED", retryable: false });
expect(failure?.cause).toBe(wrapped);
expect(acpxSidecarErrorCode(failure!)).toBe("ACP_MODEL_UNSUPPORTED");
});
it("keeps a transport failure or an advertised model's rejection unchanged", async () => {
const acp = Object.assign(new Error("Internal error"), { code: -32603, data: { details: "busy" } });
for (const [rejected, available] of [[new Error("socket closed"), ["default"]], [acp, ["default", "listed-model"]]] as const) {
const getStatus = vi.fn(async () => ({ models: { currentModelId: "default", availableModelIds: [...available] } }));
const setModel = vi.fn(async () => { throw rejected; });
await expect(requireVerifiedAcpxModel({ getStatus, setModel }, resolveQualifiedAcpxProfile("claude", "listed-model")))
.rejects.toBe(rejected);
}
});
it("accepts an exact model already reported by the provider", async () => {
const getStatus = vi.fn(async () => ({
models: {
@@ -38,22 +38,7 @@ export async function requireVerifiedAcpxModel(
);
}
// Catalogs may be incomplete. Let the provider accept or reject the exact ID.
try {
await control.setModel(providerModel);
} catch (error) {
// The provider answered the selection of a model it does not advertise with
// an ACP error: it rejected that model. Name it as such so the task asks the
// user to choose a model. Transport failures and an advertised model's
// rejection keep their original error.
const advertised = status.models?.availableModelIds ?? [];
if (!advertised.includes(providerModel) && acpErrorResponse(error)) {
throw Object.assign(
new Error(`ACP agent rejected the requested model ${requestedModel}`, { cause: error }),
{ code: "ACP_MODEL_UNSUPPORTED", retryable: false },
);
}
throw error;
}
await control.setModel(providerModel);
status = await control.getStatus();
}
if (status.models?.currentModelId !== providerModel) {
@@ -65,14 +50,6 @@ export async function requireVerifiedAcpxModel(
return normalizeVerifiedModelStatus(status, profile);
}
/** A JSON-RPC error response from the ACP agent, found on the error or its causes. */
function acpErrorResponse(error: unknown, depth = 0): boolean {
if (!error || typeof error !== "object" || depth > 5) return false;
const entry = error as Record<string, unknown>;
if (typeof entry.code === "number" && Number.isInteger(entry.code) && typeof entry.message === "string") return true;
return ["acp", "cause", "error"].some(key => acpErrorResponse(entry[key], depth + 1));
}
function acpxModelVerificationError(code: string, message: string): Error {
return Object.assign(new Error(message), { code });
}