mirror of
https://github.com/harivansh-afk/clanker-agent.git
synced 2026-04-15 05:02:07 +00:00
fix: harden computer tool helper
- remove the unimplemented accessibility observe mode from the public contract - refuse unmatched app_open requests instead of shelling out - add direct helper tests for both review findings Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
parent
e1bba1c1a5
commit
a4250bad30
2 changed files with 65 additions and 3 deletions
|
|
@ -30,7 +30,7 @@ const computerActions = [
|
||||||
"clipboard_write",
|
"clipboard_write",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
const computerObservationModes = ["hybrid", "ocr", "accessibility"] as const;
|
const computerObservationModes = ["hybrid", "ocr"] as const;
|
||||||
|
|
||||||
const DEFAULT_COMPUTER_COMMAND =
|
const DEFAULT_COMPUTER_COMMAND =
|
||||||
process.env.COMPANION_AGENT_COMPUTER_COMMAND || "agent-computer";
|
process.env.COMPANION_AGENT_COMPUTER_COMMAND || "agent-computer";
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { mkdtempSync, rmSync } from "node:fs";
|
import { spawnSync } from "node:child_process";
|
||||||
|
import { existsSync, mkdtempSync, rmSync } from "node:fs";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { join } from "node:path";
|
import { join, resolve } from "node:path";
|
||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { parseArgs } from "../src/cli/args.js";
|
import { parseArgs } from "../src/cli/args.js";
|
||||||
import { buildSystemPrompt } from "../src/core/system-prompt.js";
|
import { buildSystemPrompt } from "../src/core/system-prompt.js";
|
||||||
|
|
@ -68,6 +69,13 @@ function createMockComputerOperations(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAgentComputerScriptPath(): string {
|
||||||
|
return resolve(
|
||||||
|
process.cwd(),
|
||||||
|
"../../../../docker/companion/agent-computer.js",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
describe("computer tool", () => {
|
describe("computer tool", () => {
|
||||||
const tempDirs: string[] = [];
|
const tempDirs: string[] = [];
|
||||||
|
|
||||||
|
|
@ -172,4 +180,58 @@ describe("computer tool", () => {
|
||||||
"Prefer browser for websites and DOM-aware tasks. Switch to computer",
|
"Prefer browser for websites and DOM-aware tasks. Switch to computer",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("rejects accessibility observe mode until a non-screenshot backend exists", () => {
|
||||||
|
const stateDir = createTempDir(
|
||||||
|
"coding-agent-computer-helper-accessibility-",
|
||||||
|
);
|
||||||
|
const result = spawnSync(
|
||||||
|
process.execPath,
|
||||||
|
[
|
||||||
|
"--no-warnings",
|
||||||
|
getAgentComputerScriptPath(),
|
||||||
|
"--state-dir",
|
||||||
|
stateDir,
|
||||||
|
"--input",
|
||||||
|
JSON.stringify({
|
||||||
|
action: "observe",
|
||||||
|
mode: "accessibility",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
encoding: "utf8",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.status).not.toBe(0);
|
||||||
|
expect(result.stderr).toContain(
|
||||||
|
"backend_unavailable: accessibility observe mode is not implemented",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("refuses to shell out when app_open cannot match an installed app", () => {
|
||||||
|
const stateDir = createTempDir("coding-agent-computer-helper-app-open-");
|
||||||
|
const markerPath = join(stateDir, "should-not-exist");
|
||||||
|
const result = spawnSync(
|
||||||
|
process.execPath,
|
||||||
|
[
|
||||||
|
"--no-warnings",
|
||||||
|
getAgentComputerScriptPath(),
|
||||||
|
"--state-dir",
|
||||||
|
stateDir,
|
||||||
|
"--input",
|
||||||
|
JSON.stringify({
|
||||||
|
action: "app_open",
|
||||||
|
app: `definitely-not-an-installed-app && touch ${markerPath}`,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
encoding: "utf8",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.status).not.toBe(0);
|
||||||
|
expect(result.stderr).toContain("app_not_found:");
|
||||||
|
expect(existsSync(markerPath)).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue