windows-use 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +67 -15
- package/dist/cli.js.map +1 -1
- package/dist/index.js +37 -12
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +37 -12
- package/dist/mcp/server.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -91,21 +91,49 @@ function buildSystemPrompt() {
|
|
|
91
91
|
return `You are a precise Windows and browser automation agent. Your job is to execute instructions by calling the tools available to you.
|
|
92
92
|
|
|
93
93
|
## Workflow
|
|
94
|
-
1. Take a screenshot first to understand the current state of the screen.
|
|
94
|
+
1. Take a \`screenshot\` first to understand the current state of the screen.
|
|
95
95
|
2. Plan the minimal sequence of actions needed.
|
|
96
|
-
3. Execute
|
|
96
|
+
3. Execute actions, verifying with screenshots at key checkpoints (not after every single action).
|
|
97
97
|
4. When the task is done, you are blocked, or you need guidance, call \`report\` immediately.
|
|
98
98
|
|
|
99
|
+
## Reading Screenshots
|
|
100
|
+
- Desktop screenshots include a **coordinate grid overlay**. The grid labels show pixel coordinates that directly correspond to \`mouse_click\` and \`mouse_move\` coordinates.
|
|
101
|
+
- Use the grid numbers to estimate the (x, y) position of UI elements. For example, if a button appears near the grid label "400" horizontally and "300" vertically, click at approximately (400, 300).
|
|
102
|
+
- The bottom-right corner label shows the total screen dimensions.
|
|
103
|
+
|
|
104
|
+
## Tool Selection
|
|
105
|
+
- **Browser tasks**: Prefer \`browser_*\` tools (they use CSS selectors, more reliable than coordinates). Use \`browser_content\` to find text/elements when you can't locate them visually.
|
|
106
|
+
- **Desktop/native app tasks**: Use \`screenshot\` + \`mouse_click\`/\`keyboard_*\`. Read coordinates from the grid overlay.
|
|
107
|
+
- **Terminal tasks**: Prefer \`run_command\` over GUI interactions. It's faster and more reliable.
|
|
108
|
+
- **Mixed tasks**: You can combine all tool types. For example, use \`run_command\` to launch an app, then \`screenshot\` + mouse to interact with it.
|
|
109
|
+
|
|
110
|
+
## Smart Screenshot Strategy
|
|
111
|
+
- ALWAYS take a screenshot before your first action.
|
|
112
|
+
- Take a screenshot to verify after **critical actions** (clicking a button, submitting a form, navigating to a new page).
|
|
113
|
+
- Skip verification screenshots for **low-risk sequential actions** (typing text, pressing modifier keys, scrolling) \u2014 verify after the sequence is complete instead.
|
|
114
|
+
- If an action might trigger a loading state, wait briefly then screenshot to confirm the page has loaded.
|
|
115
|
+
|
|
99
116
|
## Rules
|
|
100
|
-
- ALWAYS take a screenshot before your first action to understand the current state.
|
|
101
|
-
- After every mouse click or keyboard action, take a screenshot to verify the result.
|
|
102
117
|
- Call ONE tool at a time. Never request multiple tools in parallel.
|
|
103
118
|
- Before each tool call, briefly state what you are about to do and why.
|
|
104
119
|
- After receiving a tool result, describe what you observed.
|
|
105
|
-
- For browser tasks, prefer using browser_* tools over clicking on-screen coordinates.
|
|
106
|
-
- For terminal tasks, prefer \`run_command\` over GUI interactions when possible.
|
|
107
120
|
- Do not read or write files unless the instruction explicitly asks for it.
|
|
108
121
|
|
|
122
|
+
## Handling Common Situations
|
|
123
|
+
- **Loading/transitions**: If a page or app is loading, take another screenshot after a moment instead of acting immediately.
|
|
124
|
+
- **Popups/dialogs**: Handle unexpected dialogs (cookie banners, notifications, confirmations) by dismissing or accepting them, then continue with the original task.
|
|
125
|
+
- **Dropdowns/menus**: Click to open, then screenshot to see options before selecting.
|
|
126
|
+
- **Scrolling**: If content is below the fold, scroll down and screenshot. Check both browser_scroll (for web pages) and mouse_scroll (for desktop apps).
|
|
127
|
+
- **Text input**: For browser forms, prefer \`browser_type\` with the CSS selector. For desktop apps, click the input field first, then use \`keyboard_type\`.
|
|
128
|
+
- **Coordinate precision**: When clicking small UI elements (buttons, links, checkboxes), aim for their center. If a click misses, adjust coordinates and try once more.
|
|
129
|
+
|
|
130
|
+
## Error Recovery
|
|
131
|
+
- If an action fails or produces unexpected results, take a screenshot to reassess the situation before trying again.
|
|
132
|
+
- Try a different approach rather than repeating the same failed action. For example:
|
|
133
|
+
- If \`browser_click\` fails on a selector, try a different selector or fall back to coordinate-based \`mouse_click\`.
|
|
134
|
+
- If a UI element is not visible, try scrolling or switching tabs/windows.
|
|
135
|
+
- If something fails **twice with different approaches**, call \`report\` with status "blocked".
|
|
136
|
+
|
|
109
137
|
## report Tool
|
|
110
138
|
Call \`report\` when:
|
|
111
139
|
- **"completed"**: The task is done successfully. Summarize what was accomplished.
|
|
@@ -121,12 +149,9 @@ report({
|
|
|
121
149
|
})
|
|
122
150
|
\`\`\`
|
|
123
151
|
|
|
124
|
-
Each screenshot tool returns a screenshot ID (e.g. img_1, img_2). Use these IDs to embed images in your report.
|
|
152
|
+
Each screenshot tool returns a screenshot ID (e.g. img_1, img_2). Use these IDs to embed images in your report. Include relevant screenshots in your report so the caller can see the final state.
|
|
125
153
|
|
|
126
|
-
|
|
127
|
-
- Do NOT keep retrying the same failing action. If something fails twice, call \`report\` with status "blocked".
|
|
128
|
-
- If a UI element is not where you expect it, try scrolling first before giving up.
|
|
129
|
-
- Keep your responses concise. Focus on actions, not explanations.`;
|
|
154
|
+
You can also use \`use_local_image\` to load a local image file and get a screenshot ID for embedding in reports.`;
|
|
130
155
|
}
|
|
131
156
|
|
|
132
157
|
// src/agent/runner.ts
|
|
@@ -709,7 +734,7 @@ var screenshotTool = {
|
|
|
709
734
|
const image = primary.captureImageSync();
|
|
710
735
|
const physW = image.width;
|
|
711
736
|
const physH = image.height;
|
|
712
|
-
const scaleFactor = primary.scaleFactor ?? 1;
|
|
737
|
+
const scaleFactor = primary.scaleFactor() ?? 1;
|
|
713
738
|
const logicalW = Math.round(physW / scaleFactor);
|
|
714
739
|
const logicalH = Math.round(physH / scaleFactor);
|
|
715
740
|
const raw = image.toRawSync();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/loader.ts","../src/config/schema.ts","../src/mcp/session-registry.ts","../src/agent/context-manager.ts","../src/agent/llm-client.ts","../src/agent/system-prompt.ts","../src/agent/runner.ts","../src/tools/browser/client.ts","../src/tools/zod-to-json.ts","../src/tools/registry.ts","../src/tools/windows/screenshot.ts","../src/tools/windows/grid-overlay.ts","../src/tools/windows/mouse.ts","../src/tools/windows/keyboard.ts","../src/tools/windows/command.ts","../src/tools/file/read.ts","../src/tools/file/write.ts","../src/tools/file/image.ts","../src/tools/browser/navigate.ts","../src/tools/browser/click.ts","../src/tools/browser/type.ts","../src/tools/browser/screenshot.ts","../src/tools/browser/content.ts","../src/tools/browser/scroll.ts","../src/tools/control/report.ts","../src/tools/index.ts","../src/tools/types.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { ConfigSchema, type Config } from './schema.js';\n\nconst CONFIG_FILE = join(homedir(), '.windows-use.json');\n\nexport interface FileConfig {\n apiKey?: string;\n baseURL?: string;\n model?: string;\n maxSteps?: number;\n maxRounds?: number;\n cdpUrl?: string;\n timeoutMs?: number;\n}\n\n/** Load saved config from ~/.windows-use.json */\nexport function loadFileConfig(): FileConfig {\n if (!existsSync(CONFIG_FILE)) return {};\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));\n } catch {\n return {};\n }\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n\n/**\n * Load config with priority: overrides > env vars > config file > defaults\n */\nexport function loadConfig(overrides?: Partial<Config>): Config {\n const file = loadFileConfig();\n\n const raw = {\n apiKey: overrides?.apiKey ?? process.env.WINDOWS_USE_API_KEY ?? file.apiKey ?? '',\n baseURL: overrides?.baseURL ?? process.env.WINDOWS_USE_BASE_URL ?? file.baseURL ?? '',\n model: overrides?.model ?? process.env.WINDOWS_USE_MODEL ?? file.model ?? '',\n maxSteps: overrides?.maxSteps ?? intEnv('WINDOWS_USE_MAX_STEPS') ?? file.maxSteps ?? 50,\n maxRounds: overrides?.maxRounds ?? intEnv('WINDOWS_USE_MAX_ROUNDS') ?? file.maxRounds ?? 20,\n cdpUrl: overrides?.cdpUrl ?? process.env.WINDOWS_USE_CDP_URL ?? file.cdpUrl ?? 'http://localhost:9222',\n timeoutMs: overrides?.timeoutMs ?? intEnv('WINDOWS_USE_TIMEOUT_MS') ?? file.timeoutMs ?? 300_000,\n };\n\n return ConfigSchema.parse(raw);\n}\n\nfunction intEnv(name: string): number | undefined {\n const val = process.env[name];\n if (val === undefined) return undefined;\n const n = parseInt(val, 10);\n return isNaN(n) ? undefined : n;\n}\n","import { z } from 'zod';\n\nexport const ConfigSchema = z.object({\n apiKey: z.string().min(1, 'API key is required'),\n baseURL: z.string().url('Must be a valid URL'),\n model: z.string().min(1, 'Model name is required'),\n maxSteps: z.number().int().positive().default(50),\n maxRounds: z.number().int().positive().default(20),\n cdpUrl: z.string().default('http://localhost:9222'),\n timeoutMs: z.number().default(300_000),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n","import crypto from 'crypto';\nimport type { Config } from '../config/schema.js';\nimport { ContextManager } from '../agent/context-manager.js';\nimport { LLMClient } from '../agent/llm-client.js';\nimport { AgentRunner } from '../agent/runner.js';\nimport { BrowserClient } from '../tools/browser/client.js';\nimport { createToolRegistry } from '../tools/index.js';\nimport { ScreenshotStore, type ToolContext } from '../tools/types.js';\n\nexport interface Session {\n id: string;\n createdAt: Date;\n lastActivityAt: Date;\n config: Config;\n runner: AgentRunner;\n browserClient: BrowserClient;\n screenshots: ScreenshotStore;\n timeoutHandle: ReturnType<typeof setTimeout>;\n}\n\nexport class SessionRegistry {\n private sessions = new Map<string, Session>();\n\n create(config: Config): Session {\n const id = crypto.randomUUID();\n const contextManager = new ContextManager();\n const llmClient = new LLMClient(config);\n const browserClient = new BrowserClient(config.cdpUrl);\n const toolRegistry = createToolRegistry();\n const screenshotStore = new ScreenshotStore();\n\n const toolContext: ToolContext = {\n sessionId: id,\n cdpUrl: config.cdpUrl,\n getBrowser: () => {\n // Lazy connection\n return browserClient.connect().then(() => browserClient);\n },\n screenshots: screenshotStore,\n };\n\n const runner = new AgentRunner(\n llmClient,\n contextManager,\n toolRegistry,\n config,\n toolContext,\n );\n\n const timeoutHandle = setTimeout(\n () => this.destroy(id),\n config.timeoutMs,\n );\n\n const session: Session = {\n id,\n createdAt: new Date(),\n lastActivityAt: new Date(),\n config,\n runner,\n browserClient,\n screenshots: screenshotStore,\n timeoutHandle,\n };\n\n this.sessions.set(id, session);\n return session;\n }\n\n get(id: string): Session | undefined {\n return this.sessions.get(id);\n }\n\n touch(id: string): void {\n const session = this.sessions.get(id);\n if (!session) return;\n session.lastActivityAt = new Date();\n clearTimeout(session.timeoutHandle);\n session.timeoutHandle = setTimeout(\n () => this.destroy(id),\n session.config.timeoutMs,\n );\n }\n\n async destroy(id: string): Promise<void> {\n const session = this.sessions.get(id);\n if (!session) return;\n clearTimeout(session.timeoutHandle);\n await session.browserClient.close().catch(() => {});\n this.sessions.delete(id);\n }\n\n async destroyAll(): Promise<void> {\n await Promise.allSettled(\n [...this.sessions.keys()].map((id) => this.destroy(id)),\n );\n }\n}\n","import type OpenAI from 'openai';\n\ntype Message = OpenAI.Chat.Completions.ChatCompletionMessageParam;\n\n/**\n * Simple message history — stores all messages without windowing.\n * Small models are cheap, no need to truncate context.\n */\nexport class ContextManager {\n private messages: Message[] = [];\n\n append(message: Message): void {\n this.messages.push(message);\n }\n\n /** Returns all messages. */\n getMessages(): Message[] {\n return [...this.messages];\n }\n\n /** Total messages stored. */\n get length(): number {\n return this.messages.length;\n }\n}\n","import OpenAI from 'openai';\nimport type { Config } from '../config/schema.js';\n\nexport class LLMClient {\n private client: OpenAI;\n private model: string;\n\n constructor(config: Config) {\n this.client = new OpenAI({\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n });\n this.model = config.model;\n }\n\n async chat(\n messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[],\n tools: OpenAI.Chat.Completions.ChatCompletionTool[],\n ): Promise<OpenAI.Chat.Completions.ChatCompletion> {\n return this.client.chat.completions.create({\n model: this.model,\n messages,\n tools: tools.length > 0 ? tools : undefined,\n tool_choice: tools.length > 0 ? 'auto' : undefined,\n });\n }\n}\n","export function buildSystemPrompt(): string {\n return `You are a precise Windows and browser automation agent. Your job is to execute instructions by calling the tools available to you.\n\n## Workflow\n1. Take a screenshot first to understand the current state of the screen.\n2. Plan the minimal sequence of actions needed.\n3. Execute each action one at a time, then verify by taking another screenshot.\n4. When the task is done, you are blocked, or you need guidance, call \\`report\\` immediately.\n\n## Rules\n- ALWAYS take a screenshot before your first action to understand the current state.\n- After every mouse click or keyboard action, take a screenshot to verify the result.\n- Call ONE tool at a time. Never request multiple tools in parallel.\n- Before each tool call, briefly state what you are about to do and why.\n- After receiving a tool result, describe what you observed.\n- For browser tasks, prefer using browser_* tools over clicking on-screen coordinates.\n- For terminal tasks, prefer \\`run_command\\` over GUI interactions when possible.\n- Do not read or write files unless the instruction explicitly asks for it.\n\n## report Tool\nCall \\`report\\` when:\n- **\"completed\"**: The task is done successfully. Summarize what was accomplished.\n- **\"blocked\"**: You cannot proceed (CAPTCHA, login wall, unexpected error). Explain what's blocking you.\n- **\"need_guidance\"**: You need a decision or clarification. Describe what you need.\n\nCalling \\`report\\` stops your execution. The \\`content\\` field supports a rich document format — mix text with screenshots using \\`[Image:img_X]\\` markers:\n\n\\`\\`\\`\nreport({\n status: \"completed\",\n content: \"Here is what I found:\\\\n[Image:img_2]\\\\nThe page shows the search results.\\\\n[Image:img_3]\\\\nI also checked the sidebar.\"\n})\n\\`\\`\\`\n\nEach screenshot tool returns a screenshot ID (e.g. img_1, img_2). Use these IDs to embed images in your report.\n\n## Important\n- Do NOT keep retrying the same failing action. If something fails twice, call \\`report\\` with status \"blocked\".\n- If a UI element is not where you expect it, try scrolling first before giving up.\n- Keep your responses concise. Focus on actions, not explanations.`;\n}\n","import type OpenAI from 'openai';\nimport type { Config } from '../config/schema.js';\nimport type { ToolRegistry } from '../tools/registry.js';\nimport type { ToolContext, ToolResult } from '../tools/types.js';\nimport { ContextManager } from './context-manager.js';\nimport { LLMClient } from './llm-client.js';\nimport { buildSystemPrompt } from './system-prompt.js';\n\nexport interface RunResult {\n status: 'completed' | 'blocked' | 'need_guidance';\n /** Rich content with [Image:img_X] markers. Use parseReportContent() to expand. */\n content: string;\n data?: unknown;\n stepsUsed: number;\n}\n\nexport type StepEvent =\n | { type: 'thinking'; step: number; content: string }\n | { type: 'tool_call'; step: number; name: string; args: unknown }\n | { type: 'tool_result'; step: number; name: string; result: string }\n | { type: 'error'; step: number; message: string };\n\nexport type OnStepCallback = (event: StepEvent) => void;\n\nexport class AgentRunner {\n private llmClient: LLMClient;\n private contextManager: ContextManager;\n private toolRegistry: ToolRegistry;\n private config: Config;\n private toolContext: ToolContext;\n private initialized = false;\n private onStep: OnStepCallback | null = null;\n private roundsUsed = 0;\n\n constructor(\n llmClient: LLMClient,\n contextManager: ContextManager,\n toolRegistry: ToolRegistry,\n config: Config,\n toolContext: ToolContext,\n ) {\n this.llmClient = llmClient;\n this.contextManager = contextManager;\n this.toolRegistry = toolRegistry;\n this.config = config;\n this.toolContext = toolContext;\n }\n\n /** Register a callback to receive step-by-step progress events */\n setOnStep(cb: OnStepCallback): void {\n this.onStep = cb;\n }\n\n private emit(event: StepEvent): void {\n this.onStep?.(event);\n }\n\n /** How many instruction rounds have been used in this session */\n get currentRound(): number {\n return this.roundsUsed;\n }\n\n /** Whether this session has exhausted its max rounds */\n get roundsExhausted(): boolean {\n return this.roundsUsed >= this.config.maxRounds;\n }\n\n async run(instruction: string): Promise<RunResult> {\n // Check round limit\n if (this.roundsExhausted) {\n return {\n status: 'blocked',\n content: `Session has reached the maximum number of instruction rounds (${this.config.maxRounds}). Create a new session to continue.`,\n stepsUsed: 0,\n };\n }\n\n this.roundsUsed++;\n\n // Inject system prompt on first run\n if (!this.initialized) {\n this.contextManager.append({\n role: 'system',\n content: buildSystemPrompt(),\n });\n this.initialized = true;\n }\n\n // Add the instruction as a user message\n this.contextManager.append({\n role: 'user',\n content: instruction,\n });\n\n let stepsUsed = 0;\n\n while (stepsUsed < this.config.maxSteps) {\n stepsUsed++;\n const remaining = this.config.maxSteps - stepsUsed;\n\n const messages = this.contextManager.getMessages();\n\n // Warn the model when steps are running low\n if (remaining <= 3 && remaining >= 0) {\n messages.push({\n role: 'system',\n content: `⚠️ You have ${remaining} steps remaining. Call \\`report\\` NOW to summarize your progress. If you do not call report, your work will be lost.`,\n });\n }\n\n const tools = this.toolRegistry.toOpenAIFormat();\n\n let response: OpenAI.Chat.Completions.ChatCompletion;\n try {\n response = await this.llmClient.chat(messages, tools);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.emit({ type: 'error', step: stepsUsed, message: `LLM API error: ${msg}` });\n return {\n status: 'blocked',\n content: `LLM API error: ${msg}`,\n stepsUsed,\n };\n }\n\n const choice = response.choices[0];\n if (!choice) {\n return {\n status: 'blocked',\n content: 'LLM returned empty response',\n stepsUsed,\n };\n }\n\n const message = choice.message;\n\n // If model has text content (thinking), emit it\n if (message.content) {\n this.emit({ type: 'thinking', step: stepsUsed, content: message.content });\n }\n\n // If model stops without tool calls, treat as implicit report\n if (choice.finish_reason === 'stop' || !message.tool_calls?.length) {\n const text = message.content ?? '';\n this.contextManager.append({ role: 'assistant', content: text });\n return {\n status: 'need_guidance',\n content: text || 'Agent stopped without calling report.',\n stepsUsed,\n };\n }\n\n // Append assistant message with tool_calls to history\n this.contextManager.append(message as any);\n\n // Process tool calls sequentially\n for (const toolCall of message.tool_calls) {\n const toolName = toolCall.function.name;\n let args: unknown;\n try {\n args = JSON.parse(toolCall.function.arguments);\n } catch {\n this.emit({ type: 'error', step: stepsUsed, message: `Failed to parse args for ${toolName}` });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: 'Error: could not parse tool arguments as JSON',\n });\n continue;\n }\n\n this.emit({ type: 'tool_call', step: stepsUsed, name: toolName, args });\n\n let result: ToolResult;\n try {\n result = await this.toolRegistry.execute(\n toolName,\n args,\n this.toolContext,\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.emit({ type: 'error', step: stepsUsed, message: `${toolName} failed: ${msg}` });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: `Error executing tool: ${msg}`,\n });\n continue;\n }\n\n // Check for report signal — the only clean exit\n if (result.type === 'report') {\n this.emit({ type: 'tool_result', step: stepsUsed, name: toolName, result: `[${result.status}] report submitted` });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: 'Report submitted. Returning control to caller.',\n });\n return {\n status: result.status,\n content: result.content,\n data: result.data,\n stepsUsed,\n };\n }\n\n // Image results: send as multimodal content with screenshot ID\n if (result.type === 'image') {\n this.emit({ type: 'tool_result', step: stepsUsed, name: toolName, result: `Screenshot captured (${result.screenshotId})` });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: [\n { type: 'text', text: `Screenshot captured. ID: ${result.screenshotId}` },\n {\n type: 'image_url',\n image_url: {\n url: `data:${result.mimeType};base64,${result.base64}`,\n },\n },\n ],\n } as any);\n } else {\n // Text results — truncate for display\n const preview = result.content.length > 200\n ? result.content.slice(0, 200) + '...'\n : result.content;\n this.emit({ type: 'tool_result', step: stepsUsed, name: toolName, result: preview });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: result.content,\n });\n }\n }\n }\n\n // Max steps exceeded\n return {\n status: 'blocked',\n content: `Exceeded maximum steps limit (${this.config.maxSteps}). Task may be incomplete.`,\n stepsUsed,\n };\n }\n}\n","import type { Browser, BrowserContext, Page } from 'playwright';\nimport { existsSync, mkdirSync, cpSync, readdirSync } from 'fs';\nimport { spawn, execSync, type ChildProcess } from 'child_process';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\n/** Common Chrome paths on Windows / macOS / Linux */\nconst CHROME_PATHS = [\n // Windows\n 'C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n 'C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n `${process.env.LOCALAPPDATA ?? ''}\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe`,\n // macOS\n '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n // Linux\n '/usr/bin/google-chrome',\n '/usr/bin/google-chrome-stable',\n '/usr/bin/chromium-browser',\n '/usr/bin/chromium',\n];\n\n/** Directories to skip when copying profile (large caches, not needed for login state) */\nconst SKIP_DIRS = new Set([\n 'Cache',\n 'Code Cache',\n 'GPUCache',\n 'Service Worker',\n 'CacheStorage',\n 'File System',\n 'blob_storage',\n 'IndexedDB',\n 'DawnCache',\n 'GrShaderCache',\n 'ShaderCache',\n 'optimization_guide_model_store',\n 'BrowserMetrics',\n 'Crashpad',\n 'component_crx_cache',\n]);\n\nfunction findChrome(): string | null {\n for (const p of CHROME_PATHS) {\n if (p && existsSync(p)) return p;\n }\n return null;\n}\n\n/** Find the user's real Chrome profile directory */\nfunction findUserDataDir(): string | null {\n const candidates = [\n // Windows\n join(process.env.LOCALAPPDATA ?? '', 'Google', 'Chrome', 'User Data'),\n // macOS\n join(homedir(), 'Library', 'Application Support', 'Google', 'Chrome'),\n // Linux\n join(homedir(), '.config', 'google-chrome'),\n join(homedir(), '.config', 'chromium'),\n ];\n for (const p of candidates) {\n if (p && existsSync(p)) return p;\n }\n return null;\n}\n\nfunction getCdpPort(cdpUrl: string): number {\n try {\n return parseInt(new URL(cdpUrl).port, 10) || 9222;\n } catch {\n return 9222;\n }\n}\n\n/** Check if any Chrome process is currently running */\nfunction isChromeRunning(): boolean {\n try {\n if (process.platform === 'win32') {\n const out = execSync('tasklist /FI \"IMAGENAME eq chrome.exe\" /NH', {\n encoding: 'utf-8',\n windowsHide: true,\n });\n return out.includes('chrome.exe');\n } else {\n execSync('pgrep -x \"chrome|chromium|google-chrome\"', { encoding: 'utf-8' });\n return true;\n }\n } catch {\n return false;\n }\n}\n\n/**\n * Copy user's Chrome profile to our working directory, skipping large cache dirs.\n * This preserves cookies, login state, extensions, etc.\n */\nfunction syncProfile(sourceDir: string, targetDir: string): void {\n mkdirSync(targetDir, { recursive: true });\n\n // Copy top-level files (Local State, etc.)\n const entries = readdirSync(sourceDir, { withFileTypes: true });\n for (const entry of entries) {\n const src = join(sourceDir, entry.name);\n const dst = join(targetDir, entry.name);\n\n if (entry.isFile()) {\n try {\n cpSync(src, dst, { force: true });\n } catch {\n // Some files may be locked, skip them\n }\n } else if (entry.isDirectory()) {\n if (entry.name === 'Default' || entry.name.startsWith('Profile ')) {\n // Copy profile dirs, skipping caches\n syncProfileDir(src, dst);\n } else if (!SKIP_DIRS.has(entry.name)) {\n // Copy other small dirs\n try {\n cpSync(src, dst, { recursive: true, force: true });\n } catch {\n // Skip locked/inaccessible dirs\n }\n }\n }\n }\n}\n\nfunction syncProfileDir(sourceDir: string, targetDir: string): void {\n mkdirSync(targetDir, { recursive: true });\n\n let entries;\n try {\n entries = readdirSync(sourceDir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (SKIP_DIRS.has(entry.name)) continue;\n\n const src = join(sourceDir, entry.name);\n const dst = join(targetDir, entry.name);\n\n try {\n if (entry.isFile()) {\n cpSync(src, dst, { force: true });\n } else if (entry.isDirectory()) {\n cpSync(src, dst, { recursive: true, force: true });\n }\n } catch {\n // Skip locked files\n }\n }\n}\n\n/**\n * Manages a Playwright CDP connection to the user's Chrome.\n * Auto-launches Chrome with --remote-debugging-port if not already running.\n * Syncs user's Chrome profile to preserve cookies/login state.\n */\nexport class BrowserClient {\n private browser: Browser | null = null;\n private context: BrowserContext | null = null;\n private _page: Page | null = null;\n private cdpUrl: string;\n private chromeProcess: ChildProcess | null = null;\n\n constructor(cdpUrl: string) {\n this.cdpUrl = cdpUrl;\n }\n\n async connect(): Promise<void> {\n if (this.browser) return;\n\n const { chromium } = await import('playwright');\n\n // Try connecting to existing Chrome with CDP\n try {\n this.browser = await chromium.connectOverCDP(this.cdpUrl);\n } catch {\n // CDP not available — need to (re)launch Chrome\n await this.launchChrome();\n this.browser = await chromium.connectOverCDP(this.cdpUrl);\n }\n\n const contexts = this.browser.contexts();\n this.context = contexts[0] ?? await this.browser.newContext();\n\n const pages = this.context.pages();\n this._page = pages[0] ?? await this.context.newPage();\n }\n\n private async launchChrome(): Promise<void> {\n const chromePath = findChrome();\n if (!chromePath) {\n throw new Error(\n 'Chrome not found. Please install Chrome or start it manually with: chrome --remote-debugging-port=9222',\n );\n }\n\n const port = getCdpPort(this.cdpUrl);\n\n // If Chrome is already running without CDP, kill it first\n if (isChromeRunning()) {\n console.error('[windows-use] Chrome is running without CDP. Restarting with --remote-debugging-port...');\n try {\n if (process.platform === 'win32') {\n execSync('taskkill /F /IM chrome.exe /T', { windowsHide: true, stdio: 'ignore' });\n } else {\n execSync('pkill -f chrome', { stdio: 'ignore' });\n }\n } catch {\n // May fail if already exited\n }\n await new Promise((r) => setTimeout(r, 1500));\n }\n\n // --user-data-dir is REQUIRED for --remote-debugging-port to work\n const targetDir = join(homedir(), '.windows-use', 'chrome-profile');\n\n // Sync user's profile to preserve cookies/login state\n const userDir = findUserDataDir();\n if (userDir) {\n console.error('[windows-use] Syncing Chrome profile (cookies, login state)...');\n syncProfile(userDir, targetDir);\n console.error('[windows-use] Profile synced.');\n } else {\n mkdirSync(targetDir, { recursive: true });\n }\n\n console.error(`[windows-use] Launching Chrome with --remote-debugging-port=${port}`);\n\n this.chromeProcess = spawn(\n chromePath,\n [\n `--remote-debugging-port=${port}`,\n `--user-data-dir=${targetDir}`,\n ],\n { detached: true, stdio: 'ignore' },\n );\n this.chromeProcess.unref();\n\n // Wait for CDP to be ready\n for (let i = 0; i < 30; i++) {\n try {\n const res = await fetch(`http://localhost:${port}/json/version`);\n if (res.ok) return;\n } catch {\n // Not ready yet\n }\n await new Promise((r) => setTimeout(r, 500));\n }\n\n throw new Error('Chrome launched but CDP endpoint did not become available within 15s');\n }\n\n async getPage(): Promise<Page> {\n await this.connect();\n return this._page!;\n }\n\n /** Create a new tab and switch to it. */\n async newPage(): Promise<Page> {\n await this.connect();\n this._page = await this.context!.newPage();\n return this._page;\n }\n\n async close(): Promise<void> {\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n this.context = null;\n this._page = null;\n }\n }\n\n get connected(): boolean {\n return this.browser !== null && this.browser.isConnected();\n }\n}\n","import type { z } from 'zod';\n\n/**\n * Simple zod-to-JSON-Schema converter for OpenAI tool definitions.\n * Handles the subset of zod types we use (object, string, number, enum, boolean, optional, default, describe).\n */\nexport function zodToJsonSchema(schema: z.ZodType): Record<string, unknown> {\n return convertZodType(schema);\n}\n\nfunction convertZodType(schema: z.ZodType): Record<string, unknown> {\n const def = (schema as any)._def;\n const typeName: string = def?.typeName;\n\n switch (typeName) {\n case 'ZodObject': {\n const shape = (schema as z.ZodObject<any>).shape;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = convertZodType(value as z.ZodType);\n if (!isOptional(value as z.ZodType)) {\n required.push(key);\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n }\n\n case 'ZodString': {\n const result: Record<string, unknown> = { type: 'string' };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodNumber': {\n const result: Record<string, unknown> = { type: 'number' };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodBoolean': {\n const result: Record<string, unknown> = { type: 'boolean' };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodEnum': {\n const result: Record<string, unknown> = {\n type: 'string',\n enum: def.values,\n };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodArray': {\n const result: Record<string, unknown> = {\n type: 'array',\n items: convertZodType(def.type),\n };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodOptional':\n return convertZodType(def.innerType);\n\n case 'ZodDefault':\n return convertZodType(def.innerType);\n\n case 'ZodEffects':\n return convertZodType(def.schema);\n\n case 'ZodUnknown':\n return {};\n\n default:\n return { type: 'string' };\n }\n}\n\nfunction isOptional(schema: z.ZodType): boolean {\n const def = (schema as any)._def;\n const typeName: string = def?.typeName;\n return typeName === 'ZodOptional' || typeName === 'ZodDefault';\n}\n","import type { ToolDefinition, ToolContext, ToolResult } from './types.js';\nimport { zodToJsonSchema } from './zod-to-json.js';\nimport type OpenAI from 'openai';\n\nexport class ToolRegistry {\n private tools = new Map<string, ToolDefinition>();\n\n register(tool: ToolDefinition): void {\n this.tools.set(tool.name, tool);\n }\n\n get(name: string): ToolDefinition | undefined {\n return this.tools.get(name);\n }\n\n toOpenAIFormat(): OpenAI.Chat.Completions.ChatCompletionTool[] {\n return Array.from(this.tools.values()).map((tool) => ({\n type: 'function' as const,\n function: {\n name: tool.name,\n description: tool.description,\n parameters: zodToJsonSchema(tool.parameters),\n },\n }));\n }\n\n async execute(\n name: string,\n args: unknown,\n context: ToolContext,\n ): Promise<ToolResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n return { type: 'text', content: `Error: unknown tool \"${name}\"` };\n }\n\n const parsed = tool.parameters.safeParse(args);\n if (!parsed.success) {\n return {\n type: 'text',\n content: `Error: invalid arguments for \"${name}\": ${parsed.error.message}`,\n };\n }\n\n return tool.execute(parsed.data, context);\n }\n}\n","import { z } from 'zod';\nimport sharp from 'sharp';\nimport type { ToolDefinition } from '../types.js';\nimport { addCoordinateGrid } from './grid-overlay.js';\n\nexport const screenshotTool: ToolDefinition = {\n name: 'screenshot',\n description:\n 'Capture the full screen with a coordinate grid overlay. The grid shows pixel coordinates that match mouse_click/mouse_move coordinates. Returns a screenshot ID.',\n parameters: z.object({}),\n async execute(_args, ctx) {\n const { Monitor } = await import('node-screenshots');\n\n const monitors = Monitor.all();\n const primary = monitors.find((m: any) => m.isPrimary()) ?? monitors[0];\n if (!primary) {\n return { type: 'text', content: 'Error: No monitor found' };\n }\n\n const image = primary.captureImageSync();\n const physW = image.width;\n const physH = image.height;\n const scaleFactor: number = (primary as any).scaleFactor ?? 1;\n\n // Logical dimensions (matching OS coordinate system used by nut-js)\n const logicalW = Math.round(physW / scaleFactor);\n const logicalH = Math.round(physH / scaleFactor);\n\n // Resize to logical resolution using raw RGBA pixels\n const raw = image.toRawSync();\n const resized = await sharp(raw, {\n raw: { width: physW, height: physH, channels: 4 },\n })\n .resize(logicalW, logicalH)\n .jpeg({ quality: 70 })\n .toBuffer();\n\n // Clean version → ScreenshotStore (for report to user/main model)\n const cleanBase64 = resized.toString('base64');\n const id = ctx.screenshots.save(cleanBase64, 'image/jpeg', 'desktop');\n\n // Grid version → LLM (for coordinate reference)\n const gridImage = await addCoordinateGrid(resized, logicalW, logicalH);\n const gridBase64 = gridImage.toString('base64');\n\n return {\n type: 'image',\n base64: gridBase64,\n mimeType: 'image/jpeg',\n screenshotId: id,\n };\n },\n};\n","import sharp from 'sharp';\n\nexport interface GridOptions {\n /** Minor grid line spacing in pixels (default: 100) */\n gridSpacing?: number;\n /** Coordinate label spacing in pixels (default: 200) */\n labelSpacing?: number;\n}\n\n/**\n * Add a coordinate grid overlay to a JPEG image buffer.\n * Returns a new JPEG buffer with grid lines and coordinate labels.\n */\nexport async function addCoordinateGrid(\n imageBuffer: Buffer,\n width: number,\n height: number,\n options: GridOptions = {},\n): Promise<Buffer> {\n const gridSpacing = options.gridSpacing ?? 100;\n const labelSpacing = options.labelSpacing ?? 200;\n const majorSpacing = gridSpacing * 5; // 500px\n\n const svgParts: string[] = [];\n\n // --- Grid lines ---\n for (let x = gridSpacing; x < width; x += gridSpacing) {\n const isMajor = x % majorSpacing === 0;\n const opacity = isMajor ? 0.35 : 0.15;\n const sw = isMajor ? 1.5 : 0.5;\n svgParts.push(\n `<line x1=\"${x}\" y1=\"0\" x2=\"${x}\" y2=\"${height}\" stroke=\"rgba(255,50,50,${opacity})\" stroke-width=\"${sw}\"/>`,\n );\n }\n for (let y = gridSpacing; y < height; y += gridSpacing) {\n const isMajor = y % majorSpacing === 0;\n const opacity = isMajor ? 0.35 : 0.15;\n const sw = isMajor ? 1.5 : 0.5;\n svgParts.push(\n `<line x1=\"0\" y1=\"${y}\" x2=\"${width}\" y2=\"${y}\" stroke=\"rgba(255,50,50,${opacity})\" stroke-width=\"${sw}\"/>`,\n );\n }\n\n // --- Coordinate labels along top edge ---\n for (let x = labelSpacing; x < width; x += labelSpacing) {\n const text = String(x);\n const tw = text.length * 7.5 + 6;\n svgParts.push(\n `<rect x=\"${x - tw / 2}\" y=\"2\" width=\"${tw}\" height=\"16\" fill=\"rgba(0,0,0,0.65)\" rx=\"3\"/>`,\n `<text x=\"${x}\" y=\"14\" text-anchor=\"middle\" fill=\"#ff6666\" font-size=\"11\" font-family=\"Consolas,monospace\" font-weight=\"bold\">${text}</text>`,\n );\n }\n\n // --- Coordinate labels along left edge ---\n for (let y = labelSpacing; y < height; y += labelSpacing) {\n const text = String(y);\n const tw = text.length * 7.5 + 6;\n svgParts.push(\n `<rect x=\"2\" y=\"${y - 8}\" width=\"${tw}\" height=\"16\" fill=\"rgba(0,0,0,0.65)\" rx=\"3\"/>`,\n `<text x=\"5\" y=\"${y + 4}\" fill=\"#ff6666\" font-size=\"11\" font-family=\"Consolas,monospace\" font-weight=\"bold\">${text}</text>`,\n );\n }\n\n // --- Origin label ---\n svgParts.push(\n `<rect x=\"2\" y=\"2\" width=\"22\" height=\"16\" fill=\"rgba(0,0,0,0.65)\" rx=\"3\"/>`,\n `<text x=\"5\" y=\"14\" fill=\"#ff6666\" font-size=\"11\" font-family=\"Consolas,monospace\" font-weight=\"bold\">0,0</text>`,\n );\n\n // --- Dimension label at bottom-right ---\n const dimText = `${width}x${height}`;\n const dimTw = dimText.length * 7.5 + 6;\n svgParts.push(\n `<rect x=\"${width - dimTw - 2}\" y=\"${height - 18}\" width=\"${dimTw}\" height=\"16\" fill=\"rgba(0,0,0,0.65)\" rx=\"3\"/>`,\n `<text x=\"${width - dimTw / 2 - 2}\" y=\"${height - 6}\" text-anchor=\"middle\" fill=\"#ff6666\" font-size=\"11\" font-family=\"Consolas,monospace\" font-weight=\"bold\">${dimText}</text>`,\n );\n\n const svg = Buffer.from(\n `<svg width=\"${width}\" height=\"${height}\" xmlns=\"http://www.w3.org/2000/svg\">${svgParts.join('')}</svg>`,\n );\n\n return sharp(imageBuffer)\n .composite([{ input: svg, top: 0, left: 0 }])\n .jpeg({ quality: 70 })\n .toBuffer();\n}\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nasync function getNutJs() {\n return import('@nut-tree-fork/nut-js');\n}\n\nexport const mouseClickTool: ToolDefinition = {\n name: 'mouse_click',\n description: 'Click the mouse at the given screen coordinates.',\n parameters: z.object({\n x: z.number().describe('X coordinate on screen'),\n y: z.number().describe('Y coordinate on screen'),\n button: z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n const point = new nut.Point(args.x, args.y);\n await nut.mouse.move(nut.straightTo(point));\n\n const buttonMap = {\n left: nut.Button.LEFT,\n right: nut.Button.RIGHT,\n middle: nut.Button.MIDDLE,\n };\n await nut.mouse.click(buttonMap[args.button]);\n\n return { type: 'text', content: `Clicked ${args.button} at (${args.x}, ${args.y})` };\n },\n};\n\nexport const mouseMoveTool: ToolDefinition = {\n name: 'mouse_move',\n description: 'Move the mouse to the given screen coordinates without clicking.',\n parameters: z.object({\n x: z.number().describe('X coordinate on screen'),\n y: z.number().describe('Y coordinate on screen'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n const point = new nut.Point(args.x, args.y);\n await nut.mouse.move(nut.straightTo(point));\n return { type: 'text', content: `Mouse moved to (${args.x}, ${args.y})` };\n },\n};\n\nexport const mouseScrollTool: ToolDefinition = {\n name: 'mouse_scroll',\n description: 'Scroll the mouse wheel.',\n parameters: z.object({\n direction: z.enum(['up', 'down']).describe('Scroll direction'),\n amount: z.number().positive().default(3).describe('Number of scroll steps'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n for (let i = 0; i < args.amount; i++) {\n if (args.direction === 'down') {\n await nut.mouse.scrollDown(1);\n } else {\n await nut.mouse.scrollUp(1);\n }\n }\n return { type: 'text', content: `Scrolled ${args.direction} ${args.amount} steps` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nasync function getNutJs() {\n return import('@nut-tree-fork/nut-js');\n}\n\nexport const keyboardTypeTool: ToolDefinition = {\n name: 'keyboard_type',\n description: 'Type text using the keyboard. The text is typed character by character.',\n parameters: z.object({\n text: z.string().describe('The text to type'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n await nut.keyboard.type(args.text);\n return { type: 'text', content: `Typed: \"${args.text}\"` };\n },\n};\n\n/**\n * Map common key names to nut-js Key enum values.\n */\nfunction resolveKey(nut: any, keyName: string): number {\n const keyMap: Record<string, string> = {\n 'ctrl': 'LeftControl',\n 'control': 'LeftControl',\n 'shift': 'LeftShift',\n 'alt': 'LeftAlt',\n 'meta': 'LeftWin',\n 'win': 'LeftWin',\n 'windows': 'LeftWin',\n 'enter': 'Return',\n 'return': 'Return',\n 'tab': 'Tab',\n 'escape': 'Escape',\n 'esc': 'Escape',\n 'backspace': 'Backspace',\n 'delete': 'Delete',\n 'space': 'Space',\n 'up': 'Up',\n 'down': 'Down',\n 'left': 'Left',\n 'right': 'Right',\n 'home': 'Home',\n 'end': 'End',\n 'pageup': 'PageUp',\n 'pagedown': 'PageDown',\n 'f1': 'F1', 'f2': 'F2', 'f3': 'F3', 'f4': 'F4',\n 'f5': 'F5', 'f6': 'F6', 'f7': 'F7', 'f8': 'F8',\n 'f9': 'F9', 'f10': 'F10', 'f11': 'F11', 'f12': 'F12',\n };\n\n const normalized = keyName.toLowerCase().trim();\n const mapped = keyMap[normalized] ?? keyName;\n\n // Try to find in the Key enum\n const key = nut.Key[mapped];\n if (key !== undefined) return key;\n\n // Try uppercase single char (e.g., 'a' -> 'A')\n if (mapped.length === 1) {\n const upper = mapped.toUpperCase();\n const k = nut.Key[upper];\n if (k !== undefined) return k;\n }\n\n throw new Error(`Unknown key: \"${keyName}\"`);\n}\n\nexport const keyboardPressTool: ToolDefinition = {\n name: 'keyboard_press',\n description: 'Press a key combination. Examples: [\"Ctrl\", \"C\"] for copy, [\"Enter\"] for enter, [\"Alt\", \"F4\"] to close window.',\n parameters: z.object({\n keys: z.array(z.string()).min(1).describe('Array of key names to press simultaneously'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n const resolved = args.keys.map((k: string) => resolveKey(nut, k));\n await nut.keyboard.pressKey(...resolved);\n await nut.keyboard.releaseKey(...resolved);\n return { type: 'text', content: `Pressed: ${args.keys.join('+')}` };\n },\n};\n","import { z } from 'zod';\nimport { exec } from 'child_process';\nimport type { ToolDefinition } from '../types.js';\n\nconst MAX_OUTPUT_LENGTH = 10_000;\n\nexport const runCommandTool: ToolDefinition = {\n name: 'run_command',\n description: 'Execute a shell command and return its output. Uses PowerShell on Windows.',\n parameters: z.object({\n command: z.string().describe('The command to execute'),\n timeout: z.number().positive().default(30_000).describe('Timeout in milliseconds'),\n }),\n async execute(args) {\n return new Promise((resolve) => {\n exec(\n args.command,\n {\n timeout: args.timeout,\n maxBuffer: 1024 * 1024,\n shell: 'powershell.exe',\n windowsHide: true,\n },\n (error, stdout, stderr) => {\n let output = '';\n if (stdout) output += stdout;\n if (stderr) output += `\\n[stderr] ${stderr}`;\n if (error && error.killed) output += '\\n[timeout] Command timed out';\n else if (error) output += `\\n[exit code ${error.code}]`;\n\n // Truncate to protect context\n if (output.length > MAX_OUTPUT_LENGTH) {\n output = output.slice(0, MAX_OUTPUT_LENGTH) + '\\n...(truncated)';\n }\n\n resolve({ type: 'text', content: output.trim() || '(no output)' });\n },\n );\n });\n },\n};\n","import { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport type { ToolDefinition } from '../types.js';\n\nconst MAX_FILE_SIZE = 100_000; // chars\n\nexport const fileReadTool: ToolDefinition = {\n name: 'file_read',\n description: 'Read the contents of a file at the given path.',\n parameters: z.object({\n path: z.string().describe('Absolute path to the file'),\n }),\n async execute(args) {\n try {\n const content = await readFile(args.path, 'utf-8');\n if (content.length > MAX_FILE_SIZE) {\n return {\n type: 'text',\n content: content.slice(0, MAX_FILE_SIZE) + '\\n...(truncated)',\n };\n }\n return { type: 'text', content };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { type: 'text', content: `Error reading file: ${msg}` };\n }\n },\n};\n","import { z } from 'zod';\nimport { writeFile, mkdir } from 'fs/promises';\nimport { dirname } from 'path';\nimport type { ToolDefinition } from '../types.js';\n\nexport const fileWriteTool: ToolDefinition = {\n name: 'file_write',\n description: 'Write content to a file at the given path. Creates parent directories if needed.',\n parameters: z.object({\n path: z.string().describe('Absolute path to the file'),\n content: z.string().describe('Content to write'),\n }),\n async execute(args) {\n try {\n await mkdir(dirname(args.path), { recursive: true });\n await writeFile(args.path, args.content, 'utf-8');\n return { type: 'text', content: `File written: ${args.path}` };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { type: 'text', content: `Error writing file: ${msg}` };\n }\n },\n};\n","import { z } from 'zod';\nimport { readFileSync, existsSync } from 'fs';\nimport { extname } from 'path';\nimport type { ToolDefinition } from '../types.js';\n\nconst IMAGE_EXTS = new Set(['.png', '.jpg', '.jpeg', '.bmp', '.webp']);\n\nexport const useLocalImageTool: ToolDefinition = {\n name: 'use_local_image',\n description: 'Load a local image file and get a screenshot ID for it. Use this to reference local images in your report via [Image:img_X].',\n parameters: z.object({\n path: z.string().describe('Absolute path to the image file'),\n label: z.string().default('local').describe('Label for the image (e.g. \"chart\", \"photo\")'),\n }),\n async execute(args, ctx) {\n if (!existsSync(args.path)) {\n return { type: 'text', content: `Error: File not found: ${args.path}` };\n }\n\n const ext = extname(args.path).toLowerCase();\n if (!IMAGE_EXTS.has(ext)) {\n return { type: 'text', content: `Error: Not a supported image format (${ext}). Supported: ${[...IMAGE_EXTS].join(', ')}` };\n }\n\n const buf = readFileSync(args.path);\n const mimeType = (ext === '.png') ? 'image/png' as const : 'image/jpeg' as const;\n const base64 = buf.toString('base64');\n const id = ctx.screenshots.save(base64, mimeType, args.label);\n\n return {\n type: 'image',\n base64,\n mimeType,\n screenshotId: id,\n };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserNavigateTool: ToolDefinition = {\n name: 'browser_navigate',\n description: 'Navigate the browser to a URL.',\n parameters: z.object({\n url: z.string().describe('The URL to navigate to'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n await page.goto(args.url, { waitUntil: 'domcontentloaded', timeout: 30_000 });\n const title = await page.title();\n return { type: 'text', content: `Navigated to: ${args.url}\\nPage title: ${title}` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserClickTool: ToolDefinition = {\n name: 'browser_click',\n description: 'Click an element on the web page using a CSS selector or text content.',\n parameters: z.object({\n selector: z.string().describe('CSS selector or text to find the element (e.g., \"button.submit\", \"text=Login\")'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n await page.click(args.selector, { timeout: 10_000 });\n return { type: 'text', content: `Clicked element: ${args.selector}` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserTypeTool: ToolDefinition = {\n name: 'browser_type',\n description: 'Type text into an input field on the web page.',\n parameters: z.object({\n selector: z.string().describe('CSS selector for the input element'),\n text: z.string().describe('Text to type'),\n clear: z.boolean().default(true).describe('Whether to clear the field before typing'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n if (args.clear) {\n await page.fill(args.selector, args.text, { timeout: 10_000 });\n } else {\n await page.type(args.selector, args.text, { timeout: 10_000 });\n }\n return { type: 'text', content: `Typed \"${args.text}\" into ${args.selector}` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserScreenshotTool: ToolDefinition = {\n name: 'browser_screenshot',\n description: 'Take a screenshot of the current browser page. Returns a screenshot ID (e.g. img_2) that you can reference later in report.',\n parameters: z.object({\n fullPage: z.boolean().default(false).describe('Whether to capture the full scrollable page'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n const buf = await page.screenshot({\n type: 'jpeg',\n quality: 70,\n fullPage: args.fullPage,\n scale: 'css',\n });\n const base64 = buf.toString('base64');\n const id = ctx.screenshots.save(base64, 'image/jpeg', 'browser');\n\n return {\n type: 'image',\n base64,\n mimeType: 'image/jpeg',\n screenshotId: id,\n };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nconst MAX_CONTENT_LENGTH = 20_000;\n\nexport const browserContentTool: ToolDefinition = {\n name: 'browser_content',\n description: 'Get the text content of the current web page. Returns visible text, not HTML.',\n parameters: z.object({}),\n async execute(_args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n const url = page.url();\n const title = await page.title();\n let text = await page.innerText('body').catch(() => '');\n\n if (text.length > MAX_CONTENT_LENGTH) {\n text = text.slice(0, MAX_CONTENT_LENGTH) + '\\n...(truncated)';\n }\n\n return {\n type: 'text',\n content: `URL: ${url}\\nTitle: ${title}\\n\\n${text}`,\n };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserScrollTool: ToolDefinition = {\n name: 'browser_scroll',\n description: 'Scroll the current web page.',\n parameters: z.object({\n direction: z.enum(['up', 'down']).describe('Scroll direction'),\n amount: z.number().positive().default(500).describe('Pixels to scroll'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n const delta = args.direction === 'down' ? args.amount : -args.amount;\n await page.evaluate((d: number) => window.scrollBy(0, d), delta);\n return { type: 'text', content: `Scrolled ${args.direction} ${args.amount}px` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const reportTool: ToolDefinition = {\n name: 'report',\n description:\n 'Report progress back to the caller. Call this when the task is completed, when you are blocked, or when you need guidance. Calling this STOPS your execution immediately.\\n\\nThe content field supports rich document format: mix text with screenshots using [Image:img_1] markers. Example:\\n\"Here is the current state:\\n[Image:img_2]\\nThe page shows...\"',\n parameters: z.object({\n status: z\n .enum(['completed', 'blocked', 'need_guidance'])\n .describe(\n '\"completed\" = task done, \"blocked\" = cannot proceed, \"need_guidance\" = need a decision',\n ),\n content: z\n .string()\n .describe('Rich report content. Use [Image:img_X] to embed screenshots captured earlier. Example: \"Task done.\\\\n[Image:img_1]\\\\nThe page shows the result.\"'),\n data: z.unknown().optional().describe('Optional structured data to return'),\n }),\n async execute(args) {\n return {\n type: 'report',\n status: args.status,\n content: args.content,\n data: args.data,\n };\n },\n};\n","import { ToolRegistry } from './registry.js';\nimport { screenshotTool } from './windows/screenshot.js';\nimport { mouseClickTool, mouseMoveTool, mouseScrollTool } from './windows/mouse.js';\nimport { keyboardTypeTool, keyboardPressTool } from './windows/keyboard.js';\nimport { runCommandTool } from './windows/command.js';\nimport { fileReadTool } from './file/read.js';\nimport { fileWriteTool } from './file/write.js';\nimport { useLocalImageTool } from './file/image.js';\nimport { browserNavigateTool } from './browser/navigate.js';\nimport { browserClickTool } from './browser/click.js';\nimport { browserTypeTool } from './browser/type.js';\nimport { browserScreenshotTool } from './browser/screenshot.js';\nimport { browserContentTool } from './browser/content.js';\nimport { browserScrollTool } from './browser/scroll.js';\nimport { reportTool } from './control/report.js';\n\nexport function createToolRegistry(): ToolRegistry {\n const registry = new ToolRegistry();\n\n // Windows tools\n registry.register(screenshotTool);\n registry.register(mouseClickTool);\n registry.register(mouseMoveTool);\n registry.register(mouseScrollTool);\n registry.register(keyboardTypeTool);\n registry.register(keyboardPressTool);\n registry.register(runCommandTool);\n\n // File tools\n registry.register(fileReadTool);\n registry.register(fileWriteTool);\n registry.register(useLocalImageTool);\n\n // Browser tools\n registry.register(browserNavigateTool);\n registry.register(browserClickTool);\n registry.register(browserTypeTool);\n registry.register(browserScreenshotTool);\n registry.register(browserContentTool);\n registry.register(browserScrollTool);\n\n // Control tools\n registry.register(reportTool);\n\n return registry;\n}\n","import type { z } from 'zod';\n\nexport interface StoredScreenshot {\n id: string;\n base64: string;\n mimeType: 'image/png' | 'image/jpeg';\n label: string; // e.g. \"desktop\", \"browser\"\n}\n\n/**\n * Simple in-memory screenshot store.\n * Screenshot tools save images here with auto-incrementing IDs.\n * Report content references them via [Image:img_1] markers.\n */\nexport class ScreenshotStore {\n private counter = 0;\n private store = new Map<string, StoredScreenshot>();\n\n save(base64: string, mimeType: 'image/png' | 'image/jpeg', label: string): string {\n this.counter++;\n const id = `img_${this.counter}`;\n this.store.set(id, { id, base64, mimeType, label });\n return id;\n }\n\n get(id: string): StoredScreenshot | undefined {\n return this.store.get(id);\n }\n\n listIds(): string[] {\n return [...this.store.keys()];\n }\n}\n\n/** A block in parsed report content */\nexport type ContentBlock =\n | { type: 'text'; text: string }\n | { type: 'image'; id: string; base64: string; mimeType: 'image/png' | 'image/jpeg'; label: string };\n\n/**\n * Parse report content string, expanding [Image:img_X] markers into image blocks.\n * Returns an array of text and image content blocks.\n */\nexport function parseReportContent(content: string, store: ScreenshotStore): ContentBlock[] {\n const blocks: ContentBlock[] = [];\n const regex = /\\[Image:(img_\\d+)\\]/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n // Text before the marker\n if (match.index > lastIndex) {\n blocks.push({ type: 'text', text: content.slice(lastIndex, match.index) });\n }\n\n const id = match[1];\n const screenshot = store.get(id);\n if (screenshot) {\n blocks.push({\n type: 'image',\n id: screenshot.id,\n base64: screenshot.base64,\n mimeType: screenshot.mimeType,\n label: screenshot.label,\n });\n } else {\n // Unknown ID — keep as text\n blocks.push({ type: 'text', text: match[0] });\n }\n\n lastIndex = regex.lastIndex;\n }\n\n // Remaining text after last marker\n if (lastIndex < content.length) {\n blocks.push({ type: 'text', text: content.slice(lastIndex) });\n }\n\n return blocks;\n}\n\n/** Strip [Image:...] markers, returning text-only content */\nexport function stripImageMarkers(content: string): string {\n return content.replace(/\\[Image:img_\\d+\\]/g, '').replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\nexport interface ToolContext {\n sessionId: string;\n cdpUrl: string;\n /** Lazy browser client getter — only connects on first call */\n getBrowser: () => Promise<import('./browser/client.js').BrowserClient>;\n /** Screenshot store — tools save screenshots here, report references by [Image:id] */\n screenshots: ScreenshotStore;\n}\n\nexport type ToolResult =\n | { type: 'text'; content: string }\n | { type: 'image'; base64: string; mimeType: 'image/png' | 'image/jpeg'; screenshotId: string }\n | {\n type: 'report';\n status: 'completed' | 'blocked' | 'need_guidance';\n content: string; // Rich content with [Image:img_1] markers\n data?: unknown;\n };\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: z.ZodType;\n execute(args: any, context: ToolContext): Promise<ToolResult>;\n}\n"],"mappings":"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","names":["existsSync","join","homedir","z","sharp","z","sharp","z","z","getNutJs","z","z","z","z","readFileSync","existsSync","z","z","z","z","z","z","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/config/loader.ts","../src/config/schema.ts","../src/mcp/session-registry.ts","../src/agent/context-manager.ts","../src/agent/llm-client.ts","../src/agent/system-prompt.ts","../src/agent/runner.ts","../src/tools/browser/client.ts","../src/tools/zod-to-json.ts","../src/tools/registry.ts","../src/tools/windows/screenshot.ts","../src/tools/windows/grid-overlay.ts","../src/tools/windows/mouse.ts","../src/tools/windows/keyboard.ts","../src/tools/windows/command.ts","../src/tools/file/read.ts","../src/tools/file/write.ts","../src/tools/file/image.ts","../src/tools/browser/navigate.ts","../src/tools/browser/click.ts","../src/tools/browser/type.ts","../src/tools/browser/screenshot.ts","../src/tools/browser/content.ts","../src/tools/browser/scroll.ts","../src/tools/control/report.ts","../src/tools/index.ts","../src/tools/types.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { ConfigSchema, type Config } from './schema.js';\n\nconst CONFIG_FILE = join(homedir(), '.windows-use.json');\n\nexport interface FileConfig {\n apiKey?: string;\n baseURL?: string;\n model?: string;\n maxSteps?: number;\n maxRounds?: number;\n cdpUrl?: string;\n timeoutMs?: number;\n}\n\n/** Load saved config from ~/.windows-use.json */\nexport function loadFileConfig(): FileConfig {\n if (!existsSync(CONFIG_FILE)) return {};\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));\n } catch {\n return {};\n }\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n\n/**\n * Load config with priority: overrides > env vars > config file > defaults\n */\nexport function loadConfig(overrides?: Partial<Config>): Config {\n const file = loadFileConfig();\n\n const raw = {\n apiKey: overrides?.apiKey ?? process.env.WINDOWS_USE_API_KEY ?? file.apiKey ?? '',\n baseURL: overrides?.baseURL ?? process.env.WINDOWS_USE_BASE_URL ?? file.baseURL ?? '',\n model: overrides?.model ?? process.env.WINDOWS_USE_MODEL ?? file.model ?? '',\n maxSteps: overrides?.maxSteps ?? intEnv('WINDOWS_USE_MAX_STEPS') ?? file.maxSteps ?? 50,\n maxRounds: overrides?.maxRounds ?? intEnv('WINDOWS_USE_MAX_ROUNDS') ?? file.maxRounds ?? 20,\n cdpUrl: overrides?.cdpUrl ?? process.env.WINDOWS_USE_CDP_URL ?? file.cdpUrl ?? 'http://localhost:9222',\n timeoutMs: overrides?.timeoutMs ?? intEnv('WINDOWS_USE_TIMEOUT_MS') ?? file.timeoutMs ?? 300_000,\n };\n\n return ConfigSchema.parse(raw);\n}\n\nfunction intEnv(name: string): number | undefined {\n const val = process.env[name];\n if (val === undefined) return undefined;\n const n = parseInt(val, 10);\n return isNaN(n) ? undefined : n;\n}\n","import { z } from 'zod';\n\nexport const ConfigSchema = z.object({\n apiKey: z.string().min(1, 'API key is required'),\n baseURL: z.string().url('Must be a valid URL'),\n model: z.string().min(1, 'Model name is required'),\n maxSteps: z.number().int().positive().default(50),\n maxRounds: z.number().int().positive().default(20),\n cdpUrl: z.string().default('http://localhost:9222'),\n timeoutMs: z.number().default(300_000),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n","import crypto from 'crypto';\nimport type { Config } from '../config/schema.js';\nimport { ContextManager } from '../agent/context-manager.js';\nimport { LLMClient } from '../agent/llm-client.js';\nimport { AgentRunner } from '../agent/runner.js';\nimport { BrowserClient } from '../tools/browser/client.js';\nimport { createToolRegistry } from '../tools/index.js';\nimport { ScreenshotStore, type ToolContext } from '../tools/types.js';\n\nexport interface Session {\n id: string;\n createdAt: Date;\n lastActivityAt: Date;\n config: Config;\n runner: AgentRunner;\n browserClient: BrowserClient;\n screenshots: ScreenshotStore;\n timeoutHandle: ReturnType<typeof setTimeout>;\n}\n\nexport class SessionRegistry {\n private sessions = new Map<string, Session>();\n\n create(config: Config): Session {\n const id = crypto.randomUUID();\n const contextManager = new ContextManager();\n const llmClient = new LLMClient(config);\n const browserClient = new BrowserClient(config.cdpUrl);\n const toolRegistry = createToolRegistry();\n const screenshotStore = new ScreenshotStore();\n\n const toolContext: ToolContext = {\n sessionId: id,\n cdpUrl: config.cdpUrl,\n getBrowser: () => {\n // Lazy connection\n return browserClient.connect().then(() => browserClient);\n },\n screenshots: screenshotStore,\n };\n\n const runner = new AgentRunner(\n llmClient,\n contextManager,\n toolRegistry,\n config,\n toolContext,\n );\n\n const timeoutHandle = setTimeout(\n () => this.destroy(id),\n config.timeoutMs,\n );\n\n const session: Session = {\n id,\n createdAt: new Date(),\n lastActivityAt: new Date(),\n config,\n runner,\n browserClient,\n screenshots: screenshotStore,\n timeoutHandle,\n };\n\n this.sessions.set(id, session);\n return session;\n }\n\n get(id: string): Session | undefined {\n return this.sessions.get(id);\n }\n\n touch(id: string): void {\n const session = this.sessions.get(id);\n if (!session) return;\n session.lastActivityAt = new Date();\n clearTimeout(session.timeoutHandle);\n session.timeoutHandle = setTimeout(\n () => this.destroy(id),\n session.config.timeoutMs,\n );\n }\n\n async destroy(id: string): Promise<void> {\n const session = this.sessions.get(id);\n if (!session) return;\n clearTimeout(session.timeoutHandle);\n await session.browserClient.close().catch(() => {});\n this.sessions.delete(id);\n }\n\n async destroyAll(): Promise<void> {\n await Promise.allSettled(\n [...this.sessions.keys()].map((id) => this.destroy(id)),\n );\n }\n}\n","import type OpenAI from 'openai';\n\ntype Message = OpenAI.Chat.Completions.ChatCompletionMessageParam;\n\n/**\n * Simple message history — stores all messages without windowing.\n * Small models are cheap, no need to truncate context.\n */\nexport class ContextManager {\n private messages: Message[] = [];\n\n append(message: Message): void {\n this.messages.push(message);\n }\n\n /** Returns all messages. */\n getMessages(): Message[] {\n return [...this.messages];\n }\n\n /** Total messages stored. */\n get length(): number {\n return this.messages.length;\n }\n}\n","import OpenAI from 'openai';\nimport type { Config } from '../config/schema.js';\n\nexport class LLMClient {\n private client: OpenAI;\n private model: string;\n\n constructor(config: Config) {\n this.client = new OpenAI({\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n });\n this.model = config.model;\n }\n\n async chat(\n messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[],\n tools: OpenAI.Chat.Completions.ChatCompletionTool[],\n ): Promise<OpenAI.Chat.Completions.ChatCompletion> {\n return this.client.chat.completions.create({\n model: this.model,\n messages,\n tools: tools.length > 0 ? tools : undefined,\n tool_choice: tools.length > 0 ? 'auto' : undefined,\n });\n }\n}\n","export function buildSystemPrompt(): string {\n return `You are a precise Windows and browser automation agent. Your job is to execute instructions by calling the tools available to you.\n\n## Workflow\n1. Take a \\`screenshot\\` first to understand the current state of the screen.\n2. Plan the minimal sequence of actions needed.\n3. Execute actions, verifying with screenshots at key checkpoints (not after every single action).\n4. When the task is done, you are blocked, or you need guidance, call \\`report\\` immediately.\n\n## Reading Screenshots\n- Desktop screenshots include a **coordinate grid overlay**. The grid labels show pixel coordinates that directly correspond to \\`mouse_click\\` and \\`mouse_move\\` coordinates.\n- Use the grid numbers to estimate the (x, y) position of UI elements. For example, if a button appears near the grid label \"400\" horizontally and \"300\" vertically, click at approximately (400, 300).\n- The bottom-right corner label shows the total screen dimensions.\n\n## Tool Selection\n- **Browser tasks**: Prefer \\`browser_*\\` tools (they use CSS selectors, more reliable than coordinates). Use \\`browser_content\\` to find text/elements when you can't locate them visually.\n- **Desktop/native app tasks**: Use \\`screenshot\\` + \\`mouse_click\\`/\\`keyboard_*\\`. Read coordinates from the grid overlay.\n- **Terminal tasks**: Prefer \\`run_command\\` over GUI interactions. It's faster and more reliable.\n- **Mixed tasks**: You can combine all tool types. For example, use \\`run_command\\` to launch an app, then \\`screenshot\\` + mouse to interact with it.\n\n## Smart Screenshot Strategy\n- ALWAYS take a screenshot before your first action.\n- Take a screenshot to verify after **critical actions** (clicking a button, submitting a form, navigating to a new page).\n- Skip verification screenshots for **low-risk sequential actions** (typing text, pressing modifier keys, scrolling) — verify after the sequence is complete instead.\n- If an action might trigger a loading state, wait briefly then screenshot to confirm the page has loaded.\n\n## Rules\n- Call ONE tool at a time. Never request multiple tools in parallel.\n- Before each tool call, briefly state what you are about to do and why.\n- After receiving a tool result, describe what you observed.\n- Do not read or write files unless the instruction explicitly asks for it.\n\n## Handling Common Situations\n- **Loading/transitions**: If a page or app is loading, take another screenshot after a moment instead of acting immediately.\n- **Popups/dialogs**: Handle unexpected dialogs (cookie banners, notifications, confirmations) by dismissing or accepting them, then continue with the original task.\n- **Dropdowns/menus**: Click to open, then screenshot to see options before selecting.\n- **Scrolling**: If content is below the fold, scroll down and screenshot. Check both browser_scroll (for web pages) and mouse_scroll (for desktop apps).\n- **Text input**: For browser forms, prefer \\`browser_type\\` with the CSS selector. For desktop apps, click the input field first, then use \\`keyboard_type\\`.\n- **Coordinate precision**: When clicking small UI elements (buttons, links, checkboxes), aim for their center. If a click misses, adjust coordinates and try once more.\n\n## Error Recovery\n- If an action fails or produces unexpected results, take a screenshot to reassess the situation before trying again.\n- Try a different approach rather than repeating the same failed action. For example:\n - If \\`browser_click\\` fails on a selector, try a different selector or fall back to coordinate-based \\`mouse_click\\`.\n - If a UI element is not visible, try scrolling or switching tabs/windows.\n- If something fails **twice with different approaches**, call \\`report\\` with status \"blocked\".\n\n## report Tool\nCall \\`report\\` when:\n- **\"completed\"**: The task is done successfully. Summarize what was accomplished.\n- **\"blocked\"**: You cannot proceed (CAPTCHA, login wall, unexpected error). Explain what's blocking you.\n- **\"need_guidance\"**: You need a decision or clarification. Describe what you need.\n\nCalling \\`report\\` stops your execution. The \\`content\\` field supports a rich document format — mix text with screenshots using \\`[Image:img_X]\\` markers:\n\n\\`\\`\\`\nreport({\n status: \"completed\",\n content: \"Here is what I found:\\\\n[Image:img_2]\\\\nThe page shows the search results.\\\\n[Image:img_3]\\\\nI also checked the sidebar.\"\n})\n\\`\\`\\`\n\nEach screenshot tool returns a screenshot ID (e.g. img_1, img_2). Use these IDs to embed images in your report. Include relevant screenshots in your report so the caller can see the final state.\n\nYou can also use \\`use_local_image\\` to load a local image file and get a screenshot ID for embedding in reports.`;\n}\n","import type OpenAI from 'openai';\nimport type { Config } from '../config/schema.js';\nimport type { ToolRegistry } from '../tools/registry.js';\nimport type { ToolContext, ToolResult } from '../tools/types.js';\nimport { ContextManager } from './context-manager.js';\nimport { LLMClient } from './llm-client.js';\nimport { buildSystemPrompt } from './system-prompt.js';\n\nexport interface RunResult {\n status: 'completed' | 'blocked' | 'need_guidance';\n /** Rich content with [Image:img_X] markers. Use parseReportContent() to expand. */\n content: string;\n data?: unknown;\n stepsUsed: number;\n}\n\nexport type StepEvent =\n | { type: 'thinking'; step: number; content: string }\n | { type: 'tool_call'; step: number; name: string; args: unknown }\n | { type: 'tool_result'; step: number; name: string; result: string }\n | { type: 'error'; step: number; message: string };\n\nexport type OnStepCallback = (event: StepEvent) => void;\n\nexport class AgentRunner {\n private llmClient: LLMClient;\n private contextManager: ContextManager;\n private toolRegistry: ToolRegistry;\n private config: Config;\n private toolContext: ToolContext;\n private initialized = false;\n private onStep: OnStepCallback | null = null;\n private roundsUsed = 0;\n\n constructor(\n llmClient: LLMClient,\n contextManager: ContextManager,\n toolRegistry: ToolRegistry,\n config: Config,\n toolContext: ToolContext,\n ) {\n this.llmClient = llmClient;\n this.contextManager = contextManager;\n this.toolRegistry = toolRegistry;\n this.config = config;\n this.toolContext = toolContext;\n }\n\n /** Register a callback to receive step-by-step progress events */\n setOnStep(cb: OnStepCallback): void {\n this.onStep = cb;\n }\n\n private emit(event: StepEvent): void {\n this.onStep?.(event);\n }\n\n /** How many instruction rounds have been used in this session */\n get currentRound(): number {\n return this.roundsUsed;\n }\n\n /** Whether this session has exhausted its max rounds */\n get roundsExhausted(): boolean {\n return this.roundsUsed >= this.config.maxRounds;\n }\n\n async run(instruction: string): Promise<RunResult> {\n // Check round limit\n if (this.roundsExhausted) {\n return {\n status: 'blocked',\n content: `Session has reached the maximum number of instruction rounds (${this.config.maxRounds}). Create a new session to continue.`,\n stepsUsed: 0,\n };\n }\n\n this.roundsUsed++;\n\n // Inject system prompt on first run\n if (!this.initialized) {\n this.contextManager.append({\n role: 'system',\n content: buildSystemPrompt(),\n });\n this.initialized = true;\n }\n\n // Add the instruction as a user message\n this.contextManager.append({\n role: 'user',\n content: instruction,\n });\n\n let stepsUsed = 0;\n\n while (stepsUsed < this.config.maxSteps) {\n stepsUsed++;\n const remaining = this.config.maxSteps - stepsUsed;\n\n const messages = this.contextManager.getMessages();\n\n // Warn the model when steps are running low\n if (remaining <= 3 && remaining >= 0) {\n messages.push({\n role: 'system',\n content: `⚠️ You have ${remaining} steps remaining. Call \\`report\\` NOW to summarize your progress. If you do not call report, your work will be lost.`,\n });\n }\n\n const tools = this.toolRegistry.toOpenAIFormat();\n\n let response: OpenAI.Chat.Completions.ChatCompletion;\n try {\n response = await this.llmClient.chat(messages, tools);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.emit({ type: 'error', step: stepsUsed, message: `LLM API error: ${msg}` });\n return {\n status: 'blocked',\n content: `LLM API error: ${msg}`,\n stepsUsed,\n };\n }\n\n const choice = response.choices[0];\n if (!choice) {\n return {\n status: 'blocked',\n content: 'LLM returned empty response',\n stepsUsed,\n };\n }\n\n const message = choice.message;\n\n // If model has text content (thinking), emit it\n if (message.content) {\n this.emit({ type: 'thinking', step: stepsUsed, content: message.content });\n }\n\n // If model stops without tool calls, treat as implicit report\n if (choice.finish_reason === 'stop' || !message.tool_calls?.length) {\n const text = message.content ?? '';\n this.contextManager.append({ role: 'assistant', content: text });\n return {\n status: 'need_guidance',\n content: text || 'Agent stopped without calling report.',\n stepsUsed,\n };\n }\n\n // Append assistant message with tool_calls to history\n this.contextManager.append(message as any);\n\n // Process tool calls sequentially\n for (const toolCall of message.tool_calls) {\n const toolName = toolCall.function.name;\n let args: unknown;\n try {\n args = JSON.parse(toolCall.function.arguments);\n } catch {\n this.emit({ type: 'error', step: stepsUsed, message: `Failed to parse args for ${toolName}` });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: 'Error: could not parse tool arguments as JSON',\n });\n continue;\n }\n\n this.emit({ type: 'tool_call', step: stepsUsed, name: toolName, args });\n\n let result: ToolResult;\n try {\n result = await this.toolRegistry.execute(\n toolName,\n args,\n this.toolContext,\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.emit({ type: 'error', step: stepsUsed, message: `${toolName} failed: ${msg}` });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: `Error executing tool: ${msg}`,\n });\n continue;\n }\n\n // Check for report signal — the only clean exit\n if (result.type === 'report') {\n this.emit({ type: 'tool_result', step: stepsUsed, name: toolName, result: `[${result.status}] report submitted` });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: 'Report submitted. Returning control to caller.',\n });\n return {\n status: result.status,\n content: result.content,\n data: result.data,\n stepsUsed,\n };\n }\n\n // Image results: send as multimodal content with screenshot ID\n if (result.type === 'image') {\n this.emit({ type: 'tool_result', step: stepsUsed, name: toolName, result: `Screenshot captured (${result.screenshotId})` });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: [\n { type: 'text', text: `Screenshot captured. ID: ${result.screenshotId}` },\n {\n type: 'image_url',\n image_url: {\n url: `data:${result.mimeType};base64,${result.base64}`,\n },\n },\n ],\n } as any);\n } else {\n // Text results — truncate for display\n const preview = result.content.length > 200\n ? result.content.slice(0, 200) + '...'\n : result.content;\n this.emit({ type: 'tool_result', step: stepsUsed, name: toolName, result: preview });\n this.contextManager.append({\n role: 'tool',\n tool_call_id: toolCall.id,\n content: result.content,\n });\n }\n }\n }\n\n // Max steps exceeded\n return {\n status: 'blocked',\n content: `Exceeded maximum steps limit (${this.config.maxSteps}). Task may be incomplete.`,\n stepsUsed,\n };\n }\n}\n","import type { Browser, BrowserContext, Page } from 'playwright';\nimport { existsSync, mkdirSync, cpSync, readdirSync } from 'fs';\nimport { spawn, execSync, type ChildProcess } from 'child_process';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\n/** Common Chrome paths on Windows / macOS / Linux */\nconst CHROME_PATHS = [\n // Windows\n 'C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n 'C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n `${process.env.LOCALAPPDATA ?? ''}\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe`,\n // macOS\n '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n // Linux\n '/usr/bin/google-chrome',\n '/usr/bin/google-chrome-stable',\n '/usr/bin/chromium-browser',\n '/usr/bin/chromium',\n];\n\n/** Directories to skip when copying profile (large caches, not needed for login state) */\nconst SKIP_DIRS = new Set([\n 'Cache',\n 'Code Cache',\n 'GPUCache',\n 'Service Worker',\n 'CacheStorage',\n 'File System',\n 'blob_storage',\n 'IndexedDB',\n 'DawnCache',\n 'GrShaderCache',\n 'ShaderCache',\n 'optimization_guide_model_store',\n 'BrowserMetrics',\n 'Crashpad',\n 'component_crx_cache',\n]);\n\nfunction findChrome(): string | null {\n for (const p of CHROME_PATHS) {\n if (p && existsSync(p)) return p;\n }\n return null;\n}\n\n/** Find the user's real Chrome profile directory */\nfunction findUserDataDir(): string | null {\n const candidates = [\n // Windows\n join(process.env.LOCALAPPDATA ?? '', 'Google', 'Chrome', 'User Data'),\n // macOS\n join(homedir(), 'Library', 'Application Support', 'Google', 'Chrome'),\n // Linux\n join(homedir(), '.config', 'google-chrome'),\n join(homedir(), '.config', 'chromium'),\n ];\n for (const p of candidates) {\n if (p && existsSync(p)) return p;\n }\n return null;\n}\n\nfunction getCdpPort(cdpUrl: string): number {\n try {\n return parseInt(new URL(cdpUrl).port, 10) || 9222;\n } catch {\n return 9222;\n }\n}\n\n/** Check if any Chrome process is currently running */\nfunction isChromeRunning(): boolean {\n try {\n if (process.platform === 'win32') {\n const out = execSync('tasklist /FI \"IMAGENAME eq chrome.exe\" /NH', {\n encoding: 'utf-8',\n windowsHide: true,\n });\n return out.includes('chrome.exe');\n } else {\n execSync('pgrep -x \"chrome|chromium|google-chrome\"', { encoding: 'utf-8' });\n return true;\n }\n } catch {\n return false;\n }\n}\n\n/**\n * Copy user's Chrome profile to our working directory, skipping large cache dirs.\n * This preserves cookies, login state, extensions, etc.\n */\nfunction syncProfile(sourceDir: string, targetDir: string): void {\n mkdirSync(targetDir, { recursive: true });\n\n // Copy top-level files (Local State, etc.)\n const entries = readdirSync(sourceDir, { withFileTypes: true });\n for (const entry of entries) {\n const src = join(sourceDir, entry.name);\n const dst = join(targetDir, entry.name);\n\n if (entry.isFile()) {\n try {\n cpSync(src, dst, { force: true });\n } catch {\n // Some files may be locked, skip them\n }\n } else if (entry.isDirectory()) {\n if (entry.name === 'Default' || entry.name.startsWith('Profile ')) {\n // Copy profile dirs, skipping caches\n syncProfileDir(src, dst);\n } else if (!SKIP_DIRS.has(entry.name)) {\n // Copy other small dirs\n try {\n cpSync(src, dst, { recursive: true, force: true });\n } catch {\n // Skip locked/inaccessible dirs\n }\n }\n }\n }\n}\n\nfunction syncProfileDir(sourceDir: string, targetDir: string): void {\n mkdirSync(targetDir, { recursive: true });\n\n let entries;\n try {\n entries = readdirSync(sourceDir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (SKIP_DIRS.has(entry.name)) continue;\n\n const src = join(sourceDir, entry.name);\n const dst = join(targetDir, entry.name);\n\n try {\n if (entry.isFile()) {\n cpSync(src, dst, { force: true });\n } else if (entry.isDirectory()) {\n cpSync(src, dst, { recursive: true, force: true });\n }\n } catch {\n // Skip locked files\n }\n }\n}\n\n/**\n * Manages a Playwright CDP connection to the user's Chrome.\n * Auto-launches Chrome with --remote-debugging-port if not already running.\n * Syncs user's Chrome profile to preserve cookies/login state.\n */\nexport class BrowserClient {\n private browser: Browser | null = null;\n private context: BrowserContext | null = null;\n private _page: Page | null = null;\n private cdpUrl: string;\n private chromeProcess: ChildProcess | null = null;\n\n constructor(cdpUrl: string) {\n this.cdpUrl = cdpUrl;\n }\n\n async connect(): Promise<void> {\n if (this.browser) return;\n\n const { chromium } = await import('playwright');\n\n // Try connecting to existing Chrome with CDP\n try {\n this.browser = await chromium.connectOverCDP(this.cdpUrl);\n } catch {\n // CDP not available — need to (re)launch Chrome\n await this.launchChrome();\n this.browser = await chromium.connectOverCDP(this.cdpUrl);\n }\n\n const contexts = this.browser.contexts();\n this.context = contexts[0] ?? await this.browser.newContext();\n\n const pages = this.context.pages();\n this._page = pages[0] ?? await this.context.newPage();\n }\n\n private async launchChrome(): Promise<void> {\n const chromePath = findChrome();\n if (!chromePath) {\n throw new Error(\n 'Chrome not found. Please install Chrome or start it manually with: chrome --remote-debugging-port=9222',\n );\n }\n\n const port = getCdpPort(this.cdpUrl);\n\n // If Chrome is already running without CDP, kill it first\n if (isChromeRunning()) {\n console.error('[windows-use] Chrome is running without CDP. Restarting with --remote-debugging-port...');\n try {\n if (process.platform === 'win32') {\n execSync('taskkill /F /IM chrome.exe /T', { windowsHide: true, stdio: 'ignore' });\n } else {\n execSync('pkill -f chrome', { stdio: 'ignore' });\n }\n } catch {\n // May fail if already exited\n }\n await new Promise((r) => setTimeout(r, 1500));\n }\n\n // --user-data-dir is REQUIRED for --remote-debugging-port to work\n const targetDir = join(homedir(), '.windows-use', 'chrome-profile');\n\n // Sync user's profile to preserve cookies/login state\n const userDir = findUserDataDir();\n if (userDir) {\n console.error('[windows-use] Syncing Chrome profile (cookies, login state)...');\n syncProfile(userDir, targetDir);\n console.error('[windows-use] Profile synced.');\n } else {\n mkdirSync(targetDir, { recursive: true });\n }\n\n console.error(`[windows-use] Launching Chrome with --remote-debugging-port=${port}`);\n\n this.chromeProcess = spawn(\n chromePath,\n [\n `--remote-debugging-port=${port}`,\n `--user-data-dir=${targetDir}`,\n ],\n { detached: true, stdio: 'ignore' },\n );\n this.chromeProcess.unref();\n\n // Wait for CDP to be ready\n for (let i = 0; i < 30; i++) {\n try {\n const res = await fetch(`http://localhost:${port}/json/version`);\n if (res.ok) return;\n } catch {\n // Not ready yet\n }\n await new Promise((r) => setTimeout(r, 500));\n }\n\n throw new Error('Chrome launched but CDP endpoint did not become available within 15s');\n }\n\n async getPage(): Promise<Page> {\n await this.connect();\n return this._page!;\n }\n\n /** Create a new tab and switch to it. */\n async newPage(): Promise<Page> {\n await this.connect();\n this._page = await this.context!.newPage();\n return this._page;\n }\n\n async close(): Promise<void> {\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n this.context = null;\n this._page = null;\n }\n }\n\n get connected(): boolean {\n return this.browser !== null && this.browser.isConnected();\n }\n}\n","import type { z } from 'zod';\n\n/**\n * Simple zod-to-JSON-Schema converter for OpenAI tool definitions.\n * Handles the subset of zod types we use (object, string, number, enum, boolean, optional, default, describe).\n */\nexport function zodToJsonSchema(schema: z.ZodType): Record<string, unknown> {\n return convertZodType(schema);\n}\n\nfunction convertZodType(schema: z.ZodType): Record<string, unknown> {\n const def = (schema as any)._def;\n const typeName: string = def?.typeName;\n\n switch (typeName) {\n case 'ZodObject': {\n const shape = (schema as z.ZodObject<any>).shape;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = convertZodType(value as z.ZodType);\n if (!isOptional(value as z.ZodType)) {\n required.push(key);\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n }\n\n case 'ZodString': {\n const result: Record<string, unknown> = { type: 'string' };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodNumber': {\n const result: Record<string, unknown> = { type: 'number' };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodBoolean': {\n const result: Record<string, unknown> = { type: 'boolean' };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodEnum': {\n const result: Record<string, unknown> = {\n type: 'string',\n enum: def.values,\n };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodArray': {\n const result: Record<string, unknown> = {\n type: 'array',\n items: convertZodType(def.type),\n };\n if (def.description) result.description = def.description;\n return result;\n }\n\n case 'ZodOptional':\n return convertZodType(def.innerType);\n\n case 'ZodDefault':\n return convertZodType(def.innerType);\n\n case 'ZodEffects':\n return convertZodType(def.schema);\n\n case 'ZodUnknown':\n return {};\n\n default:\n return { type: 'string' };\n }\n}\n\nfunction isOptional(schema: z.ZodType): boolean {\n const def = (schema as any)._def;\n const typeName: string = def?.typeName;\n return typeName === 'ZodOptional' || typeName === 'ZodDefault';\n}\n","import type { ToolDefinition, ToolContext, ToolResult } from './types.js';\nimport { zodToJsonSchema } from './zod-to-json.js';\nimport type OpenAI from 'openai';\n\nexport class ToolRegistry {\n private tools = new Map<string, ToolDefinition>();\n\n register(tool: ToolDefinition): void {\n this.tools.set(tool.name, tool);\n }\n\n get(name: string): ToolDefinition | undefined {\n return this.tools.get(name);\n }\n\n toOpenAIFormat(): OpenAI.Chat.Completions.ChatCompletionTool[] {\n return Array.from(this.tools.values()).map((tool) => ({\n type: 'function' as const,\n function: {\n name: tool.name,\n description: tool.description,\n parameters: zodToJsonSchema(tool.parameters),\n },\n }));\n }\n\n async execute(\n name: string,\n args: unknown,\n context: ToolContext,\n ): Promise<ToolResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n return { type: 'text', content: `Error: unknown tool \"${name}\"` };\n }\n\n const parsed = tool.parameters.safeParse(args);\n if (!parsed.success) {\n return {\n type: 'text',\n content: `Error: invalid arguments for \"${name}\": ${parsed.error.message}`,\n };\n }\n\n return tool.execute(parsed.data, context);\n }\n}\n","import { z } from 'zod';\nimport sharp from 'sharp';\nimport type { ToolDefinition } from '../types.js';\nimport { addCoordinateGrid } from './grid-overlay.js';\n\nexport const screenshotTool: ToolDefinition = {\n name: 'screenshot',\n description:\n 'Capture the full screen with a coordinate grid overlay. The grid shows pixel coordinates that match mouse_click/mouse_move coordinates. Returns a screenshot ID.',\n parameters: z.object({}),\n async execute(_args, ctx) {\n const { Monitor } = await import('node-screenshots');\n\n const monitors = Monitor.all();\n const primary = monitors.find((m: any) => m.isPrimary()) ?? monitors[0];\n if (!primary) {\n return { type: 'text', content: 'Error: No monitor found' };\n }\n\n const image = primary.captureImageSync();\n const physW = image.width;\n const physH = image.height;\n const scaleFactor: number = (primary as any).scaleFactor() ?? 1;\n\n // Logical dimensions (matching OS coordinate system used by nut-js)\n const logicalW = Math.round(physW / scaleFactor);\n const logicalH = Math.round(physH / scaleFactor);\n\n // Resize to logical resolution using raw RGBA pixels\n const raw = image.toRawSync();\n const resized = await sharp(raw, {\n raw: { width: physW, height: physH, channels: 4 },\n })\n .resize(logicalW, logicalH)\n .jpeg({ quality: 70 })\n .toBuffer();\n\n // Clean version → ScreenshotStore (for report to user/main model)\n const cleanBase64 = resized.toString('base64');\n const id = ctx.screenshots.save(cleanBase64, 'image/jpeg', 'desktop');\n\n // Grid version → LLM (for coordinate reference)\n const gridImage = await addCoordinateGrid(resized, logicalW, logicalH);\n const gridBase64 = gridImage.toString('base64');\n\n return {\n type: 'image',\n base64: gridBase64,\n mimeType: 'image/jpeg',\n screenshotId: id,\n };\n },\n};\n","import sharp from 'sharp';\n\nexport interface GridOptions {\n /** Minor grid line spacing in pixels (default: 100) */\n gridSpacing?: number;\n /** Coordinate label spacing in pixels (default: 200) */\n labelSpacing?: number;\n}\n\n/**\n * Add a coordinate grid overlay to a JPEG image buffer.\n * Returns a new JPEG buffer with grid lines and coordinate labels.\n */\nexport async function addCoordinateGrid(\n imageBuffer: Buffer,\n width: number,\n height: number,\n options: GridOptions = {},\n): Promise<Buffer> {\n const gridSpacing = options.gridSpacing ?? 100;\n const labelSpacing = options.labelSpacing ?? 200;\n const majorSpacing = gridSpacing * 5; // 500px\n\n const svgParts: string[] = [];\n\n // --- Grid lines ---\n for (let x = gridSpacing; x < width; x += gridSpacing) {\n const isMajor = x % majorSpacing === 0;\n const opacity = isMajor ? 0.35 : 0.15;\n const sw = isMajor ? 1.5 : 0.5;\n svgParts.push(\n `<line x1=\"${x}\" y1=\"0\" x2=\"${x}\" y2=\"${height}\" stroke=\"rgba(255,50,50,${opacity})\" stroke-width=\"${sw}\"/>`,\n );\n }\n for (let y = gridSpacing; y < height; y += gridSpacing) {\n const isMajor = y % majorSpacing === 0;\n const opacity = isMajor ? 0.35 : 0.15;\n const sw = isMajor ? 1.5 : 0.5;\n svgParts.push(\n `<line x1=\"0\" y1=\"${y}\" x2=\"${width}\" y2=\"${y}\" stroke=\"rgba(255,50,50,${opacity})\" stroke-width=\"${sw}\"/>`,\n );\n }\n\n // --- Coordinate labels along top edge ---\n for (let x = labelSpacing; x < width; x += labelSpacing) {\n const text = String(x);\n const tw = text.length * 7.5 + 6;\n svgParts.push(\n `<rect x=\"${x - tw / 2}\" y=\"2\" width=\"${tw}\" height=\"16\" fill=\"rgba(0,0,0,0.65)\" rx=\"3\"/>`,\n `<text x=\"${x}\" y=\"14\" text-anchor=\"middle\" fill=\"#ff6666\" font-size=\"11\" font-family=\"Consolas,monospace\" font-weight=\"bold\">${text}</text>`,\n );\n }\n\n // --- Coordinate labels along left edge ---\n for (let y = labelSpacing; y < height; y += labelSpacing) {\n const text = String(y);\n const tw = text.length * 7.5 + 6;\n svgParts.push(\n `<rect x=\"2\" y=\"${y - 8}\" width=\"${tw}\" height=\"16\" fill=\"rgba(0,0,0,0.65)\" rx=\"3\"/>`,\n `<text x=\"5\" y=\"${y + 4}\" fill=\"#ff6666\" font-size=\"11\" font-family=\"Consolas,monospace\" font-weight=\"bold\">${text}</text>`,\n );\n }\n\n // --- Origin label ---\n svgParts.push(\n `<rect x=\"2\" y=\"2\" width=\"22\" height=\"16\" fill=\"rgba(0,0,0,0.65)\" rx=\"3\"/>`,\n `<text x=\"5\" y=\"14\" fill=\"#ff6666\" font-size=\"11\" font-family=\"Consolas,monospace\" font-weight=\"bold\">0,0</text>`,\n );\n\n // --- Dimension label at bottom-right ---\n const dimText = `${width}x${height}`;\n const dimTw = dimText.length * 7.5 + 6;\n svgParts.push(\n `<rect x=\"${width - dimTw - 2}\" y=\"${height - 18}\" width=\"${dimTw}\" height=\"16\" fill=\"rgba(0,0,0,0.65)\" rx=\"3\"/>`,\n `<text x=\"${width - dimTw / 2 - 2}\" y=\"${height - 6}\" text-anchor=\"middle\" fill=\"#ff6666\" font-size=\"11\" font-family=\"Consolas,monospace\" font-weight=\"bold\">${dimText}</text>`,\n );\n\n const svg = Buffer.from(\n `<svg width=\"${width}\" height=\"${height}\" xmlns=\"http://www.w3.org/2000/svg\">${svgParts.join('')}</svg>`,\n );\n\n return sharp(imageBuffer)\n .composite([{ input: svg, top: 0, left: 0 }])\n .jpeg({ quality: 70 })\n .toBuffer();\n}\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nasync function getNutJs() {\n return import('@nut-tree-fork/nut-js');\n}\n\nexport const mouseClickTool: ToolDefinition = {\n name: 'mouse_click',\n description: 'Click the mouse at the given screen coordinates.',\n parameters: z.object({\n x: z.number().describe('X coordinate on screen'),\n y: z.number().describe('Y coordinate on screen'),\n button: z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n const point = new nut.Point(args.x, args.y);\n await nut.mouse.move(nut.straightTo(point));\n\n const buttonMap = {\n left: nut.Button.LEFT,\n right: nut.Button.RIGHT,\n middle: nut.Button.MIDDLE,\n };\n await nut.mouse.click(buttonMap[args.button]);\n\n return { type: 'text', content: `Clicked ${args.button} at (${args.x}, ${args.y})` };\n },\n};\n\nexport const mouseMoveTool: ToolDefinition = {\n name: 'mouse_move',\n description: 'Move the mouse to the given screen coordinates without clicking.',\n parameters: z.object({\n x: z.number().describe('X coordinate on screen'),\n y: z.number().describe('Y coordinate on screen'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n const point = new nut.Point(args.x, args.y);\n await nut.mouse.move(nut.straightTo(point));\n return { type: 'text', content: `Mouse moved to (${args.x}, ${args.y})` };\n },\n};\n\nexport const mouseScrollTool: ToolDefinition = {\n name: 'mouse_scroll',\n description: 'Scroll the mouse wheel.',\n parameters: z.object({\n direction: z.enum(['up', 'down']).describe('Scroll direction'),\n amount: z.number().positive().default(3).describe('Number of scroll steps'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n for (let i = 0; i < args.amount; i++) {\n if (args.direction === 'down') {\n await nut.mouse.scrollDown(1);\n } else {\n await nut.mouse.scrollUp(1);\n }\n }\n return { type: 'text', content: `Scrolled ${args.direction} ${args.amount} steps` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nasync function getNutJs() {\n return import('@nut-tree-fork/nut-js');\n}\n\nexport const keyboardTypeTool: ToolDefinition = {\n name: 'keyboard_type',\n description: 'Type text using the keyboard. The text is typed character by character.',\n parameters: z.object({\n text: z.string().describe('The text to type'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n await nut.keyboard.type(args.text);\n return { type: 'text', content: `Typed: \"${args.text}\"` };\n },\n};\n\n/**\n * Map common key names to nut-js Key enum values.\n */\nfunction resolveKey(nut: any, keyName: string): number {\n const keyMap: Record<string, string> = {\n 'ctrl': 'LeftControl',\n 'control': 'LeftControl',\n 'shift': 'LeftShift',\n 'alt': 'LeftAlt',\n 'meta': 'LeftWin',\n 'win': 'LeftWin',\n 'windows': 'LeftWin',\n 'enter': 'Return',\n 'return': 'Return',\n 'tab': 'Tab',\n 'escape': 'Escape',\n 'esc': 'Escape',\n 'backspace': 'Backspace',\n 'delete': 'Delete',\n 'space': 'Space',\n 'up': 'Up',\n 'down': 'Down',\n 'left': 'Left',\n 'right': 'Right',\n 'home': 'Home',\n 'end': 'End',\n 'pageup': 'PageUp',\n 'pagedown': 'PageDown',\n 'f1': 'F1', 'f2': 'F2', 'f3': 'F3', 'f4': 'F4',\n 'f5': 'F5', 'f6': 'F6', 'f7': 'F7', 'f8': 'F8',\n 'f9': 'F9', 'f10': 'F10', 'f11': 'F11', 'f12': 'F12',\n };\n\n const normalized = keyName.toLowerCase().trim();\n const mapped = keyMap[normalized] ?? keyName;\n\n // Try to find in the Key enum\n const key = nut.Key[mapped];\n if (key !== undefined) return key;\n\n // Try uppercase single char (e.g., 'a' -> 'A')\n if (mapped.length === 1) {\n const upper = mapped.toUpperCase();\n const k = nut.Key[upper];\n if (k !== undefined) return k;\n }\n\n throw new Error(`Unknown key: \"${keyName}\"`);\n}\n\nexport const keyboardPressTool: ToolDefinition = {\n name: 'keyboard_press',\n description: 'Press a key combination. Examples: [\"Ctrl\", \"C\"] for copy, [\"Enter\"] for enter, [\"Alt\", \"F4\"] to close window.',\n parameters: z.object({\n keys: z.array(z.string()).min(1).describe('Array of key names to press simultaneously'),\n }),\n async execute(args) {\n const nut = await getNutJs();\n const resolved = args.keys.map((k: string) => resolveKey(nut, k));\n await nut.keyboard.pressKey(...resolved);\n await nut.keyboard.releaseKey(...resolved);\n return { type: 'text', content: `Pressed: ${args.keys.join('+')}` };\n },\n};\n","import { z } from 'zod';\nimport { exec } from 'child_process';\nimport type { ToolDefinition } from '../types.js';\n\nconst MAX_OUTPUT_LENGTH = 10_000;\n\nexport const runCommandTool: ToolDefinition = {\n name: 'run_command',\n description: 'Execute a shell command and return its output. Uses PowerShell on Windows.',\n parameters: z.object({\n command: z.string().describe('The command to execute'),\n timeout: z.number().positive().default(30_000).describe('Timeout in milliseconds'),\n }),\n async execute(args) {\n return new Promise((resolve) => {\n exec(\n args.command,\n {\n timeout: args.timeout,\n maxBuffer: 1024 * 1024,\n shell: 'powershell.exe',\n windowsHide: true,\n },\n (error, stdout, stderr) => {\n let output = '';\n if (stdout) output += stdout;\n if (stderr) output += `\\n[stderr] ${stderr}`;\n if (error && error.killed) output += '\\n[timeout] Command timed out';\n else if (error) output += `\\n[exit code ${error.code}]`;\n\n // Truncate to protect context\n if (output.length > MAX_OUTPUT_LENGTH) {\n output = output.slice(0, MAX_OUTPUT_LENGTH) + '\\n...(truncated)';\n }\n\n resolve({ type: 'text', content: output.trim() || '(no output)' });\n },\n );\n });\n },\n};\n","import { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport type { ToolDefinition } from '../types.js';\n\nconst MAX_FILE_SIZE = 100_000; // chars\n\nexport const fileReadTool: ToolDefinition = {\n name: 'file_read',\n description: 'Read the contents of a file at the given path.',\n parameters: z.object({\n path: z.string().describe('Absolute path to the file'),\n }),\n async execute(args) {\n try {\n const content = await readFile(args.path, 'utf-8');\n if (content.length > MAX_FILE_SIZE) {\n return {\n type: 'text',\n content: content.slice(0, MAX_FILE_SIZE) + '\\n...(truncated)',\n };\n }\n return { type: 'text', content };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { type: 'text', content: `Error reading file: ${msg}` };\n }\n },\n};\n","import { z } from 'zod';\nimport { writeFile, mkdir } from 'fs/promises';\nimport { dirname } from 'path';\nimport type { ToolDefinition } from '../types.js';\n\nexport const fileWriteTool: ToolDefinition = {\n name: 'file_write',\n description: 'Write content to a file at the given path. Creates parent directories if needed.',\n parameters: z.object({\n path: z.string().describe('Absolute path to the file'),\n content: z.string().describe('Content to write'),\n }),\n async execute(args) {\n try {\n await mkdir(dirname(args.path), { recursive: true });\n await writeFile(args.path, args.content, 'utf-8');\n return { type: 'text', content: `File written: ${args.path}` };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { type: 'text', content: `Error writing file: ${msg}` };\n }\n },\n};\n","import { z } from 'zod';\nimport { readFileSync, existsSync } from 'fs';\nimport { extname } from 'path';\nimport type { ToolDefinition } from '../types.js';\n\nconst IMAGE_EXTS = new Set(['.png', '.jpg', '.jpeg', '.bmp', '.webp']);\n\nexport const useLocalImageTool: ToolDefinition = {\n name: 'use_local_image',\n description: 'Load a local image file and get a screenshot ID for it. Use this to reference local images in your report via [Image:img_X].',\n parameters: z.object({\n path: z.string().describe('Absolute path to the image file'),\n label: z.string().default('local').describe('Label for the image (e.g. \"chart\", \"photo\")'),\n }),\n async execute(args, ctx) {\n if (!existsSync(args.path)) {\n return { type: 'text', content: `Error: File not found: ${args.path}` };\n }\n\n const ext = extname(args.path).toLowerCase();\n if (!IMAGE_EXTS.has(ext)) {\n return { type: 'text', content: `Error: Not a supported image format (${ext}). Supported: ${[...IMAGE_EXTS].join(', ')}` };\n }\n\n const buf = readFileSync(args.path);\n const mimeType = (ext === '.png') ? 'image/png' as const : 'image/jpeg' as const;\n const base64 = buf.toString('base64');\n const id = ctx.screenshots.save(base64, mimeType, args.label);\n\n return {\n type: 'image',\n base64,\n mimeType,\n screenshotId: id,\n };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserNavigateTool: ToolDefinition = {\n name: 'browser_navigate',\n description: 'Navigate the browser to a URL.',\n parameters: z.object({\n url: z.string().describe('The URL to navigate to'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n await page.goto(args.url, { waitUntil: 'domcontentloaded', timeout: 30_000 });\n const title = await page.title();\n return { type: 'text', content: `Navigated to: ${args.url}\\nPage title: ${title}` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserClickTool: ToolDefinition = {\n name: 'browser_click',\n description: 'Click an element on the web page using a CSS selector or text content.',\n parameters: z.object({\n selector: z.string().describe('CSS selector or text to find the element (e.g., \"button.submit\", \"text=Login\")'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n await page.click(args.selector, { timeout: 10_000 });\n return { type: 'text', content: `Clicked element: ${args.selector}` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserTypeTool: ToolDefinition = {\n name: 'browser_type',\n description: 'Type text into an input field on the web page.',\n parameters: z.object({\n selector: z.string().describe('CSS selector for the input element'),\n text: z.string().describe('Text to type'),\n clear: z.boolean().default(true).describe('Whether to clear the field before typing'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n if (args.clear) {\n await page.fill(args.selector, args.text, { timeout: 10_000 });\n } else {\n await page.type(args.selector, args.text, { timeout: 10_000 });\n }\n return { type: 'text', content: `Typed \"${args.text}\" into ${args.selector}` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserScreenshotTool: ToolDefinition = {\n name: 'browser_screenshot',\n description: 'Take a screenshot of the current browser page. Returns a screenshot ID (e.g. img_2) that you can reference later in report.',\n parameters: z.object({\n fullPage: z.boolean().default(false).describe('Whether to capture the full scrollable page'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n const buf = await page.screenshot({\n type: 'jpeg',\n quality: 70,\n fullPage: args.fullPage,\n scale: 'css',\n });\n const base64 = buf.toString('base64');\n const id = ctx.screenshots.save(base64, 'image/jpeg', 'browser');\n\n return {\n type: 'image',\n base64,\n mimeType: 'image/jpeg',\n screenshotId: id,\n };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nconst MAX_CONTENT_LENGTH = 20_000;\n\nexport const browserContentTool: ToolDefinition = {\n name: 'browser_content',\n description: 'Get the text content of the current web page. Returns visible text, not HTML.',\n parameters: z.object({}),\n async execute(_args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n const url = page.url();\n const title = await page.title();\n let text = await page.innerText('body').catch(() => '');\n\n if (text.length > MAX_CONTENT_LENGTH) {\n text = text.slice(0, MAX_CONTENT_LENGTH) + '\\n...(truncated)';\n }\n\n return {\n type: 'text',\n content: `URL: ${url}\\nTitle: ${title}\\n\\n${text}`,\n };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const browserScrollTool: ToolDefinition = {\n name: 'browser_scroll',\n description: 'Scroll the current web page.',\n parameters: z.object({\n direction: z.enum(['up', 'down']).describe('Scroll direction'),\n amount: z.number().positive().default(500).describe('Pixels to scroll'),\n }),\n async execute(args, ctx) {\n const browser = await ctx.getBrowser();\n const page = await browser.getPage();\n const delta = args.direction === 'down' ? args.amount : -args.amount;\n await page.evaluate((d: number) => window.scrollBy(0, d), delta);\n return { type: 'text', content: `Scrolled ${args.direction} ${args.amount}px` };\n },\n};\n","import { z } from 'zod';\nimport type { ToolDefinition } from '../types.js';\n\nexport const reportTool: ToolDefinition = {\n name: 'report',\n description:\n 'Report progress back to the caller. Call this when the task is completed, when you are blocked, or when you need guidance. Calling this STOPS your execution immediately.\\n\\nThe content field supports rich document format: mix text with screenshots using [Image:img_1] markers. Example:\\n\"Here is the current state:\\n[Image:img_2]\\nThe page shows...\"',\n parameters: z.object({\n status: z\n .enum(['completed', 'blocked', 'need_guidance'])\n .describe(\n '\"completed\" = task done, \"blocked\" = cannot proceed, \"need_guidance\" = need a decision',\n ),\n content: z\n .string()\n .describe('Rich report content. Use [Image:img_X] to embed screenshots captured earlier. Example: \"Task done.\\\\n[Image:img_1]\\\\nThe page shows the result.\"'),\n data: z.unknown().optional().describe('Optional structured data to return'),\n }),\n async execute(args) {\n return {\n type: 'report',\n status: args.status,\n content: args.content,\n data: args.data,\n };\n },\n};\n","import { ToolRegistry } from './registry.js';\nimport { screenshotTool } from './windows/screenshot.js';\nimport { mouseClickTool, mouseMoveTool, mouseScrollTool } from './windows/mouse.js';\nimport { keyboardTypeTool, keyboardPressTool } from './windows/keyboard.js';\nimport { runCommandTool } from './windows/command.js';\nimport { fileReadTool } from './file/read.js';\nimport { fileWriteTool } from './file/write.js';\nimport { useLocalImageTool } from './file/image.js';\nimport { browserNavigateTool } from './browser/navigate.js';\nimport { browserClickTool } from './browser/click.js';\nimport { browserTypeTool } from './browser/type.js';\nimport { browserScreenshotTool } from './browser/screenshot.js';\nimport { browserContentTool } from './browser/content.js';\nimport { browserScrollTool } from './browser/scroll.js';\nimport { reportTool } from './control/report.js';\n\nexport function createToolRegistry(): ToolRegistry {\n const registry = new ToolRegistry();\n\n // Windows tools\n registry.register(screenshotTool);\n registry.register(mouseClickTool);\n registry.register(mouseMoveTool);\n registry.register(mouseScrollTool);\n registry.register(keyboardTypeTool);\n registry.register(keyboardPressTool);\n registry.register(runCommandTool);\n\n // File tools\n registry.register(fileReadTool);\n registry.register(fileWriteTool);\n registry.register(useLocalImageTool);\n\n // Browser tools\n registry.register(browserNavigateTool);\n registry.register(browserClickTool);\n registry.register(browserTypeTool);\n registry.register(browserScreenshotTool);\n registry.register(browserContentTool);\n registry.register(browserScrollTool);\n\n // Control tools\n registry.register(reportTool);\n\n return registry;\n}\n","import type { z } from 'zod';\n\nexport interface StoredScreenshot {\n id: string;\n base64: string;\n mimeType: 'image/png' | 'image/jpeg';\n label: string; // e.g. \"desktop\", \"browser\"\n}\n\n/**\n * Simple in-memory screenshot store.\n * Screenshot tools save images here with auto-incrementing IDs.\n * Report content references them via [Image:img_1] markers.\n */\nexport class ScreenshotStore {\n private counter = 0;\n private store = new Map<string, StoredScreenshot>();\n\n save(base64: string, mimeType: 'image/png' | 'image/jpeg', label: string): string {\n this.counter++;\n const id = `img_${this.counter}`;\n this.store.set(id, { id, base64, mimeType, label });\n return id;\n }\n\n get(id: string): StoredScreenshot | undefined {\n return this.store.get(id);\n }\n\n listIds(): string[] {\n return [...this.store.keys()];\n }\n}\n\n/** A block in parsed report content */\nexport type ContentBlock =\n | { type: 'text'; text: string }\n | { type: 'image'; id: string; base64: string; mimeType: 'image/png' | 'image/jpeg'; label: string };\n\n/**\n * Parse report content string, expanding [Image:img_X] markers into image blocks.\n * Returns an array of text and image content blocks.\n */\nexport function parseReportContent(content: string, store: ScreenshotStore): ContentBlock[] {\n const blocks: ContentBlock[] = [];\n const regex = /\\[Image:(img_\\d+)\\]/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n // Text before the marker\n if (match.index > lastIndex) {\n blocks.push({ type: 'text', text: content.slice(lastIndex, match.index) });\n }\n\n const id = match[1];\n const screenshot = store.get(id);\n if (screenshot) {\n blocks.push({\n type: 'image',\n id: screenshot.id,\n base64: screenshot.base64,\n mimeType: screenshot.mimeType,\n label: screenshot.label,\n });\n } else {\n // Unknown ID — keep as text\n blocks.push({ type: 'text', text: match[0] });\n }\n\n lastIndex = regex.lastIndex;\n }\n\n // Remaining text after last marker\n if (lastIndex < content.length) {\n blocks.push({ type: 'text', text: content.slice(lastIndex) });\n }\n\n return blocks;\n}\n\n/** Strip [Image:...] markers, returning text-only content */\nexport function stripImageMarkers(content: string): string {\n return content.replace(/\\[Image:img_\\d+\\]/g, '').replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\nexport interface ToolContext {\n sessionId: string;\n cdpUrl: string;\n /** Lazy browser client getter — only connects on first call */\n getBrowser: () => Promise<import('./browser/client.js').BrowserClient>;\n /** Screenshot store — tools save screenshots here, report references by [Image:id] */\n screenshots: ScreenshotStore;\n}\n\nexport type ToolResult =\n | { type: 'text'; content: string }\n | { type: 'image'; base64: string; mimeType: 'image/png' | 'image/jpeg'; screenshotId: string }\n | {\n type: 'report';\n status: 'completed' | 'blocked' | 'need_guidance';\n content: string; // Rich content with [Image:img_1] markers\n data?: unknown;\n };\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: z.ZodType;\n execute(args: any, context: ToolContext): Promise<ToolResult>;\n}\n"],"mappings":"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","names":["existsSync","join","homedir","z","sharp","z","sharp","z","z","getNutJs","z","z","z","z","readFileSync","existsSync","z","z","z","z","z","z","z"]}
|
package/dist/mcp/server.js
CHANGED
|
@@ -48,21 +48,49 @@ function buildSystemPrompt() {
|
|
|
48
48
|
return `You are a precise Windows and browser automation agent. Your job is to execute instructions by calling the tools available to you.
|
|
49
49
|
|
|
50
50
|
## Workflow
|
|
51
|
-
1. Take a screenshot first to understand the current state of the screen.
|
|
51
|
+
1. Take a \`screenshot\` first to understand the current state of the screen.
|
|
52
52
|
2. Plan the minimal sequence of actions needed.
|
|
53
|
-
3. Execute
|
|
53
|
+
3. Execute actions, verifying with screenshots at key checkpoints (not after every single action).
|
|
54
54
|
4. When the task is done, you are blocked, or you need guidance, call \`report\` immediately.
|
|
55
55
|
|
|
56
|
+
## Reading Screenshots
|
|
57
|
+
- Desktop screenshots include a **coordinate grid overlay**. The grid labels show pixel coordinates that directly correspond to \`mouse_click\` and \`mouse_move\` coordinates.
|
|
58
|
+
- Use the grid numbers to estimate the (x, y) position of UI elements. For example, if a button appears near the grid label "400" horizontally and "300" vertically, click at approximately (400, 300).
|
|
59
|
+
- The bottom-right corner label shows the total screen dimensions.
|
|
60
|
+
|
|
61
|
+
## Tool Selection
|
|
62
|
+
- **Browser tasks**: Prefer \`browser_*\` tools (they use CSS selectors, more reliable than coordinates). Use \`browser_content\` to find text/elements when you can't locate them visually.
|
|
63
|
+
- **Desktop/native app tasks**: Use \`screenshot\` + \`mouse_click\`/\`keyboard_*\`. Read coordinates from the grid overlay.
|
|
64
|
+
- **Terminal tasks**: Prefer \`run_command\` over GUI interactions. It's faster and more reliable.
|
|
65
|
+
- **Mixed tasks**: You can combine all tool types. For example, use \`run_command\` to launch an app, then \`screenshot\` + mouse to interact with it.
|
|
66
|
+
|
|
67
|
+
## Smart Screenshot Strategy
|
|
68
|
+
- ALWAYS take a screenshot before your first action.
|
|
69
|
+
- Take a screenshot to verify after **critical actions** (clicking a button, submitting a form, navigating to a new page).
|
|
70
|
+
- Skip verification screenshots for **low-risk sequential actions** (typing text, pressing modifier keys, scrolling) \u2014 verify after the sequence is complete instead.
|
|
71
|
+
- If an action might trigger a loading state, wait briefly then screenshot to confirm the page has loaded.
|
|
72
|
+
|
|
56
73
|
## Rules
|
|
57
|
-
- ALWAYS take a screenshot before your first action to understand the current state.
|
|
58
|
-
- After every mouse click or keyboard action, take a screenshot to verify the result.
|
|
59
74
|
- Call ONE tool at a time. Never request multiple tools in parallel.
|
|
60
75
|
- Before each tool call, briefly state what you are about to do and why.
|
|
61
76
|
- After receiving a tool result, describe what you observed.
|
|
62
|
-
- For browser tasks, prefer using browser_* tools over clicking on-screen coordinates.
|
|
63
|
-
- For terminal tasks, prefer \`run_command\` over GUI interactions when possible.
|
|
64
77
|
- Do not read or write files unless the instruction explicitly asks for it.
|
|
65
78
|
|
|
79
|
+
## Handling Common Situations
|
|
80
|
+
- **Loading/transitions**: If a page or app is loading, take another screenshot after a moment instead of acting immediately.
|
|
81
|
+
- **Popups/dialogs**: Handle unexpected dialogs (cookie banners, notifications, confirmations) by dismissing or accepting them, then continue with the original task.
|
|
82
|
+
- **Dropdowns/menus**: Click to open, then screenshot to see options before selecting.
|
|
83
|
+
- **Scrolling**: If content is below the fold, scroll down and screenshot. Check both browser_scroll (for web pages) and mouse_scroll (for desktop apps).
|
|
84
|
+
- **Text input**: For browser forms, prefer \`browser_type\` with the CSS selector. For desktop apps, click the input field first, then use \`keyboard_type\`.
|
|
85
|
+
- **Coordinate precision**: When clicking small UI elements (buttons, links, checkboxes), aim for their center. If a click misses, adjust coordinates and try once more.
|
|
86
|
+
|
|
87
|
+
## Error Recovery
|
|
88
|
+
- If an action fails or produces unexpected results, take a screenshot to reassess the situation before trying again.
|
|
89
|
+
- Try a different approach rather than repeating the same failed action. For example:
|
|
90
|
+
- If \`browser_click\` fails on a selector, try a different selector or fall back to coordinate-based \`mouse_click\`.
|
|
91
|
+
- If a UI element is not visible, try scrolling or switching tabs/windows.
|
|
92
|
+
- If something fails **twice with different approaches**, call \`report\` with status "blocked".
|
|
93
|
+
|
|
66
94
|
## report Tool
|
|
67
95
|
Call \`report\` when:
|
|
68
96
|
- **"completed"**: The task is done successfully. Summarize what was accomplished.
|
|
@@ -78,12 +106,9 @@ report({
|
|
|
78
106
|
})
|
|
79
107
|
\`\`\`
|
|
80
108
|
|
|
81
|
-
Each screenshot tool returns a screenshot ID (e.g. img_1, img_2). Use these IDs to embed images in your report.
|
|
109
|
+
Each screenshot tool returns a screenshot ID (e.g. img_1, img_2). Use these IDs to embed images in your report. Include relevant screenshots in your report so the caller can see the final state.
|
|
82
110
|
|
|
83
|
-
|
|
84
|
-
- Do NOT keep retrying the same failing action. If something fails twice, call \`report\` with status "blocked".
|
|
85
|
-
- If a UI element is not where you expect it, try scrolling first before giving up.
|
|
86
|
-
- Keep your responses concise. Focus on actions, not explanations.`;
|
|
111
|
+
You can also use \`use_local_image\` to load a local image file and get a screenshot ID for embedding in reports.`;
|
|
87
112
|
}
|
|
88
113
|
|
|
89
114
|
// src/agent/runner.ts
|
|
@@ -666,7 +691,7 @@ var screenshotTool = {
|
|
|
666
691
|
const image = primary.captureImageSync();
|
|
667
692
|
const physW = image.width;
|
|
668
693
|
const physH = image.height;
|
|
669
|
-
const scaleFactor = primary.scaleFactor ?? 1;
|
|
694
|
+
const scaleFactor = primary.scaleFactor() ?? 1;
|
|
670
695
|
const logicalW = Math.round(physW / scaleFactor);
|
|
671
696
|
const logicalH = Math.round(physH / scaleFactor);
|
|
672
697
|
const raw = image.toRawSync();
|