page-agent 0.0.3 → 0.0.5
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-zh.md +128 -0
- package/README.md +6 -6
- package/dist/lib/PageAgent.d.ts +9 -2
- package/dist/lib/page-agent.js +92 -69
- package/dist/lib/page-agent.js.map +1 -1
- package/dist/umd/page-agent.umd.cjs +378 -0
- package/package.json +13 -84
package/README-zh.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# PageAgent 🤖🪄
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/page-agent) [](https://opensource.org/licenses/MIT) [](http://www.typescriptlang.org/) [](https://www.npmjs.com/package/page-agent) [](https://bundlephobia.com/package/page-agent) [](https://github.com/alibaba/page-agent)
|
|
6
|
+
|
|
7
|
+
纯 JS 实现的 GUI agent。使用自然语言操作你的 Web 应用。无须后端、客户端、浏览器插件。
|
|
8
|
+
|
|
9
|
+
🌐 [English](./README.md) | **中文**
|
|
10
|
+
|
|
11
|
+
👉 <a href="https://alibaba.github.io/page-agent/" target="_blank"><b>🚀 Demo</b></a> | <a href="https://alibaba.github.io/page-agent/#/docs/introduction/overview" target="_blank"><b>📖 Documentation</b></a>
|
|
12
|
+
|
|
13
|
+
<video id="demo-video" src="https://github.com/user-attachments/assets/141bbb01-8022-4d1f-919d-9efc9a1dc1cf" width="640" crossorigin muted autoplay loop></video>
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## ✨ Features
|
|
18
|
+
|
|
19
|
+
- **🎯 轻松集成**
|
|
20
|
+
- **🔐 端侧运行**
|
|
21
|
+
- **🧠 HTML 脱水**
|
|
22
|
+
- **💬 自然语言接口**
|
|
23
|
+
- **🎨 HITL 交互界面**
|
|
24
|
+
|
|
25
|
+
## 🗺️ Roadmap
|
|
26
|
+
|
|
27
|
+
👉 [**Roadmap**](./ROADMAP.md)
|
|
28
|
+
|
|
29
|
+
## 🚀 快速开始
|
|
30
|
+
|
|
31
|
+
### CDN 集成
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<!-- 临时 CDN URL. 未来会变更 -->
|
|
35
|
+
<script
|
|
36
|
+
src="https://hwcxiuzfylggtcktqgij.supabase.co/storage/v1/object/public/demo-public/v0.0.4/page-agent.js"
|
|
37
|
+
crossorigin="true"
|
|
38
|
+
type="text/javascript"
|
|
39
|
+
></script>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### NPM 安装
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install page-agent
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
import { PageAgent } from 'page-agent'
|
|
50
|
+
|
|
51
|
+
// 测试接口
|
|
52
|
+
// @note: 限流,限制 prompt 内容,限制来源,随时变更,请替换成你自己的
|
|
53
|
+
// @note: 使用 DeepSeek-chat(3.2) 官方版本,使用协议和隐私策略见 DeepSeek 网站
|
|
54
|
+
const DEMO_MODEL = 'PAGE-AGENT-FREE-TESTING-RANDOM'
|
|
55
|
+
const DEMO_BASE_URL = 'https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy'
|
|
56
|
+
const DEMO_API_KEY = 'PAGE-AGENT-FREE-TESTING-RANDOM'
|
|
57
|
+
|
|
58
|
+
const agent = new PageAgent({
|
|
59
|
+
modelName: DEMO_MODEL,
|
|
60
|
+
baseURL: DEMO_BASE_URL,
|
|
61
|
+
apiKey: DEMO_API_KEY,
|
|
62
|
+
language: 'zh-CN',
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
await agent.execute('点击登录按钮')
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 🏗️ 架构设计
|
|
69
|
+
|
|
70
|
+
PageAgent 采用清晰的模块化架构:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
src/
|
|
74
|
+
├── PageAgent.ts # Agent 主流程
|
|
75
|
+
├── dom/ # DOM 理解
|
|
76
|
+
├── tools/ # 代理交互工具
|
|
77
|
+
├── ui/ # UI 组件和面板
|
|
78
|
+
├── llms/ # LLM 集成层
|
|
79
|
+
└── utils/ # 事件总线和工具
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## 🤝 贡献
|
|
83
|
+
|
|
84
|
+
欢迎社区贡献!以下是参与方式:
|
|
85
|
+
|
|
86
|
+
### 开发环境
|
|
87
|
+
|
|
88
|
+
1. Fork 项目仓库
|
|
89
|
+
2. Clone or fork: `git clone https://github.com/alibaba/page-agent.git && cd page-agent`
|
|
90
|
+
3. 安装依赖: `npm install`
|
|
91
|
+
4. 启动开发: `npm start`
|
|
92
|
+
|
|
93
|
+
### 贡献指南
|
|
94
|
+
|
|
95
|
+
请在贡献前阅读我们的[行为准则](CODE_OF_CONDUCT.md)和[贡献指南](CONTRIBUTING.md)。
|
|
96
|
+
|
|
97
|
+
## 👏 致谢
|
|
98
|
+
|
|
99
|
+
本项目基于以下优秀项目构建:
|
|
100
|
+
|
|
101
|
+
- **[browser-use](https://github.com/browser-use/browser-use)**
|
|
102
|
+
|
|
103
|
+
PageAgent 专为**客户端网页增强**设计,不是服务端自动化工具。
|
|
104
|
+
|
|
105
|
+
## 📄 许可证
|
|
106
|
+
|
|
107
|
+
MIT 许可证 - 详见 [LICENSE](LICENSE) 文件。
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
DOM processing components and prompt are derived from browser-use:
|
|
111
|
+
|
|
112
|
+
Browser Use
|
|
113
|
+
Copyright (c) 2024 Gregor Zunic
|
|
114
|
+
Licensed under the MIT License
|
|
115
|
+
|
|
116
|
+
Original browser-use project: <https://github.com/browser-use/browser-use>
|
|
117
|
+
|
|
118
|
+
We gratefully acknowledge the browser-use project and its contributors for their
|
|
119
|
+
excellent work on web automation and DOM interaction patterns that helped make
|
|
120
|
+
this project possible.
|
|
121
|
+
|
|
122
|
+
Third-party dependencies and their licenses can be found in the package.json
|
|
123
|
+
file and in the node_modules directory after installation.
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
**⭐ 如果觉得 PageAgent 有用或有趣,请给项目点个星!**
|
package/README.md
CHANGED
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://badge.fury.io/js/page-agent) [](https://opensource.org/licenses/MIT) [](http://www.typescriptlang.org/) [](https://www.npmjs.com/package/page-agent) [](https://bundlephobia.com/package/page-agent) [](https://github.com/alibaba/page-agent)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
An in-page UI agent in javascript. Control web interfaces with natural language.
|
|
7
|
+
The GUI Agent Living in Your Webpage. Control web interfaces with natural language.
|
|
10
8
|
|
|
11
9
|
🌐 **English** | [中文](./README-zh.md)
|
|
12
10
|
|
|
13
|
-
👉
|
|
11
|
+
👉 <a href="https://alibaba.github.io/page-agent/" target="_blank"><b>🚀 Demo</b></a> | <a href="https://alibaba.github.io/page-agent/#/docs/introduction/overview" target="_blank"><b>📖 Documentation</b></a>
|
|
12
|
+
|
|
13
|
+
<video id="demo-video" src="https://github.com/user-attachments/assets/de8d1964-8bde-494f-a52f-2975469557a5" width="640" crossorigin muted autoplay loop></video>
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
17
|
## ✨ Features
|
|
18
18
|
|
|
19
|
-
- **🎯 Easy Integration**
|
|
19
|
+
- **🎯 Easy Integration** - Transform your webpage into an agent with a single script tag.
|
|
20
20
|
- **🔐 Client-Side Processing**
|
|
21
21
|
- **🧠 DOM Extraction**
|
|
22
22
|
- **💬 Natural Language Interface**
|
|
@@ -33,7 +33,7 @@ An in-page UI agent in javascript. Control web interfaces with natural language.
|
|
|
33
33
|
```html
|
|
34
34
|
<!-- temporary CDN URL. May change in the future -->
|
|
35
35
|
<script
|
|
36
|
-
src="https://hwcxiuzfylggtcktqgij.supabase.co/storage/v1/object/public/demo-public/v0.0.
|
|
36
|
+
src="https://hwcxiuzfylggtcktqgij.supabase.co/storage/v1/object/public/demo-public/v0.0.4/page-agent.js"
|
|
37
37
|
crossorigin="true"
|
|
38
38
|
type="text/javascript"
|
|
39
39
|
></script>
|
package/dist/lib/PageAgent.d.ts
CHANGED
|
@@ -48,6 +48,13 @@ declare interface AgentConfig {
|
|
|
48
48
|
* @note when dispose caused by page unload, reason will be 'PAGE_UNLOADING'. this method CANNOT block unloading. async operations may be cut.
|
|
49
49
|
*/
|
|
50
50
|
onDispose?: (this: PageAgent, reason?: string) => void;
|
|
51
|
+
/**
|
|
52
|
+
* @experimental
|
|
53
|
+
* Enable the experimental script execution tool that allows executing generated JavaScript code on the page.
|
|
54
|
+
* @note Can cause unpredictable side effects.
|
|
55
|
+
* @note May bypass some safe guards and data-masking mechanisms.
|
|
56
|
+
*/
|
|
57
|
+
experimentalScriptExecutionTool?: boolean;
|
|
51
58
|
/**
|
|
52
59
|
* TODO: @unimplemented
|
|
53
60
|
* hook when action causes a new page to be opened
|
|
@@ -167,11 +174,11 @@ declare class EventBus extends EventTarget {
|
|
|
167
174
|
/**
|
|
168
175
|
* Listen to built-in events
|
|
169
176
|
*/
|
|
170
|
-
on<T extends keyof PageAgentEventMap>(event: T, handler: EventHandler<T
|
|
177
|
+
on<T extends keyof PageAgentEventMap>(event: T, handler: EventHandler<T>): void;
|
|
171
178
|
/**
|
|
172
179
|
* Listen to built-in events (one-time)
|
|
173
180
|
*/
|
|
174
|
-
once<T extends keyof PageAgentEventMap>(event: T, handler: EventHandler<T
|
|
181
|
+
once<T extends keyof PageAgentEventMap>(event: T, handler: EventHandler<T>): void;
|
|
175
182
|
/**
|
|
176
183
|
* Emit built-in events
|
|
177
184
|
*/
|
package/dist/lib/page-agent.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
try {
|
|
4
4
|
if (typeof document != "undefined") {
|
|
5
5
|
var elementStyle = document.createElement("style");
|
|
6
|
-
elementStyle.appendChild(document.createTextNode("._wrapper_d1n0a_1 {\n position: fixed;\n bottom: 100px;\n left: 50%;\n transform: translateX(-50%) translateY(20px);\n opacity: 0;\n z-index: 2147483642; /* 比 SimulatorMask 高一层 */\n box-sizing: border-box;\n\n overflow: visible;\n\n * {\n box-sizing: border-box;\n }\n\n --width: 360px;\n --height: 40px;\n --border-radius: 12px;\n\n --side-space: 12px; /* 控制栏两侧的间距 */\n --history-width: calc(var(--width) - var(--side-space) * 2);\n\n --color-1: rgb(57, 182, 255);\n --color-2: rgb(189, 69, 251);\n --color-3: rgb(255, 87, 51);\n --color-4: rgb(255, 214, 0);\n\n width: var(--width);\n height: var(--height);\n\n transition: all 0.3s ease-in-out;\n\n /* 响应式设计 */\n @media (max-width: 480px) {\n width: calc(100vw - 40px);\n left: 20px;\n transform: none;\n }\n\n ._background_d1n0a_40 {\n position: absolute;\n inset: -2px -8px;\n border-radius: calc(var(--border-radius) + 4px);\n filter: blur(16px);\n overflow: hidden;\n /* mix-blend-mode: lighten; */\n /* display: none; */\n\n &::before {\n content: '';\n z-index: -1;\n pointer-events: none;\n position: absolute;\n width: 100%;\n height: 100%;\n /* left: -100%; */\n left: 0;\n top: 0;\n\n background-image: linear-gradient(\n to bottom left,\n var(--color-1),\n var(--color-2),\n var(--color-1)\n );\n animation: _mask-running_d1n0a_1 2s linear infinite;\n }\n &::after {\n content: '';\n z-index: -1;\n pointer-events: none;\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n\n background-image: linear-gradient(\n to bottom left,\n var(--color-2),\n var(--color-1),\n var(--color-2)\n );\n animation: _mask-running_d1n0a_1 2s linear infinite;\n animation-delay: 1s;\n }\n }\n}\n\n@keyframes _mask-running_d1n0a_1 {\n from {\n transform: translateX(-100%);\n }\n to {\n transform: translateX(100%);\n }\n}\n\n/* 控制栏 */\n._header_d1n0a_100 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n user-select: none;\n\n position: absolute;\n inset: 0;\n\n cursor: pointer;\n flex-shrink: 0; /* 防止 header 被压缩 */\n\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(10px);\n border-radius: var(--border-radius);\n background-clip: padding-box;\n\n box-shadow:\n 0 0 0px 2px rgba(255, 255, 255, 0.4),\n 0 0 5px 1px rgba(255, 255, 255, 0.3);\n\n ._statusSection_d1n0a_122 {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-height: 24px; /* 确保垂直居中 */\n\n ._indicator_d1n0a_129 {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.5);\n flex-shrink: 0;\n animation: none; /* 默认无动画 */\n\n /* 运行状态 - 有动画 */\n &._thinking_d1n0a_138 {\n background: rgb(57, 182, 255);\n animation: _pulse_d1n0a_1 0.8s ease-in-out infinite;\n }\n\n &._tool_executing_d1n0a_143 {\n background: rgb(189, 69, 251);\n animation: _pulse_d1n0a_1 0.6s ease-in-out infinite;\n }\n\n &._retry_d1n0a_148 {\n background: rgb(255, 214, 0);\n animation: _retryPulse_d1n0a_1 1s ease-in-out infinite;\n }\n\n /* 静止状态 - 无动画 */\n &._completed_d1n0a_154,\n &._input_d1n0a_155,\n &._output_d1n0a_156 {\n background: rgb(34, 197, 94);\n animation: none;\n }\n\n &._error_d1n0a_161 {\n background: rgb(239, 68, 68);\n animation: none;\n }\n }\n\n ._statusText_d1n0a_167 {\n color: white;\n font-size: 12px;\n line-height: 1;\n font-weight: 500;\n transition: all 0.3s ease-in-out;\n position: relative;\n overflow: hidden;\n display: flex;\n align-items: center;\n min-height: 24px; /* 确保垂直居中 */\n\n &._fadeOut_d1n0a_179 {\n animation: _statusTextFadeOut_d1n0a_1 0.3s ease forwards;\n }\n\n &._fadeIn_d1n0a_183 {\n animation: _statusTextFadeIn_d1n0a_1 0.3s ease forwards;\n }\n }\n }\n\n ._controls_d1n0a_189 {\n display: flex;\n align-items: center;\n gap: 4px;\n\n ._controlButton_d1n0a_194 {\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 4px;\n background: rgba(255, 255, 255, 0.1);\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n line-height: 1;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n }\n\n ._pauseButton_d1n0a_213 {\n font-weight: 600;\n &._paused_d1n0a_215 {\n background: rgba(34, 197, 94, 0.2); /* 绿色背景表示可以继续 */\n color: rgb(34, 197, 94);\n\n &:hover {\n background: rgba(34, 197, 94, 0.3);\n }\n }\n }\n\n ._stopButton_d1n0a_225 {\n background: rgba(239, 68, 68, 0.2);\n color: rgb(255, 41, 41);\n font-weight: 600;\n\n &:hover {\n background: rgba(239, 68, 68, 0.3);\n }\n }\n }\n}\n\n@keyframes _statusTextFadeIn_d1n0a_1 {\n 0% {\n opacity: 0;\n transform: translateY(5px);\n }\n 100% {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _statusTextFadeOut_d1n0a_1 {\n 0% {\n opacity: 1;\n transform: translateY(0);\n }\n 100% {\n opacity: 0;\n transform: translateY(-5px);\n }\n}\n\n._historySectionWrapper_d1n0a_259 {\n position: absolute;\n width: var(--history-width);\n bottom: var(--height);\n left: var(--side-space);\n z-index: -2;\n\n padding-top: 0px;\n visibility: collapse;\n overflow: hidden;\n\n transition: all 0.2s;\n\n background: rgba(2, 0, 20, 0.5);\n /* background: rgba(186, 186, 186, 0.2); */\n backdrop-filter: blur(10px);\n\n text-shadow: 0 0 1px rgba(0, 0, 0, 0.2);\n\n border-top-left-radius: calc(var(--border-radius) + 4px);\n border-top-right-radius: calc(var(--border-radius) + 4px);\n\n /* border: 2px solid rgba(255, 255, 255, 0.8); */\n border: 2px solid rgba(255, 255, 255, 0.4);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);\n\n /* @media (prefers-color-scheme: dark) {\n box-shadow:\n 0 8px 32px 0 rgba(0, 0, 0, 0.85),\n 0 2px 12px 0 rgba(57, 182, 255, 0.1);\n } */\n\n ._expanded_d1n0a_291 & {\n padding-top: 8px;\n visibility: visible;\n }\n\n ._historySection_d1n0a_259 {\n position: relative;\n overflow-y: auto;\n overscroll-behavior: contain;\n scrollbar-width: none;\n max-height: 0;\n padding-inline: 8px;\n\n transition: max-height 0.2s;\n\n ._expanded_d1n0a_291 & {\n max-height: 400px;\n }\n\n ._historyItem_d1n0a_310 {\n /* backdrop-filter: blur(10px); */\n padding: 8px 10px;\n margin-bottom: 6px;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.03));\n border-radius: 8px;\n border-left: 2px solid rgba(57, 182, 255, 0.5);\n font-size: 12px;\n color: white;\n /* color: black; */\n line-height: 1.3;\n position: relative;\n overflow: hidden;\n\n /* 微妙的内阴影 */\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.1),\n 0 1px 3px rgba(0, 0, 0, 0.1);\n\n &::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 1px;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);\n }\n\n &:hover {\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.06));\n /* transform: translateY(-1px); */\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.15),\n 0 2px 4px rgba(0, 0, 0, 0.15);\n }\n\n &:last-child {\n margin-bottom: 10px;\n }\n\n &._completed_d1n0a_154,\n &._input_d1n0a_155,\n &._output_d1n0a_156 {\n border-left-color: rgb(34, 197, 94);\n background: linear-gradient(135deg, rgba(34, 197, 94, 0.1), rgba(34, 197, 94, 0.05));\n }\n\n &._error_d1n0a_161 {\n border-left-color: rgb(239, 68, 68);\n background: linear-gradient(135deg, rgba(239, 68, 68, 0.1), rgba(239, 68, 68, 0.05));\n }\n\n &._retry_d1n0a_148 {\n border-left-color: rgb(255, 214, 0);\n background: linear-gradient(135deg, rgba(255, 214, 0, 0.1), rgba(255, 214, 0, 0.05));\n }\n\n /* 突出显示 done 成功结果 */\n &._doneSuccess_d1n0a_369 {\n background: linear-gradient(\n 135deg,\n rgba(34, 197, 94, 0.25),\n rgba(34, 197, 94, 0.15),\n rgba(34, 197, 94, 0.08)\n );\n border: none;\n border-left: 4px solid rgb(34, 197, 94);\n box-shadow:\n 0 4px 12px rgba(34, 197, 94, 0.3),\n inset 0 1px 0 rgba(255, 255, 255, 0.2),\n 0 0 20px rgba(34, 197, 94, 0.1);\n font-weight: 600;\n color: rgb(220, 252, 231);\n padding: 10px 12px;\n margin-bottom: 8px;\n border-radius: 8px;\n position: relative;\n overflow: hidden;\n\n &::before {\n background: linear-gradient(90deg, transparent, rgba(34, 197, 94, 0.4), transparent);\n }\n\n &::after {\n content: '';\n position: absolute;\n top: 0;\n left: -100%;\n width: 100%;\n height: 100%;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);\n animation: _shimmer_d1n0a_1 2s ease-in-out infinite;\n }\n\n ._historyContent_d1n0a_405 {\n ._statusIcon_d1n0a_406 {\n font-size: 16px;\n animation: _celebrate_d1n0a_1 0.8s ease-in-out;\n filter: drop-shadow(0 2px 4px rgba(34, 197, 94, 0.5));\n }\n }\n }\n\n /* 突出显示 done 失败结果 */\n &._doneError_d1n0a_415 {\n background: linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.25),\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.08)\n );\n border: none;\n border-left: 4px solid rgb(239, 68, 68);\n box-shadow:\n 0 4px 12px rgba(239, 68, 68, 0.3),\n inset 0 1px 0 rgba(255, 255, 255, 0.2),\n 0 0 20px rgba(239, 68, 68, 0.1);\n font-weight: 600;\n color: rgb(254, 226, 226);\n padding: 10px 12px;\n margin-bottom: 8px;\n border-radius: 8px;\n position: relative;\n overflow: hidden;\n\n &::before {\n background: linear-gradient(90deg, transparent, rgba(239, 68, 68, 0.4), transparent);\n }\n\n ._historyContent_d1n0a_405 {\n ._statusIcon_d1n0a_406 {\n font-size: 16px;\n filter: drop-shadow(0 2px 4px rgba(239, 68, 68, 0.5));\n }\n }\n }\n\n ._historyContent_d1n0a_405 {\n display: flex;\n align-items: center;\n gap: 8px;\n\n word-break: break-all;\n white-space: pre-wrap;\n\n /* overflow-x: auto; */\n\n ._statusIcon_d1n0a_406 {\n font-size: 12px;\n flex-shrink: 0;\n line-height: 1;\n transition: all 0.3s ease;\n }\n }\n\n ._historyMeta_d1n0a_466 {\n font-size: 10px;\n color: rgba(255, 255, 255, 0.6);\n /* color: rgb(61, 61, 61); */\n margin-top: 8px;\n line-height: 1;\n }\n }\n }\n}\n\n/* 动画关键帧 - 更快的闪烁 */\n@keyframes _pulse_d1n0a_1 {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.4;\n transform: scale(1.3);\n }\n}\n\n/* 重试动画 - 旋转脉冲 */\n@keyframes _retryPulse_d1n0a_1 {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1) rotate(0deg);\n }\n 25% {\n opacity: 0.6;\n transform: scale(1.2) rotate(90deg);\n }\n 50% {\n opacity: 0.8;\n transform: scale(1.1) rotate(180deg);\n }\n 75% {\n opacity: 0.6;\n transform: scale(1.2) rotate(270deg);\n }\n}\n\n/* 庆祝动画 */\n@keyframes _celebrate_d1n0a_1 {\n 0%,\n 100% {\n transform: scale(1);\n }\n 25% {\n transform: scale(1.2) rotate(-5deg);\n }\n 75% {\n transform: scale(1.2) rotate(5deg);\n }\n}\n\n/* done 卡片的光泽效果 */\n@keyframes _shimmer_d1n0a_1 {\n 0% {\n left: -100%;\n }\n 100% {\n left: 100%;\n }\n}\n\n/* 输入区域样式 */\n._inputSectionWrapper_d1n0a_536 {\n position: absolute;\n width: var(--history-width);\n top: var(--height);\n left: var(--side-space);\n z-index: -1;\n\n visibility: visible;\n overflow: hidden;\n\n height: 48px;\n\n transition: all 0.2s;\n\n background: rgba(186, 186, 186, 0.2);\n backdrop-filter: blur(10px);\n\n border-bottom-left-radius: calc(var(--border-radius) + 4px);\n border-bottom-right-radius: calc(var(--border-radius) + 4px);\n\n border: 2px solid rgba(255, 255, 255, 0.3);\n box-shadow: 0 1px 16px rgba(0, 0, 0, 0.4);\n\n &._hidden_d1n0a_559 {\n visibility: collapse;\n height: 0;\n }\n\n ._inputSection_d1n0a_536 {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 8px;\n\n ._taskInput_d1n0a_570 {\n flex: 1;\n background: rgba(255, 255, 255, 0.4);\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: 10px;\n padding-inline: 10px;\n color: rgb(20, 20, 20);\n font-size: 12px;\n height: 28px;\n line-height: 1;\n outline: none;\n transition: all 0.2s ease;\n\n /* text-shadow: 0 0 2px rgba(255, 255, 255, 0.8); */\n\n /* border-color: rgba(57, 182, 255, 0.3); */\n\n &::placeholder {\n color: rgb(53, 53, 53);\n }\n\n &:focus {\n background: rgba(255, 255, 255, 0.8);\n border-color: rgba(57, 182, 255, 0.6);\n box-shadow: 0 0 0 2px rgba(57, 182, 255, 0.2);\n }\n }\n }\n}\n._wrapper_1oy2s_1 {\n position: fixed;\n inset: 0;\n z-index: 2147483641; /* 确保在所有元素之上,除了 panel */\n /* pointer-events: none; */\n cursor: not-allowed;\n overflow: hidden;\n\n display: none;\n}\n/* AI 光标样式 */\n._cursor_1vrf3_2 {\n position: absolute;\n width: var(--cursor-size, 75px);\n height: var(--cursor-size, 75px);\n pointer-events: none;\n z-index: 10000;\n transform: translate(-30%, -30%);\n\n animation: _cursor-enter_1vrf3_1 300ms ease-out forwards;\n}\n\n._cursorBorder_1vrf3_13 {\n position: absolute;\n inset: 0;\n background: linear-gradient(45deg, rgb(57, 182, 255), rgb(189, 69, 251));\n mask-image: url(https://img.alicdn.com/imgextra/i1/O1CN01YHLVYR1LvqWIyo5kH_!!6000000001362-2-tps-202-202.png);\n mask-size: 100% 100%;\n mask-repeat: no-repeat;\n animation: _cursor-breathe_1vrf3_1 2s ease-in-out infinite;\n}\n\n._cursorFilling_1vrf3_23 {\n position: absolute;\n inset: 0;\n background: url(https://img.alicdn.com/imgextra/i3/O1CN01JZOqOS1Tu1sIKbPLW_!!6000000002441-2-tps-202-202.png);\n background-size: 100% 100%;\n background-repeat: no-repeat;\n}\n\n._cursorRipple_1vrf3_31 {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n._cursor_1vrf3_2._clicking_1vrf3_37 ._cursorRipple_1vrf3_31::after {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n left: -30%;\n top: -30%;\n border: 4px solid rgba(57, 182, 255, 1);\n border-radius: 50%;\n animation: _cursor-ripple_1vrf3_1 300ms ease-out forwards;\n}\n\n/* 光标动画关键帧 */\n@keyframes _cursor-breathe_1vrf3_1 {\n 0%,\n 100% {\n transform: scale(1);\n opacity: 0.9;\n }\n 50% {\n transform: scale(1.05);\n opacity: 1;\n }\n}\n\n@keyframes _cursor-rotate_1vrf3_1 {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes _cursor-enter_1vrf3_1 {\n 0% {\n transform: translate(-30%, -30%) scale(0.5);\n opacity: 0;\n }\n 100% {\n transform: translate(-30%, -30%) scale(1);\n opacity: 1;\n }\n}\n\n@keyframes _cursor-ripple_1vrf3_1 {\n 0% {\n transform: scale(0);\n opacity: 1;\n }\n 100% {\n transform: scale(2);\n opacity: 0;\n }\n}"));
|
|
6
|
+
elementStyle.appendChild(document.createTextNode("._wrapper_1j0ct_1 {\n position: fixed;\n bottom: 100px;\n left: 50%;\n transform: translateX(-50%) translateY(20px);\n opacity: 0;\n z-index: 2147483642; /* 比 SimulatorMask 高一层 */\n box-sizing: border-box;\n\n overflow: visible;\n\n * {\n box-sizing: border-box;\n }\n\n --width: 360px;\n --height: 40px;\n --border-radius: 12px;\n\n --side-space: 12px; /* 控制栏两侧的间距 */\n --history-width: calc(var(--width) - var(--side-space) * 2);\n\n --color-1: rgb(57, 182, 255);\n --color-2: rgb(189, 69, 251);\n --color-3: rgb(255, 87, 51);\n --color-4: rgb(255, 214, 0);\n\n width: var(--width);\n height: var(--height);\n\n transition: all 0.3s ease-in-out;\n\n /* 响应式设计 */\n @media (max-width: 480px) {\n width: calc(100vw - 40px);\n --width: calc(100vw - 40px);\n }\n\n ._background_1j0ct_39 {\n position: absolute;\n inset: -2px -8px;\n border-radius: calc(var(--border-radius) + 4px);\n filter: blur(16px);\n overflow: hidden;\n /* mix-blend-mode: lighten; */\n /* display: none; */\n\n &::before {\n content: '';\n z-index: -1;\n pointer-events: none;\n position: absolute;\n width: 100%;\n height: 100%;\n /* left: -100%; */\n left: 0;\n top: 0;\n\n background-image: linear-gradient(\n to bottom left,\n var(--color-1),\n var(--color-2),\n var(--color-1)\n );\n animation: _mask-running_1j0ct_1 2s linear infinite;\n }\n &::after {\n content: '';\n z-index: -1;\n pointer-events: none;\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n\n background-image: linear-gradient(\n to bottom left,\n var(--color-2),\n var(--color-1),\n var(--color-2)\n );\n animation: _mask-running_1j0ct_1 2s linear infinite;\n animation-delay: 1s;\n }\n }\n}\n\n@keyframes _mask-running_1j0ct_1 {\n from {\n transform: translateX(-100%);\n }\n to {\n transform: translateX(100%);\n }\n}\n\n/* 控制栏 */\n._header_1j0ct_99 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n user-select: none;\n\n position: absolute;\n inset: 0;\n\n cursor: pointer;\n flex-shrink: 0; /* 防止 header 被压缩 */\n\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(10px);\n border-radius: var(--border-radius);\n background-clip: padding-box;\n\n box-shadow:\n 0 0 0px 2px rgba(255, 255, 255, 0.4),\n 0 0 5px 1px rgba(255, 255, 255, 0.3);\n\n ._statusSection_1j0ct_121 {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-height: 24px; /* 确保垂直居中 */\n\n ._indicator_1j0ct_128 {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.5);\n flex-shrink: 0;\n animation: none; /* 默认无动画 */\n\n /* 运行状态 - 有动画 */\n &._thinking_1j0ct_137 {\n background: rgb(57, 182, 255);\n animation: _pulse_1j0ct_1 0.8s ease-in-out infinite;\n }\n\n &._tool_executing_1j0ct_142 {\n background: rgb(189, 69, 251);\n animation: _pulse_1j0ct_1 0.6s ease-in-out infinite;\n }\n\n &._retry_1j0ct_147 {\n background: rgb(255, 214, 0);\n animation: _retryPulse_1j0ct_1 1s ease-in-out infinite;\n }\n\n /* 静止状态 - 无动画 */\n &._completed_1j0ct_153,\n &._input_1j0ct_154,\n &._output_1j0ct_155 {\n background: rgb(34, 197, 94);\n animation: none;\n }\n\n &._error_1j0ct_160 {\n background: rgb(239, 68, 68);\n animation: none;\n }\n }\n\n ._statusText_1j0ct_166 {\n color: white;\n font-size: 12px;\n line-height: 1;\n font-weight: 500;\n transition: all 0.3s ease-in-out;\n position: relative;\n overflow: hidden;\n display: flex;\n align-items: center;\n min-height: 24px; /* 确保垂直居中 */\n\n &._fadeOut_1j0ct_178 {\n animation: _statusTextFadeOut_1j0ct_1 0.3s ease forwards;\n }\n\n &._fadeIn_1j0ct_182 {\n animation: _statusTextFadeIn_1j0ct_1 0.3s ease forwards;\n }\n }\n }\n\n ._controls_1j0ct_188 {\n display: flex;\n align-items: center;\n gap: 4px;\n\n ._controlButton_1j0ct_193 {\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 4px;\n background: rgba(255, 255, 255, 0.1);\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n line-height: 1;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n }\n\n ._pauseButton_1j0ct_212 {\n font-weight: 600;\n &._paused_1j0ct_214 {\n background: rgba(34, 197, 94, 0.2); /* 绿色背景表示可以继续 */\n color: rgb(34, 197, 94);\n\n &:hover {\n background: rgba(34, 197, 94, 0.3);\n }\n }\n }\n\n ._stopButton_1j0ct_224 {\n background: rgba(239, 68, 68, 0.2);\n color: rgb(255, 41, 41);\n font-weight: 600;\n\n &:hover {\n background: rgba(239, 68, 68, 0.3);\n }\n }\n }\n}\n\n@keyframes _statusTextFadeIn_1j0ct_1 {\n 0% {\n opacity: 0;\n transform: translateY(5px);\n }\n 100% {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _statusTextFadeOut_1j0ct_1 {\n 0% {\n opacity: 1;\n transform: translateY(0);\n }\n 100% {\n opacity: 0;\n transform: translateY(-5px);\n }\n}\n\n._historySectionWrapper_1j0ct_258 {\n position: absolute;\n width: var(--history-width);\n bottom: var(--height);\n left: var(--side-space);\n z-index: -2;\n\n padding-top: 0px;\n visibility: collapse;\n overflow: hidden;\n\n transition: all 0.2s;\n\n background: rgba(2, 0, 20, 0.5);\n /* background: rgba(186, 186, 186, 0.2); */\n backdrop-filter: blur(10px);\n\n text-shadow: 0 0 1px rgba(0, 0, 0, 0.2);\n\n border-top-left-radius: calc(var(--border-radius) + 4px);\n border-top-right-radius: calc(var(--border-radius) + 4px);\n\n /* border: 2px solid rgba(255, 255, 255, 0.8); */\n border: 2px solid rgba(255, 255, 255, 0.4);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);\n\n /* @media (prefers-color-scheme: dark) {\n box-shadow:\n 0 8px 32px 0 rgba(0, 0, 0, 0.85),\n 0 2px 12px 0 rgba(57, 182, 255, 0.1);\n } */\n\n ._expanded_1j0ct_290 & {\n padding-top: 8px;\n visibility: visible;\n }\n\n ._historySection_1j0ct_258 {\n position: relative;\n overflow-y: auto;\n overscroll-behavior: contain;\n scrollbar-width: none;\n max-height: 0;\n padding-inline: 8px;\n\n transition: max-height 0.2s;\n\n ._expanded_1j0ct_290 & {\n max-height: 400px;\n }\n\n ._historyItem_1j0ct_309 {\n /* backdrop-filter: blur(10px); */\n padding: 8px 10px;\n margin-bottom: 6px;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.03));\n border-radius: 8px;\n border-left: 2px solid rgba(57, 182, 255, 0.5);\n font-size: 12px;\n color: white;\n /* color: black; */\n line-height: 1.3;\n position: relative;\n overflow: hidden;\n\n /* 微妙的内阴影 */\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.1),\n 0 1px 3px rgba(0, 0, 0, 0.1);\n\n &::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 1px;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);\n }\n\n &:hover {\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.06));\n /* transform: translateY(-1px); */\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.15),\n 0 2px 4px rgba(0, 0, 0, 0.15);\n }\n\n &:last-child {\n margin-bottom: 10px;\n }\n\n &._completed_1j0ct_153,\n &._input_1j0ct_154,\n &._output_1j0ct_155 {\n border-left-color: rgb(34, 197, 94);\n background: linear-gradient(135deg, rgba(34, 197, 94, 0.1), rgba(34, 197, 94, 0.05));\n }\n\n &._error_1j0ct_160 {\n border-left-color: rgb(239, 68, 68);\n background: linear-gradient(135deg, rgba(239, 68, 68, 0.1), rgba(239, 68, 68, 0.05));\n }\n\n &._retry_1j0ct_147 {\n border-left-color: rgb(255, 214, 0);\n background: linear-gradient(135deg, rgba(255, 214, 0, 0.1), rgba(255, 214, 0, 0.05));\n }\n\n /* 突出显示 done 成功结果 */\n &._doneSuccess_1j0ct_368 {\n background: linear-gradient(\n 135deg,\n rgba(34, 197, 94, 0.25),\n rgba(34, 197, 94, 0.15),\n rgba(34, 197, 94, 0.08)\n );\n border: none;\n border-left: 4px solid rgb(34, 197, 94);\n box-shadow:\n 0 4px 12px rgba(34, 197, 94, 0.3),\n inset 0 1px 0 rgba(255, 255, 255, 0.2),\n 0 0 20px rgba(34, 197, 94, 0.1);\n font-weight: 600;\n color: rgb(220, 252, 231);\n padding: 10px 12px;\n margin-bottom: 8px;\n border-radius: 8px;\n position: relative;\n overflow: hidden;\n\n &::before {\n background: linear-gradient(90deg, transparent, rgba(34, 197, 94, 0.4), transparent);\n }\n\n &::after {\n content: '';\n position: absolute;\n top: 0;\n left: -100%;\n width: 100%;\n height: 100%;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);\n animation: _shimmer_1j0ct_1 2s ease-in-out infinite;\n }\n\n ._historyContent_1j0ct_404 {\n ._statusIcon_1j0ct_405 {\n font-size: 16px;\n animation: _celebrate_1j0ct_1 0.8s ease-in-out;\n filter: drop-shadow(0 2px 4px rgba(34, 197, 94, 0.5));\n }\n }\n }\n\n /* 突出显示 done 失败结果 */\n &._doneError_1j0ct_414 {\n background: linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.25),\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.08)\n );\n border: none;\n border-left: 4px solid rgb(239, 68, 68);\n box-shadow:\n 0 4px 12px rgba(239, 68, 68, 0.3),\n inset 0 1px 0 rgba(255, 255, 255, 0.2),\n 0 0 20px rgba(239, 68, 68, 0.1);\n font-weight: 600;\n color: rgb(254, 226, 226);\n padding: 10px 12px;\n margin-bottom: 8px;\n border-radius: 8px;\n position: relative;\n overflow: hidden;\n\n &::before {\n background: linear-gradient(90deg, transparent, rgba(239, 68, 68, 0.4), transparent);\n }\n\n ._historyContent_1j0ct_404 {\n ._statusIcon_1j0ct_405 {\n font-size: 16px;\n filter: drop-shadow(0 2px 4px rgba(239, 68, 68, 0.5));\n }\n }\n }\n\n ._historyContent_1j0ct_404 {\n display: flex;\n align-items: center;\n gap: 8px;\n\n word-break: break-all;\n white-space: pre-wrap;\n\n /* overflow-x: auto; */\n\n ._statusIcon_1j0ct_405 {\n font-size: 12px;\n flex-shrink: 0;\n line-height: 1;\n transition: all 0.3s ease;\n }\n }\n\n ._historyMeta_1j0ct_465 {\n font-size: 10px;\n color: rgba(255, 255, 255, 0.6);\n /* color: rgb(61, 61, 61); */\n margin-top: 8px;\n line-height: 1;\n }\n }\n }\n}\n\n/* 动画关键帧 - 更快的闪烁 */\n@keyframes _pulse_1j0ct_1 {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.4;\n transform: scale(1.3);\n }\n}\n\n/* 重试动画 - 旋转脉冲 */\n@keyframes _retryPulse_1j0ct_1 {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1) rotate(0deg);\n }\n 25% {\n opacity: 0.6;\n transform: scale(1.2) rotate(90deg);\n }\n 50% {\n opacity: 0.8;\n transform: scale(1.1) rotate(180deg);\n }\n 75% {\n opacity: 0.6;\n transform: scale(1.2) rotate(270deg);\n }\n}\n\n/* 庆祝动画 */\n@keyframes _celebrate_1j0ct_1 {\n 0%,\n 100% {\n transform: scale(1);\n }\n 25% {\n transform: scale(1.2) rotate(-5deg);\n }\n 75% {\n transform: scale(1.2) rotate(5deg);\n }\n}\n\n/* done 卡片的光泽效果 */\n@keyframes _shimmer_1j0ct_1 {\n 0% {\n left: -100%;\n }\n 100% {\n left: 100%;\n }\n}\n\n/* 输入区域样式 */\n._inputSectionWrapper_1j0ct_535 {\n position: absolute;\n width: var(--history-width);\n top: var(--height);\n left: var(--side-space);\n z-index: -1;\n\n visibility: visible;\n overflow: hidden;\n\n height: 48px;\n\n transition: all 0.2s;\n\n background: rgba(186, 186, 186, 0.2);\n backdrop-filter: blur(10px);\n\n border-bottom-left-radius: calc(var(--border-radius) + 4px);\n border-bottom-right-radius: calc(var(--border-radius) + 4px);\n\n border: 2px solid rgba(255, 255, 255, 0.3);\n box-shadow: 0 1px 16px rgba(0, 0, 0, 0.4);\n\n &._hidden_1j0ct_558 {\n visibility: collapse;\n height: 0;\n }\n\n ._inputSection_1j0ct_535 {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 8px;\n\n ._taskInput_1j0ct_569 {\n flex: 1;\n background: rgba(255, 255, 255, 0.4);\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: 10px;\n padding-inline: 10px;\n color: rgb(20, 20, 20);\n font-size: 12px;\n height: 28px;\n line-height: 1;\n outline: none;\n transition: all 0.2s ease;\n\n /* text-shadow: 0 0 2px rgba(255, 255, 255, 0.8); */\n\n /* border-color: rgba(57, 182, 255, 0.3); */\n\n &::placeholder {\n color: rgb(53, 53, 53);\n }\n\n &:focus {\n background: rgba(255, 255, 255, 0.8);\n border-color: rgba(57, 182, 255, 0.6);\n box-shadow: 0 0 0 2px rgba(57, 182, 255, 0.2);\n }\n }\n }\n}\n._wrapper_1oy2s_1 {\n position: fixed;\n inset: 0;\n z-index: 2147483641; /* 确保在所有元素之上,除了 panel */\n /* pointer-events: none; */\n cursor: not-allowed;\n overflow: hidden;\n\n display: none;\n}\n/* AI 光标样式 */\n._cursor_1vrf3_2 {\n position: absolute;\n width: var(--cursor-size, 75px);\n height: var(--cursor-size, 75px);\n pointer-events: none;\n z-index: 10000;\n transform: translate(-30%, -30%);\n\n animation: _cursor-enter_1vrf3_1 300ms ease-out forwards;\n}\n\n._cursorBorder_1vrf3_13 {\n position: absolute;\n inset: 0;\n background: linear-gradient(45deg, rgb(57, 182, 255), rgb(189, 69, 251));\n mask-image: url(https://img.alicdn.com/imgextra/i1/O1CN01YHLVYR1LvqWIyo5kH_!!6000000001362-2-tps-202-202.png);\n mask-size: 100% 100%;\n mask-repeat: no-repeat;\n animation: _cursor-breathe_1vrf3_1 2s ease-in-out infinite;\n}\n\n._cursorFilling_1vrf3_23 {\n position: absolute;\n inset: 0;\n background: url(https://img.alicdn.com/imgextra/i3/O1CN01JZOqOS1Tu1sIKbPLW_!!6000000002441-2-tps-202-202.png);\n background-size: 100% 100%;\n background-repeat: no-repeat;\n}\n\n._cursorRipple_1vrf3_31 {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n._cursor_1vrf3_2._clicking_1vrf3_37 ._cursorRipple_1vrf3_31::after {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n left: -30%;\n top: -30%;\n border: 4px solid rgba(57, 182, 255, 1);\n border-radius: 50%;\n animation: _cursor-ripple_1vrf3_1 300ms ease-out forwards;\n}\n\n/* 光标动画关键帧 */\n@keyframes _cursor-breathe_1vrf3_1 {\n 0%,\n 100% {\n transform: scale(1);\n opacity: 0.9;\n }\n 50% {\n transform: scale(1.05);\n opacity: 1;\n }\n}\n\n@keyframes _cursor-rotate_1vrf3_1 {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes _cursor-enter_1vrf3_1 {\n 0% {\n transform: translate(-30%, -30%) scale(0.5);\n opacity: 0;\n }\n 100% {\n transform: translate(-30%, -30%) scale(1);\n opacity: 1;\n }\n}\n\n@keyframes _cursor-ripple_1vrf3_1 {\n 0% {\n transform: scale(0);\n opacity: 1;\n }\n 100% {\n transform: scale(2);\n opacity: 0;\n }\n}"));
|
|
7
7
|
document.head.appendChild(elementStyle);
|
|
8
8
|
}
|
|
9
9
|
} catch (e) {
|
|
@@ -1189,7 +1189,7 @@ function flatTreeToString(flatTree, include_attributes) {
|
|
|
1189
1189
|
}
|
|
1190
1190
|
return false;
|
|
1191
1191
|
}, "hasParentWithHighlightIndex");
|
|
1192
|
-
const processNode = /* @__PURE__ */ __name((node, depth,
|
|
1192
|
+
const processNode = /* @__PURE__ */ __name((node, depth, result22) => {
|
|
1193
1193
|
let nextDepth = depth;
|
|
1194
1194
|
const depthStr = " ".repeat(depth);
|
|
1195
1195
|
if (node.type === "element") {
|
|
@@ -1264,23 +1264,23 @@ function flatTreeToString(flatTree, include_attributes) {
|
|
|
1264
1264
|
line += " ";
|
|
1265
1265
|
}
|
|
1266
1266
|
line += " />";
|
|
1267
|
-
|
|
1267
|
+
result22.push(line);
|
|
1268
1268
|
}
|
|
1269
1269
|
for (const child of node.children) {
|
|
1270
|
-
processNode(child, nextDepth,
|
|
1270
|
+
processNode(child, nextDepth, result22);
|
|
1271
1271
|
}
|
|
1272
1272
|
} else if (node.type === "text") {
|
|
1273
1273
|
if (hasParentWithHighlightIndex(node)) {
|
|
1274
1274
|
return;
|
|
1275
1275
|
}
|
|
1276
1276
|
if (node.parent && node.parent.type === "element" && node.parent.isVisible && node.parent.isTopElement) {
|
|
1277
|
-
|
|
1277
|
+
result22.push(`${depthStr}${node.text ?? ""}`);
|
|
1278
1278
|
}
|
|
1279
1279
|
}
|
|
1280
1280
|
}, "processNode");
|
|
1281
|
-
const
|
|
1282
|
-
processNode(rootNode, 0,
|
|
1283
|
-
return
|
|
1281
|
+
const result2 = [];
|
|
1282
|
+
processNode(rootNode, 0, result2);
|
|
1283
|
+
return result2.join("\n");
|
|
1284
1284
|
}
|
|
1285
1285
|
__name(flatTreeToString, "flatTreeToString");
|
|
1286
1286
|
const getAllTextTillNextClickableElement = /* @__PURE__ */ __name((node, maxDepth = -1) => {
|
|
@@ -1651,6 +1651,8 @@ function lenientParseMacroToolCall(responseData, inputSchema) {
|
|
|
1651
1651
|
}
|
|
1652
1652
|
switch (choice.finish_reason) {
|
|
1653
1653
|
case "tool_calls":
|
|
1654
|
+
case "function_call":
|
|
1655
|
+
// gemini
|
|
1654
1656
|
case "stop":
|
|
1655
1657
|
break;
|
|
1656
1658
|
case "length":
|
|
@@ -1902,8 +1904,8 @@ const _LLM = class _LLM {
|
|
|
1902
1904
|
async invoke(messages, tools2, abortSignal) {
|
|
1903
1905
|
return await withRetry(
|
|
1904
1906
|
async () => {
|
|
1905
|
-
const
|
|
1906
|
-
return
|
|
1907
|
+
const result2 = await this.client.invoke(messages, tools2, abortSignal);
|
|
1908
|
+
return result2;
|
|
1907
1909
|
},
|
|
1908
1910
|
// retry settings
|
|
1909
1911
|
{
|
|
@@ -2413,6 +2415,24 @@ tools.set(
|
|
|
2413
2415
|
}, "execute")
|
|
2414
2416
|
})
|
|
2415
2417
|
);
|
|
2418
|
+
tools.set(
|
|
2419
|
+
"execute_javascript",
|
|
2420
|
+
tool({
|
|
2421
|
+
description: "Execute JavaScript code on the current page. Supports async/await syntax. Use with caution!",
|
|
2422
|
+
inputSchema: zod.object({
|
|
2423
|
+
script: zod.string()
|
|
2424
|
+
}),
|
|
2425
|
+
execute: /* @__PURE__ */ __name(async function(input) {
|
|
2426
|
+
try {
|
|
2427
|
+
const asyncFunction = eval(`(async () => { ${input.script} })`);
|
|
2428
|
+
const result = await asyncFunction();
|
|
2429
|
+
return `✅ Executed JavaScript. Result: ${result}` + await getSystemInfo();
|
|
2430
|
+
} catch (error2) {
|
|
2431
|
+
return `❌ Error executing JavaScript: ${error2}` + await getSystemInfo();
|
|
2432
|
+
}
|
|
2433
|
+
}, "execute")
|
|
2434
|
+
})
|
|
2435
|
+
);
|
|
2416
2436
|
async function waitUntil(check, timeout = 60 * 601e3) {
|
|
2417
2437
|
if (check()) return true;
|
|
2418
2438
|
return new Promise((resolve, reject) => {
|
|
@@ -2527,48 +2547,48 @@ const _UIState = class _UIState {
|
|
|
2527
2547
|
};
|
|
2528
2548
|
__name(_UIState, "UIState");
|
|
2529
2549
|
let UIState = _UIState;
|
|
2530
|
-
const wrapper$1 = "
|
|
2531
|
-
const background = "
|
|
2532
|
-
const header = "
|
|
2533
|
-
const pulse = "
|
|
2534
|
-
const retryPulse = "
|
|
2535
|
-
const statusTextFadeOut = "
|
|
2536
|
-
const statusTextFadeIn = "
|
|
2537
|
-
const statusSection = "
|
|
2538
|
-
const indicator = "
|
|
2539
|
-
const thinking = "
|
|
2540
|
-
const tool_executing = "
|
|
2541
|
-
const retry = "
|
|
2542
|
-
const completed = "
|
|
2543
|
-
const input = "
|
|
2544
|
-
const output = "
|
|
2545
|
-
const error = "
|
|
2546
|
-
const statusText = "
|
|
2547
|
-
const fadeOut = "
|
|
2548
|
-
const fadeIn = "
|
|
2549
|
-
const controls = "
|
|
2550
|
-
const controlButton = "
|
|
2551
|
-
const pauseButton = "
|
|
2552
|
-
const paused = "
|
|
2553
|
-
const stopButton = "
|
|
2554
|
-
const historySectionWrapper = "
|
|
2555
|
-
const shimmer = "
|
|
2556
|
-
const celebrate = "
|
|
2557
|
-
const expanded = "
|
|
2558
|
-
const historySection = "
|
|
2559
|
-
const historyItem = "
|
|
2560
|
-
const doneSuccess = "
|
|
2561
|
-
const historyContent = "
|
|
2562
|
-
const statusIcon = "
|
|
2563
|
-
const doneError = "
|
|
2564
|
-
const historyMeta = "
|
|
2565
|
-
const inputSectionWrapper = "
|
|
2566
|
-
const hidden = "
|
|
2567
|
-
const inputSection = "
|
|
2568
|
-
const taskInput = "
|
|
2550
|
+
const wrapper$1 = "_wrapper_1j0ct_1";
|
|
2551
|
+
const background = "_background_1j0ct_39";
|
|
2552
|
+
const header = "_header_1j0ct_99";
|
|
2553
|
+
const pulse = "_pulse_1j0ct_1";
|
|
2554
|
+
const retryPulse = "_retryPulse_1j0ct_1";
|
|
2555
|
+
const statusTextFadeOut = "_statusTextFadeOut_1j0ct_1";
|
|
2556
|
+
const statusTextFadeIn = "_statusTextFadeIn_1j0ct_1";
|
|
2557
|
+
const statusSection = "_statusSection_1j0ct_121";
|
|
2558
|
+
const indicator = "_indicator_1j0ct_128";
|
|
2559
|
+
const thinking = "_thinking_1j0ct_137";
|
|
2560
|
+
const tool_executing = "_tool_executing_1j0ct_142";
|
|
2561
|
+
const retry = "_retry_1j0ct_147";
|
|
2562
|
+
const completed = "_completed_1j0ct_153";
|
|
2563
|
+
const input = "_input_1j0ct_154";
|
|
2564
|
+
const output = "_output_1j0ct_155";
|
|
2565
|
+
const error = "_error_1j0ct_160";
|
|
2566
|
+
const statusText = "_statusText_1j0ct_166";
|
|
2567
|
+
const fadeOut = "_fadeOut_1j0ct_178";
|
|
2568
|
+
const fadeIn = "_fadeIn_1j0ct_182";
|
|
2569
|
+
const controls = "_controls_1j0ct_188";
|
|
2570
|
+
const controlButton = "_controlButton_1j0ct_193";
|
|
2571
|
+
const pauseButton = "_pauseButton_1j0ct_212";
|
|
2572
|
+
const paused = "_paused_1j0ct_214";
|
|
2573
|
+
const stopButton = "_stopButton_1j0ct_224";
|
|
2574
|
+
const historySectionWrapper = "_historySectionWrapper_1j0ct_258";
|
|
2575
|
+
const shimmer = "_shimmer_1j0ct_1";
|
|
2576
|
+
const celebrate = "_celebrate_1j0ct_1";
|
|
2577
|
+
const expanded = "_expanded_1j0ct_290";
|
|
2578
|
+
const historySection = "_historySection_1j0ct_258";
|
|
2579
|
+
const historyItem = "_historyItem_1j0ct_309";
|
|
2580
|
+
const doneSuccess = "_doneSuccess_1j0ct_368";
|
|
2581
|
+
const historyContent = "_historyContent_1j0ct_404";
|
|
2582
|
+
const statusIcon = "_statusIcon_1j0ct_405";
|
|
2583
|
+
const doneError = "_doneError_1j0ct_414";
|
|
2584
|
+
const historyMeta = "_historyMeta_1j0ct_465";
|
|
2585
|
+
const inputSectionWrapper = "_inputSectionWrapper_1j0ct_535";
|
|
2586
|
+
const hidden = "_hidden_1j0ct_558";
|
|
2587
|
+
const inputSection = "_inputSection_1j0ct_535";
|
|
2588
|
+
const taskInput = "_taskInput_1j0ct_569";
|
|
2569
2589
|
const styles$1 = {
|
|
2570
2590
|
wrapper: wrapper$1,
|
|
2571
|
-
"mask-running": "_mask-
|
|
2591
|
+
"mask-running": "_mask-running_1j0ct_1",
|
|
2572
2592
|
background,
|
|
2573
2593
|
header,
|
|
2574
2594
|
pulse,
|
|
@@ -3372,6 +3392,9 @@ const _PageAgent = class _PageAgent extends EventTarget {
|
|
|
3372
3392
|
this.tools.set(name, tool2);
|
|
3373
3393
|
}
|
|
3374
3394
|
}
|
|
3395
|
+
if (!this.config.experimentalScriptExecutionTool) {
|
|
3396
|
+
this.tools.delete("execute_javascript");
|
|
3397
|
+
}
|
|
3375
3398
|
patchReact();
|
|
3376
3399
|
window.addEventListener("beforeunload", (e) => {
|
|
3377
3400
|
if (!this.disposed) this.dispose("PAGE_UNLOADING");
|
|
@@ -3413,7 +3436,7 @@ const _PageAgent = class _PageAgent extends EventTarget {
|
|
|
3413
3436
|
type: "thinking",
|
|
3414
3437
|
displayText: this.i18n.t("ui.panel.thinking")
|
|
3415
3438
|
});
|
|
3416
|
-
const
|
|
3439
|
+
const result2 = await __privateGet(this, _llm).invoke(
|
|
3417
3440
|
[
|
|
3418
3441
|
{
|
|
3419
3442
|
role: "system",
|
|
@@ -3427,7 +3450,7 @@ const _PageAgent = class _PageAgent extends EventTarget {
|
|
|
3427
3450
|
{ AgentOutput: __privateMethod(this, _PageAgent_instances, packMacroTool_fn).call(this) },
|
|
3428
3451
|
__privateGet(this, _abortController).signal
|
|
3429
3452
|
);
|
|
3430
|
-
const macroResult =
|
|
3453
|
+
const macroResult = result2.toolResult;
|
|
3431
3454
|
const input2 = macroResult.input;
|
|
3432
3455
|
const output2 = macroResult.output;
|
|
3433
3456
|
const brain = {
|
|
@@ -3444,7 +3467,7 @@ const _PageAgent = class _PageAgent extends EventTarget {
|
|
|
3444
3467
|
this.history.push({
|
|
3445
3468
|
brain,
|
|
3446
3469
|
action,
|
|
3447
|
-
usage:
|
|
3470
|
+
usage: result2.usage
|
|
3448
3471
|
});
|
|
3449
3472
|
console.log(chalk.green("Step finished:"), actionName);
|
|
3450
3473
|
console.groupEnd();
|
|
@@ -3452,38 +3475,38 @@ const _PageAgent = class _PageAgent extends EventTarget {
|
|
|
3452
3475
|
step++;
|
|
3453
3476
|
if (step > MAX_STEPS) {
|
|
3454
3477
|
__privateMethod(this, _PageAgent_instances, onDone_fn).call(this, "Step count exceeded maximum limit", false);
|
|
3455
|
-
const
|
|
3478
|
+
const result22 = {
|
|
3456
3479
|
success: false,
|
|
3457
3480
|
data: "Step count exceeded maximum limit",
|
|
3458
3481
|
history: this.history
|
|
3459
3482
|
};
|
|
3460
|
-
await onAfterTask.call(this,
|
|
3461
|
-
return
|
|
3483
|
+
await onAfterTask.call(this, result22);
|
|
3484
|
+
return result22;
|
|
3462
3485
|
}
|
|
3463
3486
|
if (actionName === "done") {
|
|
3464
3487
|
const success = action.input?.success ?? false;
|
|
3465
3488
|
const text = action.input?.text || "no text provided";
|
|
3466
3489
|
console.log(chalk.green.bold("Task completed"), success, text);
|
|
3467
3490
|
__privateMethod(this, _PageAgent_instances, onDone_fn).call(this, text, success);
|
|
3468
|
-
const
|
|
3491
|
+
const result22 = {
|
|
3469
3492
|
success,
|
|
3470
3493
|
data: text,
|
|
3471
3494
|
history: this.history
|
|
3472
3495
|
};
|
|
3473
|
-
await onAfterTask.call(this,
|
|
3474
|
-
return
|
|
3496
|
+
await onAfterTask.call(this, result22);
|
|
3497
|
+
return result22;
|
|
3475
3498
|
}
|
|
3476
3499
|
}
|
|
3477
3500
|
} catch (error2) {
|
|
3478
3501
|
console.error("Task failed", error2);
|
|
3479
3502
|
__privateMethod(this, _PageAgent_instances, onDone_fn).call(this, String(error2), false);
|
|
3480
|
-
const
|
|
3503
|
+
const result2 = {
|
|
3481
3504
|
success: false,
|
|
3482
3505
|
data: String(error2),
|
|
3483
3506
|
history: this.history
|
|
3484
3507
|
};
|
|
3485
|
-
await onAfterTask.call(this,
|
|
3486
|
-
return
|
|
3508
|
+
await onAfterTask.call(this, result2);
|
|
3509
|
+
return result2;
|
|
3487
3510
|
}
|
|
3488
3511
|
}
|
|
3489
3512
|
dispose(reason) {
|
|
@@ -3558,16 +3581,16 @@ packMacroTool_fn = /* @__PURE__ */ __name(function() {
|
|
|
3558
3581
|
displayText: getToolExecutingText(toolName, toolInput, this.i18n)
|
|
3559
3582
|
});
|
|
3560
3583
|
const startTime = Date.now();
|
|
3561
|
-
let
|
|
3584
|
+
let result2 = await tool2.execute.bind(this)(toolInput);
|
|
3562
3585
|
const duration = Date.now() - startTime;
|
|
3563
|
-
console.log(chalk.green.bold(`Tool (${toolName}) executed for ${duration}ms`),
|
|
3586
|
+
console.log(chalk.green.bold(`Tool (${toolName}) executed for ${duration}ms`), result2);
|
|
3564
3587
|
if (toolName === "wait") {
|
|
3565
3588
|
__privateSet(this, _totalWaitTime, __privateGet(this, _totalWaitTime) + Math.round(toolInput.seconds + duration / 1e3));
|
|
3566
|
-
|
|
3589
|
+
result2 += `
|
|
3567
3590
|
<sys> You have waited ${__privateGet(this, _totalWaitTime)} seconds accumulatively.`;
|
|
3568
3591
|
if (__privateGet(this, _totalWaitTime) >= 3)
|
|
3569
|
-
|
|
3570
|
-
|
|
3592
|
+
result2 += "\nDo NOT wait any longer unless you have a good reason.\n";
|
|
3593
|
+
result2 += "</sys>";
|
|
3571
3594
|
} else {
|
|
3572
3595
|
__privateSet(this, _totalWaitTime, 0);
|
|
3573
3596
|
}
|
|
@@ -3577,14 +3600,14 @@ packMacroTool_fn = /* @__PURE__ */ __name(function() {
|
|
|
3577
3600
|
type: "tool_executing",
|
|
3578
3601
|
toolName,
|
|
3579
3602
|
toolArgs: toolInput,
|
|
3580
|
-
toolResult:
|
|
3603
|
+
toolResult: result2,
|
|
3581
3604
|
displayText: displayResult,
|
|
3582
3605
|
duration
|
|
3583
3606
|
});
|
|
3584
3607
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
3585
3608
|
return {
|
|
3586
3609
|
input: input2,
|
|
3587
|
-
output:
|
|
3610
|
+
output: result2
|
|
3588
3611
|
};
|
|
3589
3612
|
}, "execute")
|
|
3590
3613
|
};
|