ai-browser 0.1.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/README.md +130 -0
- package/dist/agent/agent-loop.d.ts +35 -0
- package/dist/agent/agent-loop.d.ts.map +1 -0
- package/dist/agent/agent-loop.js +406 -0
- package/dist/agent/agent-loop.js.map +1 -0
- package/dist/agent/api-client.d.ts +12 -0
- package/dist/agent/api-client.d.ts.map +1 -0
- package/dist/agent/api-client.js +59 -0
- package/dist/agent/api-client.js.map +1 -0
- package/dist/agent/config.d.ts +10 -0
- package/dist/agent/config.d.ts.map +1 -0
- package/dist/agent/config.js +10 -0
- package/dist/agent/config.js.map +1 -0
- package/dist/agent/index.d.ts +2 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +84 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/prompt.d.ts +2 -0
- package/dist/agent/prompt.d.ts.map +1 -0
- package/dist/agent/prompt.js +64 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/tools.d.ts +3 -0
- package/dist/agent/tools.d.ts.map +1 -0
- package/dist/agent/tools.js +166 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/agent/types.d.ts +57 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +2 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/api/errors.d.ts +24 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +33 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +4 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/mcp-sse.d.ts +4 -0
- package/dist/api/mcp-sse.d.ts.map +1 -0
- package/dist/api/mcp-sse.js +45 -0
- package/dist/api/mcp-sse.js.map +1 -0
- package/dist/api/routes.d.ts +4 -0
- package/dist/api/routes.d.ts.map +1 -0
- package/dist/api/routes.js +628 -0
- package/dist/api/routes.js.map +1 -0
- package/dist/browser/BrowserManager.d.ts +26 -0
- package/dist/browser/BrowserManager.d.ts.map +1 -0
- package/dist/browser/BrowserManager.js +82 -0
- package/dist/browser/BrowserManager.js.map +1 -0
- package/dist/browser/CookieStore.d.ts +20 -0
- package/dist/browser/CookieStore.d.ts.map +1 -0
- package/dist/browser/CookieStore.js +77 -0
- package/dist/browser/CookieStore.js.map +1 -0
- package/dist/browser/SessionManager.d.ts +41 -0
- package/dist/browser/SessionManager.d.ts.map +1 -0
- package/dist/browser/SessionManager.js +146 -0
- package/dist/browser/SessionManager.js.map +1 -0
- package/dist/browser/actions.d.ts +7 -0
- package/dist/browser/actions.d.ts.map +1 -0
- package/dist/browser/actions.js +110 -0
- package/dist/browser/actions.js.map +1 -0
- package/dist/browser/index.d.ts +4 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +4 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/cli/mcp-stdio.d.ts +3 -0
- package/dist/cli/mcp-stdio.d.ts.map +1 -0
- package/dist/cli/mcp-stdio.js +34 -0
- package/dist/cli/mcp-stdio.js.map +1 -0
- package/dist/cli/server.d.ts +3 -0
- package/dist/cli/server.d.ts.map +1 -0
- package/dist/cli/server.js +75 -0
- package/dist/cli/server.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/browser-mcp-server.d.ts +8 -0
- package/dist/mcp/browser-mcp-server.d.ts.map +1 -0
- package/dist/mcp/browser-mcp-server.js +276 -0
- package/dist/mcp/browser-mcp-server.js.map +1 -0
- package/dist/semantic/ContentExtractor.d.ts +23 -0
- package/dist/semantic/ContentExtractor.d.ts.map +1 -0
- package/dist/semantic/ContentExtractor.js +119 -0
- package/dist/semantic/ContentExtractor.js.map +1 -0
- package/dist/semantic/ElementCollector.d.ts +15 -0
- package/dist/semantic/ElementCollector.d.ts.map +1 -0
- package/dist/semantic/ElementCollector.js +133 -0
- package/dist/semantic/ElementCollector.js.map +1 -0
- package/dist/semantic/ElementMatcher.d.ts +13 -0
- package/dist/semantic/ElementMatcher.d.ts.map +1 -0
- package/dist/semantic/ElementMatcher.js +84 -0
- package/dist/semantic/ElementMatcher.js.map +1 -0
- package/dist/semantic/IframeHandler.d.ts +17 -0
- package/dist/semantic/IframeHandler.d.ts.map +1 -0
- package/dist/semantic/IframeHandler.js +72 -0
- package/dist/semantic/IframeHandler.js.map +1 -0
- package/dist/semantic/ModelAdapter.d.ts +26 -0
- package/dist/semantic/ModelAdapter.d.ts.map +1 -0
- package/dist/semantic/ModelAdapter.js +47 -0
- package/dist/semantic/ModelAdapter.js.map +1 -0
- package/dist/semantic/PageAnalyzer.d.ts +15 -0
- package/dist/semantic/PageAnalyzer.d.ts.map +1 -0
- package/dist/semantic/PageAnalyzer.js +131 -0
- package/dist/semantic/PageAnalyzer.js.map +1 -0
- package/dist/semantic/RegionDetector.d.ts +8 -0
- package/dist/semantic/RegionDetector.d.ts.map +1 -0
- package/dist/semantic/RegionDetector.js +53 -0
- package/dist/semantic/RegionDetector.js.map +1 -0
- package/dist/semantic/StateTracker.d.ts +24 -0
- package/dist/semantic/StateTracker.d.ts.map +1 -0
- package/dist/semantic/StateTracker.js +111 -0
- package/dist/semantic/StateTracker.js.map +1 -0
- package/dist/semantic/index.d.ts +9 -0
- package/dist/semantic/index.d.ts.map +1 -0
- package/dist/semantic/index.js +9 -0
- package/dist/semantic/index.js.map +1 -0
- package/dist/types/enums.d.ts +23 -0
- package/dist/types/enums.d.ts.map +1 -0
- package/dist/types/enums.js +26 -0
- package/dist/types/enums.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/semantic.d.ts +13 -0
- package/dist/types/semantic.d.ts.map +1 -0
- package/dist/types/semantic.js +2 -0
- package/dist/types/semantic.js.map +1 -0
- package/dist/types/state.d.ts +15 -0
- package/dist/types/state.d.ts.map +1 -0
- package/dist/types/state.js +2 -0
- package/dist/types/state.js.map +1 -0
- package/dist/types/structures.d.ts +28 -0
- package/dist/types/structures.d.ts.map +1 -0
- package/dist/types/structures.js +2 -0
- package/dist/types/structures.js.map +1 -0
- package/package.json +52 -0
- package/public/agent.html +932 -0
- package/public/index.html +752 -0
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# AI Browser
|
|
2
|
+
|
|
3
|
+
An AI-driven browser automation service that enables LLM agents to browse and interact with web pages through semantic analysis and the MCP (Model Context Protocol).
|
|
4
|
+
|
|
5
|
+
[中文文档](./README_CN.md)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Semantic Web Analysis** — Extracts structured elements (buttons, links, inputs) from pages using the Chrome Accessibility Tree, assigning each a unique semantic ID for reliable interaction
|
|
10
|
+
- **LLM-Powered Agent** — An autonomous browsing agent driven by LLM tool calls, capable of navigating, searching, form-filling, and information extraction
|
|
11
|
+
- **MCP Protocol Integration** — Browser tools exposed via MCP, enabling standardized communication between the agent and browser
|
|
12
|
+
- **Real-time Monitoring** — Web UI with SSE-based live streaming of agent actions, tool calls, and results
|
|
13
|
+
- **Multi-Session Support** — Concurrent browser sessions with multi-tab management and automatic cleanup
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
|
|
19
|
+
│ Web UI │────▶│ Fastify API │────▶│ Browsing Agent │
|
|
20
|
+
│ (SSE) │ │ (REST) │ │ (LLM Loop) │
|
|
21
|
+
└─────────────┘ └──────────────┘ └────────┬─────────┘
|
|
22
|
+
│ MCP
|
|
23
|
+
┌────────▼─────────┐
|
|
24
|
+
│ MCP Server │
|
|
25
|
+
│ (Browser Tools) │
|
|
26
|
+
└────────┬─────────┘
|
|
27
|
+
│
|
|
28
|
+
┌────────▼─────────┐
|
|
29
|
+
│ Puppeteer │
|
|
30
|
+
│ + Semantic Layer │
|
|
31
|
+
└──────────────────┘
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- **Browser Layer** (`src/browser/`) — Puppeteer-based browser management with multi-tab session support
|
|
35
|
+
- **Semantic Layer** (`src/semantic/`) — Accessibility tree analysis, content extraction, element matching, page classification
|
|
36
|
+
- **MCP Layer** (`src/mcp/`) — MCP server exposing browser tools (navigate, click, type, scroll, etc.)
|
|
37
|
+
- **Agent Layer** (`src/agent/`) — LLM-driven agent loop with tool calling, loop detection, and step management
|
|
38
|
+
- **API Layer** (`src/api/`) — Fastify HTTP server with REST endpoints and SSE event streaming
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### Prerequisites
|
|
43
|
+
|
|
44
|
+
- Node.js >= 18
|
|
45
|
+
- An OpenAI-compatible LLM API
|
|
46
|
+
|
|
47
|
+
### Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
git clone https://github.com/chenpu17/ai-browser.git
|
|
51
|
+
cd ai-browser
|
|
52
|
+
npm install
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Configuration
|
|
56
|
+
|
|
57
|
+
Set environment variables:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
export LLM_API_KEY="your-api-key"
|
|
61
|
+
export LLM_BASE_URL="https://api.openai.com/v1" # or any OpenAI-compatible endpoint
|
|
62
|
+
export LLM_MODEL="gpt-4" # model name
|
|
63
|
+
export PROXY_SERVER="127.0.0.1:7897" # optional, HTTP proxy for browser
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Run
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Development mode
|
|
70
|
+
npm run dev
|
|
71
|
+
|
|
72
|
+
# Or with environment variables inline
|
|
73
|
+
LLM_API_KEY=your-key npx tsx src/index.ts
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Open `http://localhost:3000` for the web UI.
|
|
77
|
+
|
|
78
|
+
## MCP Tools
|
|
79
|
+
|
|
80
|
+
The agent has access to the following browser tools via MCP:
|
|
81
|
+
|
|
82
|
+
| Tool | Description |
|
|
83
|
+
|------|-------------|
|
|
84
|
+
| `navigate` | Open a URL, with timeout degradation for slow pages |
|
|
85
|
+
| `get_page_info` | Get interactive elements (buttons, links, inputs) with semantic IDs |
|
|
86
|
+
| `get_page_content` | Extract page text content (title, body, links, metadata) |
|
|
87
|
+
| `find_element` | Fuzzy search for elements by name, type, or Chinese/English aliases |
|
|
88
|
+
| `click` | Click an element by semantic ID |
|
|
89
|
+
| `type_text` | Type text into an input, with optional `submit=true` to press Enter |
|
|
90
|
+
| `press_key` | Press keyboard keys (Enter, Escape, Tab, etc.) |
|
|
91
|
+
| `scroll` | Scroll the page up or down |
|
|
92
|
+
| `go_back` | Navigate back to the previous page |
|
|
93
|
+
| `wait` | Wait for page loading |
|
|
94
|
+
|
|
95
|
+
## API Endpoints
|
|
96
|
+
|
|
97
|
+
| Method | Path | Description |
|
|
98
|
+
|--------|------|-------------|
|
|
99
|
+
| `GET` | `/health` | Health check |
|
|
100
|
+
| `POST` | `/v1/sessions` | Create a browser session |
|
|
101
|
+
| `GET` | `/v1/sessions/:id/semantic` | Get semantic elements |
|
|
102
|
+
| `POST` | `/v1/sessions/:id/action` | Execute browser action |
|
|
103
|
+
| `GET` | `/v1/sessions/:id/screenshot` | Take a page screenshot |
|
|
104
|
+
| `POST` | `/v1/agent/run` | Start an agent task |
|
|
105
|
+
| `GET` | `/v1/agent/:id/events` | SSE stream of agent events |
|
|
106
|
+
|
|
107
|
+
## Development
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm run build # Build TypeScript
|
|
111
|
+
npm run dev # Dev server with hot reload
|
|
112
|
+
npm test # Run tests
|
|
113
|
+
npm run test:run # Run tests once
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Testing
|
|
117
|
+
|
|
118
|
+
The project includes a 20-scenario real-world browsing test suite:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
node tests/run-scenarios.mjs
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Scenarios cover: search engines, news sites, documentation, e-commerce, and more.
|
|
125
|
+
|
|
126
|
+
> **Note:** The agent's system prompt defaults to Chinese. You can customize it in `src/agent/prompt.ts`.
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
MIT
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { ChatCompletionMessageParam } from 'openai/resources/chat/completions.js';
|
|
3
|
+
import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
4
|
+
import type { AgentRunResult } from './types.js';
|
|
5
|
+
export declare class BrowsingAgent extends EventEmitter {
|
|
6
|
+
private openai;
|
|
7
|
+
private mcpClient;
|
|
8
|
+
private state;
|
|
9
|
+
private messages;
|
|
10
|
+
private model;
|
|
11
|
+
private maxIterations;
|
|
12
|
+
private initialMessages;
|
|
13
|
+
private tools;
|
|
14
|
+
private recentToolCalls;
|
|
15
|
+
private stepWarningInjected;
|
|
16
|
+
private pendingInputResolve;
|
|
17
|
+
private pendingInputRequestId;
|
|
18
|
+
constructor(options: {
|
|
19
|
+
apiKey?: string;
|
|
20
|
+
baseURL?: string;
|
|
21
|
+
model?: string;
|
|
22
|
+
mcpClient: Client;
|
|
23
|
+
maxIterations?: number;
|
|
24
|
+
initialMessages?: ChatCompletionMessageParam[];
|
|
25
|
+
});
|
|
26
|
+
get sessionId(): string;
|
|
27
|
+
resolveInput(requestId: string, response: Record<string, string>): boolean;
|
|
28
|
+
private emitEvent;
|
|
29
|
+
private discoverTools;
|
|
30
|
+
run(task: string): Promise<AgentRunResult>;
|
|
31
|
+
private loop;
|
|
32
|
+
private executeToolCalls;
|
|
33
|
+
cleanup(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=agent-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAAE,0BAA0B,EAAsB,MAAM,sCAAsC,CAAC;AAC3G,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGxE,OAAO,KAAK,EAAc,cAAc,EAA0B,MAAM,YAAY,CAAC;AA8CrF,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,mBAAmB,CAA6D;IACxF,OAAO,CAAC,qBAAqB,CAAuB;gBAExC,OAAO,EAAE;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,eAAe,CAAC,EAAE,0BAA0B,EAAE,CAAC;KAChD;IAmBD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO;IAe1E,OAAO,CAAC,SAAS;YAIH,aAAa;IA2DrB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;YA8ClC,IAAI;YAoEJ,gBAAgB;IA4IxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAa/B"}
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import OpenAI from 'openai';
|
|
4
|
+
import { config } from './config.js';
|
|
5
|
+
import { SYSTEM_PROMPT } from './prompt.js';
|
|
6
|
+
const MAX_CONTENT_LENGTH = 4000;
|
|
7
|
+
function truncate(text, max = MAX_CONTENT_LENGTH) {
|
|
8
|
+
if (text.length <= max)
|
|
9
|
+
return text;
|
|
10
|
+
return text.slice(0, max) + `\n...(已截断,共${text.length}字符)`;
|
|
11
|
+
}
|
|
12
|
+
function formatForLLM(rawText, toolName) {
|
|
13
|
+
try {
|
|
14
|
+
const data = JSON.parse(rawText);
|
|
15
|
+
if (toolName === 'get_page_info' && data?.elements) {
|
|
16
|
+
const summary = {
|
|
17
|
+
page: data.page,
|
|
18
|
+
elementCount: data.elements.length,
|
|
19
|
+
elements: data.elements.slice(0, 30).map((e) => ({
|
|
20
|
+
id: e.id,
|
|
21
|
+
type: e.type,
|
|
22
|
+
label: e.label,
|
|
23
|
+
})),
|
|
24
|
+
intents: data.intents,
|
|
25
|
+
};
|
|
26
|
+
if (data.elements.length > 30) {
|
|
27
|
+
summary.note = `显示前30个元素,共${data.elements.length}个`;
|
|
28
|
+
}
|
|
29
|
+
return truncate(JSON.stringify(summary, null, 2));
|
|
30
|
+
}
|
|
31
|
+
if (toolName === 'get_page_content') {
|
|
32
|
+
let md = `# ${data.title || ''}\n\n`;
|
|
33
|
+
const sections = Array.isArray(data.sections) ? data.sections : [];
|
|
34
|
+
for (const s of sections) {
|
|
35
|
+
const stars = s.attention >= 0.7 ? '★★★'
|
|
36
|
+
: s.attention >= 0.4 ? '★★'
|
|
37
|
+
: '★';
|
|
38
|
+
md += `[${stars}] ${s.text}\n\n`;
|
|
39
|
+
}
|
|
40
|
+
if (sections.length === 0)
|
|
41
|
+
md += '(未提取到内容)\n';
|
|
42
|
+
return truncate(md);
|
|
43
|
+
}
|
|
44
|
+
return truncate(JSON.stringify(data));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return truncate(rawText);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export class BrowsingAgent extends EventEmitter {
|
|
51
|
+
openai;
|
|
52
|
+
mcpClient;
|
|
53
|
+
state;
|
|
54
|
+
messages;
|
|
55
|
+
model;
|
|
56
|
+
maxIterations;
|
|
57
|
+
initialMessages;
|
|
58
|
+
tools = [];
|
|
59
|
+
recentToolCalls = []; // 循环检测:记录最近工具调用签名
|
|
60
|
+
stepWarningInjected = false;
|
|
61
|
+
pendingInputResolve = null;
|
|
62
|
+
pendingInputRequestId = null;
|
|
63
|
+
constructor(options) {
|
|
64
|
+
super();
|
|
65
|
+
this.model = options.model || config.llm.model;
|
|
66
|
+
this.openai = new OpenAI({
|
|
67
|
+
baseURL: options.baseURL || config.llm.baseURL,
|
|
68
|
+
apiKey: options.apiKey || config.llm.apiKey,
|
|
69
|
+
});
|
|
70
|
+
this.mcpClient = options.mcpClient;
|
|
71
|
+
this.maxIterations = options.maxIterations ?? config.maxIterations;
|
|
72
|
+
this.initialMessages = options.initialMessages || [];
|
|
73
|
+
this.state = {
|
|
74
|
+
sessionId: '',
|
|
75
|
+
iteration: 0,
|
|
76
|
+
consecutiveErrors: 0,
|
|
77
|
+
done: false,
|
|
78
|
+
};
|
|
79
|
+
this.messages = [];
|
|
80
|
+
}
|
|
81
|
+
get sessionId() {
|
|
82
|
+
return this.state.sessionId;
|
|
83
|
+
}
|
|
84
|
+
resolveInput(requestId, response) {
|
|
85
|
+
if (this.pendingInputRequestId !== requestId || !this.pendingInputResolve) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
// Clear the timeout timer to prevent resource leak
|
|
89
|
+
if (this._askHumanTimer) {
|
|
90
|
+
clearTimeout(this._askHumanTimer);
|
|
91
|
+
this._askHumanTimer = null;
|
|
92
|
+
}
|
|
93
|
+
this.pendingInputResolve(response);
|
|
94
|
+
this.pendingInputResolve = null;
|
|
95
|
+
this.pendingInputRequestId = null;
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
emitEvent(event) {
|
|
99
|
+
this.emit('event', event);
|
|
100
|
+
}
|
|
101
|
+
async discoverTools() {
|
|
102
|
+
const { tools: mcpTools } = await this.mcpClient.listTools();
|
|
103
|
+
// 过滤内部工具,不暴露给 LLM
|
|
104
|
+
const INTERNAL_TOOLS = ['create_session', 'close_session'];
|
|
105
|
+
this.tools = mcpTools
|
|
106
|
+
.filter((t) => !INTERNAL_TOOLS.includes(t.name))
|
|
107
|
+
.map((t) => ({
|
|
108
|
+
type: 'function',
|
|
109
|
+
function: {
|
|
110
|
+
name: t.name,
|
|
111
|
+
description: t.description || '',
|
|
112
|
+
parameters: t.inputSchema,
|
|
113
|
+
},
|
|
114
|
+
}));
|
|
115
|
+
// Add the 'done' tool (agent-only, not from MCP)
|
|
116
|
+
this.tools.push({
|
|
117
|
+
type: 'function',
|
|
118
|
+
function: {
|
|
119
|
+
name: 'done',
|
|
120
|
+
description: '任务完成时调用。报告最终结果并结束任务。',
|
|
121
|
+
parameters: {
|
|
122
|
+
type: 'object',
|
|
123
|
+
properties: {
|
|
124
|
+
result: { type: 'string', description: '任务的最终结果描述' },
|
|
125
|
+
},
|
|
126
|
+
required: ['result'],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
// Add the 'ask_human' tool for requesting user input (e.g. login credentials)
|
|
131
|
+
this.tools.push({
|
|
132
|
+
type: 'function',
|
|
133
|
+
function: {
|
|
134
|
+
name: 'ask_human',
|
|
135
|
+
description: '向用户请求信息(如登录凭据)。调用后会暂停等待用户输入。',
|
|
136
|
+
parameters: {
|
|
137
|
+
type: 'object',
|
|
138
|
+
properties: {
|
|
139
|
+
question: { type: 'string', description: '向用户提出的问题' },
|
|
140
|
+
fields: {
|
|
141
|
+
type: 'array',
|
|
142
|
+
items: {
|
|
143
|
+
type: 'object',
|
|
144
|
+
properties: {
|
|
145
|
+
name: { type: 'string' },
|
|
146
|
+
label: { type: 'string' },
|
|
147
|
+
type: { type: 'string', enum: ['text', 'password'] },
|
|
148
|
+
},
|
|
149
|
+
required: ['name', 'label', 'type'],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
required: ['question', 'fields'],
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
console.log(`[Agent] 发现 ${this.tools.length} 个工具`);
|
|
158
|
+
}
|
|
159
|
+
async run(task) {
|
|
160
|
+
// Discover tools from MCP server
|
|
161
|
+
await this.discoverTools();
|
|
162
|
+
// Create session via MCP
|
|
163
|
+
console.log('[Agent] 创建浏览器会话...');
|
|
164
|
+
let sessionResult;
|
|
165
|
+
try {
|
|
166
|
+
sessionResult = await this.mcpClient.callTool({ name: 'create_session', arguments: {} });
|
|
167
|
+
const text = sessionResult.content[0]?.text;
|
|
168
|
+
const parsed = JSON.parse(text);
|
|
169
|
+
this.state.sessionId = parsed.sessionId;
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
const result = { success: false, error: `创建会话失败: ${err.message}`, iterations: 0 };
|
|
173
|
+
this.emitEvent({ type: 'done', success: false, error: result.error, iterations: 0 });
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
console.log(`[Agent] 会话已创建: ${this.state.sessionId}`);
|
|
177
|
+
this.emitEvent({ type: 'session_created', sessionId: this.state.sessionId });
|
|
178
|
+
// Build messages: system + initialMessages (conversation memory) + user task
|
|
179
|
+
this.messages = [
|
|
180
|
+
{ role: 'system', content: SYSTEM_PROMPT },
|
|
181
|
+
...this.initialMessages,
|
|
182
|
+
{ role: 'user', content: task },
|
|
183
|
+
];
|
|
184
|
+
let finalResult;
|
|
185
|
+
try {
|
|
186
|
+
finalResult = await this.loop();
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
finalResult = { success: false, error: err.message, iterations: this.state.iteration };
|
|
190
|
+
}
|
|
191
|
+
this.emitEvent({
|
|
192
|
+
type: 'done',
|
|
193
|
+
success: finalResult.success,
|
|
194
|
+
result: finalResult.result,
|
|
195
|
+
error: finalResult.error,
|
|
196
|
+
iterations: finalResult.iterations,
|
|
197
|
+
});
|
|
198
|
+
await this.cleanup();
|
|
199
|
+
return finalResult;
|
|
200
|
+
}
|
|
201
|
+
async loop() {
|
|
202
|
+
while (this.state.iteration < this.maxIterations && !this.state.done) {
|
|
203
|
+
this.state.iteration++;
|
|
204
|
+
console.log(`\n[Agent] === 第 ${this.state.iteration} 步 ===`);
|
|
205
|
+
// 接近步数上限时注入提醒(仅一次,且 maxIterations > 3 时才有意义)
|
|
206
|
+
const remainingSteps = this.maxIterations - this.state.iteration;
|
|
207
|
+
if (!this.stepWarningInjected && remainingSteps <= 2 && remainingSteps > 0 && this.maxIterations > 3) {
|
|
208
|
+
this.stepWarningInjected = true;
|
|
209
|
+
this.messages.push({
|
|
210
|
+
role: 'system',
|
|
211
|
+
content: `⚠️ 你还剩 ${remainingSteps} 步就达到上限,请立即用 done 工具报告已获取的所有信息,不要再做额外操作。`,
|
|
212
|
+
});
|
|
213
|
+
console.log(`[Agent] 注入步数提醒,剩余 ${remainingSteps} 步`);
|
|
214
|
+
}
|
|
215
|
+
let response;
|
|
216
|
+
try {
|
|
217
|
+
response = await this.openai.chat.completions.create({
|
|
218
|
+
model: this.model,
|
|
219
|
+
messages: this.messages,
|
|
220
|
+
tools: this.tools,
|
|
221
|
+
tool_choice: 'auto',
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
this.state.consecutiveErrors++;
|
|
226
|
+
console.log(`[Agent] LLM API 错误 (${this.state.consecutiveErrors}/${config.maxConsecutiveErrors}): ${err.message}`);
|
|
227
|
+
this.emitEvent({ type: 'error', message: err.message, iteration: this.state.iteration });
|
|
228
|
+
if (this.state.consecutiveErrors >= config.maxConsecutiveErrors) {
|
|
229
|
+
return { success: false, error: `LLM API 连续失败: ${err.message}`, iterations: this.state.iteration };
|
|
230
|
+
}
|
|
231
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const message = response.choices[0]?.message;
|
|
235
|
+
if (!message) {
|
|
236
|
+
return { success: false, error: 'LLM 返回空响应', iterations: this.state.iteration };
|
|
237
|
+
}
|
|
238
|
+
if (message.content) {
|
|
239
|
+
console.log(`[Agent] 思考: ${message.content}`);
|
|
240
|
+
this.emitEvent({ type: 'thinking', content: message.content, iteration: this.state.iteration });
|
|
241
|
+
}
|
|
242
|
+
this.messages.push(message);
|
|
243
|
+
if (!message.tool_calls || message.tool_calls.length === 0) {
|
|
244
|
+
console.log('[Agent] LLM 未调用工具,任务结束');
|
|
245
|
+
return {
|
|
246
|
+
success: true,
|
|
247
|
+
result: message.content || '任务完成',
|
|
248
|
+
iterations: this.state.iteration,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
const doneResult = await this.executeToolCalls(message.tool_calls);
|
|
252
|
+
if (doneResult) {
|
|
253
|
+
return doneResult;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (!this.state.done) {
|
|
257
|
+
return { success: false, error: `达到最大迭代次数 ${this.maxIterations}`, iterations: this.state.iteration };
|
|
258
|
+
}
|
|
259
|
+
return { success: true, iterations: this.state.iteration };
|
|
260
|
+
}
|
|
261
|
+
async executeToolCalls(toolCalls) {
|
|
262
|
+
for (const toolCall of toolCalls) {
|
|
263
|
+
const name = toolCall.function.name;
|
|
264
|
+
let args;
|
|
265
|
+
try {
|
|
266
|
+
args = JSON.parse(toolCall.function.arguments || '{}');
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
console.log(`[Agent] 工具参数解析失败: ${toolCall.function.arguments}`);
|
|
270
|
+
this.messages.push({
|
|
271
|
+
role: 'tool',
|
|
272
|
+
tool_call_id: toolCall.id,
|
|
273
|
+
content: JSON.stringify({ error: '工具参数 JSON 解析失败' }),
|
|
274
|
+
});
|
|
275
|
+
this.state.consecutiveErrors++;
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
console.log(`[Agent] 调用工具: ${name}(${JSON.stringify(args)})`);
|
|
279
|
+
this.emitEvent({ type: 'tool_call', name, args, iteration: this.state.iteration });
|
|
280
|
+
// 循环检测:记录工具调用签名
|
|
281
|
+
const callSig = `${name}:${JSON.stringify(args)}`;
|
|
282
|
+
this.recentToolCalls.push(callSig);
|
|
283
|
+
if (this.recentToolCalls.length > 3) {
|
|
284
|
+
this.recentToolCalls.shift();
|
|
285
|
+
}
|
|
286
|
+
if (this.recentToolCalls.length === 3 &&
|
|
287
|
+
this.recentToolCalls[0] === this.recentToolCalls[1] &&
|
|
288
|
+
this.recentToolCalls[1] === this.recentToolCalls[2]) {
|
|
289
|
+
console.log('[Agent] 检测到循环调用,注入提醒');
|
|
290
|
+
this.messages.push({
|
|
291
|
+
role: 'system',
|
|
292
|
+
content: '⚠️ 你已连续3次调用相同工具且参数相同,这不会产生新结果。请换一种方式操作,或用 done 工具报告当前已获取的信息。',
|
|
293
|
+
});
|
|
294
|
+
this.recentToolCalls = [];
|
|
295
|
+
}
|
|
296
|
+
if (name === 'done') {
|
|
297
|
+
const result = args.result || '任务完成';
|
|
298
|
+
console.log(`[Agent] 任务完成: ${result}`);
|
|
299
|
+
this.state.done = true;
|
|
300
|
+
return { success: true, result, iterations: this.state.iteration };
|
|
301
|
+
}
|
|
302
|
+
// ask_human: 暂停等待用户输入
|
|
303
|
+
if (name === 'ask_human') {
|
|
304
|
+
const requestId = randomUUID();
|
|
305
|
+
const question = args.question || '';
|
|
306
|
+
const fields = args.fields || [];
|
|
307
|
+
const passwordFieldNames = new Set(fields.filter(f => f.type === 'password').map(f => f.name));
|
|
308
|
+
console.log(`[Agent] 请求用户输入: ${question}`);
|
|
309
|
+
this.pendingInputRequestId = requestId;
|
|
310
|
+
this.emitEvent({ type: 'input_required', requestId, question, fields });
|
|
311
|
+
let userResponse;
|
|
312
|
+
try {
|
|
313
|
+
userResponse = await new Promise((resolve, reject) => {
|
|
314
|
+
this.pendingInputResolve = resolve;
|
|
315
|
+
const timer = setTimeout(() => {
|
|
316
|
+
if (this.pendingInputResolve) {
|
|
317
|
+
this.pendingInputResolve = null;
|
|
318
|
+
this.pendingInputRequestId = null;
|
|
319
|
+
reject(new Error('用户未响应'));
|
|
320
|
+
}
|
|
321
|
+
}, 5 * 60 * 1000);
|
|
322
|
+
// Store timer ref so resolveInput can clear it
|
|
323
|
+
this._askHumanTimer = timer;
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
userResponse = { error: '用户未在规定时间内响应' };
|
|
328
|
+
}
|
|
329
|
+
// Build redacted version for SSE event (mask password values)
|
|
330
|
+
const redacted = {};
|
|
331
|
+
for (const [k, v] of Object.entries(userResponse)) {
|
|
332
|
+
redacted[k] = passwordFieldNames.has(k) ? '***' : v;
|
|
333
|
+
}
|
|
334
|
+
const redactedText = JSON.stringify(redacted);
|
|
335
|
+
const responseText = JSON.stringify(userResponse);
|
|
336
|
+
console.log(`[Agent] 用户输入已收到`);
|
|
337
|
+
this.emitEvent({ type: 'tool_result', name: 'ask_human', success: true, summary: redactedText, iteration: this.state.iteration });
|
|
338
|
+
this.messages.push({ role: 'tool', tool_call_id: toolCall.id, content: responseText });
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
// 强制覆盖 sessionId,防止 LLM 猜测错误的值
|
|
342
|
+
const mcpArgs = { ...args };
|
|
343
|
+
if (this.state.sessionId) {
|
|
344
|
+
mcpArgs.sessionId = this.state.sessionId;
|
|
345
|
+
}
|
|
346
|
+
let rawText;
|
|
347
|
+
let success = true;
|
|
348
|
+
try {
|
|
349
|
+
const mcpResult = await this.mcpClient.callTool({ name, arguments: mcpArgs });
|
|
350
|
+
rawText = mcpResult.content[0]?.text || '{}';
|
|
351
|
+
if (mcpResult.isError)
|
|
352
|
+
success = false;
|
|
353
|
+
}
|
|
354
|
+
catch (err) {
|
|
355
|
+
rawText = JSON.stringify({ error: err.message });
|
|
356
|
+
success = false;
|
|
357
|
+
}
|
|
358
|
+
if (!success) {
|
|
359
|
+
this.state.consecutiveErrors++;
|
|
360
|
+
console.log(`[Agent] 错误 (${this.state.consecutiveErrors}/${config.maxConsecutiveErrors}): ${rawText}`);
|
|
361
|
+
if (this.state.consecutiveErrors >= config.maxConsecutiveErrors) {
|
|
362
|
+
this.messages.push({ role: 'tool', tool_call_id: toolCall.id, content: rawText });
|
|
363
|
+
return {
|
|
364
|
+
success: false,
|
|
365
|
+
error: `连续 ${config.maxConsecutiveErrors} 次错误,任务中止`,
|
|
366
|
+
iterations: this.state.iteration,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
this.state.consecutiveErrors = 0;
|
|
372
|
+
}
|
|
373
|
+
// SSE event sends full content; LLM message gets truncated version
|
|
374
|
+
const formatted = formatForLLM(rawText, name);
|
|
375
|
+
console.log(`[Agent] 结果: ${formatted.slice(0, 200)}${formatted.length > 200 ? '...' : ''}`);
|
|
376
|
+
this.emitEvent({
|
|
377
|
+
type: 'tool_result',
|
|
378
|
+
name,
|
|
379
|
+
success,
|
|
380
|
+
summary: rawText,
|
|
381
|
+
iteration: this.state.iteration,
|
|
382
|
+
});
|
|
383
|
+
this.messages.push({
|
|
384
|
+
role: 'tool',
|
|
385
|
+
tool_call_id: toolCall.id,
|
|
386
|
+
content: formatted,
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
async cleanup() {
|
|
392
|
+
if (this.state.sessionId) {
|
|
393
|
+
console.log('[Agent] 清理浏览器会话...');
|
|
394
|
+
try {
|
|
395
|
+
await this.mcpClient.callTool({
|
|
396
|
+
name: 'close_session',
|
|
397
|
+
arguments: { sessionId: this.state.sessionId },
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
catch (err) {
|
|
401
|
+
console.log(`[Agent] 清理警告: ${err.message}`);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
//# sourceMappingURL=agent-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-loop.js","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,SAAS,QAAQ,CAAC,IAAY,EAAE,GAAG,GAAG,kBAAkB;IACtD,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,cAAc,IAAI,CAAC,MAAM,KAAK,CAAC;AAC7D,CAAC;AAED,SAAS,YAAY,CAAC,OAAe,EAAE,QAAgB;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,QAAQ,KAAK,eAAe,IAAI,IAAI,EAAE,QAAQ,EAAE,CAAC;YACnD,MAAM,OAAO,GAAG;gBACd,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;gBAClC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;oBACpD,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,KAAK,EAAE,CAAC,CAAC,KAAK;iBACf,CAAC,CAAC;gBACH,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CAAC;YACF,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBAC7B,OAAe,CAAC,IAAI,GAAG,aAAa,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;YAC/D,CAAC;YACD,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,QAAQ,KAAK,kBAAkB,EAAE,CAAC;YACpC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC,KAAK,IAAI,EAAE,MAAM,CAAC;YACrC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK;oBAC7B,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI;wBAC3B,CAAC,CAAC,GAAG,CAAC;gBACjB,EAAE,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC;YACnC,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,EAAE,IAAI,YAAY,CAAC;YAC9C,OAAO,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,OAAO,aAAc,SAAQ,YAAY;IACrC,MAAM,CAAS;IACf,SAAS,CAAS;IAClB,KAAK,CAAa;IAClB,QAAQ,CAA+B;IACvC,KAAK,CAAS;IACd,aAAa,CAAS;IACtB,eAAe,CAA+B;IAC9C,KAAK,GAAyB,EAAE,CAAC;IACjC,eAAe,GAAa,EAAE,CAAC,CAAC,kBAAkB;IAClD,mBAAmB,GAAG,KAAK,CAAC;IAC5B,mBAAmB,GAAwD,IAAI,CAAC;IAChF,qBAAqB,GAAkB,IAAI,CAAC;IAEpD,YAAY,OAOX;QACC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QAC/C,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC;YACvB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO;YAC9C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM;SAC5C,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC;QACnE,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;QACrD,IAAI,CAAC,KAAK,GAAG;YACX,SAAS,EAAE,EAAE;YACb,SAAS,EAAE,CAAC;YACZ,iBAAiB,EAAE,CAAC;YACpB,IAAI,EAAE,KAAK;SACZ,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;IAC9B,CAAC;IAED,YAAY,CAAC,SAAiB,EAAE,QAAgC;QAC9D,IAAI,IAAI,CAAC,qBAAqB,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1E,OAAO,KAAK,CAAC;QACf,CAAC;QACD,mDAAmD;QACnD,IAAK,IAAY,CAAC,cAAc,EAAE,CAAC;YACjC,YAAY,CAAE,IAAY,CAAC,cAAc,CAAC,CAAC;YAC1C,IAAY,CAAC,cAAc,GAAG,IAAI,CAAC;QACtC,CAAC;QACD,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,SAAS,CAAC,KAAiB;QACjC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;QAC7D,kBAAkB;QAClB,MAAM,cAAc,GAAG,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK,GAAG,QAAQ;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,UAAmB;YACzB,QAAQ,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;gBAChC,UAAU,EAAE,CAAC,CAAC,WAAkB;aACjC;SACF,CAAC,CAAC,CAAC;QACN,iDAAiD;QACjD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE;gBACR,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,sBAAsB;gBACnC,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE;qBACrD;oBACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;iBACrB;aACF;SACF,CAAC,CAAC;QACH,8EAA8E;QAC9E,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE;gBACR,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,8BAA8B;gBAC3C,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE;wBACrD,MAAM,EAAE;4BACN,IAAI,EAAE,OAAO;4BACb,KAAK,EAAE;gCACL,IAAI,EAAE,QAAQ;gCACd,UAAU,EAAE;oCACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oCACxB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oCACzB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE;iCACrD;gCACD,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC;6BACpC;yBACF;qBACF;oBACD,QAAQ,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;iBACjC;aACF;SACF,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY;QACpB,iCAAiC;QACjC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAE3B,yBAAyB;QACzB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,IAAI,aAAa,CAAC;QAClB,IAAI,CAAC;YACH,aAAa,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;YACzF,MAAM,IAAI,GAAI,aAAa,CAAC,OAAe,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;YACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,MAAM,GAAmB,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,GAAG,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;YAClG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;YACrF,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QAE7E,6EAA6E;QAC7E,IAAI,CAAC,QAAQ,GAAG;YACd,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE;YAC1C,GAAG,IAAI,CAAC,eAAe;YACvB,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;SAChC,CAAC;QAEF,IAAI,WAA2B,CAAC;QAChC,IAAI,CAAC;YACH,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,WAAW,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACzF,CAAC;QAED,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,UAAU,EAAE,WAAW,CAAC,UAAU;SACnC,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,WAAW,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACrE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,KAAK,CAAC,SAAS,QAAQ,CAAC,CAAC;YAE7D,6CAA6C;YAC7C,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC,mBAAmB,IAAI,cAAc,IAAI,CAAC,IAAI,cAAc,GAAG,CAAC,IAAI,IAAI,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;gBACrG,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;gBAChC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACjB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,UAAU,cAAc,0CAA0C;iBAC5E,CAAC,CAAC;gBACH,OAAO,CAAC,GAAG,CAAC,qBAAqB,cAAc,IAAI,CAAC,CAAC;YACvD,CAAC;YAED,IAAI,QAAQ,CAAC;YACb,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;oBACnD,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,WAAW,EAAE,MAAM;iBACpB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,MAAM,CAAC,oBAAoB,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACnH,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;gBACzF,IAAI,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;oBAChE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACrG,CAAC;gBACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC5C,SAAS;YACX,CAAC;YAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;YAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YAClF,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC9C,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YAClG,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE5B,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3D,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;gBACtC,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,OAAO,CAAC,OAAO,IAAI,MAAM;oBACjC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS;iBACjC,CAAC;YACJ,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAiB,CAAC,CAAC;YAC1E,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACrB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC,aAAa,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACvG,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;IAC7D,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,SAA+E;QAC5G,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;YACpC,IAAI,IAAyB,CAAC;YAC9B,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;gBAChE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACjB,IAAI,EAAE,MAAM;oBACZ,YAAY,EAAE,QAAQ,CAAC,EAAE;oBACzB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;iBACrD,CAAC,CAAC;gBACH,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBAC/B,SAAS;YACX,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9D,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YAEnF,gBAAgB;YAChB,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnC,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAC/B,CAAC;YACD,IACE,IAAI,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC;gBACjC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;gBACnD,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EACnD,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;gBACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACjB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,8DAA8D;iBACxE,CAAC,CAAC;gBACH,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;YAC5B,CAAC;YAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC;gBACrC,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC;gBACvC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;gBACvB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACrE,CAAC;YAED,sBAAsB;YACtB,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;gBACzB,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;gBAC/B,MAAM,QAAQ,GAAW,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;gBAC7C,MAAM,MAAM,GAAiB,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;gBAC/C,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC/F,OAAO,CAAC,GAAG,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;gBAC3C,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;gBACvC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;gBAExE,IAAI,YAAoC,CAAC;gBACzC,IAAI,CAAC;oBACH,YAAY,GAAG,MAAM,IAAI,OAAO,CAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBAC3E,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC;wBACnC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;4BAC5B,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gCAC7B,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;gCAChC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;gCAClC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;4BAC7B,CAAC;wBACH,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;wBAClB,+CAA+C;wBAC9C,IAAY,CAAC,cAAc,GAAG,KAAK,CAAC;oBACvC,CAAC,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,YAAY,GAAG,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;gBAC1C,CAAC;gBAED,8DAA8D;gBAC9D,MAAM,QAAQ,GAA2B,EAAE,CAAC;gBAC5C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;oBAClD,QAAQ,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtD,CAAC;gBACD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;gBAElD,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;gBAC/B,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;gBAClI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;gBACvF,SAAS;YACX,CAAC;YAED,+BAA+B;YAC/B,MAAM,OAAO,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACzB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YAC3C,CAAC;YAED,IAAI,OAAe,CAAC;YACpB,IAAI,OAAO,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC9E,OAAO,GAAI,SAAS,CAAC,OAAe,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;gBACtD,IAAI,SAAS,CAAC,OAAO;oBAAE,OAAO,GAAG,KAAK,CAAC;YACzC,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACjD,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;YAED,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,MAAM,CAAC,oBAAoB,MAAM,OAAO,EAAE,CAAC,CAAC;gBACvG,IAAI,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;oBAChE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;oBAClF,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,MAAM,MAAM,CAAC,oBAAoB,WAAW;wBACnD,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS;qBACjC,CAAC;gBACJ,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,CAAC;YACnC,CAAC;YAED,mEAAmE;YACnE,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,eAAe,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5F,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,aAAa;gBACnB,IAAI;gBACJ,OAAO;gBACP,OAAO,EAAE,OAAO;gBAChB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS;aAChC,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,MAAM;gBACZ,YAAY,EAAE,QAAQ,CAAC,EAAE;gBACzB,OAAO,EAAE,SAAS;aACnB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;oBAC5B,IAAI,EAAE,eAAe;oBACrB,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;iBAC/C,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ToolResult } from './types.js';
|
|
2
|
+
export declare const browserApi: {
|
|
3
|
+
createSession(): Promise<ToolResult>;
|
|
4
|
+
deleteSession(sessionId: string): Promise<ToolResult>;
|
|
5
|
+
navigate(sessionId: string, url: string): Promise<ToolResult>;
|
|
6
|
+
getSemantic(sessionId: string): Promise<ToolResult>;
|
|
7
|
+
getContent(sessionId: string): Promise<ToolResult>;
|
|
8
|
+
executeAction(sessionId: string, action: string, elementId?: string, value?: string): Promise<ToolResult>;
|
|
9
|
+
matchElements(sessionId: string, query: string, limit?: number): Promise<ToolResult>;
|
|
10
|
+
wait(sessionId: string, milliseconds?: number, selector?: string): Promise<ToolResult>;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/agent/api-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA8B7C,eAAO,MAAM,UAAU;qBACJ,OAAO,CAAC,UAAU,CAAC;6BAIX,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;wBAIjC,MAAM,OAAO,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;2BAItC,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;0BAI7B,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;6BAIzB,MAAM,UAAU,MAAM,cAAc,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;6BAIhF,MAAM,SAAS,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;oBAIpE,MAAM,iBAAiB,MAAM,aAAa,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAGvF,CAAC"}
|