@nuanu-ai/agentbrowse 0.2.47 → 0.2.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -10
- package/dist/agentpay-gateway.d.ts +9 -0
- package/dist/agentpay-gateway.d.ts.map +1 -1
- package/dist/agentpay-gateway.js +31 -1
- package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
- package/dist/agentpay-stagehand-llm.js +9 -1
- package/dist/command-api-tracing.d.ts +19 -0
- package/dist/command-api-tracing.d.ts.map +1 -0
- package/dist/command-api-tracing.js +137 -0
- package/dist/commands/act.d.ts.map +1 -1
- package/dist/commands/act.js +822 -670
- package/dist/commands/act.test-harness.d.ts +6 -0
- package/dist/commands/act.test-harness.d.ts.map +1 -1
- package/dist/commands/act.test-harness.js +44 -1
- package/dist/commands/action-acceptance.d.ts.map +1 -1
- package/dist/commands/action-acceptance.js +115 -0
- package/dist/commands/captcha-solve.d.ts.map +1 -1
- package/dist/commands/captcha-solve.js +83 -16
- package/dist/commands/click-action-executor.d.ts +0 -1
- package/dist/commands/click-action-executor.d.ts.map +1 -1
- package/dist/commands/click-action-executor.js +31 -77
- package/dist/commands/close.d.ts +3 -3
- package/dist/commands/close.d.ts.map +1 -1
- package/dist/commands/close.js +178 -0
- package/dist/commands/descriptor-validation.d.ts.map +1 -1
- package/dist/commands/descriptor-validation.js +75 -57
- package/dist/commands/end-session.d.ts +25 -0
- package/dist/commands/end-session.d.ts.map +1 -0
- package/dist/commands/end-session.js +161 -0
- package/dist/commands/extract-stagehand-executor.js +1 -1
- package/dist/commands/extract.d.ts.map +1 -1
- package/dist/commands/extract.js +339 -202
- package/dist/commands/fill-secret.d.ts +3 -3
- package/dist/commands/fill-secret.d.ts.map +1 -1
- package/dist/commands/fill-secret.js +419 -234
- package/dist/commands/get-secrets-catalog.d.ts.map +1 -1
- package/dist/commands/get-secrets-catalog.js +66 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +6 -3
- package/dist/commands/interaction-kernel.d.ts +46 -0
- package/dist/commands/interaction-kernel.d.ts.map +1 -0
- package/dist/commands/interaction-kernel.js +215 -0
- package/dist/commands/launch.d.ts +1 -3
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +115 -27
- package/dist/commands/navigate.d.ts.map +1 -1
- package/dist/commands/navigate.js +188 -45
- package/dist/commands/observe-accessibility.d.ts.map +1 -1
- package/dist/commands/observe-accessibility.js +46 -39
- package/dist/commands/observe-dom-label-contract.d.ts.map +1 -1
- package/dist/commands/observe-dom-label-contract.js +5 -0
- package/dist/commands/observe-inventory.d.ts +13 -0
- package/dist/commands/observe-inventory.d.ts.map +1 -1
- package/dist/commands/observe-inventory.js +320 -65
- package/dist/commands/observe-persistence.d.ts.map +1 -1
- package/dist/commands/observe-persistence.js +3 -0
- package/dist/commands/observe-projection.d.ts +1 -0
- package/dist/commands/observe-projection.d.ts.map +1 -1
- package/dist/commands/observe-projection.js +7 -2
- package/dist/commands/observe-protected.d.ts +1 -0
- package/dist/commands/observe-protected.d.ts.map +1 -1
- package/dist/commands/observe-protected.js +9 -4
- package/dist/commands/observe-semantics.d.ts.map +1 -1
- package/dist/commands/observe-semantics.js +5 -2
- package/dist/commands/observe-stagehand.d.ts +1 -0
- package/dist/commands/observe-stagehand.d.ts.map +1 -1
- package/dist/commands/observe-stagehand.js +2 -0
- package/dist/commands/observe.d.ts +2 -0
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +387 -203
- package/dist/commands/observe.test-harness.d.ts +8 -0
- package/dist/commands/observe.test-harness.d.ts.map +1 -1
- package/dist/commands/observe.test-harness.js +48 -1
- package/dist/commands/poll-secret.d.ts +6 -0
- package/dist/commands/poll-secret.d.ts.map +1 -0
- package/dist/commands/poll-secret.js +159 -0
- package/dist/commands/request-secret.d.ts +6 -0
- package/dist/commands/request-secret.d.ts.map +1 -0
- package/dist/commands/request-secret.js +284 -0
- package/dist/commands/screenshot.d.ts.map +1 -1
- package/dist/commands/screenshot.js +172 -7
- package/dist/commands/select-action-executor.d.ts.map +1 -1
- package/dist/commands/semantic-observe.d.ts +4 -0
- package/dist/commands/semantic-observe.d.ts.map +1 -1
- package/dist/commands/semantic-observe.js +388 -17
- package/dist/commands/start-session.d.ts +31 -0
- package/dist/commands/start-session.d.ts.map +1 -0
- package/dist/commands/start-session.js +347 -0
- package/dist/commands/status.d.ts +2 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +166 -144
- package/dist/control-semantics.d.ts +1 -0
- package/dist/control-semantics.d.ts.map +1 -1
- package/dist/control-semantics.js +51 -9
- package/dist/generated/build-config.d.ts +2 -0
- package/dist/generated/build-config.d.ts.map +1 -0
- package/dist/generated/build-config.js +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +163 -63
- package/dist/otel-exporter.d.ts +58 -0
- package/dist/otel-exporter.d.ts.map +1 -0
- package/dist/otel-exporter.js +263 -0
- package/dist/otel-projector.d.ts +75 -0
- package/dist/otel-projector.d.ts.map +1 -0
- package/dist/otel-projector.js +409 -0
- package/dist/owned-browser.d.ts +1 -1
- package/dist/owned-browser.d.ts.map +1 -1
- package/dist/owned-browser.js +13 -1
- package/dist/owned-process.d.ts +2 -0
- package/dist/owned-process.d.ts.map +1 -1
- package/dist/owned-process.js +7 -3
- package/dist/playwright-runtime.d.ts +1 -1
- package/dist/playwright-runtime.d.ts.map +1 -1
- package/dist/playwright-runtime.js +8 -8
- package/dist/run-observability.d.ts +25 -0
- package/dist/run-observability.d.ts.map +1 -0
- package/dist/run-observability.js +115 -0
- package/dist/run-store.d.ts +274 -0
- package/dist/run-store.d.ts.map +1 -0
- package/dist/run-store.js +631 -0
- package/dist/runtime-metrics.d.ts +27 -0
- package/dist/runtime-metrics.d.ts.map +1 -0
- package/dist/runtime-metrics.js +66 -0
- package/dist/runtime-page-state.d.ts +11 -0
- package/dist/runtime-page-state.d.ts.map +1 -0
- package/dist/runtime-page-state.js +62 -0
- package/dist/runtime-protected-state.d.ts +16 -0
- package/dist/runtime-protected-state.d.ts.map +1 -0
- package/dist/runtime-protected-state.js +157 -0
- package/dist/runtime-state.d.ts +10 -44
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +57 -222
- package/dist/secrets/backend.d.ts +65 -16
- package/dist/secrets/backend.d.ts.map +1 -1
- package/dist/secrets/backend.js +135 -95
- package/dist/secrets/catalog-sync.d.ts.map +1 -1
- package/dist/secrets/catalog-sync.js +4 -1
- package/dist/secrets/form-matcher.d.ts +5 -5
- package/dist/secrets/form-matcher.d.ts.map +1 -1
- package/dist/secrets/form-matcher.js +292 -164
- package/dist/secrets/intent-output.d.ts +6 -10
- package/dist/secrets/intent-output.d.ts.map +1 -1
- package/dist/secrets/intent-output.js +4 -58
- package/dist/secrets/mock-agentpay-cabinet.d.ts +38 -27
- package/dist/secrets/mock-agentpay-cabinet.d.ts.map +1 -1
- package/dist/secrets/mock-agentpay-cabinet.js +177 -111
- package/dist/secrets/protected-artifact-guard.d.ts +2 -2
- package/dist/secrets/protected-artifact-guard.d.ts.map +1 -1
- package/dist/secrets/protected-artifact-guard.js +2 -2
- package/dist/secrets/protected-bindings.d.ts +1 -1
- package/dist/secrets/protected-bindings.d.ts.map +1 -1
- package/dist/secrets/protected-bindings.js +6 -0
- package/dist/secrets/protected-field-semantics.d.ts +9 -0
- package/dist/secrets/protected-field-semantics.d.ts.map +1 -0
- package/dist/secrets/protected-field-semantics.js +154 -0
- package/dist/secrets/protected-field-values.d.ts.map +1 -1
- package/dist/secrets/protected-field-values.js +3 -3
- package/dist/secrets/protected-fill.d.ts +1 -1
- package/dist/secrets/protected-fill.d.ts.map +1 -1
- package/dist/secrets/protected-fill.js +45 -149
- package/dist/secrets/protected-value-adapters.d.ts +2 -1
- package/dist/secrets/protected-value-adapters.d.ts.map +1 -1
- package/dist/secrets/protected-value-adapters.js +80 -1
- package/dist/secrets/request-output.d.ts +11 -0
- package/dist/secrets/request-output.d.ts.map +1 -0
- package/dist/secrets/request-output.js +75 -0
- package/dist/secrets/types.d.ts +15 -9
- package/dist/secrets/types.d.ts.map +1 -1
- package/dist/secrets/types.js +3 -0
- package/dist/session-event-exporter.d.ts +36 -0
- package/dist/session-event-exporter.d.ts.map +1 -0
- package/dist/session-event-exporter.js +428 -0
- package/dist/session.d.ts +16 -7
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +150 -23
- package/dist/sessions-backend.d.ts +354 -0
- package/dist/sessions-backend.d.ts.map +1 -0
- package/dist/sessions-backend.js +126 -0
- package/dist/solver/browser-launcher.d.ts +1 -1
- package/dist/solver/browser-launcher.d.ts.map +1 -1
- package/dist/solver/browser-launcher.js +39 -13
- package/dist/solver/captcha-solver.d.ts.map +1 -1
- package/dist/solver/captcha-solver.js +8 -1
- package/dist/solver/config.d.ts +0 -1
- package/dist/solver/config.d.ts.map +1 -1
- package/dist/solver/config.js +0 -22
- package/dist/solver/types.d.ts +1 -0
- package/dist/solver/types.d.ts.map +1 -1
- package/dist/workflow-session-completion.d.ts +33 -0
- package/dist/workflow-session-completion.d.ts.map +1 -0
- package/dist/workflow-session-completion.js +156 -0
- package/package.json +11 -1
- package/dist/commands/create-intent.d.ts +0 -6
- package/dist/commands/create-intent.d.ts.map +0 -1
- package/dist/commands/create-intent.js +0 -75
- package/dist/commands/poll-intent.d.ts +0 -6
- package/dist/commands/poll-intent.d.ts.map +0 -1
- package/dist/commands/poll-intent.js +0 -57
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { buildAgentpaySessionSecretsCatalogUrl, buildAgentpayCompleteSessionUrl, buildAgentpayClaimSecretUrl, buildAgentpaySessionEventsUrl, buildAgentpaySessionSecretRequestUrl, buildAgentpaySessionSecretRequestsUrl, buildAgentpaySessionUrl, buildAgentpaySessionsUrl, resolveAgentpayGatewayConfig, } from './agentpay-gateway.js';
|
|
2
|
+
export class AgentpayRequestError extends Error {
|
|
3
|
+
status;
|
|
4
|
+
payload;
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'AgentpayRequestError';
|
|
8
|
+
this.status = options.status;
|
|
9
|
+
this.payload = options.payload;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
async function requestJson(gateway, method, path, body, fetchImpl = fetch) {
|
|
13
|
+
const response = await fetchImpl(path, {
|
|
14
|
+
method,
|
|
15
|
+
headers: {
|
|
16
|
+
authorization: `Bearer ${gateway.apiKey}`,
|
|
17
|
+
...(body === undefined ? {} : { 'content-type': 'application/json' }),
|
|
18
|
+
},
|
|
19
|
+
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
20
|
+
});
|
|
21
|
+
const rawText = await response.text();
|
|
22
|
+
const parsed = rawText.length > 0 ? JSON.parse(rawText) : null;
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
const message = parsed && typeof parsed === 'object' && typeof parsed.error === 'string'
|
|
25
|
+
? parsed.error
|
|
26
|
+
: `AgentPay API request failed with HTTP ${response.status}`;
|
|
27
|
+
throw new AgentpayRequestError(message, {
|
|
28
|
+
status: response.status,
|
|
29
|
+
payload: parsed,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return parsed;
|
|
33
|
+
}
|
|
34
|
+
export async function createRemoteSession(input, options = {}) {
|
|
35
|
+
const gateway = resolveAgentpayGatewayConfig();
|
|
36
|
+
return requestJson(gateway, 'POST', buildAgentpaySessionsUrl(gateway.apiUrl), {
|
|
37
|
+
browser_session_id: input.browserSessionId,
|
|
38
|
+
entry_command: 'start-session',
|
|
39
|
+
...(input.description ? { description: input.description } : {}),
|
|
40
|
+
...(input.merchantName ? { merchant_name: input.merchantName } : {}),
|
|
41
|
+
...(input.page ? { page: input.page } : {}),
|
|
42
|
+
...(input.context ? { context: input.context } : {}),
|
|
43
|
+
...(input.metadata ? { metadata: input.metadata } : {}),
|
|
44
|
+
...(input.telemetry ? { telemetry: input.telemetry } : {}),
|
|
45
|
+
run: input.run,
|
|
46
|
+
step: input.step,
|
|
47
|
+
}, options.fetchImpl);
|
|
48
|
+
}
|
|
49
|
+
export async function getRemoteSession(sessionId, options = {}) {
|
|
50
|
+
const gateway = resolveAgentpayGatewayConfig();
|
|
51
|
+
return requestJson(gateway, 'GET', buildAgentpaySessionUrl(gateway.apiUrl, sessionId), undefined, options.fetchImpl);
|
|
52
|
+
}
|
|
53
|
+
export async function getRemoteSessionSecretCatalog(sessionId, host, options = {}) {
|
|
54
|
+
const gateway = resolveAgentpayGatewayConfig();
|
|
55
|
+
return requestJson(gateway, 'GET', `${buildAgentpaySessionSecretsCatalogUrl(gateway.apiUrl, sessionId)}?host=${encodeURIComponent(host)}`, undefined, options.fetchImpl);
|
|
56
|
+
}
|
|
57
|
+
export async function createRemoteSessionEvent(sessionId, input, options = {}) {
|
|
58
|
+
const gateway = resolveAgentpayGatewayConfig();
|
|
59
|
+
return requestJson(gateway, 'POST', buildAgentpaySessionEventsUrl(gateway.apiUrl, sessionId), {
|
|
60
|
+
client_event_id: input.clientEventId,
|
|
61
|
+
sequence_no: input.sequenceNo,
|
|
62
|
+
type: input.type,
|
|
63
|
+
command: input.command,
|
|
64
|
+
status: input.status,
|
|
65
|
+
summary: input.summary,
|
|
66
|
+
timestamp: input.timestamp,
|
|
67
|
+
...(input.page ? { page: input.page } : {}),
|
|
68
|
+
...(input.details ? { details: input.details } : {}),
|
|
69
|
+
...(input.telemetry ? { telemetry: input.telemetry } : {}),
|
|
70
|
+
...(input.run ? { run: input.run } : {}),
|
|
71
|
+
...(input.step ? { step: input.step } : {}),
|
|
72
|
+
}, options.fetchImpl);
|
|
73
|
+
}
|
|
74
|
+
export async function completeRemoteSession(sessionId, input, options = {}) {
|
|
75
|
+
const gateway = resolveAgentpayGatewayConfig();
|
|
76
|
+
return requestJson(gateway, 'POST', buildAgentpayCompleteSessionUrl(gateway.apiUrl, sessionId), {
|
|
77
|
+
client_completion_id: input.clientCompletionId,
|
|
78
|
+
status: input.status,
|
|
79
|
+
command: input.command,
|
|
80
|
+
summary: input.summary,
|
|
81
|
+
timestamp: input.timestamp,
|
|
82
|
+
...(input.page ? { page: input.page } : {}),
|
|
83
|
+
...(input.details ? { details: input.details } : {}),
|
|
84
|
+
...(input.telemetry ? { telemetry: input.telemetry } : {}),
|
|
85
|
+
run: input.run,
|
|
86
|
+
...(input.step ? { step: input.step } : {}),
|
|
87
|
+
}, options.fetchImpl);
|
|
88
|
+
}
|
|
89
|
+
export async function createRemoteSecretRequest(sessionId, input, options = {}) {
|
|
90
|
+
const gateway = resolveAgentpayGatewayConfig();
|
|
91
|
+
return requestJson(gateway, 'POST', buildAgentpaySessionSecretRequestsUrl(gateway.apiUrl, sessionId), {
|
|
92
|
+
client_request_id: input.clientRequestId,
|
|
93
|
+
fill_ref: input.fillRef,
|
|
94
|
+
purpose: input.purpose,
|
|
95
|
+
merchant_name: input.merchantName,
|
|
96
|
+
...(input.page ? { page: input.page } : {}),
|
|
97
|
+
secret_hint: {
|
|
98
|
+
...(input.secretHint.storedSecretRef
|
|
99
|
+
? { stored_secret_ref: input.secretHint.storedSecretRef }
|
|
100
|
+
: {}),
|
|
101
|
+
...(input.secretHint.credentialKey
|
|
102
|
+
? { credential_key: input.secretHint.credentialKey }
|
|
103
|
+
: {}),
|
|
104
|
+
...(input.secretHint.credentialName
|
|
105
|
+
? { credential_name: input.secretHint.credentialName }
|
|
106
|
+
: {}),
|
|
107
|
+
...(input.secretHint.kind ? { kind: input.secretHint.kind } : {}),
|
|
108
|
+
...(input.secretHint.host ? { host: input.secretHint.host } : {}),
|
|
109
|
+
...(input.secretHint.scopeRef ? { scope_ref: input.secretHint.scopeRef } : {}),
|
|
110
|
+
...(input.secretHint.fields ? { fields: input.secretHint.fields } : {}),
|
|
111
|
+
},
|
|
112
|
+
...(input.telemetry ? { telemetry: input.telemetry } : {}),
|
|
113
|
+
...(input.run ? { run: input.run } : {}),
|
|
114
|
+
...(input.step ? { step: input.step } : {}),
|
|
115
|
+
}, options.fetchImpl);
|
|
116
|
+
}
|
|
117
|
+
export async function getRemoteSecretRequest(sessionId, requestId, options = {}) {
|
|
118
|
+
const gateway = resolveAgentpayGatewayConfig();
|
|
119
|
+
return requestJson(gateway, 'GET', buildAgentpaySessionSecretRequestUrl(gateway.apiUrl, sessionId, requestId), undefined, options.fetchImpl);
|
|
120
|
+
}
|
|
121
|
+
export async function claimRemoteSecret(sessionId, requestId, claimId, options = {}) {
|
|
122
|
+
const gateway = resolveAgentpayGatewayConfig();
|
|
123
|
+
return requestJson(gateway, 'POST', buildAgentpayClaimSecretUrl(gateway.apiUrl, sessionId, requestId), {
|
|
124
|
+
claim_id: claimId,
|
|
125
|
+
}, options.fetchImpl);
|
|
126
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-launcher.d.ts","sourceRoot":"","sources":["../../src/solver/browser-launcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser-launcher.d.ts","sourceRoot":"","sources":["../../src/solver/browser-launcher.ts"],"names":[],"mappings":"AAIA,OAAO,EAA+B,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjF,OAAO,KAAK,EAAsB,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkBjF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAAC;AAwBF,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,EACpB,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,aAAa,CAAC,CAyDxB;AAkXD,wBAAgB,wBAAwB,CACtC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAGV"}
|
|
@@ -2,6 +2,7 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
+
import { connect as connectPuppeteer } from 'puppeteer';
|
|
5
6
|
import puppeteerExtra from 'puppeteer-extra';
|
|
6
7
|
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
|
|
7
8
|
import { buildTurnstileApiShimSource, isTurnstileApiRequest } from './turnstile-challenge.js';
|
|
@@ -16,6 +17,7 @@ const AUTO_CDP_PORT = 0;
|
|
|
16
17
|
const CDP_DISCOVERY_TIMEOUT_MS = 30_000;
|
|
17
18
|
const CDP_DISCOVERY_INTERVAL_MS = 500;
|
|
18
19
|
const BROWSER_CLOSE_TIMEOUT_MS = 1_000;
|
|
20
|
+
const EXTRA_PAGE_CLOSE_TIMEOUT_MS = 250;
|
|
19
21
|
const INTERCEPTED_PAGES = new WeakSet();
|
|
20
22
|
const LINUX_CI_CHROME_ARGS = [
|
|
21
23
|
'--no-sandbox',
|
|
@@ -46,7 +48,7 @@ export async function launchSolver(profile, opts) {
|
|
|
46
48
|
if (!cdpUrl) {
|
|
47
49
|
throw buildCdpDiscoveryError(chromeProcess, opts?.cdpPort, profile.userDataDir);
|
|
48
50
|
}
|
|
49
|
-
const browser = await
|
|
51
|
+
const browser = await connectToBrowser(cdpUrl, opts?.stealth);
|
|
50
52
|
let page;
|
|
51
53
|
if (opts?.url) {
|
|
52
54
|
page = await createConfiguredPage(browser, fp);
|
|
@@ -55,18 +57,7 @@ export async function launchSolver(profile, opts) {
|
|
|
55
57
|
else {
|
|
56
58
|
page = await createConfiguredPage(browser, fp);
|
|
57
59
|
}
|
|
58
|
-
|
|
59
|
-
const allPages = await browser.pages();
|
|
60
|
-
for (const p of allPages) {
|
|
61
|
-
if (p !== page) {
|
|
62
|
-
try {
|
|
63
|
-
await p.close();
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
/* already closed */
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
60
|
+
await closeLaunchLeftoverPages(browser, page);
|
|
70
61
|
return {
|
|
71
62
|
browser,
|
|
72
63
|
page,
|
|
@@ -91,6 +82,12 @@ export async function launchSolver(profile, opts) {
|
|
|
91
82
|
throw error;
|
|
92
83
|
}
|
|
93
84
|
}
|
|
85
|
+
async function connectToBrowser(browserWSEndpoint, stealth) {
|
|
86
|
+
if (stealth === false) {
|
|
87
|
+
return connectPuppeteer({ browserWSEndpoint });
|
|
88
|
+
}
|
|
89
|
+
return enhancedPuppeteer.connect({ browserWSEndpoint });
|
|
90
|
+
}
|
|
94
91
|
async function discoverCdpUrl(options) {
|
|
95
92
|
const deadline = Date.now() + CDP_DISCOVERY_TIMEOUT_MS;
|
|
96
93
|
const activePortPath = path.join(options.userDataDir, 'DevToolsActivePort');
|
|
@@ -131,6 +128,35 @@ async function closeBrowserWithinTimeout(browser, timeoutMs) {
|
|
|
131
128
|
clearTimeout(timeoutId);
|
|
132
129
|
}
|
|
133
130
|
}
|
|
131
|
+
async function closeLaunchLeftoverPages(browser, activePage) {
|
|
132
|
+
const allPages = await browser.pages();
|
|
133
|
+
for (const candidate of allPages) {
|
|
134
|
+
if (candidate === activePage || !isCloseableLaunchLeftover(candidate.url())) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
await closePageWithinTimeout(candidate, EXTRA_PAGE_CLOSE_TIMEOUT_MS);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function isCloseableLaunchLeftover(url) {
|
|
141
|
+
const normalized = url.trim().toLowerCase();
|
|
142
|
+
return (normalized.length === 0 ||
|
|
143
|
+
normalized === 'about:blank' ||
|
|
144
|
+
normalized === 'chrome://newtab/' ||
|
|
145
|
+
normalized === 'chrome://new-tab-page/' ||
|
|
146
|
+
normalized === 'chrome://newtab');
|
|
147
|
+
}
|
|
148
|
+
async function closePageWithinTimeout(page, timeoutMs) {
|
|
149
|
+
let timeoutId;
|
|
150
|
+
await Promise.race([
|
|
151
|
+
page.close().catch(() => undefined),
|
|
152
|
+
new Promise((resolve) => {
|
|
153
|
+
timeoutId = setTimeout(resolve, timeoutMs);
|
|
154
|
+
}),
|
|
155
|
+
]);
|
|
156
|
+
if (timeoutId) {
|
|
157
|
+
clearTimeout(timeoutId);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
134
160
|
async function discoverCdpUrlOnPort(port) {
|
|
135
161
|
try {
|
|
136
162
|
const res = await fetch(`http://127.0.0.1:${port}/json/version`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"captcha-solver.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-solver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"captcha-solver.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-solver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;AAEpE,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAiBF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAMF;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAc;gBAEzB,MAAM,EAAE,mBAAmB;IAgBjC,KAAK,CACT,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;YAqBhB,UAAU;YAkBV,aAAa;YAOb,OAAO;CAkDtB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { tracedFetch } from '../command-api-tracing.js';
|
|
1
2
|
const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
2
3
|
const DEFAULT_TASK_POLL_MS = 5_000;
|
|
3
4
|
const DEFAULT_TASK_TIMEOUT_MS = 120_000;
|
|
@@ -69,11 +70,17 @@ export class CaptchaSolver {
|
|
|
69
70
|
}
|
|
70
71
|
let response;
|
|
71
72
|
try {
|
|
72
|
-
response = await
|
|
73
|
+
response = await tracedFetch(url, {
|
|
73
74
|
method,
|
|
74
75
|
headers,
|
|
75
76
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
76
77
|
signal: AbortSignal.timeout(this.requestTimeoutMs),
|
|
78
|
+
}, {
|
|
79
|
+
spanName: method === 'POST' ? 'agentpay.captcha.tasks.create' : 'agentpay.captcha.tasks.get',
|
|
80
|
+
attributes: {
|
|
81
|
+
'agentbrowse.api.system': 'agentpay',
|
|
82
|
+
'agentbrowse.api.route': method === 'POST' ? '/tools/captcha/tasks' : '/tools/captcha/tasks/:taskId',
|
|
83
|
+
},
|
|
77
84
|
});
|
|
78
85
|
}
|
|
79
86
|
catch (err) {
|
package/dist/solver/config.d.ts
CHANGED
|
@@ -5,7 +5,6 @@ export declare function getConfigPath(): string;
|
|
|
5
5
|
export declare function ensureDirs(): void;
|
|
6
6
|
export declare function readConfig(): SolverConfig;
|
|
7
7
|
export declare function writeConfig(config: SolverConfig): void;
|
|
8
|
-
export declare function applyDemoProxyBootstrap(): boolean;
|
|
9
8
|
export declare function getProfileDir(profileName: string): string;
|
|
10
9
|
export declare function getExistingProfileDir(profileName: string): string | null;
|
|
11
10
|
export declare function getUserDataDir(profileName: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/solver/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/solver/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/C,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED,wBAAgB,UAAU,IAAI,YAAY,CAOzC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAGtD;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxE;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9D"}
|
package/dist/solver/config.js
CHANGED
|
@@ -5,7 +5,6 @@ const AGENTPAY_DIR = path.join(os.homedir(), '.agentpay');
|
|
|
5
5
|
const PRIMARY_DIR = path.join(AGENTPAY_DIR, 'agentbrowse');
|
|
6
6
|
const PRIMARY_CONFIG_PATH = path.join(AGENTPAY_DIR, 'config.json');
|
|
7
7
|
const PRIMARY_PROFILES_DIR = path.join(PRIMARY_DIR, 'profiles');
|
|
8
|
-
const DEMO_PROXY_PLACEHOLDER = 'http://user:pass@31.98.19.10:6186/';
|
|
9
8
|
export function getSolverDir() {
|
|
10
9
|
return PRIMARY_DIR;
|
|
11
10
|
}
|
|
@@ -31,27 +30,6 @@ export function writeConfig(config) {
|
|
|
31
30
|
ensureDirs();
|
|
32
31
|
fs.writeFileSync(PRIMARY_CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
33
32
|
}
|
|
34
|
-
export function applyDemoProxyBootstrap() {
|
|
35
|
-
const existingProxy = readConfig().defaults?.proxy;
|
|
36
|
-
if (typeof existingProxy === 'string' && existingProxy.trim().length > 0) {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
if (existingProxy &&
|
|
40
|
-
typeof existingProxy === 'object' &&
|
|
41
|
-
typeof existingProxy.server === 'string' &&
|
|
42
|
-
existingProxy.server.trim().length > 0) {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
const current = readConfig();
|
|
46
|
-
writeConfig({
|
|
47
|
-
...current,
|
|
48
|
-
defaults: {
|
|
49
|
-
...current.defaults,
|
|
50
|
-
proxy: DEMO_PROXY_PLACEHOLDER,
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
33
|
export function getProfileDir(profileName) {
|
|
56
34
|
return path.join(PRIMARY_PROFILES_DIR, profileName);
|
|
57
35
|
}
|
package/dist/solver/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/solver/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,CAAC;AAEhD,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,kBAAkB,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,KAAK,CAAC,EAAE,YAAY,CAAC;KACtB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;AAEpE,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,sBAAsB,CAAC;AACrE,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAAG,UAAU,GAAG,cAAc,CAAC;AAEjF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/solver/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,CAAC;AAEhD,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,kBAAkB,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,KAAK,CAAC,EAAE,YAAY,CAAC;KACtB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;AAEpE,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,sBAAsB,CAAC;AACrE,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAAG,UAAU,GAAG,cAAc,CAAC;AAEjF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type StepCommand } from './run-store.js';
|
|
2
|
+
import type { BrowseSession } from './session.js';
|
|
3
|
+
import { type CompleteRemoteSessionResponse } from './sessions-backend.js';
|
|
4
|
+
export type WorkflowSessionTerminalStatus = 'completed' | 'canceled' | 'error';
|
|
5
|
+
export type WorkflowRunTerminalStatus = 'completed' | 'aborted' | 'failed';
|
|
6
|
+
export type CompleteWorkflowSessionRemoteResult = {
|
|
7
|
+
success: true;
|
|
8
|
+
response: CompleteRemoteSessionResponse;
|
|
9
|
+
completedAt: string;
|
|
10
|
+
runId: string;
|
|
11
|
+
stepId: string | null;
|
|
12
|
+
} | {
|
|
13
|
+
success: false;
|
|
14
|
+
error: 'workflow_session_unavailable' | 'workflow_run_unavailable' | 'workflow_step_unavailable' | 'backend_session_complete_failed';
|
|
15
|
+
reason: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function formatUnknownWorkflowCompletionError(error: unknown): string;
|
|
18
|
+
export declare function clearWorkflowState(session: BrowseSession): BrowseSession;
|
|
19
|
+
export declare function completeWorkflowSessionRemote(params: {
|
|
20
|
+
session: BrowseSession;
|
|
21
|
+
stepId: string | undefined;
|
|
22
|
+
command: StepCommand;
|
|
23
|
+
terminalStatus: WorkflowSessionTerminalStatus;
|
|
24
|
+
runStatus: WorkflowRunTerminalStatus;
|
|
25
|
+
summary: string;
|
|
26
|
+
outcomeType: string;
|
|
27
|
+
message: string;
|
|
28
|
+
reason?: string;
|
|
29
|
+
details?: Record<string, unknown>;
|
|
30
|
+
allowMissingStep?: boolean;
|
|
31
|
+
fetchImpl?: typeof fetch;
|
|
32
|
+
}): Promise<CompleteWorkflowSessionRemoteResult>;
|
|
33
|
+
//# sourceMappingURL=workflow-session-completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-session-completion.d.ts","sourceRoot":"","sources":["../src/workflow-session-completion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,6BAA6B,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;AAC/E,MAAM,MAAM,yBAAyB,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3E,MAAM,MAAM,mCAAmC,GAC3C;IACE,OAAO,EAAE,IAAI,CAAC;IACd,QAAQ,EAAE,6BAA6B,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,GACD;IACE,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EACD,8BAA8B,GAC9B,0BAA0B,GAC1B,2BAA2B,GAC3B,iCAAiC,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAe3E;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAUxE;AAgBD,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,WAAW,CAAC;IACrB,cAAc,EAAE,6BAA6B,CAAC;IAC9C,SAAS,EAAE,yBAAyB,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,GAAG,OAAO,CAAC,mCAAmC,CAAC,CAkI/C"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { loadRunRecord, loadStepRecord } from './run-store.js';
|
|
2
|
+
import { completeRemoteSession, } from './sessions-backend.js';
|
|
3
|
+
export function formatUnknownWorkflowCompletionError(error) {
|
|
4
|
+
if (error instanceof Error) {
|
|
5
|
+
return error.message;
|
|
6
|
+
}
|
|
7
|
+
if (typeof error === 'string') {
|
|
8
|
+
return error;
|
|
9
|
+
}
|
|
10
|
+
if (error && typeof error === 'object') {
|
|
11
|
+
try {
|
|
12
|
+
return JSON.stringify(error);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return Object.prototype.toString.call(error);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return String(error);
|
|
19
|
+
}
|
|
20
|
+
export function clearWorkflowState(session) {
|
|
21
|
+
const nextSession = { ...session };
|
|
22
|
+
delete nextSession.browserSessionId;
|
|
23
|
+
delete nextSession.activeRunId;
|
|
24
|
+
delete nextSession.intentSessionId;
|
|
25
|
+
delete nextSession.currentRequestId;
|
|
26
|
+
delete nextSession.lastKnownStatus;
|
|
27
|
+
delete nextSession.lastEventSeq;
|
|
28
|
+
delete nextSession.transientSecretCache;
|
|
29
|
+
return nextSession;
|
|
30
|
+
}
|
|
31
|
+
function currentPageSummary(session) {
|
|
32
|
+
const pageRef = session.runtime?.currentPageRef;
|
|
33
|
+
const page = pageRef ? session.runtime?.pages[pageRef] : undefined;
|
|
34
|
+
return {
|
|
35
|
+
...(pageRef ? { pageRef } : {}),
|
|
36
|
+
...(page?.url ? { url: page.url } : {}),
|
|
37
|
+
...(page?.title ? { title: page.title } : {}),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export async function completeWorkflowSessionRemote(params) {
|
|
41
|
+
if (!params.session.intentSessionId) {
|
|
42
|
+
return {
|
|
43
|
+
success: false,
|
|
44
|
+
error: 'workflow_session_unavailable',
|
|
45
|
+
reason: 'No active workflow session is bound to this browser session.',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (!params.session.activeRunId) {
|
|
49
|
+
return {
|
|
50
|
+
success: false,
|
|
51
|
+
error: 'workflow_run_unavailable',
|
|
52
|
+
reason: 'The active workflow session is missing its local run binding.',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (!params.stepId && !params.allowMissingStep) {
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
error: 'workflow_step_unavailable',
|
|
59
|
+
reason: 'The terminal command step was not created locally before session completion.',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const run = loadRunRecord(params.session.activeRunId);
|
|
63
|
+
if (!run) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
error: 'workflow_run_unavailable',
|
|
67
|
+
reason: `Local run ${params.session.activeRunId} was not found.`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const step = params.stepId ? loadStepRecord(run.runId, params.stepId) : null;
|
|
71
|
+
if (params.stepId && !step && !params.allowMissingStep) {
|
|
72
|
+
return {
|
|
73
|
+
success: false,
|
|
74
|
+
error: 'workflow_step_unavailable',
|
|
75
|
+
reason: `Local step ${params.stepId} was not found.`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const completedAt = new Date().toISOString();
|
|
79
|
+
const page = currentPageSummary(params.session);
|
|
80
|
+
const clientCompletionId = step?.stepId ?? `${params.command}:${run.runId}:${params.terminalStatus}`;
|
|
81
|
+
try {
|
|
82
|
+
const response = await completeRemoteSession(params.session.intentSessionId, {
|
|
83
|
+
clientCompletionId,
|
|
84
|
+
status: params.terminalStatus,
|
|
85
|
+
command: params.command,
|
|
86
|
+
summary: params.summary,
|
|
87
|
+
timestamp: completedAt,
|
|
88
|
+
...(page.pageRef || page.url || page.title
|
|
89
|
+
? {
|
|
90
|
+
page: {
|
|
91
|
+
...(page.pageRef ? { ref: page.pageRef } : {}),
|
|
92
|
+
...(page.url ? { url: page.url } : {}),
|
|
93
|
+
...(page.title ? { title: page.title } : {}),
|
|
94
|
+
},
|
|
95
|
+
}
|
|
96
|
+
: {}),
|
|
97
|
+
...(params.details ? { details: params.details } : {}),
|
|
98
|
+
run: {
|
|
99
|
+
id: run.runId,
|
|
100
|
+
trace_id: run.traceContext.traceId,
|
|
101
|
+
started_at: run.startedAt,
|
|
102
|
+
ended_at: completedAt,
|
|
103
|
+
source: run.source,
|
|
104
|
+
status: params.runStatus,
|
|
105
|
+
...(run.profile ? { profile: run.profile } : {}),
|
|
106
|
+
...(run.hostHints?.[0] ? { site_host: run.hostHints[0] } : {}),
|
|
107
|
+
protected_run: run.protectedRun,
|
|
108
|
+
},
|
|
109
|
+
...(step
|
|
110
|
+
? {
|
|
111
|
+
step: {
|
|
112
|
+
id: step.stepId,
|
|
113
|
+
ordinal: step.ordinal,
|
|
114
|
+
command: step.command,
|
|
115
|
+
started_at: step.startedAt,
|
|
116
|
+
ended_at: completedAt,
|
|
117
|
+
span_id: step.otel.spanId,
|
|
118
|
+
success: params.terminalStatus !== 'error',
|
|
119
|
+
outcome_type: params.outcomeType,
|
|
120
|
+
message: params.message,
|
|
121
|
+
...(params.reason ? { reason: params.reason } : {}),
|
|
122
|
+
...(step.refs?.pageRef
|
|
123
|
+
? { page_ref: step.refs.pageRef }
|
|
124
|
+
: page.pageRef
|
|
125
|
+
? { page_ref: page.pageRef }
|
|
126
|
+
: {}),
|
|
127
|
+
...(step.refs?.targetRef ? { target_ref: step.refs.targetRef } : {}),
|
|
128
|
+
...(step.refs?.surfaceRef ? { surface_ref: step.refs.surfaceRef } : {}),
|
|
129
|
+
...(step.refs?.fillRef ? { fill_ref: step.refs.fillRef } : {}),
|
|
130
|
+
...(step.beforeSnapshotId ? { before_snapshot_id: step.beforeSnapshotId } : {}),
|
|
131
|
+
...(step.afterSnapshotId ? { after_snapshot_id: step.afterSnapshotId } : {}),
|
|
132
|
+
event_count: step.eventIds.length,
|
|
133
|
+
child_span_count: step.childSpans?.length ?? 0,
|
|
134
|
+
protected_step: step.protectedStep,
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
: {}),
|
|
138
|
+
}, {
|
|
139
|
+
fetchImpl: params.fetchImpl,
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
success: true,
|
|
143
|
+
response,
|
|
144
|
+
completedAt,
|
|
145
|
+
runId: run.runId,
|
|
146
|
+
stepId: step?.stepId ?? null,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
return {
|
|
151
|
+
success: false,
|
|
152
|
+
error: 'backend_session_complete_failed',
|
|
153
|
+
reason: formatUnknownWorkflowCompletionError(error),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuanu-ai/agentbrowse",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.49",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Browser automation CLI for AI agents: control a CDP browser, observe UI surfaces, act on refs, extract data, capture screenshots, complete protected fills, and solve captchas",
|
|
6
6
|
"keywords": [
|
|
@@ -41,8 +41,16 @@
|
|
|
41
41
|
"node": ">=18.0.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
|
+
"build:config:dev": "node scripts/write-build-config.mjs https://durcottggsiesxxqzvbb.supabase.co/functions/v1/api",
|
|
45
|
+
"build:config:prod": "node scripts/write-build-config.mjs https://agents-api.mercuryo.io/functions/v1/api",
|
|
44
46
|
"build": "node -e \"require('node:fs').rmSync('dist',{ recursive: true, force: true })\" && tsc -p tsconfig.build.json",
|
|
45
47
|
"agentbrowse": "tsx src/index.ts",
|
|
48
|
+
"poc:browserql": "tsx poc/browserql-execution-layer/src/cli.ts",
|
|
49
|
+
"poc:browserql:check-types": "tsc --noEmit -p poc/browserql-execution-layer/tsconfig.json",
|
|
50
|
+
"poc:agentql": "tsx poc/agentql-semantic-grounding/src/cli.ts",
|
|
51
|
+
"poc:agentql:check-types": "tsc --noEmit -p poc/agentql-semantic-grounding/tsconfig.json",
|
|
52
|
+
"poc:skyvern": "tsx poc/skyvern-managed-agent/src/cli.ts",
|
|
53
|
+
"poc:skyvern:check-types": "tsc --noEmit -p poc/skyvern-managed-agent/tsconfig.json",
|
|
46
54
|
"test": "pnpm run test:unit && pnpm run test:e2e",
|
|
47
55
|
"test:unit": "vitest run --exclude \"src/__tests__/*.e2e.test.ts\"",
|
|
48
56
|
"test:e2e": "vitest run --no-file-parallelism --maxWorkers=1 src/__tests__/observe-stagehand.e2e.test.ts src/__tests__/extract.e2e.test.ts src/__tests__/protected-fill.e2e.test.ts src/__tests__/runtime.e2e.test.ts",
|
|
@@ -63,6 +71,8 @@
|
|
|
63
71
|
"devDependencies": {
|
|
64
72
|
"@agentpay/config": "workspace:*",
|
|
65
73
|
"@types/node": "^22.0.0",
|
|
74
|
+
"agentql": "^1.18.1",
|
|
75
|
+
"playwright": "^1.58.2",
|
|
66
76
|
"tsx": "^4.19.0",
|
|
67
77
|
"typescript": "5.9.2",
|
|
68
78
|
"vitest": "^4.0.18"
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* browse create-intent <fillRef> <storedSecretRef> — Create or reuse a stored-secret access intent.
|
|
3
|
-
*/
|
|
4
|
-
import type { BrowseSession } from '../session.js';
|
|
5
|
-
export declare function createIntent(session: BrowseSession, fillRef: string, storedSecretRef: string): Promise<void>;
|
|
6
|
-
//# sourceMappingURL=create-intent.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-intent.d.ts","sourceRoot":"","sources":["../../src/commands/create-intent.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAmBnD,wBAAsB,YAAY,CAChC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAqEf"}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* browse create-intent <fillRef> <storedSecretRef> — Create or reuse a stored-secret access intent.
|
|
3
|
-
*/
|
|
4
|
-
import { outputFailure, outputJSON } from '../output.js';
|
|
5
|
-
import { getFillableForm, saveSecretIntentSnapshot } from '../runtime-state.js';
|
|
6
|
-
import { saveSession } from '../session.js';
|
|
7
|
-
import { tryResolveCatalogHost } from '../secrets/catalog-sync.js';
|
|
8
|
-
import { getSecretBackend } from '../secrets/backend.js';
|
|
9
|
-
import { describeSecretIntentStatus, serializeSecretIntent } from '../secrets/intent-output.js';
|
|
10
|
-
function deriveRequestedFieldKeys(fillableForm, storedSecret) {
|
|
11
|
-
if (storedSecret.fieldKeys && storedSecret.fieldKeys.length > 0) {
|
|
12
|
-
return [...storedSecret.fieldKeys];
|
|
13
|
-
}
|
|
14
|
-
return fillableForm.fields.map((field) => field.fieldKey);
|
|
15
|
-
}
|
|
16
|
-
export async function createIntent(session, fillRef, storedSecretRef) {
|
|
17
|
-
const fillableForm = getFillableForm(session, fillRef);
|
|
18
|
-
if (!fillableForm) {
|
|
19
|
-
return outputFailure({
|
|
20
|
-
error: 'unknown_fill_ref',
|
|
21
|
-
outcomeType: 'blocked',
|
|
22
|
-
message: 'Protected intent was not created because the requested fill reference is unknown.',
|
|
23
|
-
reason: 'The provided fillRef does not match any currently observed protected fill target.',
|
|
24
|
-
fillRef,
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
const storedSecret = fillableForm.storedSecretCandidates.find((candidate) => candidate.storedSecretRef === storedSecretRef);
|
|
28
|
-
if (!storedSecret) {
|
|
29
|
-
return outputFailure({
|
|
30
|
-
error: 'stored_secret_not_available_for_fill_ref',
|
|
31
|
-
outcomeType: 'blocked',
|
|
32
|
-
message: 'Protected intent was not created because this stored secret is not available for the requested fill target.',
|
|
33
|
-
reason: 'The provided storedSecretRef is not a candidate for the requested protected fill target.',
|
|
34
|
-
fillRef,
|
|
35
|
-
storedSecretRef,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
const pageUrl = session.runtime?.pages?.[fillableForm.pageRef]?.url;
|
|
39
|
-
const host = tryResolveCatalogHost(pageUrl);
|
|
40
|
-
if (!host) {
|
|
41
|
-
return outputFailure({
|
|
42
|
-
error: 'secret_intent_host_resolution_failed',
|
|
43
|
-
outcomeType: 'blocked',
|
|
44
|
-
message: 'Protected intent was not created because AgentBrowse could not determine the current site host.',
|
|
45
|
-
reason: 'The current page URL did not resolve to a usable host for protected intent creation.',
|
|
46
|
-
fillRef,
|
|
47
|
-
storedSecretRef,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
const result = await getSecretBackend().createOrReuseSecretIntent({
|
|
51
|
-
fillRef,
|
|
52
|
-
storedSecretRef,
|
|
53
|
-
host,
|
|
54
|
-
pageRef: fillableForm.pageRef,
|
|
55
|
-
scopeRef: fillableForm.scopeRef,
|
|
56
|
-
purpose: fillableForm.purpose,
|
|
57
|
-
secretKind: storedSecret.kind,
|
|
58
|
-
requestedFieldKeys: deriveRequestedFieldKeys(fillableForm, storedSecret),
|
|
59
|
-
});
|
|
60
|
-
const snapshot = saveSecretIntentSnapshot(session, result.intent);
|
|
61
|
-
saveSession(session);
|
|
62
|
-
const statusContract = describeSecretIntentStatus(snapshot.status);
|
|
63
|
-
const reasonPrefix = result.reused
|
|
64
|
-
? 'AgentBrowse reused an existing intent for this fill target.'
|
|
65
|
-
: 'AgentBrowse created a new intent for this fill target.';
|
|
66
|
-
outputJSON({
|
|
67
|
-
success: true,
|
|
68
|
-
...serializeSecretIntent(snapshot),
|
|
69
|
-
reused: result.reused,
|
|
70
|
-
...(statusContract.outcomeType ? { outcomeType: statusContract.outcomeType } : {}),
|
|
71
|
-
message: statusContract.message,
|
|
72
|
-
reason: `${reasonPrefix} ${statusContract.reason}`,
|
|
73
|
-
...(statusContract.nextAction ? { nextAction: statusContract.nextAction } : {}),
|
|
74
|
-
});
|
|
75
|
-
}
|