@nuanu-ai/agentbrowse 0.2.31 → 0.2.33

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.
@@ -24,7 +24,7 @@ function ensureValue(action, value) {
24
24
  return value;
25
25
  throw new Error(`Act value is required for action: ${action}`);
26
26
  }
27
- const MUTABLE_FIELD_REBIND_RETRY_DELAYS_MS = [0, 25, 50];
27
+ const MUTABLE_FIELD_REBIND_RETRY_DELAYS_MS = [0, 25, 50, 100];
28
28
  function emitActPreflightFailure(params) {
29
29
  return outputContractFailure({
30
30
  error: params.error,
@@ -1 +1 @@
1
- {"version":3,"file":"captcha-solve.d.ts","sourceRoot":"","sources":["../../src/commands/captcha-solve.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAOnD,wBAAsB,YAAY,CAChC,OAAO,EAAE,aAAa,GAAG,IAAI,EAC7B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAyCf"}
1
+ {"version":3,"file":"captcha-solve.d.ts","sourceRoot":"","sources":["../../src/commands/captcha-solve.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAOnD,wBAAsB,YAAY,CAChC,OAAO,EAAE,aAAa,GAAG,IAAI,EAC7B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CA6Cf"}
@@ -26,12 +26,15 @@ export async function captchaSolve(session, timeoutSeconds) {
26
26
  const gateway = resolveAgentpayGatewayConfig();
27
27
  applyAgentpayGatewayEnv(gateway);
28
28
  const cdpUrl = session.cdpUrl;
29
+ const sessionProxy = session.transport?.proxyMode === 'proxy' ? session.transport.proxy : undefined;
29
30
  const timeoutMs = Math.max(1, timeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS) * 1000;
30
31
  info(`[captcha] solve-captcha started (timeout ${Math.ceil(timeoutMs / 1000)}s, endpoint ${cdpUrl})`);
31
32
  const result = await solveCaptchasByCdp(cdpUrl, gateway.apiKey, {
32
33
  timeoutMs,
33
34
  solveTimeoutMs: Math.min(timeoutMs, 120000),
34
35
  apiUrl: gateway.apiUrl,
36
+ proxy: sessionProxy,
37
+ sharedTransport: Boolean(sessionProxy),
35
38
  onProgress: (message) => info(message),
36
39
  });
37
40
  outputJSON({
@@ -61,11 +61,12 @@ function buildLaunchFailure(err) {
61
61
  async function launchManaged(url, profileName, headless, compact, proxyOverride, noProxy = false) {
62
62
  let session;
63
63
  let browser = null;
64
+ let runtimeProxy;
64
65
  let secretCatalogSummary;
65
66
  try {
66
67
  const baseProfile = ensureProfile(profileName);
67
68
  const config = readConfig();
68
- const runtimeProxy = resolveLaunchProxy({
69
+ runtimeProxy = resolveLaunchProxy({
69
70
  profileProxy: baseProfile.fingerprint.proxy,
70
71
  configProxy: config.defaults?.proxy,
71
72
  cliProxy: proxyOverride,
@@ -94,6 +95,14 @@ async function launchManaged(url, profileName, headless, compact, proxyOverride,
94
95
  pid: session.pid,
95
96
  profile: profileName,
96
97
  launchedAt: new Date().toISOString(),
98
+ transport: runtimeProxy
99
+ ? {
100
+ proxyMode: 'proxy',
101
+ proxy: runtimeProxy,
102
+ }
103
+ : {
104
+ proxyMode: 'direct',
105
+ },
97
106
  capabilities: {
98
107
  captchaSolve: true,
99
108
  },
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA0QA,iBAAe,IAAI,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqKhE;AAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAEhB,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAWzF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA2QA,iBAAe,IAAI,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsKhE;AAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAEhB,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAWzF"}
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import { preflightAgentpayGateway } from './agentpay-gateway.js';
7
7
  import { browseCommand, browseCommandName } from './command-name.js';
8
8
  import { loadSession } from './session.js';
9
9
  import { outputError, outputJSON, fatal, info } from './output.js';
10
+ import { applyDemoProxyBootstrapFromEnv } from './solver/config.js';
10
11
  function usageText() {
11
12
  return `Usage: ${browseCommandName()} <command> [args] [options]
12
13
 
@@ -214,6 +215,7 @@ function requireSessionRecord() {
214
215
  };
215
216
  }
216
217
  async function main(argv = process.argv) {
218
+ applyDemoProxyBootstrapFromEnv();
217
219
  const parsed = getCommand(argv);
218
220
  if (!parsed)
219
221
  process.exit(1);
package/dist/session.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import type { BrowseRuntimeState } from './runtime-state.js';
6
6
  import type { StoredSecretFieldKey } from './secrets/types.js';
7
+ import type { ProxyConfig } from './solver/types.js';
7
8
  export interface CachedTransientSecretEntry {
8
9
  intentId: string;
9
10
  fillRef: string;
@@ -20,6 +21,7 @@ export interface BrowseSession {
20
21
  port?: number;
21
22
  profile?: string;
22
23
  identity?: BrowseSessionIdentity;
24
+ transport?: BrowseSessionTransport;
23
25
  capabilities?: {
24
26
  captchaSolve?: boolean;
25
27
  };
@@ -34,6 +36,10 @@ export interface BrowseSessionIdentity {
34
36
  launchedAt: string;
35
37
  ownership: 'agentbrowse';
36
38
  }
39
+ export interface BrowseSessionTransport {
40
+ proxyMode: 'direct' | 'proxy';
41
+ proxy?: ProxyConfig;
42
+ }
37
43
  export declare function cleanupTransientSecretCache(session: BrowseSession, options?: {
38
44
  now?: string;
39
45
  }): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAK/D,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,YAAY,CAAC,EAAE;QACb,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;CACnE;AAED,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;CAC1B;AAkDD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,OAAO,CAqBT;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,0BAA0B,GAChC,0BAA0B,CAQ5B;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,0BAA0B,GAAG,IAAI,CAMnC;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAW7F;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAW/D;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,CAAC,GAChD,aAAa,CAaf;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAGxD;AAED,wBAAgB,WAAW,IAAI,aAAa,GAAG,IAAI,CAclD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,GAAG,MAAM,CAWpE;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,CAE3E;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,GACxC,OAAO,IAAI,aAAa,GAAG;IAAE,QAAQ,EAAE,qBAAqB,CAAA;CAAE,CAahE;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAO9D"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import type { DetectedCaptcha } from './types.js';
4
4
  export type SolveVisibleCaptchasOptions = {
5
5
  solveTimeoutMs?: number;
6
6
  onProgress?: (message: string) => void;
7
+ sharedTransport?: boolean;
7
8
  skipCaptcha?: (captcha: DetectedCaptcha) => boolean;
8
9
  onSolvedCaptcha?: (captcha: DetectedCaptcha) => void;
9
10
  onCaptchaResult?: (result: CaptchaSolveOutcome) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"captcha-detector.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,2BAA2B,GAAG;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC;IACpD,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACrD,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAKF,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAwI3E;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAG7F;AAED,wBAAsB,+BAA+B,CACnD,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,EACrB,IAAI,CAAC,EAAE,2BAA2B,GACjC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAuHhC;AA2YD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA4B3E"}
1
+ {"version":3,"file":"captcha-detector.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,2BAA2B,GAAG;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC;IACpD,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACrD,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAKF,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAwI3E;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAG7F;AAED,wBAAsB,+BAA+B,CACnD,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,EACrB,IAAI,CAAC,EAAE,2BAA2B,GACjC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAuHhC;AA2YD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA4B3E"}
@@ -128,7 +128,7 @@ export async function solveVisibleCaptchasWithOptions(page, solver, opts) {
128
128
  opts?.onCaptchaResult?.(missingParamsOutcome);
129
129
  continue;
130
130
  }
131
- if (captcha.variant === 'cloudflare-challenge') {
131
+ if (captcha.variant === 'cloudflare-challenge' && opts?.sharedTransport !== true) {
132
132
  const transportRequiredOutcome = {
133
133
  captcha,
134
134
  injected: false,
@@ -1,9 +1,12 @@
1
+ import type { ProxyConfig } from './types.js';
1
2
  export type SolveCaptchasByCdpOptions = {
2
3
  timeoutMs?: number;
3
4
  pollIntervalMs?: number;
4
5
  solveTimeoutMs?: number;
5
6
  connectTimeoutMs?: number;
6
7
  apiUrl?: string;
8
+ proxy?: ProxyConfig;
9
+ sharedTransport?: boolean;
7
10
  onProgress?: (message: string) => void;
8
11
  };
9
12
  export type SolveCaptchasByCdpResult = {
@@ -1 +1 @@
1
- {"version":3,"file":"captcha-runtime.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-runtime.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAMF,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,yBAAyB,GAC/B,OAAO,CAAC,wBAAwB,CAAC,CA0HnC"}
1
+ {"version":3,"file":"captcha-runtime.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-runtime.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAMF,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,yBAAyB,GAC/B,OAAO,CAAC,wBAAwB,CAAC,CA6HnC"}
@@ -10,6 +10,7 @@ export async function solveCaptchasByCdp(cdpUrl, apiKey, opts) {
10
10
  const connectTimeoutMs = opts?.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
11
11
  const deadline = Date.now() + timeoutMs;
12
12
  const onProgress = opts?.onProgress;
13
+ const sharedTransport = opts?.sharedTransport ?? Boolean(opts?.proxy);
13
14
  onProgress?.('[captcha] connecting to browser...');
14
15
  const browser = await withTimeout(puppeteer.connect(buildConnectOptions(cdpUrl)), connectTimeoutMs, `Failed to connect to browser within ${Math.ceil(connectTimeoutMs / 1000)}s`);
15
16
  try {
@@ -17,6 +18,7 @@ export async function solveCaptchasByCdp(cdpUrl, apiKey, opts) {
17
18
  apiKey,
18
19
  apiUrl: opts?.apiUrl,
19
20
  taskTimeoutMs: opts?.solveTimeoutMs,
21
+ proxy: opts?.proxy,
20
22
  });
21
23
  let solved = 0;
22
24
  const detectedKeys = new Set();
@@ -56,6 +58,7 @@ export async function solveCaptchasByCdp(cdpUrl, apiKey, opts) {
56
58
  const outcomes = await solveVisibleCaptchasWithOptions(page, solver, {
57
59
  solveTimeoutMs: opts?.solveTimeoutMs,
58
60
  onProgress,
61
+ sharedTransport,
59
62
  skipCaptcha: (captcha) => solvedKeys.has(captchaKey(captcha)),
60
63
  });
61
64
  const hasMissingParamsChallenge = outcomes.some((outcome) => outcome.error === 'challenge-params-missing');
@@ -1,3 +1,4 @@
1
+ import type { ProxyConfig } from './types.js';
1
2
  export type CaptchaType = 'recaptcha-v2' | 'hcaptcha' | 'turnstile';
2
3
  export type CaptchaSolverConfig = {
3
4
  apiKey: string;
@@ -5,12 +6,14 @@ export type CaptchaSolverConfig = {
5
6
  requestTimeoutMs?: number;
6
7
  taskPollIntervalMs?: number;
7
8
  taskTimeoutMs?: number;
9
+ proxy?: ProxyConfig;
8
10
  };
9
11
  export type CaptchaSolveRequest = {
10
12
  action?: string;
11
13
  data?: string;
12
14
  pagedata?: string;
13
15
  userAgent?: string;
16
+ proxy?: ProxyConfig;
14
17
  };
15
18
  export type CaptchaSolveResult = {
16
19
  token: string;
@@ -25,6 +28,7 @@ export declare class CaptchaSolver {
25
28
  private readonly requestTimeoutMs;
26
29
  private readonly taskPollIntervalMs;
27
30
  private readonly taskTimeoutMs;
31
+ private readonly proxy?;
28
32
  constructor(config: CaptchaSolverConfig);
29
33
  solve(type: CaptchaType, siteKey: string, pageUrl: string, request?: CaptchaSolveRequest): Promise<CaptchaSolveResult>;
30
34
  private createTask;
@@ -1 +1 @@
1
- {"version":3,"file":"captcha-solver.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-solver.ts"],"names":[],"mappings":"AAAA,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;CACxB,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;CACpB,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;gBAE3B,MAAM,EAAE,mBAAmB;IAejC,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;YAiBV,aAAa;YAOb,OAAO;CAsCtB"}
1
+ {"version":3,"file":"captcha-solver.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-solver.ts"],"names":[],"mappings":"AAAA,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;CAsCtB"}
@@ -10,12 +10,14 @@ export class CaptchaSolver {
10
10
  requestTimeoutMs;
11
11
  taskPollIntervalMs;
12
12
  taskTimeoutMs;
13
+ proxy;
13
14
  constructor(config) {
14
15
  this.apiKey = config.apiKey;
15
16
  this.apiUrl = (config.apiUrl || process.env.AGENTPAY_API_URL || '').replace(/\/$/, '');
16
17
  this.requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
17
18
  this.taskPollIntervalMs = config.taskPollIntervalMs ?? DEFAULT_TASK_POLL_MS;
18
19
  this.taskTimeoutMs = config.taskTimeoutMs ?? DEFAULT_TASK_TIMEOUT_MS;
20
+ this.proxy = config.proxy;
19
21
  if (!this.apiKey || this.apiKey.trim().length === 0) {
20
22
  throw new Error('CaptchaSolver: apiKey is required');
21
23
  }
@@ -50,6 +52,7 @@ export class CaptchaSolver {
50
52
  data: request?.data,
51
53
  pagedata: request?.pagedata,
52
54
  user_agent: request?.userAgent,
55
+ proxy: request?.proxy ?? this.proxy,
53
56
  });
54
57
  }
55
58
  async getTaskStatus(taskId) {
@@ -5,6 +5,7 @@ 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 applyDemoProxyBootstrapFromEnv(): boolean;
8
9
  export declare function getProfileDir(profileName: string): string;
9
10
  export declare function getExistingProfileDir(profileName: string): string | null;
10
11
  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;AAU/C,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAQvC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED,wBAAgB,UAAU,IAAI,YAAY,CAYzC;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,CAUxE;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/solver/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAW/C,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAQvC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED,wBAAgB,UAAU,IAAI,YAAY,CAYzC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAGtD;AAED,wBAAgB,8BAA8B,IAAI,OAAO,CAmBxD;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUxE;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9D"}
@@ -8,6 +8,7 @@ const PRIMARY_CONFIG_PATH = path.join(PRIMARY_DIR, 'config.json');
8
8
  const LEGACY_CONFIG_PATH = path.join(LEGACY_DIR, 'config.json');
9
9
  const PRIMARY_PROFILES_DIR = path.join(PRIMARY_DIR, 'profiles');
10
10
  const LEGACY_PROFILES_DIR = path.join(LEGACY_DIR, 'profiles');
11
+ const DEMO_PROXY_ENV = 'AGENTBROWSE_DEMO_PROXY';
11
12
  export function getSolverDir() {
12
13
  return PRIMARY_DIR;
13
14
  }
@@ -45,6 +46,24 @@ export function writeConfig(config) {
45
46
  ensureDirs();
46
47
  fs.writeFileSync(PRIMARY_CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf-8');
47
48
  }
49
+ export function applyDemoProxyBootstrapFromEnv() {
50
+ const demoProxy = process.env[DEMO_PROXY_ENV]?.trim();
51
+ if (!demoProxy) {
52
+ return false;
53
+ }
54
+ const current = readConfig();
55
+ if (current.defaults?.proxy === demoProxy) {
56
+ return false;
57
+ }
58
+ writeConfig({
59
+ ...current,
60
+ defaults: {
61
+ ...current.defaults,
62
+ proxy: demoProxy,
63
+ },
64
+ });
65
+ return true;
66
+ }
48
67
  export function getProfileDir(profileName) {
49
68
  return path.join(PRIMARY_PROFILES_DIR, profileName);
50
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuanu-ai/agentbrowse",
3
- "version": "0.2.31",
3
+ "version": "0.2.33",
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": [