@predicatelabs/sdk 0.99.9
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 +24 -0
- package/README.md +252 -0
- package/dist/actions.d.ts +185 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +1120 -0
- package/dist/actions.js.map +1 -0
- package/dist/agent-runtime.d.ts +352 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +1170 -0
- package/dist/agent-runtime.js.map +1 -0
- package/dist/agent.d.ts +164 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +408 -0
- package/dist/agent.js.map +1 -0
- package/dist/asserts/expect.d.ts +159 -0
- package/dist/asserts/expect.d.ts.map +1 -0
- package/dist/asserts/expect.js +547 -0
- package/dist/asserts/expect.js.map +1 -0
- package/dist/asserts/index.d.ts +58 -0
- package/dist/asserts/index.d.ts.map +1 -0
- package/dist/asserts/index.js +70 -0
- package/dist/asserts/index.js.map +1 -0
- package/dist/asserts/query.d.ts +199 -0
- package/dist/asserts/query.d.ts.map +1 -0
- package/dist/asserts/query.js +288 -0
- package/dist/asserts/query.js.map +1 -0
- package/dist/backends/actions.d.ts +119 -0
- package/dist/backends/actions.d.ts.map +1 -0
- package/dist/backends/actions.js +291 -0
- package/dist/backends/actions.js.map +1 -0
- package/dist/backends/browser-use-adapter.d.ts +131 -0
- package/dist/backends/browser-use-adapter.d.ts.map +1 -0
- package/dist/backends/browser-use-adapter.js +219 -0
- package/dist/backends/browser-use-adapter.js.map +1 -0
- package/dist/backends/cdp-backend.d.ts +66 -0
- package/dist/backends/cdp-backend.d.ts.map +1 -0
- package/dist/backends/cdp-backend.js +273 -0
- package/dist/backends/cdp-backend.js.map +1 -0
- package/dist/backends/index.d.ts +80 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +101 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/protocol.d.ts +156 -0
- package/dist/backends/protocol.d.ts.map +1 -0
- package/dist/backends/protocol.js +16 -0
- package/dist/backends/protocol.js.map +1 -0
- package/dist/backends/sentience-context.d.ts +143 -0
- package/dist/backends/sentience-context.d.ts.map +1 -0
- package/dist/backends/sentience-context.js +359 -0
- package/dist/backends/sentience-context.js.map +1 -0
- package/dist/backends/snapshot.d.ts +188 -0
- package/dist/backends/snapshot.d.ts.map +1 -0
- package/dist/backends/snapshot.js +360 -0
- package/dist/backends/snapshot.js.map +1 -0
- package/dist/browser.d.ts +154 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +920 -0
- package/dist/browser.js.map +1 -0
- package/dist/canonicalization.d.ts +126 -0
- package/dist/canonicalization.d.ts.map +1 -0
- package/dist/canonicalization.js +161 -0
- package/dist/canonicalization.js.map +1 -0
- package/dist/captcha/strategies.d.ts +12 -0
- package/dist/captcha/strategies.d.ts.map +1 -0
- package/dist/captcha/strategies.js +43 -0
- package/dist/captcha/strategies.js.map +1 -0
- package/dist/captcha/types.d.ts +45 -0
- package/dist/captcha/types.d.ts.map +1 -0
- package/dist/captcha/types.js +12 -0
- package/dist/captcha/types.js.map +1 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +422 -0
- package/dist/cli.js.map +1 -0
- package/dist/conversational-agent.d.ts +123 -0
- package/dist/conversational-agent.d.ts.map +1 -0
- package/dist/conversational-agent.js +341 -0
- package/dist/conversational-agent.js.map +1 -0
- package/dist/cursor-policy.d.ts +41 -0
- package/dist/cursor-policy.d.ts.map +1 -0
- package/dist/cursor-policy.js +81 -0
- package/dist/cursor-policy.js.map +1 -0
- package/dist/debugger.d.ts +28 -0
- package/dist/debugger.d.ts.map +1 -0
- package/dist/debugger.js +107 -0
- package/dist/debugger.js.map +1 -0
- package/dist/expect.d.ts +16 -0
- package/dist/expect.d.ts.map +1 -0
- package/dist/expect.js +67 -0
- package/dist/expect.js.map +1 -0
- package/dist/failure-artifacts.d.ts +95 -0
- package/dist/failure-artifacts.d.ts.map +1 -0
- package/dist/failure-artifacts.js +805 -0
- package/dist/failure-artifacts.js.map +1 -0
- package/dist/generator.d.ts +16 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +205 -0
- package/dist/generator.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +160 -0
- package/dist/index.js.map +1 -0
- package/dist/inspector.d.ts +13 -0
- package/dist/inspector.d.ts.map +1 -0
- package/dist/inspector.js +153 -0
- package/dist/inspector.js.map +1 -0
- package/dist/llm-provider.d.ts +144 -0
- package/dist/llm-provider.d.ts.map +1 -0
- package/dist/llm-provider.js +460 -0
- package/dist/llm-provider.js.map +1 -0
- package/dist/ordinal.d.ts +90 -0
- package/dist/ordinal.d.ts.map +1 -0
- package/dist/ordinal.js +249 -0
- package/dist/ordinal.js.map +1 -0
- package/dist/overlay.d.ts +63 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +102 -0
- package/dist/overlay.js.map +1 -0
- package/dist/protocols/browser-protocol.d.ts +79 -0
- package/dist/protocols/browser-protocol.d.ts.map +1 -0
- package/dist/protocols/browser-protocol.js +9 -0
- package/dist/protocols/browser-protocol.js.map +1 -0
- package/dist/query.d.ts +66 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +482 -0
- package/dist/query.js.map +1 -0
- package/dist/read.d.ts +47 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/read.js +128 -0
- package/dist/read.js.map +1 -0
- package/dist/recorder.d.ts +44 -0
- package/dist/recorder.d.ts.map +1 -0
- package/dist/recorder.js +262 -0
- package/dist/recorder.js.map +1 -0
- package/dist/runtime-agent.d.ts +72 -0
- package/dist/runtime-agent.d.ts.map +1 -0
- package/dist/runtime-agent.js +357 -0
- package/dist/runtime-agent.js.map +1 -0
- package/dist/screenshot.d.ts +17 -0
- package/dist/screenshot.d.ts.map +1 -0
- package/dist/screenshot.js +40 -0
- package/dist/screenshot.js.map +1 -0
- package/dist/snapshot-diff.d.ts +23 -0
- package/dist/snapshot-diff.d.ts.map +1 -0
- package/dist/snapshot-diff.js +119 -0
- package/dist/snapshot-diff.js.map +1 -0
- package/dist/snapshot.d.ts +47 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +358 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/textSearch.d.ts +64 -0
- package/dist/textSearch.d.ts.map +1 -0
- package/dist/textSearch.js +113 -0
- package/dist/textSearch.js.map +1 -0
- package/dist/tools/context.d.ts +18 -0
- package/dist/tools/context.d.ts.map +1 -0
- package/dist/tools/context.js +40 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/defaults.d.ts +5 -0
- package/dist/tools/defaults.d.ts.map +1 -0
- package/dist/tools/defaults.js +368 -0
- package/dist/tools/defaults.js.map +1 -0
- package/dist/tools/filesystem.d.ts +12 -0
- package/dist/tools/filesystem.d.ts.map +1 -0
- package/dist/tools/filesystem.js +137 -0
- package/dist/tools/filesystem.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +15 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +38 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +100 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tracing/cloud-sink.d.ts +189 -0
- package/dist/tracing/cloud-sink.d.ts.map +1 -0
- package/dist/tracing/cloud-sink.js +1067 -0
- package/dist/tracing/cloud-sink.js.map +1 -0
- package/dist/tracing/index-schema.d.ts +231 -0
- package/dist/tracing/index-schema.d.ts.map +1 -0
- package/dist/tracing/index-schema.js +235 -0
- package/dist/tracing/index-schema.js.map +1 -0
- package/dist/tracing/index.d.ts +12 -0
- package/dist/tracing/index.d.ts.map +1 -0
- package/dist/tracing/index.js +28 -0
- package/dist/tracing/index.js.map +1 -0
- package/dist/tracing/indexer.d.ts +20 -0
- package/dist/tracing/indexer.d.ts.map +1 -0
- package/dist/tracing/indexer.js +347 -0
- package/dist/tracing/indexer.js.map +1 -0
- package/dist/tracing/jsonl-sink.d.ts +51 -0
- package/dist/tracing/jsonl-sink.d.ts.map +1 -0
- package/dist/tracing/jsonl-sink.js +329 -0
- package/dist/tracing/jsonl-sink.js.map +1 -0
- package/dist/tracing/sink.d.ts +25 -0
- package/dist/tracing/sink.d.ts.map +1 -0
- package/dist/tracing/sink.js +15 -0
- package/dist/tracing/sink.js.map +1 -0
- package/dist/tracing/tracer-factory.d.ts +102 -0
- package/dist/tracing/tracer-factory.d.ts.map +1 -0
- package/dist/tracing/tracer-factory.js +375 -0
- package/dist/tracing/tracer-factory.js.map +1 -0
- package/dist/tracing/tracer.d.ts +140 -0
- package/dist/tracing/tracer.d.ts.map +1 -0
- package/dist/tracing/tracer.js +336 -0
- package/dist/tracing/tracer.js.map +1 -0
- package/dist/tracing/types.d.ts +203 -0
- package/dist/tracing/types.d.ts.map +1 -0
- package/dist/tracing/types.js +8 -0
- package/dist/tracing/types.js.map +1 -0
- package/dist/types.d.ts +422 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/action-executor.d.ts +25 -0
- package/dist/utils/action-executor.d.ts.map +1 -0
- package/dist/utils/action-executor.js +121 -0
- package/dist/utils/action-executor.js.map +1 -0
- package/dist/utils/browser-evaluator.d.ts +76 -0
- package/dist/utils/browser-evaluator.d.ts.map +1 -0
- package/dist/utils/browser-evaluator.js +130 -0
- package/dist/utils/browser-evaluator.js.map +1 -0
- package/dist/utils/browser.d.ts +30 -0
- package/dist/utils/browser.d.ts.map +1 -0
- package/dist/utils/browser.js +75 -0
- package/dist/utils/browser.js.map +1 -0
- package/dist/utils/element-filter.d.ts +76 -0
- package/dist/utils/element-filter.d.ts.map +1 -0
- package/dist/utils/element-filter.js +195 -0
- package/dist/utils/element-filter.js.map +1 -0
- package/dist/utils/grid-utils.d.ts +37 -0
- package/dist/utils/grid-utils.d.ts.map +1 -0
- package/dist/utils/grid-utils.js +283 -0
- package/dist/utils/grid-utils.js.map +1 -0
- package/dist/utils/llm-interaction-handler.d.ts +41 -0
- package/dist/utils/llm-interaction-handler.d.ts.map +1 -0
- package/dist/utils/llm-interaction-handler.js +171 -0
- package/dist/utils/llm-interaction-handler.js.map +1 -0
- package/dist/utils/llm-response-builder.d.ts +56 -0
- package/dist/utils/llm-response-builder.d.ts.map +1 -0
- package/dist/utils/llm-response-builder.js +130 -0
- package/dist/utils/llm-response-builder.js.map +1 -0
- package/dist/utils/selector-utils.d.ts +12 -0
- package/dist/utils/selector-utils.d.ts.map +1 -0
- package/dist/utils/selector-utils.js +32 -0
- package/dist/utils/selector-utils.js.map +1 -0
- package/dist/utils/snapshot-event-builder.d.ts +28 -0
- package/dist/utils/snapshot-event-builder.d.ts.map +1 -0
- package/dist/utils/snapshot-event-builder.js +88 -0
- package/dist/utils/snapshot-event-builder.js.map +1 -0
- package/dist/utils/snapshot-processor.d.ts +27 -0
- package/dist/utils/snapshot-processor.d.ts.map +1 -0
- package/dist/utils/snapshot-processor.js +47 -0
- package/dist/utils/snapshot-processor.js.map +1 -0
- package/dist/utils/trace-event-builder.d.ts +122 -0
- package/dist/utils/trace-event-builder.d.ts.map +1 -0
- package/dist/utils/trace-event-builder.js +365 -0
- package/dist/utils/trace-event-builder.js.map +1 -0
- package/dist/utils/trace-file-manager.d.ts +70 -0
- package/dist/utils/trace-file-manager.d.ts.map +1 -0
- package/dist/utils/trace-file-manager.js +194 -0
- package/dist/utils/trace-file-manager.js.map +1 -0
- package/dist/utils/zod.d.ts +5 -0
- package/dist/utils/zod.d.ts.map +1 -0
- package/dist/utils/zod.js +80 -0
- package/dist/utils/zod.js.map +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +13 -0
- package/dist/utils.js.map +1 -0
- package/dist/verification.d.ts +194 -0
- package/dist/verification.d.ts.map +1 -0
- package/dist/verification.js +530 -0
- package/dist/verification.js.map +1 -0
- package/dist/vision-executor.d.ts +18 -0
- package/dist/vision-executor.d.ts.map +1 -0
- package/dist/vision-executor.js +60 -0
- package/dist/vision-executor.js.map +1 -0
- package/dist/visual-agent.d.ts +120 -0
- package/dist/visual-agent.d.ts.map +1 -0
- package/dist/visual-agent.js +796 -0
- package/dist/visual-agent.js.map +1 -0
- package/dist/wait.d.ts +35 -0
- package/dist/wait.d.ts.map +1 -0
- package/dist/wait.js +76 -0
- package/dist/wait.js.map +1 -0
- package/package.json +94 -0
- package/spec/README.md +72 -0
- package/spec/SNAPSHOT_V1.md +208 -0
- package/spec/sdk-types.md +259 -0
- package/spec/snapshot.schema.json +148 -0
- package/src/extension/background.js +104 -0
- package/src/extension/content.js +162 -0
- package/src/extension/injected_api.js +1399 -0
- package/src/extension/manifest.json +36 -0
- package/src/extension/pkg/README.md +1340 -0
- package/src/extension/pkg/package.json +15 -0
- package/src/extension/pkg/sentience_core.d.ts +51 -0
- package/src/extension/pkg/sentience_core.js +371 -0
- package/src/extension/pkg/sentience_core_bg.wasm +0 -0
- package/src/extension/pkg/sentience_core_bg.wasm.d.ts +10 -0
- package/src/extension/release.json +116 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AgentRuntime-backed agent with optional vision executor fallback.
|
|
4
|
+
*
|
|
5
|
+
* This keeps the control plane verification-first:
|
|
6
|
+
* - Actions may be proposed by either a structured executor (DOM snapshot prompt)
|
|
7
|
+
* or a vision executor (screenshot prompt).
|
|
8
|
+
* - Verification is always executed via AgentRuntime predicates.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.RuntimeAgent = void 0;
|
|
12
|
+
const llm_interaction_handler_1 = require("./utils/llm-interaction-handler");
|
|
13
|
+
class RuntimeAgent {
|
|
14
|
+
constructor(opts) {
|
|
15
|
+
this.runtime = opts.runtime;
|
|
16
|
+
this.executor = opts.executor;
|
|
17
|
+
this.visionExecutor = opts.visionExecutor;
|
|
18
|
+
this.visionVerifier = opts.visionVerifier;
|
|
19
|
+
this.shortCircuitCanvas = opts.shortCircuitCanvas ?? true;
|
|
20
|
+
this.structuredLLM = new llm_interaction_handler_1.LLMInteractionHandler(this.executor, false);
|
|
21
|
+
}
|
|
22
|
+
async runStep(opts) {
|
|
23
|
+
const { taskGoal, step, onStepStart, onStepEnd } = opts;
|
|
24
|
+
const stepId = this.runtime.beginStep(step.goal);
|
|
25
|
+
await this.runHook(onStepStart, {
|
|
26
|
+
stepId,
|
|
27
|
+
stepIndex: this.runtime.stepIndex,
|
|
28
|
+
goal: step.goal,
|
|
29
|
+
attempt: 0,
|
|
30
|
+
url: this.runtime.lastSnapshot?.url ?? this.runtime.page?.url?.() ?? null,
|
|
31
|
+
});
|
|
32
|
+
let ok = false;
|
|
33
|
+
let emitted = false;
|
|
34
|
+
let outcome = null;
|
|
35
|
+
let errorMessage = null;
|
|
36
|
+
try {
|
|
37
|
+
const snap = await this.snapshotWithRamp(step);
|
|
38
|
+
if (await this.shouldShortCircuitToVision(step, snap)) {
|
|
39
|
+
ok = await this.visionExecutorAttempt({ taskGoal, step, snap });
|
|
40
|
+
outcome = ok ? 'ok' : 'verification_failed';
|
|
41
|
+
return ok;
|
|
42
|
+
}
|
|
43
|
+
// 1) Structured executor attempt.
|
|
44
|
+
const action = await this.proposeStructuredAction({ taskGoal, step, snap });
|
|
45
|
+
await this.executeAction(action, snap);
|
|
46
|
+
ok = await this.applyVerifications(step);
|
|
47
|
+
if (ok) {
|
|
48
|
+
outcome = 'ok';
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
// 2) Optional vision executor fallback (bounded).
|
|
52
|
+
const enabled = step.visionExecutorEnabled ?? true;
|
|
53
|
+
const maxAttempts = step.maxVisionExecutorAttempts ?? 1;
|
|
54
|
+
if (enabled && maxAttempts > 0) {
|
|
55
|
+
ok = await this.visionExecutorAttempt({ taskGoal, step, snap });
|
|
56
|
+
outcome = ok ? 'ok' : 'verification_failed';
|
|
57
|
+
return ok;
|
|
58
|
+
}
|
|
59
|
+
outcome = 'verification_failed';
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
errorMessage = String(error?.message ?? error);
|
|
64
|
+
outcome = 'exception';
|
|
65
|
+
this.runtime.emitStepEnd({
|
|
66
|
+
success: false,
|
|
67
|
+
verifyPassed: false,
|
|
68
|
+
error: errorMessage,
|
|
69
|
+
outcome: 'exception',
|
|
70
|
+
});
|
|
71
|
+
emitted = true;
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
if (!emitted) {
|
|
76
|
+
this.runtime.emitStepEnd({
|
|
77
|
+
success: ok,
|
|
78
|
+
verifyPassed: ok,
|
|
79
|
+
outcome: ok ? 'ok' : 'verification_failed',
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
await this.runHook(onStepEnd, {
|
|
83
|
+
stepId,
|
|
84
|
+
stepIndex: this.runtime.stepIndex,
|
|
85
|
+
goal: step.goal,
|
|
86
|
+
attempt: 0,
|
|
87
|
+
url: this.runtime.lastSnapshot?.url ?? this.runtime.page?.url?.() ?? null,
|
|
88
|
+
success: ok,
|
|
89
|
+
outcome,
|
|
90
|
+
error: errorMessage,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async runHook(hook, ctx) {
|
|
95
|
+
if (!hook)
|
|
96
|
+
return;
|
|
97
|
+
try {
|
|
98
|
+
await Promise.resolve(hook(ctx));
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// best-effort hook; ignore errors
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async snapshotWithRamp(step) {
|
|
105
|
+
const base = step.snapshotLimitBase ?? 60;
|
|
106
|
+
const stepInc = step.snapshotLimitStep ?? 40;
|
|
107
|
+
const max = step.snapshotLimitMax ?? 220;
|
|
108
|
+
const attempts = Math.max(1, step.maxSnapshotAttempts ?? 3);
|
|
109
|
+
const minConf = step.minConfidence;
|
|
110
|
+
const minActionables = step.minActionables;
|
|
111
|
+
let limit = base;
|
|
112
|
+
let last = null;
|
|
113
|
+
for (let i = 0; i < attempts; i++) {
|
|
114
|
+
last = await this.runtime.snapshot({ limit, goal: step.goal });
|
|
115
|
+
if (typeof minConf === 'number') {
|
|
116
|
+
const conf = last?.diagnostics?.confidence;
|
|
117
|
+
if (typeof conf === 'number' && Number.isFinite(conf) && conf < minConf) {
|
|
118
|
+
limit = Math.min(max, limit + stepInc);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (typeof minActionables === 'number') {
|
|
123
|
+
if (this.countActionables(last) < minActionables) {
|
|
124
|
+
limit = Math.min(max, limit + stepInc);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return last;
|
|
129
|
+
}
|
|
130
|
+
if (!last)
|
|
131
|
+
throw new Error('snapshot() returned null/undefined repeatedly');
|
|
132
|
+
return last;
|
|
133
|
+
}
|
|
134
|
+
async proposeStructuredAction(opts) {
|
|
135
|
+
const { taskGoal, step, snap } = opts;
|
|
136
|
+
const domContext = this.structuredLLM.buildContext(snap, step.goal);
|
|
137
|
+
const combinedGoal = `${taskGoal}\n\nSTEP: ${step.goal}`;
|
|
138
|
+
const resp = await this.structuredLLM.queryLLM(domContext, combinedGoal);
|
|
139
|
+
return this.extractActionFromText(resp.content);
|
|
140
|
+
}
|
|
141
|
+
async visionExecutorAttempt(opts) {
|
|
142
|
+
const { taskGoal, step, snap } = opts;
|
|
143
|
+
const provider = this.visionExecutor;
|
|
144
|
+
if (!provider || !provider.supportsVision?.())
|
|
145
|
+
return false;
|
|
146
|
+
const url = this.runtime.page?.url?.() ?? snap?.url ?? '(unknown)';
|
|
147
|
+
const buf = (await this.runtime.page.screenshot({ type: 'png' }));
|
|
148
|
+
const imageBase64 = Buffer.from(buf).toString('base64');
|
|
149
|
+
const { systemPrompt, userPrompt } = this.visionExecutorPrompts({
|
|
150
|
+
taskGoal,
|
|
151
|
+
step,
|
|
152
|
+
url,
|
|
153
|
+
snap,
|
|
154
|
+
});
|
|
155
|
+
const resp = await provider.generateWithImage(systemPrompt, userPrompt, imageBase64, {
|
|
156
|
+
temperature: 0.0,
|
|
157
|
+
});
|
|
158
|
+
const action = this.extractActionFromText(resp.content);
|
|
159
|
+
await this.executeAction(action, snap ?? undefined);
|
|
160
|
+
// This is a retry of the same step; clear prior step assertions.
|
|
161
|
+
this.runtime.flushAssertions();
|
|
162
|
+
return await this.applyVerifications(step);
|
|
163
|
+
}
|
|
164
|
+
async applyVerifications(step) {
|
|
165
|
+
const verifications = step.verifications ?? [];
|
|
166
|
+
if (verifications.length === 0)
|
|
167
|
+
return true;
|
|
168
|
+
let allOk = true;
|
|
169
|
+
for (const v of verifications) {
|
|
170
|
+
const required = v.required ?? true;
|
|
171
|
+
const eventually = v.eventually ?? true;
|
|
172
|
+
let ok;
|
|
173
|
+
if (eventually) {
|
|
174
|
+
ok = await this.runtime.check(v.predicate, v.label, required).eventually({
|
|
175
|
+
timeoutMs: v.timeoutMs ?? 10000,
|
|
176
|
+
pollMs: v.pollMs ?? 250,
|
|
177
|
+
minConfidence: v.minConfidence,
|
|
178
|
+
maxSnapshotAttempts: v.maxSnapshotAttempts,
|
|
179
|
+
visionProvider: this.visionVerifier,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
ok = this.runtime.assert(v.predicate, v.label, required);
|
|
184
|
+
}
|
|
185
|
+
allOk = allOk && ok;
|
|
186
|
+
}
|
|
187
|
+
return this.runtime.requiredAssertionsPassed() && allOk;
|
|
188
|
+
}
|
|
189
|
+
async executeAction(action, snap) {
|
|
190
|
+
const url = this.runtime.page?.url?.() ?? snap?.url;
|
|
191
|
+
await this.runtime.recordAction(action, url);
|
|
192
|
+
const parsed = this.parseAction(action);
|
|
193
|
+
if (parsed.kind === 'finish')
|
|
194
|
+
return;
|
|
195
|
+
if (parsed.kind === 'press') {
|
|
196
|
+
await this.runtime.page.keyboard.press(parsed.key);
|
|
197
|
+
await this.stabilizeBestEffort();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (parsed.kind === 'click_xy') {
|
|
201
|
+
await this.runtime.page.mouse.click(parsed.x, parsed.y);
|
|
202
|
+
await this.stabilizeBestEffort();
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (parsed.kind === 'click_rect') {
|
|
206
|
+
const x = parsed.x + parsed.w / 2;
|
|
207
|
+
const y = parsed.y + parsed.h / 2;
|
|
208
|
+
await this.runtime.page.mouse.click(x, y);
|
|
209
|
+
await this.stabilizeBestEffort();
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (!snap)
|
|
213
|
+
throw new Error('Cannot execute CLICK(id)/TYPE(id, ...) without a snapshot');
|
|
214
|
+
if (parsed.kind === 'click_id') {
|
|
215
|
+
const el = this.findElement(snap, parsed.id);
|
|
216
|
+
if (!el)
|
|
217
|
+
throw new Error(`Element id ${parsed.id} not found in snapshot`);
|
|
218
|
+
await this.clickBBox(el.bbox);
|
|
219
|
+
await this.stabilizeBestEffort();
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (parsed.kind === 'type_id') {
|
|
223
|
+
const el = this.findElement(snap, parsed.id);
|
|
224
|
+
if (!el)
|
|
225
|
+
throw new Error(`Element id ${parsed.id} not found in snapshot`);
|
|
226
|
+
await this.clickBBox(el.bbox);
|
|
227
|
+
await this.runtime.page.keyboard.type(parsed.text);
|
|
228
|
+
await this.stabilizeBestEffort();
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async stabilizeBestEffort() {
|
|
233
|
+
try {
|
|
234
|
+
await this.runtime.page.waitForTimeout(50);
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
// best-effort
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
clickBBox(bbox) {
|
|
241
|
+
const x = bbox.x + bbox.width / 2;
|
|
242
|
+
const y = bbox.y + bbox.height / 2;
|
|
243
|
+
return this.runtime.page.mouse.click(x, y);
|
|
244
|
+
}
|
|
245
|
+
findElement(snap, id) {
|
|
246
|
+
return snap.elements.find(e => e.id === id);
|
|
247
|
+
}
|
|
248
|
+
countActionables(snap) {
|
|
249
|
+
let n = 0;
|
|
250
|
+
for (const el of snap.elements ?? []) {
|
|
251
|
+
if (el.visual_cues?.is_clickable)
|
|
252
|
+
n += 1;
|
|
253
|
+
}
|
|
254
|
+
return n;
|
|
255
|
+
}
|
|
256
|
+
async shouldShortCircuitToVision(step, snap) {
|
|
257
|
+
const enabled = step.visionExecutorEnabled ?? true;
|
|
258
|
+
if (!enabled)
|
|
259
|
+
return false;
|
|
260
|
+
if (!this.visionExecutor || !this.visionExecutor.supportsVision?.())
|
|
261
|
+
return false;
|
|
262
|
+
if (!snap)
|
|
263
|
+
return true;
|
|
264
|
+
const minActionables = step.minActionables;
|
|
265
|
+
if (typeof minActionables === 'number' && this.countActionables(snap) < minActionables) {
|
|
266
|
+
if (this.shortCircuitCanvas) {
|
|
267
|
+
try {
|
|
268
|
+
const n = await this.runtime.page.evaluate("document.querySelectorAll('canvas').length");
|
|
269
|
+
if (typeof n === 'number' && n > 0)
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// ignore
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
visionExecutorPrompts(opts) {
|
|
280
|
+
const verifyTargets = this.verificationTargetsHuman(opts.step.verifications ?? []);
|
|
281
|
+
const snapshotSummary = opts.snap
|
|
282
|
+
? `\n\nStructured snapshot summary:\n- url: ${opts.snap.url}\n- elements: ${opts.snap.elements?.length ?? 0}\n`
|
|
283
|
+
: '';
|
|
284
|
+
const systemPrompt = `You are a vision-capable web automation executor.
|
|
285
|
+
|
|
286
|
+
TASK GOAL:
|
|
287
|
+
${opts.taskGoal}
|
|
288
|
+
|
|
289
|
+
STEP GOAL:
|
|
290
|
+
${opts.step.goal}
|
|
291
|
+
|
|
292
|
+
CURRENT URL (text):
|
|
293
|
+
${opts.url || '(unknown)'}
|
|
294
|
+
|
|
295
|
+
VERIFICATION TARGETS (text):
|
|
296
|
+
${verifyTargets || '(none provided)'}${snapshotSummary}
|
|
297
|
+
|
|
298
|
+
RESPONSE FORMAT:
|
|
299
|
+
Return ONLY ONE of:
|
|
300
|
+
- CLICK(id)
|
|
301
|
+
- TYPE(id, "text")
|
|
302
|
+
- CLICK_XY(x, y)
|
|
303
|
+
- CLICK_RECT(x, y, w, h)
|
|
304
|
+
- PRESS("key")
|
|
305
|
+
- FINISH()
|
|
306
|
+
|
|
307
|
+
No explanations, no markdown.
|
|
308
|
+
`;
|
|
309
|
+
return {
|
|
310
|
+
systemPrompt,
|
|
311
|
+
userPrompt: 'From the screenshot, return the single best next action:',
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
verificationTargetsHuman(verifications) {
|
|
315
|
+
if (!verifications.length)
|
|
316
|
+
return '';
|
|
317
|
+
return verifications
|
|
318
|
+
.map(v => `- ${v.label} (${(v.required ?? true) ? 'required' : 'optional'})`)
|
|
319
|
+
.join('\n');
|
|
320
|
+
}
|
|
321
|
+
parseAction(action) {
|
|
322
|
+
const s = action.trim();
|
|
323
|
+
if (/^FINISH\s*\(\s*\)\s*$/i.test(s))
|
|
324
|
+
return { kind: 'finish' };
|
|
325
|
+
const mXY = s.match(/^CLICK_XY\s*\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\)\s*$/i);
|
|
326
|
+
if (mXY)
|
|
327
|
+
return { kind: 'click_xy', x: Number(mXY[1]), y: Number(mXY[2]) };
|
|
328
|
+
const mRect = s.match(/^CLICK_RECT\s*\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\)\s*$/i);
|
|
329
|
+
if (mRect) {
|
|
330
|
+
return {
|
|
331
|
+
kind: 'click_rect',
|
|
332
|
+
x: Number(mRect[1]),
|
|
333
|
+
y: Number(mRect[2]),
|
|
334
|
+
w: Number(mRect[3]),
|
|
335
|
+
h: Number(mRect[4]),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const mClick = s.match(/^CLICK\s*\(\s*(\d+)\s*\)\s*$/i);
|
|
339
|
+
if (mClick)
|
|
340
|
+
return { kind: 'click_id', id: Number(mClick[1]) };
|
|
341
|
+
const mType = s.match(/^TYPE\s*\(\s*(\d+)\s*,\s*["']([^"']*)["']\s*\)\s*$/i);
|
|
342
|
+
if (mType)
|
|
343
|
+
return { kind: 'type_id', id: Number(mType[1]), text: mType[2] };
|
|
344
|
+
const mPress = s.match(/^PRESS\s*\(\s*["']([^"']+)["']\s*\)\s*$/i);
|
|
345
|
+
if (mPress)
|
|
346
|
+
return { kind: 'press', key: mPress[1] };
|
|
347
|
+
throw new Error(`Unknown action format: ${action}`);
|
|
348
|
+
}
|
|
349
|
+
extractActionFromText(text) {
|
|
350
|
+
const cleaned = (text || '').replace(/```[\w]*\n?/g, '').trim();
|
|
351
|
+
const pat = /(CLICK_XY\s*\(\s*-?\d+(?:\.\d+)?\s*,\s*-?\d+(?:\.\d+)?\s*\)|CLICK_RECT\s*\(\s*-?\d+(?:\.\d+)?\s*,\s*-?\d+(?:\.\d+)?\s*,\s*-?\d+(?:\.\d+)?\s*,\s*-?\d+(?:\.\d+)?\s*\)|CLICK\s*\(\s*\d+\s*\)|TYPE\s*\(\s*\d+\s*,\s*["'].*?["']\s*\)|PRESS\s*\(\s*["'].*?["']\s*\)|FINISH\s*\(\s*\))/i;
|
|
352
|
+
const m = cleaned.match(pat);
|
|
353
|
+
return m ? m[1] : cleaned;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
exports.RuntimeAgent = RuntimeAgent;
|
|
357
|
+
//# sourceMappingURL=runtime-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-agent.js","sourceRoot":"","sources":["../src/runtime-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot functionality - standalone screenshot capture
|
|
3
|
+
*/
|
|
4
|
+
import { SentienceBrowser } from './browser';
|
|
5
|
+
export interface ScreenshotOptions {
|
|
6
|
+
format?: 'png' | 'jpeg';
|
|
7
|
+
quality?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Capture screenshot of current page
|
|
11
|
+
*
|
|
12
|
+
* @param browser - SentienceBrowser instance
|
|
13
|
+
* @param options - Screenshot options
|
|
14
|
+
* @returns Base64-encoded screenshot data URL (e.g., "data:image/png;base64,...")
|
|
15
|
+
*/
|
|
16
|
+
export declare function screenshot(browser: SentienceBrowser, options?: ScreenshotOptions): Promise<string>;
|
|
17
|
+
//# sourceMappingURL=screenshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../src/screenshot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC,CA8BjB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Screenshot functionality - standalone screenshot capture
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.screenshot = screenshot;
|
|
7
|
+
/**
|
|
8
|
+
* Capture screenshot of current page
|
|
9
|
+
*
|
|
10
|
+
* @param browser - SentienceBrowser instance
|
|
11
|
+
* @param options - Screenshot options
|
|
12
|
+
* @returns Base64-encoded screenshot data URL (e.g., "data:image/png;base64,...")
|
|
13
|
+
*/
|
|
14
|
+
async function screenshot(browser, options = {}) {
|
|
15
|
+
const page = browser.getPage();
|
|
16
|
+
if (!page) {
|
|
17
|
+
throw new Error('Browser not started. Call start() first.');
|
|
18
|
+
}
|
|
19
|
+
const format = options.format || 'png';
|
|
20
|
+
const quality = options.quality;
|
|
21
|
+
if (format === 'jpeg' && quality !== undefined) {
|
|
22
|
+
if (quality < 1 || quality > 100) {
|
|
23
|
+
throw new Error('Quality must be between 1 and 100 for JPEG format');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Use Playwright's screenshot with base64 encoding
|
|
27
|
+
const screenshotOptions = {
|
|
28
|
+
type: format,
|
|
29
|
+
encoding: 'base64',
|
|
30
|
+
};
|
|
31
|
+
if (format === 'jpeg' && quality !== undefined) {
|
|
32
|
+
screenshotOptions.quality = quality;
|
|
33
|
+
}
|
|
34
|
+
// Capture screenshot
|
|
35
|
+
const base64Data = await page.screenshot(screenshotOptions);
|
|
36
|
+
// Return as data URL
|
|
37
|
+
const mimeType = format === 'png' ? 'image/png' : 'image/jpeg';
|
|
38
|
+
return `data:${mimeType};base64,${base64Data}`;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=screenshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../src/screenshot.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAgBH,gCAiCC;AAxCD;;;;;;GAMG;AACI,KAAK,UAAU,UAAU,CAC9B,OAAyB,EACzB,UAA6B,EAAE;IAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAEhC,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/C,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,MAAM,iBAAiB,GAAQ;QAC7B,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,QAAQ;KACnB,CAAC;IAEF,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/C,iBAAiB,CAAC,OAAO,GAAG,OAAO,CAAC;IACtC,CAAC;IAED,qBAAqB;IACrB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAE5D,qBAAqB;IACrB,MAAM,QAAQ,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;IAC/D,OAAO,QAAQ,QAAQ,WAAW,UAAU,EAAE,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot comparison utilities for diff_status detection.
|
|
3
|
+
* Implements change detection logic for the Diff Overlay feature.
|
|
4
|
+
*
|
|
5
|
+
* Uses shared canonicalization helpers from canonicalization.ts to ensure
|
|
6
|
+
* consistent comparison behavior with tracing/indexer.ts.
|
|
7
|
+
*/
|
|
8
|
+
import { Element, Snapshot } from './types';
|
|
9
|
+
export declare class SnapshotDiff {
|
|
10
|
+
/**
|
|
11
|
+
* Compare current snapshot with previous and set diff_status on elements.
|
|
12
|
+
*
|
|
13
|
+
* Uses canonicalized comparisons:
|
|
14
|
+
* - Text is normalized (trimmed, collapsed whitespace, lowercased)
|
|
15
|
+
* - Bbox is rounded to 2px grid to ignore sub-pixel differences
|
|
16
|
+
*
|
|
17
|
+
* @param current - Current snapshot
|
|
18
|
+
* @param previous - Previous snapshot (undefined if this is the first snapshot)
|
|
19
|
+
* @returns List of elements with diff_status set (includes REMOVED elements from previous)
|
|
20
|
+
*/
|
|
21
|
+
static computeDiffStatus(current: Snapshot, previous: Snapshot | undefined): Element[];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=snapshot-diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-diff.d.ts","sourceRoot":"","sources":["../src/snapshot-diff.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAuB5C,qBAAa,YAAY;IACvB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,EAAE;CA8EvF"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Snapshot comparison utilities for diff_status detection.
|
|
4
|
+
* Implements change detection logic for the Diff Overlay feature.
|
|
5
|
+
*
|
|
6
|
+
* Uses shared canonicalization helpers from canonicalization.ts to ensure
|
|
7
|
+
* consistent comparison behavior with tracing/indexer.ts.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SnapshotDiff = void 0;
|
|
11
|
+
const canonicalization_1 = require("./canonicalization");
|
|
12
|
+
/**
|
|
13
|
+
* Convert Element to ElementData for canonicalization helpers.
|
|
14
|
+
*/
|
|
15
|
+
function elementToData(el) {
|
|
16
|
+
return {
|
|
17
|
+
id: el.id,
|
|
18
|
+
role: el.role,
|
|
19
|
+
text: el.text,
|
|
20
|
+
bbox: {
|
|
21
|
+
x: el.bbox.x,
|
|
22
|
+
y: el.bbox.y,
|
|
23
|
+
width: el.bbox.width,
|
|
24
|
+
height: el.bbox.height,
|
|
25
|
+
},
|
|
26
|
+
visual_cues: {
|
|
27
|
+
is_primary: el.visual_cues.is_primary,
|
|
28
|
+
is_clickable: el.visual_cues.is_clickable,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
class SnapshotDiff {
|
|
33
|
+
/**
|
|
34
|
+
* Compare current snapshot with previous and set diff_status on elements.
|
|
35
|
+
*
|
|
36
|
+
* Uses canonicalized comparisons:
|
|
37
|
+
* - Text is normalized (trimmed, collapsed whitespace, lowercased)
|
|
38
|
+
* - Bbox is rounded to 2px grid to ignore sub-pixel differences
|
|
39
|
+
*
|
|
40
|
+
* @param current - Current snapshot
|
|
41
|
+
* @param previous - Previous snapshot (undefined if this is the first snapshot)
|
|
42
|
+
* @returns List of elements with diff_status set (includes REMOVED elements from previous)
|
|
43
|
+
*/
|
|
44
|
+
static computeDiffStatus(current, previous) {
|
|
45
|
+
// If no previous snapshot, all current elements are ADDED
|
|
46
|
+
if (!previous) {
|
|
47
|
+
return current.elements.map(el => ({
|
|
48
|
+
...el,
|
|
49
|
+
diff_status: 'ADDED',
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
// Build lookup maps by element ID
|
|
53
|
+
const currentById = new Map(current.elements.map(el => [el.id, el]));
|
|
54
|
+
const previousById = new Map(previous.elements.map(el => [el.id, el]));
|
|
55
|
+
const currentIds = new Set(currentById.keys());
|
|
56
|
+
const previousIds = new Set(previousById.keys());
|
|
57
|
+
const result = [];
|
|
58
|
+
// Process current elements
|
|
59
|
+
for (const el of current.elements) {
|
|
60
|
+
if (!previousIds.has(el.id)) {
|
|
61
|
+
// Element is new - mark as ADDED
|
|
62
|
+
result.push({
|
|
63
|
+
...el,
|
|
64
|
+
diff_status: 'ADDED',
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// Element existed before - check for changes using canonicalized comparisons
|
|
69
|
+
const prevEl = previousById.get(el.id);
|
|
70
|
+
// Convert to ElementData for canonicalization helpers
|
|
71
|
+
const elData = elementToData(el);
|
|
72
|
+
const prevElData = elementToData(prevEl);
|
|
73
|
+
const hasBboxChanged = (0, canonicalization_1.bboxChanged)(elData.bbox, prevElData.bbox);
|
|
74
|
+
const hasContentChanged = (0, canonicalization_1.contentChanged)(elData, prevElData);
|
|
75
|
+
if (hasBboxChanged && hasContentChanged) {
|
|
76
|
+
// Both position and content changed - mark as MODIFIED
|
|
77
|
+
result.push({
|
|
78
|
+
...el,
|
|
79
|
+
diff_status: 'MODIFIED',
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
else if (hasBboxChanged) {
|
|
83
|
+
// Only position changed - mark as MOVED
|
|
84
|
+
result.push({
|
|
85
|
+
...el,
|
|
86
|
+
diff_status: 'MOVED',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else if (hasContentChanged) {
|
|
90
|
+
// Only content changed - mark as MODIFIED
|
|
91
|
+
result.push({
|
|
92
|
+
...el,
|
|
93
|
+
diff_status: 'MODIFIED',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// No change - don't set diff_status (frontend expects undefined)
|
|
98
|
+
result.push({
|
|
99
|
+
...el,
|
|
100
|
+
diff_status: undefined,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Process removed elements (existed in previous but not in current)
|
|
106
|
+
for (const prevId of previousIds) {
|
|
107
|
+
if (!currentIds.has(prevId)) {
|
|
108
|
+
const prevEl = previousById.get(prevId);
|
|
109
|
+
result.push({
|
|
110
|
+
...prevEl,
|
|
111
|
+
diff_status: 'REMOVED',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.SnapshotDiff = SnapshotDiff;
|
|
119
|
+
//# sourceMappingURL=snapshot-diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-diff.js","sourceRoot":"","sources":["../src/snapshot-diff.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,yDAA8E;AAG9E;;GAEG;AACH,SAAS,aAAa,CAAC,EAAW;IAChC,OAAO;QACL,EAAE,EAAE,EAAE,CAAC,EAAE;QACT,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,IAAI,EAAE;YACJ,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;YACZ,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;YACZ,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK;YACpB,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM;SACvB;QACD,WAAW,EAAE;YACX,UAAU,EAAE,EAAE,CAAC,WAAW,CAAC,UAAU;YACrC,YAAY,EAAE,EAAE,CAAC,WAAW,CAAC,YAAY;SAC1C;KACF,CAAC;AACJ,CAAC;AAED,MAAa,YAAY;IACvB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAiB,EAAE,QAA8B;QACxE,0DAA0D;QAC1D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBACjC,GAAG,EAAE;gBACL,WAAW,EAAE,OAAgB;aAC9B,CAAC,CAAC,CAAC;QACN,CAAC;QAED,kCAAkC;QAClC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAEvE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAEjD,MAAM,MAAM,GAAc,EAAE,CAAC;QAE7B,2BAA2B;QAC3B,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC5B,iCAAiC;gBACjC,MAAM,CAAC,IAAI,CAAC;oBACV,GAAG,EAAE;oBACL,WAAW,EAAE,OAAO;iBACrB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,6EAA6E;gBAC7E,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAE,CAAC;gBAExC,sDAAsD;gBACtD,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;gBACjC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;gBAEzC,MAAM,cAAc,GAAG,IAAA,8BAAW,EAAC,MAAM,CAAC,IAAK,EAAE,UAAU,CAAC,IAAK,CAAC,CAAC;gBACnE,MAAM,iBAAiB,GAAG,IAAA,iCAAc,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBAE7D,IAAI,cAAc,IAAI,iBAAiB,EAAE,CAAC;oBACxC,uDAAuD;oBACvD,MAAM,CAAC,IAAI,CAAC;wBACV,GAAG,EAAE;wBACL,WAAW,EAAE,UAAU;qBACxB,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,cAAc,EAAE,CAAC;oBAC1B,wCAAwC;oBACxC,MAAM,CAAC,IAAI,CAAC;wBACV,GAAG,EAAE;wBACL,WAAW,EAAE,OAAO;qBACrB,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,iBAAiB,EAAE,CAAC;oBAC7B,0CAA0C;oBAC1C,MAAM,CAAC,IAAI,CAAC;wBACV,GAAG,EAAE;wBACL,WAAW,EAAE,UAAU;qBACxB,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,iEAAiE;oBACjE,MAAM,CAAC,IAAI,CAAC;wBACV,GAAG,EAAE;wBACL,WAAW,EAAE,SAAS;qBACvB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,oEAAoE;QACpE,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;YACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;gBACzC,MAAM,CAAC,IAAI,CAAC;oBACV,GAAG,MAAM;oBACT,WAAW,EAAE,SAAS;iBACvB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA1FD,oCA0FC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot functionality - calls window.sentience.snapshot() or server-side API
|
|
3
|
+
*/
|
|
4
|
+
import { IBrowser } from './protocols/browser-protocol';
|
|
5
|
+
import { Snapshot } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Structured error for server-side (gateway) snapshot failures.
|
|
8
|
+
*
|
|
9
|
+
* Keeps HTTP status/URL/response details available to callers for better logging/debugging.
|
|
10
|
+
*/
|
|
11
|
+
export declare class SnapshotGatewayError extends Error {
|
|
12
|
+
statusCode?: number;
|
|
13
|
+
url?: string;
|
|
14
|
+
requestId?: string;
|
|
15
|
+
responseText?: string;
|
|
16
|
+
cause?: unknown;
|
|
17
|
+
constructor(message: string, opts?: {
|
|
18
|
+
statusCode?: number;
|
|
19
|
+
url?: string;
|
|
20
|
+
requestId?: string;
|
|
21
|
+
responseText?: string;
|
|
22
|
+
cause?: unknown;
|
|
23
|
+
});
|
|
24
|
+
static snip(s: string | undefined, n?: number): string | undefined;
|
|
25
|
+
}
|
|
26
|
+
export interface SnapshotOptions {
|
|
27
|
+
screenshot?: boolean | {
|
|
28
|
+
format: 'png' | 'jpeg';
|
|
29
|
+
quality?: number;
|
|
30
|
+
};
|
|
31
|
+
limit?: number;
|
|
32
|
+
filter?: {
|
|
33
|
+
min_area?: number;
|
|
34
|
+
allowed_roles?: string[];
|
|
35
|
+
min_z_index?: number;
|
|
36
|
+
};
|
|
37
|
+
use_api?: boolean;
|
|
38
|
+
gatewayTimeoutMs?: number;
|
|
39
|
+
save_trace?: boolean;
|
|
40
|
+
trace_path?: string;
|
|
41
|
+
goal?: string;
|
|
42
|
+
show_overlay?: boolean;
|
|
43
|
+
show_grid?: boolean;
|
|
44
|
+
grid_id?: number | null;
|
|
45
|
+
}
|
|
46
|
+
export declare function snapshot(browser: IBrowser, options?: SnapshotOptions): Promise<Snapshot>;
|
|
47
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQnC;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAGrB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;QACL,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;IAWH,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,GAAE,MAAY,GAAG,MAAM,GAAG,SAAS;CAKxE;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,OAAO,GAAG;QAAE,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAsBD,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,QAAQ,EACjB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,QAAQ,CAAC,CAenB"}
|