misoai-web 1.0.5 → 1.5.6
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/LICENSE +21 -21
- package/README.md +9 -353
- package/bin/midscene-playground +2 -2
- package/dist/es/agent.js +9 -191
- package/dist/es/agent.js.map +1 -1
- package/dist/es/bridge-mode-browser.js +3 -3
- package/dist/es/bridge-mode-browser.js.map +1 -1
- package/dist/es/bridge-mode.js +11 -193
- package/dist/es/bridge-mode.js.map +1 -1
- package/dist/es/chrome-extension.js +10 -192
- package/dist/es/chrome-extension.js.map +1 -1
- package/dist/es/index.js +13 -195
- package/dist/es/index.js.map +1 -1
- package/dist/es/midscene-playground.js +9 -191
- package/dist/es/midscene-playground.js.map +1 -1
- package/dist/es/midscene-server.js.map +1 -1
- package/dist/es/playground.js +9 -191
- package/dist/es/playground.js.map +1 -1
- package/dist/es/playwright-report.js.map +1 -1
- package/dist/es/playwright.js +10 -192
- package/dist/es/playwright.js.map +1 -1
- package/dist/es/puppeteer-agent-launcher.js +13 -195
- package/dist/es/puppeteer-agent-launcher.js.map +1 -1
- package/dist/es/puppeteer.js +13 -195
- package/dist/es/puppeteer.js.map +1 -1
- package/dist/es/ui-utils.js.map +1 -1
- package/dist/es/utils.js.map +1 -1
- package/dist/es/yaml.js +5 -3
- package/dist/es/yaml.js.map +1 -1
- package/dist/lib/agent.js +9 -191
- package/dist/lib/agent.js.map +1 -1
- package/dist/lib/bridge-mode-browser.js +3 -3
- package/dist/lib/bridge-mode-browser.js.map +1 -1
- package/dist/lib/bridge-mode.js +11 -193
- package/dist/lib/bridge-mode.js.map +1 -1
- package/dist/lib/chrome-extension.js +10 -192
- package/dist/lib/chrome-extension.js.map +1 -1
- package/dist/lib/index.js +13 -195
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/midscene-playground.js +9 -191
- package/dist/lib/midscene-playground.js.map +1 -1
- package/dist/lib/midscene-server.js.map +1 -1
- package/dist/lib/playground.js +9 -191
- package/dist/lib/playground.js.map +1 -1
- package/dist/lib/playwright-report.js.map +1 -1
- package/dist/lib/playwright.js +10 -192
- package/dist/lib/playwright.js.map +1 -1
- package/dist/lib/puppeteer-agent-launcher.js +13 -195
- package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
- package/dist/lib/puppeteer.js +13 -195
- package/dist/lib/puppeteer.js.map +1 -1
- package/dist/lib/ui-utils.js.map +1 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/yaml.js +5 -3
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/agent.d.ts +1 -27
- package/dist/types/bridge-mode-browser.d.ts +2 -2
- package/dist/types/bridge-mode.d.ts +2 -2
- package/dist/types/{browser-a1877d18.d.ts → browser-aec1055d.d.ts} +1 -1
- package/dist/types/chrome-extension.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/midscene-server.d.ts +1 -1
- package/dist/types/{page-663ece08.d.ts → page-86ab0fe1.d.ts} +34 -34
- package/dist/types/playground.d.ts +2 -2
- package/dist/types/playwright.d.ts +1 -1
- package/dist/types/puppeteer-agent-launcher.d.ts +1 -1
- package/dist/types/puppeteer.d.ts +1 -1
- package/dist/types/utils.d.ts +1 -1
- package/dist/types/yaml.d.ts +1 -1
- package/iife-script/htmlElement.js +2 -2
- package/iife-script/htmlElementDebug.js +2 -2
- package/package.json +3 -3
package/LICENSE
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
MIT License
|
2
|
-
|
3
|
-
Copyright (c) 2024-present Bytedance, Inc. and its affiliates.
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
13
|
-
copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
-
SOFTWARE.
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2024-present Bytedance, Inc. and its affiliates.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
@@ -1,353 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
- **🧠 Cumulative Context System**: AI remembers previous actions and data across steps
|
11
|
-
- **🗣️ Natural Language Data References**: No more `{stored.key}` syntax needed
|
12
|
-
- **🎯 Smart Context-Aware Assertions**: Intelligent data replacement in assertions
|
13
|
-
- **🔄 Multi-Step Workflows**: Seamless information flow between actions
|
14
|
-
- **🛡️ Built-in CAPTCHA Solving**: Advanced AI-powered CAPTCHA detection and solving
|
15
|
-
- **📊 Comprehensive Logging**: Full visibility into context operations and AI calls
|
16
|
-
- **🎭 Framework Support**: Works with Puppeteer, Playwright, and more
|
17
|
-
|
18
|
-
## 📦 Installation
|
19
|
-
|
20
|
-
```bash
|
21
|
-
npm install @midscene/web puppeteer
|
22
|
-
# or
|
23
|
-
yarn add @midscene/web puppeteer
|
24
|
-
```
|
25
|
-
|
26
|
-
## 🎯 Quick Start
|
27
|
-
|
28
|
-
### Basic Usage with Cumulative Context
|
29
|
-
|
30
|
-
```javascript
|
31
|
-
import { PuppeteerAgent } from '@midscene/web';
|
32
|
-
import puppeteer from 'puppeteer';
|
33
|
-
|
34
|
-
const browser = await puppeteer.launch({ headless: false });
|
35
|
-
const page = await browser.newPage();
|
36
|
-
|
37
|
-
// Create agent with cumulative context enabled
|
38
|
-
const agent = new PuppeteerAgent(page, {
|
39
|
-
enableCumulativeContext: true, // 🔥 Enable context system
|
40
|
-
autoClearContext: true, // 🧹 Start with clean context
|
41
|
-
testId: 'my-automation'
|
42
|
-
});
|
43
|
-
|
44
|
-
await page.goto('https://example.com');
|
45
|
-
|
46
|
-
// Step 1: Store data with natural language
|
47
|
-
await agent.aiQuery('kullanıcı adını "john_doe" olarak username şeklinde kaydet');
|
48
|
-
|
49
|
-
// Step 2: Use stored data without {stored.key} syntax!
|
50
|
-
await agent.aiAction('arama kutusuna username verisini yaz');
|
51
|
-
|
52
|
-
// Step 3: Context-aware assertion
|
53
|
-
await agent.aiAssert('arama kutusunda username değeri görünüyor');
|
54
|
-
|
55
|
-
await browser.close();
|
56
|
-
```
|
57
|
-
|
58
|
-
## 🧠 Cumulative Context System
|
59
|
-
|
60
|
-
### Natural Language Data Storage
|
61
|
-
|
62
|
-
```javascript
|
63
|
-
// Turkish natural language storage
|
64
|
-
await agent.aiQuery('ürün adını "iPhone 15" olarak urun_adi şeklinde kaydet');
|
65
|
-
await agent.aiQuery('fiyatı "999$" olarak fiyat şeklinde kaydet');
|
66
|
-
|
67
|
-
// English natural language storage
|
68
|
-
await agent.aiQuery('extract username and store as user_name');
|
69
|
-
await agent.aiQuery('get email address, store as email');
|
70
|
-
```
|
71
|
-
|
72
|
-
### Automatic Data Usage
|
73
|
-
|
74
|
-
```javascript
|
75
|
-
// No need for {stored.key} syntax!
|
76
|
-
await agent.aiAction('formu urun_adi ve fiyat ile doldur');
|
77
|
-
await agent.aiAction('use user_name and email to fill the form');
|
78
|
-
|
79
|
-
// Multiple data references in one action
|
80
|
-
await agent.aiAction('sepete urun_adi ürününü fiyat fiyatıyla ekle');
|
81
|
-
```
|
82
|
-
|
83
|
-
### Context-Aware Assertions
|
84
|
-
|
85
|
-
```javascript
|
86
|
-
// Smart replacement - AI decides when to replace
|
87
|
-
await agent.aiAssert('sepette urun_adi ürünü görünüyor'); // ✅ Will replace
|
88
|
-
await agent.aiAssert('sayfada iPhone yazısı var'); // ❓ Context-dependent
|
89
|
-
```
|
90
|
-
|
91
|
-
## 🛡️ AI CAPTCHA Solving
|
92
|
-
|
93
|
-
The `aiCaptcha` method provides intelligent CAPTCHA detection and solving capabilities with automatic execution:
|
94
|
-
|
95
|
-
```javascript
|
96
|
-
// Basic CAPTCHA solving (auto-detects complexity)
|
97
|
-
await agent.aiCaptcha();
|
98
|
-
|
99
|
-
// Advanced CAPTCHA solving with options
|
100
|
-
await agent.aiCaptcha({
|
101
|
-
deepThink: true, // Force deep analysis
|
102
|
-
autoDetectComplexity: true // Auto-detect if deep thinking needed (default: true)
|
103
|
-
});
|
104
|
-
```
|
105
|
-
|
106
|
-
### CAPTCHA Features
|
107
|
-
|
108
|
-
- **🔍 Automatic Detection**: Identifies CAPTCHA type (text, image, unknown)
|
109
|
-
- **🧠 Complexity Analysis**: Auto-detects if deep thinking is needed
|
110
|
-
- **📝 Text CAPTCHAs**: Solves distorted text and automatically inputs solution
|
111
|
-
- **🖼️ Image CAPTCHAs**: Handles "select all images with..." challenges with coordinate clicking
|
112
|
-
- **🎯 Automatic Execution**: Performs all required actions (click, input, verify) automatically
|
113
|
-
- **⚡ Smart Processing**: Uses appropriate AI model based on complexity
|
114
|
-
- **🔄 Action Sequence**: Executes complete CAPTCHA solving workflow
|
115
|
-
|
116
|
-
### CAPTCHA Response Format
|
117
|
-
|
118
|
-
The AI returns a structured response with:
|
119
|
-
|
120
|
-
```javascript
|
121
|
-
{
|
122
|
-
captchaType: "text" | "image" | "unknown",
|
123
|
-
solution: "The solution text or description",
|
124
|
-
thought: "AI reasoning process",
|
125
|
-
actions: [
|
126
|
-
{
|
127
|
-
type: "click" | "input" | "verify",
|
128
|
-
target: "Description of target element",
|
129
|
-
value: "Text to input (for input actions)",
|
130
|
-
coordinates: [x, y] // For precise clicking
|
131
|
-
}
|
132
|
-
]
|
133
|
-
}
|
134
|
-
```
|
135
|
-
|
136
|
-
### CAPTCHA Example
|
137
|
-
|
138
|
-
```javascript
|
139
|
-
// Navigate to page with CAPTCHA
|
140
|
-
await page.goto('https://example.com/login');
|
141
|
-
|
142
|
-
// Fill login form
|
143
|
-
await agent.aiInput('john@example.com', 'email field');
|
144
|
-
await agent.aiInput('password123', 'password field');
|
145
|
-
|
146
|
-
// Solve CAPTCHA automatically - AI will:
|
147
|
-
// 1. Analyze the CAPTCHA type and complexity
|
148
|
-
// 2. Generate solution
|
149
|
-
// 3. Execute all required actions automatically
|
150
|
-
const captchaResult = await agent.aiCaptcha({
|
151
|
-
autoDetectComplexity: true
|
152
|
-
});
|
153
|
-
|
154
|
-
console.log('CAPTCHA solved:', captchaResult.result.captchaType);
|
155
|
-
console.log('Solution:', captchaResult.result.solution);
|
156
|
-
console.log('Actions performed:', captchaResult.result.actions.length);
|
157
|
-
|
158
|
-
// Form is now ready to submit
|
159
|
-
await agent.aiTap('login button');
|
160
|
-
```
|
161
|
-
|
162
|
-
### Advanced CAPTCHA Scenarios
|
163
|
-
|
164
|
-
```javascript
|
165
|
-
// Complex image CAPTCHA with deep thinking
|
166
|
-
await agent.aiCaptcha({
|
167
|
-
deepThink: true // Forces detailed analysis for complex puzzles
|
168
|
-
});
|
169
|
-
|
170
|
-
// Text CAPTCHA with automatic input
|
171
|
-
// AI will automatically:
|
172
|
-
// - Click on input field
|
173
|
-
// - Type the solution
|
174
|
-
// - Click verify button
|
175
|
-
await agent.aiCaptcha();
|
176
|
-
|
177
|
-
// Using with cumulative context
|
178
|
-
await agent.aiQuery('CAPTCHA çözümünü captcha_cozum olarak kaydet');
|
179
|
-
await agent.aiCaptcha();
|
180
|
-
await agent.aiAssert('CAPTCHA başarıyla çözüldü');
|
181
|
-
```
|
182
|
-
|
183
|
-
## ⚙️ Configuration Options
|
184
|
-
|
185
|
-
```javascript
|
186
|
-
const agent = new PuppeteerAgent(page, {
|
187
|
-
// Context System
|
188
|
-
enableCumulativeContext: true, // Enable/disable context system
|
189
|
-
autoClearContext: false, // Auto-clear on agent creation
|
190
|
-
|
191
|
-
// Basic Options
|
192
|
-
testId: 'my-test', // Test identifier
|
193
|
-
cacheId: 'my-cache', // Cache identifier
|
194
|
-
aiActionContext: 'context', // AI behavior context
|
195
|
-
|
196
|
-
// Reporting
|
197
|
-
generateReport: true, // Generate HTML reports
|
198
|
-
autoPrintReportMsg: true, // Print report messages
|
199
|
-
|
200
|
-
// Navigation
|
201
|
-
forceSameTabNavigation: true, // Force same-tab navigation
|
202
|
-
waitForNavigationTimeout: 30000, // Navigation timeout
|
203
|
-
waitForNetworkIdleTimeout: 5000 // Network idle timeout
|
204
|
-
});
|
205
|
-
```
|
206
|
-
|
207
|
-
## 📊 Context Management
|
208
|
-
|
209
|
-
### Direct Context Access
|
210
|
-
|
211
|
-
```javascript
|
212
|
-
// Get stored data
|
213
|
-
const storedData = agent.getStoredData();
|
214
|
-
console.log('Stored:', storedData);
|
215
|
-
|
216
|
-
// Get step summary
|
217
|
-
const summary = agent.getStepSummary();
|
218
|
-
console.log('Steps:', summary);
|
219
|
-
|
220
|
-
// Clear context manually
|
221
|
-
agent.clearContext();
|
222
|
-
|
223
|
-
// Get context store instance
|
224
|
-
const contextStore = agent.getContextStore();
|
225
|
-
```
|
226
|
-
|
227
|
-
### Manual Data Storage
|
228
|
-
|
229
|
-
```javascript
|
230
|
-
const contextStore = agent.getContextStore();
|
231
|
-
|
232
|
-
// Store data manually
|
233
|
-
contextStore.storeData('customKey', 'customValue');
|
234
|
-
|
235
|
-
// Store with aliases for natural language
|
236
|
-
contextStore.storeDataWithAliases('productName', 'iPhone 15', ['urun', 'product']);
|
237
|
-
|
238
|
-
// Get recent steps
|
239
|
-
const recentSteps = contextStore.getRecentSteps(5);
|
240
|
-
```
|
241
|
-
|
242
|
-
## 🔍 Debug Logging
|
243
|
-
|
244
|
-
Enable comprehensive logging to see context operations:
|
245
|
-
|
246
|
-
```bash
|
247
|
-
# All debug logs
|
248
|
-
DEBUG=midscene:* node your-script.js
|
249
|
-
|
250
|
-
# Context-specific logs
|
251
|
-
DEBUG=midscene:agent node your-script.js
|
252
|
-
|
253
|
-
# AI call logs
|
254
|
-
DEBUG=midscene:ai:*,midscene:agent node your-script.js
|
255
|
-
```
|
256
|
-
|
257
|
-
### Log Examples
|
258
|
-
|
259
|
-
```
|
260
|
-
DEBUG midscene:agent Context replacement in aiAction: {
|
261
|
-
original: "type username in search box",
|
262
|
-
processed: "type john_doe in search box",
|
263
|
-
storedData: { "username": "john_doe" }
|
264
|
-
}
|
265
|
-
|
266
|
-
DEBUG midscene:agent Stored query result with aliases: {
|
267
|
-
key: "username",
|
268
|
-
value: "john_doe",
|
269
|
-
aliases: ["username", "user", "kullanici"]
|
270
|
-
}
|
271
|
-
```
|
272
|
-
|
273
|
-
## 🎭 Multi-Step Workflow Example
|
274
|
-
|
275
|
-
```javascript
|
276
|
-
// E-commerce automation with context
|
277
|
-
const agent = new PuppeteerAgent(page, {
|
278
|
-
enableCumulativeContext: true,
|
279
|
-
autoClearContext: true
|
280
|
-
});
|
281
|
-
|
282
|
-
await page.goto('https://shop.example.com');
|
283
|
-
|
284
|
-
// Step 1: Search and store product info
|
285
|
-
await agent.aiAction('arama kutusuna "laptop" yaz ve ara');
|
286
|
-
await agent.aiQuery('ilk ürünün adını urun_adi olarak kaydet');
|
287
|
-
await agent.aiQuery('ilk ürünün fiyatını urun_fiyati olarak kaydet');
|
288
|
-
|
289
|
-
// Step 2: Add to cart using stored data
|
290
|
-
await agent.aiAction('urun_adi ürününü sepete ekle');
|
291
|
-
|
292
|
-
// Step 3: Verify cart contents
|
293
|
-
await agent.aiAction('sepete git');
|
294
|
-
await agent.aiAssert('sepette urun_adi ürünü urun_fiyati fiyatıyla görünüyor');
|
295
|
-
|
296
|
-
// Step 4: Proceed to checkout
|
297
|
-
await agent.aiAction('ödeme sayfasına git');
|
298
|
-
await agent.aiAssert('ödeme sayfasında urun_adi ürünü listeleniyor');
|
299
|
-
```
|
300
|
-
|
301
|
-
## 🔄 Backward Compatibility
|
302
|
-
|
303
|
-
The new context system is fully backward compatible:
|
304
|
-
|
305
|
-
```javascript
|
306
|
-
// Old syntax still works
|
307
|
-
await agent.aiQuery('extract username, store as user');
|
308
|
-
await agent.aiAction('type {stored.user} in field');
|
309
|
-
|
310
|
-
// New syntax (recommended)
|
311
|
-
await agent.aiQuery('kullanıcı adını user olarak kaydet');
|
312
|
-
await agent.aiAction('alana user verisini yaz');
|
313
|
-
|
314
|
-
// Mixed usage
|
315
|
-
await agent.aiAction('use {stored.email} and user verisi together');
|
316
|
-
```
|
317
|
-
|
318
|
-
## 📚 API Reference
|
319
|
-
|
320
|
-
### Core Methods
|
321
|
-
|
322
|
-
- `aiAction(prompt)` - Perform actions with context awareness
|
323
|
-
- `aiQuery(prompt)` - Extract data with automatic storage
|
324
|
-
- `aiAssert(assertion)` - Context-aware assertions
|
325
|
-
- `aiCaptcha(options)` - Intelligent CAPTCHA solving
|
326
|
-
- `aiTap(target, options)` - Click elements
|
327
|
-
- `aiInput(text, target, options)` - Input text
|
328
|
-
|
329
|
-
### Context Methods
|
330
|
-
|
331
|
-
- `getStoredData()` - Get all stored data
|
332
|
-
- `getStepSummary()` - Get step summary
|
333
|
-
- `clearContext()` - Clear context store
|
334
|
-
- `getContextStore()` - Get context store instance
|
335
|
-
|
336
|
-
## 🤝 Contributing
|
337
|
-
|
338
|
-
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
339
|
-
|
340
|
-
## 📄 License
|
341
|
-
|
342
|
-
MIT License - see [LICENSE](LICENSE) file for details.
|
343
|
-
|
344
|
-
## 🔗 Links
|
345
|
-
|
346
|
-
- [Documentation](https://midscenejs.com)
|
347
|
-
- [GitHub Repository](https://github.com/web-infra-dev/midscene)
|
348
|
-
- [NPM Package](https://www.npmjs.com/package/@midscene/web)
|
349
|
-
- [Examples](https://github.com/web-infra-dev/midscene/tree/main/packages/web-integration/examples)
|
350
|
-
|
351
|
-
---
|
352
|
-
|
353
|
-
**Made with ❤️ by the Midscene Team**
|
1
|
+
## Documentation
|
2
|
+
|
3
|
+
Automate UI actions, extract data, and perform assertions using AI. It offers JavaScript SDK, Chrome extension, and support for scripting in YAML.
|
4
|
+
|
5
|
+
See https://midscenejs.com/ for details.
|
6
|
+
|
7
|
+
## License
|
8
|
+
|
9
|
+
Midscene is MIT licensed.
|
package/bin/midscene-playground
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
3
|
require('../dist/lib/midscene-playground.js');
|
package/dist/es/agent.js
CHANGED
@@ -17,10 +17,11 @@ var ScriptPlayer = class {
|
|
17
17
|
this.unnamedResultIndex = 0;
|
18
18
|
this.pageAgent = null;
|
19
19
|
this.result = {};
|
20
|
+
const target = script.target || script.web || script.android;
|
20
21
|
if (ifInBrowser) {
|
21
22
|
this.output = void 0;
|
22
|
-
} else if (
|
23
|
-
this.output = resolve(process.cwd(),
|
23
|
+
} else if (target?.output) {
|
24
|
+
this.output = resolve(process.cwd(), target.output);
|
24
25
|
} else {
|
25
26
|
this.output = join(getMidsceneRunSubDir("output"), `${process.pid}.json`);
|
26
27
|
}
|
@@ -94,12 +95,13 @@ var ScriptPlayer = class {
|
|
94
95
|
} else if ("aiAssert" in flowItem) {
|
95
96
|
const assertTask = flowItem;
|
96
97
|
const prompt = assertTask.aiAssert;
|
98
|
+
const msg = assertTask.errorMessage;
|
97
99
|
assert(prompt, "missing prompt for aiAssert");
|
98
100
|
assert(
|
99
101
|
typeof prompt === "string",
|
100
102
|
"prompt for aiAssert must be a string"
|
101
103
|
);
|
102
|
-
await agent.aiAssert(prompt);
|
104
|
+
await agent.aiAssert(prompt, msg);
|
103
105
|
} else if ("aiQuery" in flowItem) {
|
104
106
|
const queryTask = flowItem;
|
105
107
|
const prompt = queryTask.aiQuery;
|
@@ -1660,7 +1662,7 @@ import yaml3 from "js-yaml";
|
|
1660
1662
|
import semver from "semver";
|
1661
1663
|
|
1662
1664
|
// package.json
|
1663
|
-
var version = "1.
|
1665
|
+
var version = "1.5.6";
|
1664
1666
|
|
1665
1667
|
// src/common/task-cache.ts
|
1666
1668
|
var debug3 = getDebug3("cache");
|
@@ -1842,13 +1844,10 @@ var PageAgent = class {
|
|
1842
1844
|
generateReport: true,
|
1843
1845
|
autoPrintReportMsg: true,
|
1844
1846
|
groupName: "Midscene Report",
|
1845
|
-
groupDescription: ""
|
1846
|
-
enableCumulativeContext: true,
|
1847
|
-
autoClearContext: false
|
1847
|
+
groupDescription: ""
|
1848
1848
|
},
|
1849
1849
|
opts || {}
|
1850
1850
|
);
|
1851
|
-
this.initializeContextStore();
|
1852
1851
|
if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
|
1853
1852
|
this.page.waitForNavigationTimeout = this.opts.waitForNavigationTimeout || DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
|
1854
1853
|
this.page.waitForNetworkIdleTimeout = this.opts.waitForNetworkIdleTimeout || DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
|
@@ -1875,69 +1874,6 @@ var PageAgent = class {
|
|
1875
1874
|
opts?.testId || this.page.pageType || "web"
|
1876
1875
|
);
|
1877
1876
|
}
|
1878
|
-
/**
|
1879
|
-
* Initialize context store for cumulative context functionality
|
1880
|
-
*/
|
1881
|
-
async initializeContextStore() {
|
1882
|
-
if (!this.opts.enableCumulativeContext) {
|
1883
|
-
debug4("Cumulative context disabled via options");
|
1884
|
-
return;
|
1885
|
-
}
|
1886
|
-
try {
|
1887
|
-
const aiModel = await import("misoai-core/ai-model");
|
1888
|
-
this.contextStore = aiModel.getContextStore();
|
1889
|
-
debug4("Context store initialized successfully", {
|
1890
|
-
autoClearContext: this.opts.autoClearContext,
|
1891
|
-
testId: this.opts.testId
|
1892
|
-
});
|
1893
|
-
if (this.opts.autoClearContext) {
|
1894
|
-
this.contextStore.clear();
|
1895
|
-
debug4("Context store cleared due to autoClearContext option");
|
1896
|
-
} else {
|
1897
|
-
const existingData = this.contextStore.getAllData();
|
1898
|
-
const existingSteps = this.contextStore.getRecentSteps(100).length;
|
1899
|
-
debug4("Context store preserving existing data", {
|
1900
|
-
existingDataKeys: Object.keys(existingData),
|
1901
|
-
existingStepsCount: existingSteps
|
1902
|
-
});
|
1903
|
-
}
|
1904
|
-
} catch (error) {
|
1905
|
-
debug4("Failed to initialize context store:", error);
|
1906
|
-
console.warn("⚠️ Could not initialize context store:", error);
|
1907
|
-
}
|
1908
|
-
}
|
1909
|
-
/**
|
1910
|
-
* Get the context store instance
|
1911
|
-
*/
|
1912
|
-
getContextStore() {
|
1913
|
-
return this.contextStore;
|
1914
|
-
}
|
1915
|
-
/**
|
1916
|
-
* Clear the context store
|
1917
|
-
*/
|
1918
|
-
clearContext() {
|
1919
|
-
if (this.contextStore) {
|
1920
|
-
this.contextStore.clear();
|
1921
|
-
}
|
1922
|
-
}
|
1923
|
-
/**
|
1924
|
-
* Get all stored data from context store
|
1925
|
-
*/
|
1926
|
-
getStoredData() {
|
1927
|
-
if (this.contextStore) {
|
1928
|
-
return this.contextStore.getAllData();
|
1929
|
-
}
|
1930
|
-
return {};
|
1931
|
-
}
|
1932
|
-
/**
|
1933
|
-
* Get step summary from context store
|
1934
|
-
*/
|
1935
|
-
getStepSummary() {
|
1936
|
-
if (this.contextStore) {
|
1937
|
-
return this.contextStore.getStepSummary();
|
1938
|
-
}
|
1939
|
-
return "";
|
1940
|
-
}
|
1941
1877
|
async getUIContext(action) {
|
1942
1878
|
if (action && (action === "extract" || action === "assert" || action === "captcha")) {
|
1943
1879
|
return await parseContextFromWebPage(this.page, {
|
@@ -2173,31 +2109,6 @@ var PageAgent = class {
|
|
2173
2109
|
};
|
2174
2110
|
}
|
2175
2111
|
async aiAction(taskPrompt, opt) {
|
2176
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2177
|
-
try {
|
2178
|
-
const originalPrompt = taskPrompt;
|
2179
|
-
const processedPrompt = this.contextStore.replaceAllReferences(taskPrompt, "action");
|
2180
|
-
if (originalPrompt !== processedPrompt) {
|
2181
|
-
debug4("Context replacement in aiAction:", {
|
2182
|
-
original: originalPrompt,
|
2183
|
-
processed: processedPrompt,
|
2184
|
-
storedData: this.contextStore.getAllData()
|
2185
|
-
});
|
2186
|
-
}
|
2187
|
-
this.contextStore.addStep({
|
2188
|
-
type: "action",
|
2189
|
-
summary: `Action: ${processedPrompt}`,
|
2190
|
-
prompt: processedPrompt
|
2191
|
-
});
|
2192
|
-
debug4("Added action step to context store:", {
|
2193
|
-
stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
|
2194
|
-
totalSteps: this.contextStore.getRecentSteps(100).length
|
2195
|
-
});
|
2196
|
-
taskPrompt = processedPrompt;
|
2197
|
-
} catch (error) {
|
2198
|
-
debug4("Context store operation failed:", error);
|
2199
|
-
}
|
2200
|
-
}
|
2201
2112
|
const cacheable = opt?.cacheable;
|
2202
2113
|
const isVlmUiTars = vlLocateMode() === "vlm-ui-tars";
|
2203
2114
|
const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
|
@@ -2244,75 +2155,7 @@ var PageAgent = class {
|
|
2244
2155
|
};
|
2245
2156
|
}
|
2246
2157
|
async aiQuery(demand) {
|
2247
|
-
|
2248
|
-
let storageKey;
|
2249
|
-
try {
|
2250
|
-
const aiModel = await import("misoai-core/ai-model");
|
2251
|
-
const contextStore = aiModel.getContextStore();
|
2252
|
-
if (typeof demand === "string") {
|
2253
|
-
const storageInstruction = contextStore.parseStorageInstruction(demand);
|
2254
|
-
if (storageInstruction) {
|
2255
|
-
storageKey = storageInstruction.key;
|
2256
|
-
processedDemand = storageInstruction.cleanText;
|
2257
|
-
contextStore._pendingAliases = storageInstruction.aliases;
|
2258
|
-
} else {
|
2259
|
-
const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
|
2260
|
-
if (storageMatch) {
|
2261
|
-
storageKey = storageMatch[1];
|
2262
|
-
processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
|
2263
|
-
}
|
2264
|
-
}
|
2265
|
-
}
|
2266
|
-
} catch (error) {
|
2267
|
-
debug4("Context store not available:", error);
|
2268
|
-
}
|
2269
|
-
const { output, executor } = await this.taskExecutor.query(processedDemand);
|
2270
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2271
|
-
if (storageKey && output) {
|
2272
|
-
try {
|
2273
|
-
const pendingAliases = this.contextStore._pendingAliases;
|
2274
|
-
if (pendingAliases) {
|
2275
|
-
this.contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
|
2276
|
-
delete this.contextStore._pendingAliases;
|
2277
|
-
debug4("Stored query result with aliases:", {
|
2278
|
-
key: storageKey,
|
2279
|
-
value: output,
|
2280
|
-
aliases: pendingAliases
|
2281
|
-
});
|
2282
|
-
} else {
|
2283
|
-
this.contextStore.storeData(storageKey, output);
|
2284
|
-
debug4("Stored query result:", {
|
2285
|
-
key: storageKey,
|
2286
|
-
value: output
|
2287
|
-
});
|
2288
|
-
}
|
2289
|
-
this.contextStore.addStep({
|
2290
|
-
type: "query",
|
2291
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
|
2292
|
-
data: output,
|
2293
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2294
|
-
});
|
2295
|
-
debug4("Added query step to context store:", {
|
2296
|
-
storageKey,
|
2297
|
-
totalStoredItems: Object.keys(this.contextStore.getAllData()).length,
|
2298
|
-
totalSteps: this.contextStore.getRecentSteps(100).length
|
2299
|
-
});
|
2300
|
-
} catch (error) {
|
2301
|
-
debug4("Failed to store query result:", error);
|
2302
|
-
}
|
2303
|
-
} else {
|
2304
|
-
try {
|
2305
|
-
this.contextStore.addStep({
|
2306
|
-
type: "query",
|
2307
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
|
2308
|
-
data: output,
|
2309
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2310
|
-
});
|
2311
|
-
} catch (error) {
|
2312
|
-
debug4("Failed to add query step:", error);
|
2313
|
-
}
|
2314
|
-
}
|
2315
|
-
}
|
2158
|
+
const { output, executor } = await this.taskExecutor.query(demand);
|
2316
2159
|
const metadata = this.afterTaskRunning(executor);
|
2317
2160
|
return {
|
2318
2161
|
result: output,
|
@@ -2422,31 +2265,6 @@ var PageAgent = class {
|
|
2422
2265
|
};
|
2423
2266
|
}
|
2424
2267
|
async aiAssert(assertion, msg, opt) {
|
2425
|
-
let processedAssertion = assertion;
|
2426
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2427
|
-
try {
|
2428
|
-
const originalAssertion = assertion;
|
2429
|
-
processedAssertion = this.contextStore.replaceAllReferences(assertion, "assertion");
|
2430
|
-
if (originalAssertion !== processedAssertion) {
|
2431
|
-
debug4("Context replacement in aiAssert:", {
|
2432
|
-
original: originalAssertion,
|
2433
|
-
processed: processedAssertion,
|
2434
|
-
context: "assertion",
|
2435
|
-
storedData: this.contextStore.getAllData()
|
2436
|
-
});
|
2437
|
-
}
|
2438
|
-
this.contextStore.addStep({
|
2439
|
-
type: "assertion",
|
2440
|
-
summary: `Assertion: ${processedAssertion}`,
|
2441
|
-
prompt: processedAssertion
|
2442
|
-
});
|
2443
|
-
debug4("Added assertion step to context store:", {
|
2444
|
-
totalSteps: this.contextStore.getRecentSteps(100).length
|
2445
|
-
});
|
2446
|
-
} catch (error) {
|
2447
|
-
debug4("Context store operation failed:", error);
|
2448
|
-
}
|
2449
|
-
}
|
2450
2268
|
let currentUrl = "";
|
2451
2269
|
if (this.page.url) {
|
2452
2270
|
try {
|
@@ -2454,7 +2272,7 @@ var PageAgent = class {
|
|
2454
2272
|
} catch (e) {
|
2455
2273
|
}
|
2456
2274
|
}
|
2457
|
-
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${
|
2275
|
+
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2458
2276
|
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2459
2277
|
const metadata = this.afterTaskRunning(executor, true);
|
2460
2278
|
if (output && opt?.keepRawResponse) {
|