Clarify ACPX session config failures

This commit is contained in:
Dotta committed 2026-05-05 12:13:35 -05:00
1 parent ace632af3e
commit 27bb649dd3
3 files changed
+45 -2

No files matched your search

@@ -832,7 +832,10 @@ async function applySessionConfigOptions(input: {
const options = sessionConfigOptions(input.prepared);
if (options.length === 0) return;
if (!input.runtime.setConfigOption) {
throw new Error("ACPX runtime does not expose session config controls.");
const message =
"ACPX runtime does not expose session config controls; upgrade ACPX or remove configured model, effort, and fast mode overrides.";
await input.onLog("stderr", `[paperclip] ${message}\n`);
throw new Error(message);
}
for (const option of options) {
await input.runtime.setConfigOption({
@@ -5,6 +5,7 @@ import {
DEFAULT_ACPX_LOCAL_NON_INTERACTIVE_PERMISSIONS,
DEFAULT_ACPX_LOCAL_PERMISSION_MODE,
DEFAULT_ACPX_LOCAL_TIMEOUT_SEC,
DEFAULT_ACPX_LOCAL_WARM_HANDLE_IDLE_MS,
} from "../index.js";
function parseCommaArgs(value: string): string[] {
@@ -88,7 +89,7 @@ export function buildAcpxLocalConfig(v: CreateConfigValues): Record<string, unkn
nonInteractivePermissions:
schemaValues.nonInteractivePermissions || DEFAULT_ACPX_LOCAL_NON_INTERACTIVE_PERMISSIONS,
timeoutSec: readNumber(schemaValues.timeoutSec, DEFAULT_ACPX_LOCAL_TIMEOUT_SEC),
warmHandleIdleMs: readNumber(schemaValues.warmHandleIdleMs, 0),
warmHandleIdleMs: readNumber(schemaValues.warmHandleIdleMs, DEFAULT_ACPX_LOCAL_WARM_HANDLE_IDLE_MS),
};
for (const key of [
@@ -273,6 +273,45 @@ describe("acpx_local execute", () => {
}
});
it("logs a clear error when configured session options need unsupported runtime controls", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-acpx-missing-config-controls-"));
try {
const runtime = new FakeRuntime({} as AcpRuntimeOptions);
Object.defineProperty(runtime, "setConfigOption", { value: undefined });
const logs: LogEntry[] = [];
const execute = createAcpxLocalExecutor({
createRuntime: () => runtime,
});
const result = await execute(buildContext(root, {
config: {
agent: "codex",
cwd: root,
stateDir: path.join(root, "state"),
promptTemplate: "Do the assigned work.",
model: "gpt-5.4",
},
onLog: async (stream, chunk) => logs.push({ stream, chunk }),
}));
expect(result.exitCode).toBe(1);
expect(result.errorMessage).toContain("does not expose session config controls");
expect(logs).toEqual(expect.arrayContaining([
expect.objectContaining({
stream: "stderr",
chunk: expect.stringContaining("upgrade ACPX or remove configured model"),
}),
]));
expect(runtime.closeInputs).toEqual([
expect.objectContaining({
reason: "paperclip config cleanup",
discardPersistentState: false,
}),
]);
} finally {
await fs.rm(root, { recursive: true, force: true });
}
});
it("reuses a compatible warm session and starts fresh when cwd changes", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-acpx-reuse-"));
const other = path.join(root, "other");