aboutsummaryrefslogtreecommitdiff
path: root/src/prompt.ts
blob: db0e6a4c8b272ca1cd1d79fc4b18d3aa11a4d258 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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 ${describeChrome(target)} through \`browser_*\` tools alongside the
standard pi tools. Per-tool usage lives in tool descriptions, parameter schemas,
and tool-specific guidelines.

- Operate only inside this session's owned Chrome window. Never reach into the
  user's other tabs or windows. Close owned tabs once no later step needs them.
- Mutating tools (click, type, fill, press_key, scroll, navigate, history, tab
  switch/new/close, upload, download, headers, viewport, drag, web_search) are
  serialized. Observations (snapshot, screenshot, page_info, current_tab, list_tabs,
  console, network_requests, http_get, read_page, execute_js, wait, wait_for) may run
  concurrently with them. \`browser_run_script\` bypasses that lane: keep mutating
  scripts sequential with other browser calls. Parallelize only independent calls.
- Agents sharing a session share its active tab. Check \`browser_current_tab\`
  before a mutation to confirm the expected tab when another agent may switch it.
- Read any appended "Page changes" diff to confirm an interaction. Tools without a
  diff, including \`browser_run_script\`, need explicit state verification.
- If a tool reports "ref is stale", call \`browser_snapshot\` for fresh refs before
  retrying; do not reuse the stale handle.
`;
}