dsh-browser-playwright-codex 0.7.8 → 0.8.1
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/CHANGELOG.md +92 -0
- package/NOTICE.md +26 -5
- package/README.md +33 -10
- package/assets/swarm-rebuild.js +3864 -0
- package/lib/browser-lifecycle.js +27 -1
- package/lib/challenge.d.ts +7 -4
- package/lib/challenge.js +28 -6
- package/lib/client.js +1245 -647
- package/lib/config.d.ts +26 -0
- package/lib/config.js +19 -0
- package/lib/errors.d.ts +17 -0
- package/lib/errors.js +28 -0
- package/lib/gates-patch.d.ts +41 -1
- package/lib/gates-patch.js +103 -5
- package/lib/injected.js +45 -0
- package/lib/page-actions.d.ts +24 -0
- package/lib/page-actions.js +73 -11
- package/lib/provider.js +8 -0
- package/lib/read-deadline.d.ts +5 -1
- package/lib/read-deadline.js +10 -3
- package/lib/runtime-state.d.ts +26 -0
- package/lib/runtime-state.js +100 -0
- package/lib/session.d.ts +11 -0
- package/lib/session.js +80 -11
- package/lib/settings-card.js +123 -0
- package/lib/snapshot-render.js +52 -7
- package/lib/swarm-contract.d.ts +232 -0
- package/lib/swarm-contract.js +215 -0
- package/lib/swarm-curtain.d.ts +22 -0
- package/lib/swarm-curtain.js +115 -0
- package/lib/swarm-intro.d.ts +66 -0
- package/lib/swarm-intro.js +829 -0
- package/lib/tool-types.d.ts +10 -0
- package/lib/tool.js +20 -6
- package/lib/types.d.ts +6 -0
- package/package.json +18 -13
package/lib/tool-types.d.ts
CHANGED
|
@@ -46,6 +46,16 @@ export interface ChallengeNode {
|
|
|
46
46
|
readonly name?: string;
|
|
47
47
|
/** Accessible role. Both built-in engines provide one; it gates the wording tier. */
|
|
48
48
|
readonly role?: string;
|
|
49
|
+
/** Whether a checkbox/radio is checked; present on toggles. */
|
|
50
|
+
readonly checked?: boolean;
|
|
51
|
+
/** Whether an option is selected; present on options. */
|
|
52
|
+
readonly selected?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Current value of a textbox/textarea/select. The no-progress fingerprint
|
|
55
|
+
* includes it so that filling a field registers as change — otherwise a
|
|
56
|
+
* normal fill looks like "no visible change" and trips the anti-bot guess.
|
|
57
|
+
*/
|
|
58
|
+
readonly value?: string;
|
|
49
59
|
readonly children?: readonly ChallengeNode[];
|
|
50
60
|
}
|
|
51
61
|
/** The slice of a snapshot the challenge detector reads. */
|
package/lib/tool.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import z from '@deepseek-ai/schemastery';
|
|
2
2
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
3
3
|
import { BlockAssembler, createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
4
|
-
import { BrowserError, cdpDisabled, evaluateDisabled } from "./errors.js";
|
|
4
|
+
import { BrowserError, cdpDisabled, evaluateDisabled, normalizeEvaluateResult } from "./errors.js";
|
|
5
5
|
import { registeredSuffixes } from "./contract.js";
|
|
6
6
|
import { getEnabled, publishGates, publishLoginSites } from "./runtime-state.js";
|
|
7
7
|
import { summarizeLoginSites } from "./login-sites.js";
|
|
@@ -138,13 +138,18 @@ export function apply(ctx, config) {
|
|
|
138
138
|
waitFor: {
|
|
139
139
|
type: 'string',
|
|
140
140
|
enum: ['load', 'domcontentloaded', 'networkidle'],
|
|
141
|
-
description: 'Load condition to wait for. Defaults to load
|
|
141
|
+
description: 'Load condition to wait for. Defaults to domcontentloaded; load never fires on long-polling or ' +
|
|
142
|
+
'download pages and hangs the call (issue #5).',
|
|
142
143
|
},
|
|
143
144
|
},
|
|
144
145
|
output: { schema: SNAPSHOT_SCHEMA, render: renderSnapshotValue },
|
|
145
146
|
async execute(args, exec) {
|
|
146
147
|
const session = await acquire(exec);
|
|
147
|
-
|
|
148
|
+
// domcontentloaded, not load: a page with an endless subresource (long
|
|
149
|
+
// poll, streaming download, ad frame that never settles) never reaches
|
|
150
|
+
// 'load', so the default burned the whole navigation timeout on pages
|
|
151
|
+
// that were perfectly usable already (issue #5).
|
|
152
|
+
const waitUntil = args.waitFor ?? 'domcontentloaded';
|
|
148
153
|
return snapshotValue(await session.navigate(args.url, waitUntil, exec.signal));
|
|
149
154
|
},
|
|
150
155
|
}));
|
|
@@ -435,13 +440,18 @@ export function apply(ctx, config) {
|
|
|
435
440
|
waitFor: {
|
|
436
441
|
type: 'string',
|
|
437
442
|
enum: ['load', 'domcontentloaded', 'networkidle'],
|
|
438
|
-
description: 'Load condition to wait for. Defaults to load
|
|
443
|
+
description: 'Load condition to wait for. Defaults to domcontentloaded; load never fires on long-polling or ' +
|
|
444
|
+
'download pages and hangs the call (issue #5).',
|
|
439
445
|
},
|
|
440
446
|
},
|
|
441
447
|
output: { schema: SNAPSHOT_SCHEMA, render: renderSnapshotValue },
|
|
442
448
|
async execute(args, exec) {
|
|
443
449
|
const session = await acquire(exec);
|
|
444
|
-
|
|
450
|
+
// domcontentloaded, not load: a page with an endless subresource (long
|
|
451
|
+
// poll, streaming download, ad frame that never settles) never reaches
|
|
452
|
+
// 'load', so the default burned the whole navigation timeout on pages
|
|
453
|
+
// that were perfectly usable already (issue #5).
|
|
454
|
+
const waitUntil = args.waitFor ?? 'domcontentloaded';
|
|
445
455
|
return snapshotValue(await session.openTab(args.url, waitUntil, exec.signal));
|
|
446
456
|
},
|
|
447
457
|
}));
|
|
@@ -553,6 +563,9 @@ export function apply(ctx, config) {
|
|
|
553
563
|
registerMaybe('evaluate', defineTool({
|
|
554
564
|
name: p('evaluate'),
|
|
555
565
|
description: 'Evaluate one JavaScript expression in the page and return its JSON-serializable result. ' +
|
|
566
|
+
'Return value rules: an object, string, number, boolean or null comes back as-is; ' +
|
|
567
|
+
'a top-level ARRAY, undefined or a function is returned as a JSON string with a note saying it was converted ' +
|
|
568
|
+
'(wrap it yourself, e.g. {items: [...]} , if you need the array shape). ' +
|
|
556
569
|
'Disabled by default; the deployment must enable allowEvaluate. ' +
|
|
557
570
|
'IRON RULE: prefer read-only expressions to INSPECT state (value, outerHTML, checked, textContent) before ' +
|
|
558
571
|
'concluding an interaction failed. If you write to the DOM directly (setting value/textContent), ' +
|
|
@@ -580,7 +593,8 @@ export function apply(ctx, config) {
|
|
|
580
593
|
throw evaluateDisabled();
|
|
581
594
|
}
|
|
582
595
|
const session = await acquire(exec);
|
|
583
|
-
|
|
596
|
+
const raw = await session.evaluate(args.expression, exec.signal);
|
|
597
|
+
return normalizeEvaluateResult(raw);
|
|
584
598
|
},
|
|
585
599
|
}));
|
|
586
600
|
registerMaybe('cdp', defineTool({
|
package/lib/types.d.ts
CHANGED
|
@@ -21,6 +21,12 @@ export interface BrowserNode {
|
|
|
21
21
|
readonly selected?: boolean;
|
|
22
22
|
/** Whether the element is disabled. */
|
|
23
23
|
readonly disabled?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Current value of a textbox, textarea or select, clipped to the snapshot's
|
|
26
|
+
* text budget. Present so the model can see what a fill actually left behind
|
|
27
|
+
* and so the no-progress fingerprint registers a value change as change.
|
|
28
|
+
*/
|
|
29
|
+
readonly value?: string;
|
|
24
30
|
/** Href for links; present when the page is same-origin. */
|
|
25
31
|
readonly href?: string;
|
|
26
32
|
readonly children: readonly BrowserNode[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-browser-playwright-codex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Browser automation for DeepSeek Harness, one plugin: fill in forms, scrape lists and work across tabs in real pages, using the logins you already have. Runs in a visible window that stays quiet when minimised; native dialogs are parked instead of confirmed, CAPTCHA pages are flagged with a note that says stop and hand the page back, password / one-time-code / card fields are refused by browser_fill, and the Settings card (enable/disable, page-reading mode, capability gates) now lives inside this package.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -44,6 +44,8 @@
|
|
|
44
44
|
"CHANGELOG.md",
|
|
45
45
|
"SECURITY.md",
|
|
46
46
|
"NOTICE.md",
|
|
47
|
+
"assets",
|
|
48
|
+
"!assets/swarm-rebuild.upstream.js",
|
|
47
49
|
"locale",
|
|
48
50
|
"scripts/doctor.mjs",
|
|
49
51
|
"scripts/dsh-browser-verify.mjs"
|
|
@@ -57,10 +59,12 @@
|
|
|
57
59
|
"verify": "npm run build && node scripts/dsh-browser-verify.mjs",
|
|
58
60
|
"verify:live": "npm run build && node scripts/dsh-browser-verify.mjs --live",
|
|
59
61
|
"doctor": "node scripts/doctor.mjs",
|
|
62
|
+
"swarm:patch": "node scripts/swarm-patch.mjs",
|
|
63
|
+
"swarm:check": "node scripts/swarm-patch.mjs --check",
|
|
60
64
|
"cost": "node node_modules/tsx/dist/cli.mjs scripts/measure-prompt-cost.mjs",
|
|
61
65
|
"format": "node node_modules/prettier/bin/prettier.cjs --write \"src/**/*.ts\" \"tests/**/*.ts\" \"scripts/**/*.mjs\"",
|
|
62
66
|
"format:check": "node node_modules/prettier/bin/prettier.cjs --check \"src/**/*.ts\" \"tests/**/*.ts\" \"scripts/**/*.mjs\"",
|
|
63
|
-
"prepublishOnly": "npm run build && npm run typecheck && npm test && npm run verify && npm run preflight",
|
|
67
|
+
"prepublishOnly": "npm run build && npm run typecheck && npm test && npm run swarm:check && npm run verify && npm run preflight",
|
|
64
68
|
"preflight": "node scripts/preflight.mjs ."
|
|
65
69
|
},
|
|
66
70
|
"dependencies": {
|
|
@@ -68,19 +72,20 @@
|
|
|
68
72
|
"playwright-core": "~1.62.1"
|
|
69
73
|
},
|
|
70
74
|
"peerDependencies": {
|
|
71
|
-
"@deepseek-ai/cordis": ">=4.0
|
|
72
|
-
"@deepseek-ai/dsh-llm": ">=0.2.
|
|
73
|
-
"@deepseek-ai/dsh-tools": ">=0.2.
|
|
75
|
+
"@deepseek-ai/cordis": ">=4.1.0",
|
|
76
|
+
"@deepseek-ai/dsh-llm": ">=0.2.2-rc.1",
|
|
77
|
+
"@deepseek-ai/dsh-tools": ">=0.2.2-rc.1"
|
|
74
78
|
},
|
|
75
79
|
"devDependencies": {
|
|
76
|
-
"@deepseek-ai/cordis": "4.0
|
|
77
|
-
"@deepseek-ai/dsh-agent": "0.2.
|
|
78
|
-
"@deepseek-ai/dsh-attachment": "0.2.
|
|
79
|
-
"@deepseek-ai/dsh-llm": "0.2.
|
|
80
|
-
"@deepseek-ai/dsh-session": "0.2.
|
|
81
|
-
"@deepseek-ai/dsh-system-prompt": "0.2.
|
|
82
|
-
"@deepseek-ai/dsh-tools": "0.2.
|
|
83
|
-
"@deepseek-ai/
|
|
80
|
+
"@deepseek-ai/cordis": "4.1.0",
|
|
81
|
+
"@deepseek-ai/dsh-agent": "0.2.2-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-attachment": "0.2.2-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-llm": "0.2.2-rc.1",
|
|
84
|
+
"@deepseek-ai/dsh-session": "0.2.2-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-system-prompt": "0.2.2-rc.1",
|
|
86
|
+
"@deepseek-ai/dsh-tools": "0.2.2-rc.1",
|
|
87
|
+
"@deepseek-ai/dsh-tool-executor-native": "0.2.2-rc.1",
|
|
88
|
+
"@deepseek-ai/schemastery": "3.19.0",
|
|
84
89
|
"@types/node": "^24.13.3",
|
|
85
90
|
"prettier": "^3.9.9",
|
|
86
91
|
"tsx": "^4.20.0",
|