diff options
| author | Igor Soarez <igor@soarez.org> | 2026-09-13 18:30:51 +0100 |
|---|---|---|
| committer | Igor Soarez <igor@soarez.org> | 2026-10-14 12:19:26 +0100 |
| commit | 792336dfef913291358f2312cd82c55944d18199 (patch) | |
| tree | 623af861c7a41d1afc865e3945b7b9b37036e778 | |
| parent | c8fd7b7078da841d5537aee9334291887445889f (diff) | |
feat(prompt): say which Chrome browser_* drives
The prompt told the model it drives "the user's running instance". With this
fork's default that is wrong: it is castle's shared Chrome, signed out of every
account. It now matters which is which, because pi-chrome's chrome_* tools
drive the user's signed-in Brave, and the model has to route between the two.
getBrowserSystemPrompt() takes the resolved target and describes it: castle's
shared browser for the built-in default, the user's own Chrome for local, the
endpoint otherwise.
| -rw-r--r-- | src/index.ts | 3 | ||||
| -rw-r--r-- | src/prompt.ts | 21 |
2 files changed, 21 insertions, 3 deletions
diff --git a/src/index.ts b/src/index.ts index 152c94d..e4d23f8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -261,8 +261,9 @@ export default function browserHarnessExtension(pi: ExtensionAPI): void { }); pi.on("before_agent_start", async (event) => { + const target = resolveCdpTarget(process.env, await readTarget()); return { - systemPrompt: event.systemPrompt + getBrowserSystemPrompt(client?.status().alive ?? false), + systemPrompt: event.systemPrompt + getBrowserSystemPrompt(client?.status().alive ?? false, target), }; }); } diff --git a/src/prompt.ts b/src/prompt.ts index 4fb78a7..db0e6a4 100644 --- a/src/prompt.ts +++ b/src/prompt.ts @@ -1,11 +1,28 @@ -export function getBrowserSystemPrompt(connected = true): string { +import { type CdpTarget, DEFAULT_REMOTE_CDP } from "./cdp/endpoint"; + +/** + * FORK: which Chrome browser_* drives. Upstream always means "the user's own + * Chrome"; here the default is castle's shared one, signed out of everything, + * and pi-chrome's chrome_* tools drive a signed-in Brave - so the model has to + * be told which is which to route between them. + */ +const describeChrome = (target?: CdpTarget): string => { + if (!target || target.kind === "invalid") return "a real Chrome (not headless)"; + if (target.kind === "local") return "a real Chrome (the user's own, on this machine)"; + if (`${target.host}:${target.port}` === DEFAULT_REMOTE_CDP) { + return "a real Chrome (castle's shared browser on the wire network, signed out of every account — not the user's own browser)"; + } + return `a real Chrome (the one at ${target.host}:${target.port})`; +}; + +export function getBrowserSystemPrompt(connected = true, target?: CdpTarget): string { const connectionNotice = connected ? "" : "Browser is not connected. Run browser_setup or /browser-setup to connect.\n\n"; return ` ## Browser Control -${connectionNotice}You control the user's running Chrome through \`browser_*\` tools alongside the +${connectionNotice}You control ${describeChrome(target)} through \`browser_*\` tools alongside the standard pi tools. Per-tool usage lives in tool descriptions, parameter schemas, and tool-specific guidelines. |
