agents 0.15.0 → 0.16.0

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.
Files changed (53) hide show
  1. package/dist/{agent-tool-types-VPsjVYL0.d.ts → agent-tool-types-NofdbL9X.d.ts} +57 -4
  2. package/dist/agent-tool-types.d.ts +1 -1
  3. package/dist/{agent-tools-BGpgfpJT.d.ts → agent-tools-DLquv-dp.d.ts} +2 -2
  4. package/dist/agent-tools.d.ts +1 -1
  5. package/dist/browser/ai.d.ts +126 -7
  6. package/dist/browser/ai.js +73 -29
  7. package/dist/browser/ai.js.map +1 -1
  8. package/dist/browser/index.d.ts +81 -69
  9. package/dist/browser/index.js +3 -2
  10. package/dist/browser/tanstack-ai.d.ts +13 -7
  11. package/dist/browser/tanstack-ai.js +18 -19
  12. package/dist/browser/tanstack-ai.js.map +1 -1
  13. package/dist/chat/index.d.ts +111 -5
  14. package/dist/chat/index.js +207 -35
  15. package/dist/chat/index.js.map +1 -1
  16. package/dist/chat-sdk/index.d.ts +1 -1
  17. package/dist/{classPrivateFieldGet2-Beqsfu2Z.js → classPrivateFieldGet2-CZ7QjTXN.js} +5 -5
  18. package/dist/{classPrivateMethodInitSpec-B5ko1s2R.js → classPrivateMethodInitSpec-D-0__zd9.js} +2 -2
  19. package/dist/client.d.ts +19 -2
  20. package/dist/client.js +31 -11
  21. package/dist/client.js.map +1 -1
  22. package/dist/{compaction-helpers-BEUILPss.d.ts → compaction-helpers-DVcu5lPN.d.ts} +91 -12
  23. package/dist/connector-D6yYzYHg.js +1080 -0
  24. package/dist/connector-D6yYzYHg.js.map +1 -0
  25. package/dist/connector-DXursxV5.d.ts +340 -0
  26. package/dist/experimental/memory/session/index.d.ts +75 -12
  27. package/dist/experimental/memory/session/index.js +226 -21
  28. package/dist/experimental/memory/session/index.js.map +1 -1
  29. package/dist/experimental/memory/utils/index.d.ts +2 -2
  30. package/dist/{index-CPe1OtI0.d.ts → index-B7IbEeze.d.ts} +32 -1
  31. package/dist/index.d.ts +8 -2
  32. package/dist/index.js +116 -45
  33. package/dist/index.js.map +1 -1
  34. package/dist/mcp/client.d.ts +1 -1
  35. package/dist/mcp/index.d.ts +1 -1
  36. package/dist/mcp/index.js +1 -1
  37. package/dist/mcp/index.js.map +1 -1
  38. package/dist/observability/index.d.ts +1 -1
  39. package/dist/react.d.ts +12 -1
  40. package/dist/react.js +101 -30
  41. package/dist/react.js.map +1 -1
  42. package/dist/{retries-CF_HKSlJ.d.ts → retries-CwlpAGet.d.ts} +35 -5
  43. package/dist/retries.d.ts +9 -5
  44. package/dist/retries.js +87 -1
  45. package/dist/retries.js.map +1 -1
  46. package/dist/serializable.d.ts +1 -1
  47. package/dist/skills/index.js +2 -2
  48. package/dist/sub-routing.d.ts +1 -1
  49. package/dist/workflows.d.ts +1 -1
  50. package/package.json +10 -10
  51. package/dist/shared-4CAYLCTO.d.ts +0 -34
  52. package/dist/shared-wyII629d.js +0 -432
  53. package/dist/shared-wyII629d.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"retries.js","names":[],"sources":["../src/retries.ts"],"sourcesContent":["/**\n * Retry options for schedule(), scheduleEvery(), queue(), and this.retry().\n */\nexport interface RetryOptions {\n /** Max number of attempts (including the first). Default: 3 */\n maxAttempts?: number;\n /** Base delay in ms for exponential backoff. Default: 100 */\n baseDelayMs?: number;\n /** Max delay cap in ms. Default: 3000 */\n maxDelayMs?: number;\n}\n\n/**\n * Internal options for tryN -- extends RetryOptions with a shouldRetry predicate.\n */\ninterface TryNOptions extends RetryOptions {\n /**\n * Predicate to determine if an error should be retried.\n * Receives the error and the next attempt number (so callers can\n * make attempt-aware decisions).\n * If not provided, all errors are retried.\n */\n shouldRetry?: (err: unknown, nextAttempt: number) => boolean;\n}\n\n/**\n * Validate retry options eagerly so invalid config fails at enqueue/schedule time\n * rather than at execution time. Checks individual field ranges, enforces integer\n * maxAttempts, and validates cross-field constraints after resolving against\n * defaults when provided.\n */\nexport function validateRetryOptions(\n options: RetryOptions,\n defaults?: Required<RetryOptions>\n): void {\n if (options.maxAttempts !== undefined) {\n if (!Number.isFinite(options.maxAttempts) || options.maxAttempts < 1) {\n throw new Error(\"retry.maxAttempts must be >= 1\");\n }\n if (!Number.isInteger(options.maxAttempts)) {\n throw new Error(\"retry.maxAttempts must be an integer\");\n }\n }\n if (options.baseDelayMs !== undefined) {\n if (!Number.isFinite(options.baseDelayMs) || options.baseDelayMs <= 0) {\n throw new Error(\"retry.baseDelayMs must be > 0\");\n }\n }\n if (options.maxDelayMs !== undefined) {\n if (!Number.isFinite(options.maxDelayMs) || options.maxDelayMs <= 0) {\n throw new Error(\"retry.maxDelayMs must be > 0\");\n }\n }\n\n // Resolve against defaults (when provided) so that cross-field checks\n // catch e.g. { baseDelayMs: 5000 } against default maxDelayMs: 3000.\n const resolvedBase = options.baseDelayMs ?? defaults?.baseDelayMs;\n const resolvedMax = options.maxDelayMs ?? defaults?.maxDelayMs;\n if (\n resolvedBase !== undefined &&\n resolvedMax !== undefined &&\n resolvedBase > resolvedMax\n ) {\n throw new Error(\"retry.baseDelayMs must be <= retry.maxDelayMs\");\n }\n}\n\n/**\n * Returns the number of milliseconds to wait before retrying a request.\n * Uses the \"Full Jitter\" approach from\n * https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/\n *\n * @param attempt The current attempt number (1-indexed).\n * @param baseDelayMs Base delay multiplier in ms.\n * @param maxDelayMs Maximum delay cap in ms.\n * @returns Milliseconds to wait before retrying.\n */\nexport function jitterBackoff(\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number\n): number {\n const upperBoundMs = Math.min(2 ** attempt * baseDelayMs, maxDelayMs);\n return Math.floor(Math.random() * upperBoundMs);\n}\n\n/**\n * Retry an async function up to `n` total attempts with jittered exponential backoff.\n *\n * @param n Total number of attempts (must be a finite integer >= 1).\n * @param fn The async function to retry. Receives the current attempt number (1-indexed).\n * @param options Retry configuration.\n * @returns The result of `fn` on success.\n * @throws The last error if all attempts fail or `shouldRetry` returns false.\n */\nexport async function tryN<T>(\n n: number,\n fn: (attempt: number) => Promise<T>,\n options?: TryNOptions\n): Promise<T> {\n if (!Number.isFinite(n) || n < 1) {\n throw new Error(\"retry.maxAttempts must be >= 1\");\n }\n n = Math.floor(n);\n\n const rawBase = options?.baseDelayMs ?? 100;\n const rawMax = options?.maxDelayMs ?? 3000;\n\n if (!Number.isFinite(rawBase) || rawBase <= 0) {\n throw new Error(\"retry.baseDelayMs must be > 0\");\n }\n if (!Number.isFinite(rawMax) || rawMax <= 0) {\n throw new Error(\"retry.maxDelayMs must be > 0\");\n }\n\n const baseDelayMs = Math.floor(rawBase);\n const maxDelayMs = Math.floor(rawMax);\n\n if (baseDelayMs > maxDelayMs) {\n throw new Error(\"retry.baseDelayMs must be <= retry.maxDelayMs\");\n }\n\n let attempt = 1;\n while (true) {\n try {\n return await fn(attempt);\n } catch (err) {\n const nextAttempt = attempt + 1;\n if (\n nextAttempt > n ||\n (options?.shouldRetry && !options.shouldRetry(err, nextAttempt))\n ) {\n throw err;\n }\n const delay = jitterBackoff(attempt, baseDelayMs, maxDelayMs);\n await new Promise((resolve) => setTimeout(resolve, delay));\n attempt = nextAttempt;\n }\n }\n}\n\n/**\n * Returns true if the given error is retryable according to Durable Object error handling.\n * See https://developers.cloudflare.com/durable-objects/best-practices/error-handling/\n *\n * An error is retryable if it has `retryable: true` but is NOT an overloaded error.\n */\nexport function isErrorRetryable(err: unknown): boolean {\n if (typeof err !== \"object\" || err === null) {\n return false;\n }\n const msg = String(err);\n const typed = err as { retryable?: boolean; overloaded?: boolean };\n return (\n Boolean(typed.retryable) &&\n !typed.overloaded &&\n !msg.includes(\"Durable Object is overloaded\")\n );\n}\n"],"mappings":";;;;;;;AA+BA,SAAgB,qBACd,SACA,UACM;CACN,IAAI,QAAQ,gBAAgB,KAAA,GAAW;EACrC,IAAI,CAAC,OAAO,SAAS,QAAQ,WAAW,KAAK,QAAQ,cAAc,GACjE,MAAM,IAAI,MAAM,gCAAgC;EAElD,IAAI,CAAC,OAAO,UAAU,QAAQ,WAAW,GACvC,MAAM,IAAI,MAAM,sCAAsC;CAE1D;CACA,IAAI,QAAQ,gBAAgB,KAAA;MACtB,CAAC,OAAO,SAAS,QAAQ,WAAW,KAAK,QAAQ,eAAe,GAClE,MAAM,IAAI,MAAM,+BAA+B;CAAA;CAGnD,IAAI,QAAQ,eAAe,KAAA;MACrB,CAAC,OAAO,SAAS,QAAQ,UAAU,KAAK,QAAQ,cAAc,GAChE,MAAM,IAAI,MAAM,8BAA8B;CAAA;CAMlD,MAAM,eAAe,QAAQ,eAAe,UAAU;CACtD,MAAM,cAAc,QAAQ,cAAc,UAAU;CACpD,IACE,iBAAiB,KAAA,KACjB,gBAAgB,KAAA,KAChB,eAAe,aAEf,MAAM,IAAI,MAAM,+CAA+C;AAEnE;;;;;;;;;;;AAYA,SAAgB,cACd,SACA,aACA,YACQ;CACR,MAAM,eAAe,KAAK,IAAI,KAAK,UAAU,aAAa,UAAU;CACpE,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY;AAChD;;;;;;;;;;AAWA,eAAsB,KACpB,GACA,IACA,SACY;CACZ,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAC7B,MAAM,IAAI,MAAM,gCAAgC;CAElD,IAAI,KAAK,MAAM,CAAC;CAEhB,MAAM,UAAU,SAAS,eAAe;CACxC,MAAM,SAAS,SAAS,cAAc;CAEtC,IAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,GAC1C,MAAM,IAAI,MAAM,+BAA+B;CAEjD,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,GACxC,MAAM,IAAI,MAAM,8BAA8B;CAGhD,MAAM,cAAc,KAAK,MAAM,OAAO;CACtC,MAAM,aAAa,KAAK,MAAM,MAAM;CAEpC,IAAI,cAAc,YAChB,MAAM,IAAI,MAAM,+CAA+C;CAGjE,IAAI,UAAU;CACd,OAAO,MACL,IAAI;EACF,OAAO,MAAM,GAAG,OAAO;CACzB,SAAS,KAAK;EACZ,MAAM,cAAc,UAAU;EAC9B,IACE,cAAc,KACb,SAAS,eAAe,CAAC,QAAQ,YAAY,KAAK,WAAW,GAE9D,MAAM;EAER,MAAM,QAAQ,cAAc,SAAS,aAAa,UAAU;EAC5D,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,KAAK,CAAC;EACzD,UAAU;CACZ;AAEJ;;;;;;;AAQA,SAAgB,iBAAiB,KAAuB;CACtD,IAAI,OAAO,QAAQ,YAAY,QAAQ,MACrC,OAAO;CAET,MAAM,MAAM,OAAO,GAAG;CACtB,MAAM,QAAQ;CACd,OACE,QAAQ,MAAM,SAAS,KACvB,CAAC,MAAM,cACP,CAAC,IAAI,SAAS,8BAA8B;AAEhD"}
1
+ {"version":3,"file":"retries.js","names":[],"sources":["../src/retries.ts"],"sourcesContent":["/**\n * Retry options for schedule(), scheduleEvery(), queue(), and this.retry().\n */\nexport interface RetryOptions {\n /** Max number of attempts (including the first). Default: 3 */\n maxAttempts?: number;\n /** Base delay in ms for exponential backoff. Default: 100 */\n baseDelayMs?: number;\n /** Max delay cap in ms. Default: 3000 */\n maxDelayMs?: number;\n}\n\n/**\n * Internal options for tryN -- extends RetryOptions with a shouldRetry predicate.\n */\ninterface TryNOptions extends RetryOptions {\n /**\n * Predicate to determine if an error should be retried.\n * Receives the error and the next attempt number (so callers can\n * make attempt-aware decisions).\n * If not provided, all errors are retried.\n */\n shouldRetry?: (err: unknown, nextAttempt: number) => boolean;\n}\n\n/**\n * Validate retry options eagerly so invalid config fails at enqueue/schedule time\n * rather than at execution time. Checks individual field ranges, enforces integer\n * maxAttempts, and validates cross-field constraints after resolving against\n * defaults when provided.\n */\nexport function validateRetryOptions(\n options: RetryOptions,\n defaults?: Required<RetryOptions>\n): void {\n if (options.maxAttempts !== undefined) {\n if (!Number.isFinite(options.maxAttempts) || options.maxAttempts < 1) {\n throw new Error(\"retry.maxAttempts must be >= 1\");\n }\n if (!Number.isInteger(options.maxAttempts)) {\n throw new Error(\"retry.maxAttempts must be an integer\");\n }\n }\n if (options.baseDelayMs !== undefined) {\n if (!Number.isFinite(options.baseDelayMs) || options.baseDelayMs <= 0) {\n throw new Error(\"retry.baseDelayMs must be > 0\");\n }\n }\n if (options.maxDelayMs !== undefined) {\n if (!Number.isFinite(options.maxDelayMs) || options.maxDelayMs <= 0) {\n throw new Error(\"retry.maxDelayMs must be > 0\");\n }\n }\n\n // Resolve against defaults (when provided) so that cross-field checks\n // catch e.g. { baseDelayMs: 5000 } against default maxDelayMs: 3000.\n const resolvedBase = options.baseDelayMs ?? defaults?.baseDelayMs;\n const resolvedMax = options.maxDelayMs ?? defaults?.maxDelayMs;\n if (\n resolvedBase !== undefined &&\n resolvedMax !== undefined &&\n resolvedBase > resolvedMax\n ) {\n throw new Error(\"retry.baseDelayMs must be <= retry.maxDelayMs\");\n }\n}\n\n/**\n * Returns the number of milliseconds to wait before retrying a request.\n * Uses the \"Full Jitter\" approach from\n * https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/\n *\n * @param attempt The current attempt number (1-indexed).\n * @param baseDelayMs Base delay multiplier in ms.\n * @param maxDelayMs Maximum delay cap in ms.\n * @returns Milliseconds to wait before retrying.\n */\nexport function jitterBackoff(\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number\n): number {\n const upperBoundMs = Math.min(2 ** attempt * baseDelayMs, maxDelayMs);\n return Math.floor(Math.random() * upperBoundMs);\n}\n\n/**\n * Retry an async function up to `n` total attempts with jittered exponential backoff.\n *\n * @param n Total number of attempts (must be a finite integer >= 1).\n * @param fn The async function to retry. Receives the current attempt number (1-indexed).\n * @param options Retry configuration.\n * @returns The result of `fn` on success.\n * @throws The last error if all attempts fail or `shouldRetry` returns false.\n */\nexport async function tryN<T>(\n n: number,\n fn: (attempt: number) => Promise<T>,\n options?: TryNOptions\n): Promise<T> {\n if (!Number.isFinite(n) || n < 1) {\n throw new Error(\"retry.maxAttempts must be >= 1\");\n }\n n = Math.floor(n);\n\n const rawBase = options?.baseDelayMs ?? 100;\n const rawMax = options?.maxDelayMs ?? 3000;\n\n if (!Number.isFinite(rawBase) || rawBase <= 0) {\n throw new Error(\"retry.baseDelayMs must be > 0\");\n }\n if (!Number.isFinite(rawMax) || rawMax <= 0) {\n throw new Error(\"retry.maxDelayMs must be > 0\");\n }\n\n const baseDelayMs = Math.floor(rawBase);\n const maxDelayMs = Math.floor(rawMax);\n\n if (baseDelayMs > maxDelayMs) {\n throw new Error(\"retry.baseDelayMs must be <= retry.maxDelayMs\");\n }\n\n let attempt = 1;\n while (true) {\n try {\n return await fn(attempt);\n } catch (err) {\n const nextAttempt = attempt + 1;\n if (\n nextAttempt > n ||\n (options?.shouldRetry && !options.shouldRetry(err, nextAttempt))\n ) {\n throw err;\n }\n const delay = jitterBackoff(attempt, baseDelayMs, maxDelayMs);\n await new Promise((resolve) => setTimeout(resolve, delay));\n attempt = nextAttempt;\n }\n }\n}\n\n/**\n * Returns true if the given error is retryable according to Durable Object error handling.\n * See https://developers.cloudflare.com/durable-objects/best-practices/error-handling/\n *\n * An error is retryable if it has `retryable: true` but is NOT an overloaded error.\n */\nexport function isErrorRetryable(err: unknown): boolean {\n if (typeof err !== \"object\" || err === null) {\n return false;\n }\n const msg = String(err);\n const typed = err as { retryable?: boolean; overloaded?: boolean };\n return (\n Boolean(typed.retryable) &&\n !typed.overloaded &&\n !msg.includes(\"Durable Object is overloaded\")\n );\n}\n\n/**\n * The \"superseded isolate\" platform messages — the invocation is running on an\n * isolate the platform has replaced with a new version (a deploy / code\n * update). For the rest of that invocation every operation throws the same\n * error (code never reloads mid-invocation), so in-process retries are futile;\n * but the next fresh invocation runs the new code and succeeds.\n *\n * workerd surfaces this as a plain `Error` with one of a few messages, all the\n * same failure class — a message match is the only signal:\n * - \"Durable Object reset because its code was updated.\" (DO storage op on a\n * superseded isolate / deploy bounce)\n * - \"This script has been upgraded. Please send a new request to connect to\n * the new version.\" (a stub/connection to a superseded script; the message\n * literally instructs the caller to retry on the new version)\n *\n * The match stays close to the verbatim platform strings (rather than a loose\n * \"upgraded\"/\"reset\" substring) so an ordinary application error that happens\n * to mention those words is NOT misclassified as a supersede.\n */\nconst SUPERSEDED_ISOLATE_PATTERN =\n /reset because its code was updated|this script has been upgraded/i;\n\n/**\n * The \"Network connection lost.\" platform transient — the connection between\n * the isolate and its storage (or another DO) dropped. Unlike a supersede this\n * MAY succeed on an in-process retry (a momentary blip), so it must not skip\n * the in-process retry budget — but during a deploy-reset window it never\n * succeeds in-process and surfaces interleaved with the supersede messages\n * (SQL ops throw `SqlError: SQL query failed: Network connection lost.` while\n * KV ops throw the reset message), so on retry exhaustion it must be treated\n * as the platform's failure, not the callback's.\n */\nconst CONNECTION_LOST_PATTERN = /network connection lost/i;\n\nfunction errorMessageOf(error: unknown): string {\n return error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"\";\n}\n\n/**\n * Iterate an error and its `cause` chain (depth-limited so a cyclic chain\n * can't spin). Wrappers like `SqlError` carry the original platform error in\n * `cause` and may not propagate signal properties (e.g. the CF `retryable`\n * flag), so classification must look through them.\n */\nfunction* selfAndCauses(error: unknown): Generator<unknown> {\n let current = error;\n for (let depth = 0; depth < 8 && current != null; depth++) {\n yield current;\n current =\n typeof current === \"object\"\n ? (current as { cause?: unknown }).cause\n : undefined;\n }\n}\n\n/**\n * Whether an error (or anything in its `cause` chain) is a transient\n * \"superseded isolate\" failure — see `SUPERSEDED_ISOLATE_PATTERN`. In-process\n * retries are futile for this class; the work must be deferred to a fresh\n * invocation, which runs the new code and succeeds.\n */\nexport function isDurableObjectCodeUpdateReset(error: unknown): boolean {\n for (const e of selfAndCauses(error)) {\n if (SUPERSEDED_ISOLATE_PATTERN.test(errorMessageOf(e))) return true;\n }\n return false;\n}\n\n/**\n * Whether an error (or anything in its `cause` chain) is a transient failure\n * of the PLATFORM rather than of the code that threw it:\n *\n * - a superseded-isolate reset (\"reset because its code was updated\" /\n * \"this script has been upgraded\") — a deploy replaced the isolate;\n * - an error the platform itself flags `retryable: true` (excluding\n * overloaded errors, where retrying the same object won't help) — see\n * `isErrorRetryable`;\n * - \"Network connection lost.\" — the storage/stub connection dropped. The\n * CF `retryable` flag does not survive error wrappers (e.g. `SqlError`\n * copies only the message + `cause`) and is absent in some local-dev\n * shapes, so the verbatim message is matched as well.\n *\n * Used to decide whether failed work should be RE-RUN LATER (platform\n * transient — the same work succeeds once the platform recovers, typically\n * seconds after a deploy) versus ABANDONED as genuinely failing (application\n * error — re-running yields the same failure). A genuine application error\n * carries none of these signals, so it is never misclassified by this check.\n */\nexport function isPlatformTransientError(error: unknown): boolean {\n for (const e of selfAndCauses(error)) {\n const message = errorMessageOf(e);\n if (SUPERSEDED_ISOLATE_PATTERN.test(message)) return true;\n if (CONNECTION_LOST_PATTERN.test(message)) return true;\n if (isErrorRetryable(e)) return true;\n }\n return false;\n}\n"],"mappings":";;;;;;;AA+BA,SAAgB,qBACd,SACA,UACM;CACN,IAAI,QAAQ,gBAAgB,KAAA,GAAW;EACrC,IAAI,CAAC,OAAO,SAAS,QAAQ,WAAW,KAAK,QAAQ,cAAc,GACjE,MAAM,IAAI,MAAM,gCAAgC;EAElD,IAAI,CAAC,OAAO,UAAU,QAAQ,WAAW,GACvC,MAAM,IAAI,MAAM,sCAAsC;CAE1D;CACA,IAAI,QAAQ,gBAAgB,KAAA;MACtB,CAAC,OAAO,SAAS,QAAQ,WAAW,KAAK,QAAQ,eAAe,GAClE,MAAM,IAAI,MAAM,+BAA+B;CAAA;CAGnD,IAAI,QAAQ,eAAe,KAAA;MACrB,CAAC,OAAO,SAAS,QAAQ,UAAU,KAAK,QAAQ,cAAc,GAChE,MAAM,IAAI,MAAM,8BAA8B;CAAA;CAMlD,MAAM,eAAe,QAAQ,eAAe,UAAU;CACtD,MAAM,cAAc,QAAQ,cAAc,UAAU;CACpD,IACE,iBAAiB,KAAA,KACjB,gBAAgB,KAAA,KAChB,eAAe,aAEf,MAAM,IAAI,MAAM,+CAA+C;AAEnE;;;;;;;;;;;AAYA,SAAgB,cACd,SACA,aACA,YACQ;CACR,MAAM,eAAe,KAAK,IAAI,KAAK,UAAU,aAAa,UAAU;CACpE,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY;AAChD;;;;;;;;;;AAWA,eAAsB,KACpB,GACA,IACA,SACY;CACZ,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAC7B,MAAM,IAAI,MAAM,gCAAgC;CAElD,IAAI,KAAK,MAAM,CAAC;CAEhB,MAAM,UAAU,SAAS,eAAe;CACxC,MAAM,SAAS,SAAS,cAAc;CAEtC,IAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,GAC1C,MAAM,IAAI,MAAM,+BAA+B;CAEjD,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,GACxC,MAAM,IAAI,MAAM,8BAA8B;CAGhD,MAAM,cAAc,KAAK,MAAM,OAAO;CACtC,MAAM,aAAa,KAAK,MAAM,MAAM;CAEpC,IAAI,cAAc,YAChB,MAAM,IAAI,MAAM,+CAA+C;CAGjE,IAAI,UAAU;CACd,OAAO,MACL,IAAI;EACF,OAAO,MAAM,GAAG,OAAO;CACzB,SAAS,KAAK;EACZ,MAAM,cAAc,UAAU;EAC9B,IACE,cAAc,KACb,SAAS,eAAe,CAAC,QAAQ,YAAY,KAAK,WAAW,GAE9D,MAAM;EAER,MAAM,QAAQ,cAAc,SAAS,aAAa,UAAU;EAC5D,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,KAAK,CAAC;EACzD,UAAU;CACZ;AAEJ;;;;;;;AAQA,SAAgB,iBAAiB,KAAuB;CACtD,IAAI,OAAO,QAAQ,YAAY,QAAQ,MACrC,OAAO;CAET,MAAM,MAAM,OAAO,GAAG;CACtB,MAAM,QAAQ;CACd,OACE,QAAQ,MAAM,SAAS,KACvB,CAAC,MAAM,cACP,CAAC,IAAI,SAAS,8BAA8B;AAEhD;;;;;;;;;;;;;;;;;;;;AAqBA,MAAM,6BACJ;;;;;;;;;;;AAYF,MAAM,0BAA0B;AAEhC,SAAS,eAAe,OAAwB;CAC9C,OAAO,iBAAiB,QACpB,MAAM,UACN,OAAO,UAAU,WACf,QACA;AACR;;;;;;;AAQA,UAAU,cAAc,OAAoC;CAC1D,IAAI,UAAU;CACd,KAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,WAAW,MAAM,SAAS;EACzD,MAAM;EACN,UACE,OAAO,YAAY,WACd,QAAgC,QACjC,KAAA;CACR;AACF;;;;;;;AAQA,SAAgB,+BAA+B,OAAyB;CACtE,KAAK,MAAM,KAAK,cAAc,KAAK,GACjC,IAAI,2BAA2B,KAAK,eAAe,CAAC,CAAC,GAAG,OAAO;CAEjE,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,yBAAyB,OAAyB;CAChE,KAAK,MAAM,KAAK,cAAc,KAAK,GAAG;EACpC,MAAM,UAAU,eAAe,CAAC;EAChC,IAAI,2BAA2B,KAAK,OAAO,GAAG,OAAO;EACrD,IAAI,wBAAwB,KAAK,OAAO,GAAG,OAAO;EAClD,IAAI,iBAAiB,CAAC,GAAG,OAAO;CAClC;CACA,OAAO;AACT"}
@@ -1,4 +1,4 @@
1
- import { $ as StreamingResponse } from "./agent-tool-types-VPsjVYL0.js";
1
+ import { $ as StreamingResponse } from "./agent-tool-types-NofdbL9X.js";
2
2
 
3
3
  //#region src/serializable.d.ts
4
4
  type SerializablePrimitive = undefined | null | string | number | boolean;
@@ -1,5 +1,5 @@
1
- import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "../classPrivateFieldGet2-Beqsfu2Z.js";
2
- import { t as _classPrivateMethodInitSpec } from "../classPrivateMethodInitSpec-B5ko1s2R.js";
1
+ import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "../classPrivateFieldGet2-CZ7QjTXN.js";
2
+ import { t as _classPrivateMethodInitSpec } from "../classPrivateMethodInitSpec-D-0__zd9.js";
3
3
  import { tool } from "ai";
4
4
  import { RpcTarget } from "cloudflare:workers";
5
5
  import { z } from "zod";
@@ -4,7 +4,7 @@ import {
4
4
  Kt as SubAgentPathMatch,
5
5
  Yt as routeSubAgentRequest,
6
6
  qt as getSubAgentByName
7
- } from "./agent-tool-types-VPsjVYL0.js";
7
+ } from "./agent-tool-types-NofdbL9X.js";
8
8
  export {
9
9
  SUB_PREFIX,
10
10
  SubAgentPathMatch,
@@ -1,4 +1,4 @@
1
- import { b as Agent } from "./agent-tool-types-VPsjVYL0.js";
1
+ import { b as Agent } from "./agent-tool-types-NofdbL9X.js";
2
2
  import {
3
3
  S as WorkflowTrackingRow,
4
4
  _ as WorkflowPage,
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "durable objects"
10
10
  ],
11
11
  "type": "module",
12
- "version": "0.15.0",
12
+ "version": "0.16.0",
13
13
  "license": "MIT",
14
14
  "repository": {
15
15
  "directory": "packages/agents",
@@ -26,36 +26,36 @@
26
26
  "dependencies": {
27
27
  "@babel/plugin-proposal-decorators": "^7.29.7",
28
28
  "@cfworker/json-schema": "^4.1.1",
29
- "@cloudflare/codemode": "^0.3.8",
29
+ "@cloudflare/codemode": "^0.4.0",
30
30
  "@modelcontextprotocol/sdk": "1.29.0",
31
31
  "@rolldown/plugin-babel": "^0.2.3",
32
32
  "cron-schedule": "^6.0.0",
33
- "esbuild": "^0.28.0",
33
+ "esbuild": "^0.28.1",
34
34
  "just-bash": "^3.0.1",
35
35
  "mimetext": "^3.0.28",
36
36
  "nanoid": "^5.1.11",
37
37
  "partyserver": "^0.5.6",
38
- "partysocket": "1.1.19",
38
+ "partysocket": "1.2.0",
39
39
  "yaml": "^2.9.0",
40
40
  "yargs": "^18.0.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@ai-sdk/react": "^3.0.198",
44
- "@tanstack/ai": "^0.27.0",
45
- "@types/react": "^19.2.16",
43
+ "@ai-sdk/react": "^3.0.204",
44
+ "@tanstack/ai": "^0.28.0",
45
+ "@types/react": "^19.2.17",
46
46
  "@types/yargs": "^17.0.35",
47
47
  "@vitest/browser-playwright": "^4.1.8",
48
48
  "@x402/core": "^2.14.0",
49
49
  "@x402/evm": "^2.14.0",
50
- "ai": "^6.0.196",
50
+ "ai": "^6.0.202",
51
51
  "chat": "^4.30.0",
52
- "glob": "^11.1.0",
52
+ "glob": "^13.0.6",
53
53
  "react": "^19.2.7",
54
54
  "vitest-browser-react": "^2.2.0",
55
55
  "zod": "^4.4.3"
56
56
  },
57
57
  "peerDependencies": {
58
- "@cloudflare/ai-chat": ">=0.8.0 <1.0.0",
58
+ "@cloudflare/ai-chat": ">=0.8.5 <1.0.0",
59
59
  "@tanstack/ai": ">=0.10.2 <1.0.0",
60
60
  "@x402/core": "^2.0.0",
61
61
  "@x402/evm": "^2.0.0",
@@ -1,34 +0,0 @@
1
- //#region src/browser/shared.d.ts
2
- interface BrowserToolsOptions {
3
- /** Browser Rendering binding (Fetcher) — used in production */
4
- browser?: Fetcher;
5
- /** Optional CDP base URL override (e.g. http://localhost:9222) */
6
- cdpUrl?: string;
7
- /** Headers to send with CDP URL discovery requests (e.g. Access headers) */
8
- cdpHeaders?: Record<string, string>;
9
- /** Loader binding for sandboxed code execution */
10
- loader: WorkerLoader;
11
- /** Execution timeout in milliseconds (default: 30000) */
12
- timeout?: number;
13
- }
14
- declare const SEARCH_DESCRIPTION =
15
- 'Search the Chrome DevTools Protocol spec using JavaScript code.\n\nAvailable in your code:\n\ndeclare const spec: {\n get(): Promise<{\n domains: Array<{\n name: string;\n description?: string;\n commands: Array<{ name: string; method: string; description?: string }>;\n events: Array<{ name: string; event: string; description?: string }>;\n types: Array<{ id: string; name: string; description?: string }>;\n }>;\n }>;\n};\n\nWrite an async arrow function in JavaScript. Do NOT use TypeScript syntax.\n\nExample:\nasync () => {\n const s = await spec.get();\n return s.domains\n .find(d => d.name === "Network")\n .commands.filter(c => c.description?.toLowerCase().includes("intercept"))\n .map(c => ({ method: c.method, description: c.description }));\n}';
16
- declare const EXECUTE_DESCRIPTION =
17
- 'Execute CDP commands against a live browser session using JavaScript code.\n\nAvailable in your code:\n\ndeclare const cdp: {\n send(method: string, params?: unknown, options?: {\n timeoutMs?: number;\n sessionId?: string;\n }): Promise<unknown>;\n attachToTarget(targetId: string, options?: {\n timeoutMs?: number;\n }): Promise<string>;\n getDebugLog(limit?: number): Promise<unknown[]>;\n clearDebugLog(): Promise<void>;\n};\n\nWrite an async arrow function in JavaScript. Do NOT use TypeScript syntax.\n\nFor page-scoped commands such as Page.*, Runtime.*, and DOM.*, first create or select a target, call cdp.attachToTarget(targetId), and pass the returned sessionId in command options.\n\nExample:\nasync () => {\n return await cdp.send("Browser.getVersion");\n}\n\nPage example:\nasync () => {\n const { targetId } = await cdp.send("Target.createTarget", {\n url: "about:blank"\n });\n const sessionId = await cdp.attachToTarget(targetId);\n await cdp.send("Page.enable", {}, { sessionId });\n await cdp.send(\n "Page.navigate",\n { url: "https://example.com" },\n { sessionId }\n );\n const { result } = await cdp.send(\n "Runtime.evaluate",\n { expression: "document.title" },\n { sessionId }\n );\n return result.value;\n}';
18
- interface ToolResult {
19
- text: string;
20
- isError?: boolean;
21
- }
22
- declare function createBrowserToolHandlers(options: BrowserToolsOptions): {
23
- search: (code: string) => Promise<ToolResult>;
24
- execute: (code: string) => Promise<ToolResult>;
25
- };
26
- //#endregion
27
- export {
28
- createBrowserToolHandlers as a,
29
- ToolResult as i,
30
- EXECUTE_DESCRIPTION as n,
31
- SEARCH_DESCRIPTION as r,
32
- BrowserToolsOptions as t
33
- };
34
- //# sourceMappingURL=shared-4CAYLCTO.d.ts.map
@@ -1,432 +0,0 @@
1
- import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-Beqsfu2Z.js";
2
- import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-B5ko1s2R.js";
3
- import { DynamicWorkerExecutor } from "@cloudflare/codemode";
4
- //#region src/browser/cdp-session.ts
5
- const DEFAULT_TIMEOUT_MS = 1e4;
6
- const MAX_DEBUG_ENTRIES = 400;
7
- var _socket = /* @__PURE__ */ new WeakMap();
8
- var _nextId = /* @__PURE__ */ new WeakMap();
9
- var _pending = /* @__PURE__ */ new WeakMap();
10
- var _debugLog = /* @__PURE__ */ new WeakMap();
11
- var _defaultTimeoutMs = /* @__PURE__ */ new WeakMap();
12
- var _dispose = /* @__PURE__ */ new WeakMap();
13
- var _CdpSession_brand = /* @__PURE__ */ new WeakSet();
14
- /**
15
- * A CDP session over an open WebSocket. Manages command correlation,
16
- * timeouts, target sessions, and a debug event ring buffer.
17
- *
18
- * Used host-side (not in the sandbox) — the sandbox calls into this
19
- * via DynamicWorkerExecutor's ToolDispatcher RPC.
20
- */
21
- var CdpSession = class {
22
- constructor(socket, defaultTimeoutMs = DEFAULT_TIMEOUT_MS, dispose) {
23
- _classPrivateMethodInitSpec(this, _CdpSession_brand);
24
- _classPrivateFieldInitSpec(this, _socket, void 0);
25
- _classPrivateFieldInitSpec(this, _nextId, 1);
26
- _classPrivateFieldInitSpec(this, _pending, /* @__PURE__ */ new Map());
27
- _classPrivateFieldInitSpec(this, _debugLog, []);
28
- _classPrivateFieldInitSpec(this, _defaultTimeoutMs, void 0);
29
- _classPrivateFieldInitSpec(this, _dispose, void 0);
30
- _classPrivateFieldSet2(_socket, this, socket);
31
- _classPrivateFieldSet2(_defaultTimeoutMs, this, defaultTimeoutMs);
32
- _classPrivateFieldSet2(_dispose, this, dispose);
33
- socket.addEventListener("message", (event) => _assertClassBrand(_CdpSession_brand, this, _handleMessage).call(this, event));
34
- socket.addEventListener("error", () => {
35
- _assertClassBrand(_CdpSession_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP socket error"));
36
- });
37
- socket.addEventListener("close", () => {
38
- _assertClassBrand(_CdpSession_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP connection closed"));
39
- });
40
- }
41
- send(method, params, options = {}) {
42
- var _this$nextId, _this$nextId2;
43
- const id = (_classPrivateFieldSet2(_nextId, this, (_this$nextId = _classPrivateFieldGet2(_nextId, this), _this$nextId2 = _this$nextId++, _this$nextId)), _this$nextId2);
44
- const timeoutMs = options.timeoutMs ?? _classPrivateFieldGet2(_defaultTimeoutMs, this);
45
- const sessionId = typeof options.sessionId === "string" && options.sessionId.length > 0 ? options.sessionId : void 0;
46
- const domain = typeof method === "string" ? method.split(".")[0] : "";
47
- if (!sessionId && domain && !["Browser", "Target"].includes(domain)) _assertClassBrand(_CdpSession_brand, this, _recordDebug).call(this, "warning", {
48
- id,
49
- method,
50
- reason: "target-scoped method sent without sessionId"
51
- });
52
- const result = new Promise((resolve, reject) => {
53
- const startedAt = performance.now();
54
- const timeoutId = setTimeout(() => {
55
- _classPrivateFieldGet2(_pending, this).delete(id);
56
- reject(/* @__PURE__ */ new Error(`CDP command timed out after ${timeoutMs}ms: ${method}`));
57
- }, timeoutMs);
58
- _classPrivateFieldGet2(_pending, this).set(id, {
59
- resolve,
60
- reject,
61
- timeoutId,
62
- method,
63
- sessionId,
64
- startedAt
65
- });
66
- });
67
- _assertClassBrand(_CdpSession_brand, this, _recordDebug).call(this, "send", {
68
- id,
69
- method,
70
- sessionId,
71
- timeoutMs
72
- });
73
- _classPrivateFieldGet2(_socket, this).send(JSON.stringify({
74
- id,
75
- method,
76
- params,
77
- sessionId
78
- }));
79
- return result;
80
- }
81
- async attachToTarget(targetId, options = {}) {
82
- if (typeof targetId !== "string" || !targetId) throw new Error("attachToTarget requires a targetId");
83
- const sessionId = (await this.send("Target.attachToTarget", {
84
- targetId,
85
- flatten: true
86
- }, { timeoutMs: options.timeoutMs }))?.sessionId ?? "";
87
- if (!sessionId) throw new Error(`Target.attachToTarget did not return a sessionId for target ${targetId}`);
88
- _assertClassBrand(_CdpSession_brand, this, _recordDebug).call(this, "attach", {
89
- targetId,
90
- sessionId
91
- });
92
- return sessionId;
93
- }
94
- getDebugLog(limit = 50) {
95
- const normalized = Number.isFinite(limit) ? Math.max(1, Math.floor(limit)) : 50;
96
- return _classPrivateFieldGet2(_debugLog, this).slice(-normalized);
97
- }
98
- clearDebugLog() {
99
- _classPrivateFieldSet2(_debugLog, this, []);
100
- }
101
- close() {
102
- _assertClassBrand(_CdpSession_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP session closed"));
103
- try {
104
- _classPrivateFieldGet2(_socket, this).close(1e3, "Done");
105
- } catch {}
106
- _classPrivateFieldGet2(_dispose, this)?.call(this);
107
- }
108
- };
109
- function _rejectAll(error) {
110
- for (const [id, pending] of _classPrivateFieldGet2(_pending, this).entries()) {
111
- clearTimeout(pending.timeoutId);
112
- _classPrivateFieldGet2(_pending, this).delete(id);
113
- pending.reject(error);
114
- }
115
- }
116
- function _handleMessage(event) {
117
- if (typeof event.data !== "string") return;
118
- let payload;
119
- try {
120
- payload = JSON.parse(event.data);
121
- } catch {
122
- return;
123
- }
124
- _assertClassBrand(_CdpSession_brand, this, _recordDebug).call(this, "receive", {
125
- id: payload.id,
126
- method: payload.method,
127
- sessionId: payload.sessionId,
128
- hasError: !!payload.error
129
- });
130
- if (typeof payload.id !== "number") return;
131
- const pending = _classPrivateFieldGet2(_pending, this).get(payload.id);
132
- if (!pending) return;
133
- clearTimeout(pending.timeoutId);
134
- _classPrivateFieldGet2(_pending, this).delete(payload.id);
135
- if (payload.error) {
136
- const err = payload.error;
137
- const code = err.code ?? "unknown";
138
- const message = err.message ?? "CDP error";
139
- pending.reject(/* @__PURE__ */ new Error(`CDP error ${code}: ${message} for ${pending.method}`));
140
- return;
141
- }
142
- pending.resolve(payload.result);
143
- }
144
- function _recordDebug(type, data) {
145
- _classPrivateFieldGet2(_debugLog, this).push({
146
- at: (/* @__PURE__ */ new Date()).toISOString(),
147
- type,
148
- ...data
149
- });
150
- if (_classPrivateFieldGet2(_debugLog, this).length > MAX_DEBUG_ENTRIES) _classPrivateFieldGet2(_debugLog, this).splice(0, _classPrivateFieldGet2(_debugLog, this).length - MAX_DEBUG_ENTRIES);
151
- }
152
- /**
153
- * Connect to a browser via the Browser Rendering binding (Fetcher).
154
- * Establishes a CDP WebSocket through the binding's fetch interface.
155
- */
156
- async function connectBrowser(browser, timeoutMs) {
157
- const response = await browser.fetch("https://localhost/v1/devtools/browser", { headers: { Upgrade: "websocket" } });
158
- const ws = response.webSocket;
159
- if (!ws) throw new Error("Browser Rendering binding did not return a WebSocket. Ensure the 'browser' binding is configured in wrangler.jsonc.");
160
- const sessionId = response.headers.get("cf-browser-session-id");
161
- if (!sessionId) throw new Error("Browser Rendering binding did not include a session ID when opening the CDP WebSocket");
162
- ws.accept();
163
- return new CdpSession(ws, timeoutMs, () => {
164
- browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}`, { method: "DELETE" });
165
- });
166
- }
167
- const LOCALHOST_HOSTS = new Set([
168
- "localhost",
169
- "127.0.0.1",
170
- "0.0.0.0",
171
- "::1",
172
- "[::1]"
173
- ]);
174
- /**
175
- * Connect to a browser via a CDP base URL (e.g. http://localhost:9222).
176
- * Discovers the WebSocket debugger URL via /json/version,
177
- * rewrites localhost URLs to the base URL host, and opens the WebSocket.
178
- *
179
- * Useful for local development with `chrome --remote-debugging-port=9222`
180
- * or when connecting through a tunnel.
181
- */
182
- async function connectUrl(baseUrl, options) {
183
- const endpoint = new URL("/json/version", baseUrl).toString();
184
- const response = await fetch(endpoint, { headers: options?.headers });
185
- if (!response.ok) throw new Error(`Failed to discover CDP endpoint at ${endpoint}: ${response.status}`);
186
- const payload = await response.json();
187
- if (!payload.webSocketDebuggerUrl) throw new Error("CDP /json/version did not include webSocketDebuggerUrl");
188
- let wsUrl = payload.webSocketDebuggerUrl;
189
- const parsed = new URL(wsUrl);
190
- if (LOCALHOST_HOSTS.has(parsed.hostname)) {
191
- const base = new URL(baseUrl);
192
- parsed.hostname = base.hostname;
193
- parsed.port = base.port;
194
- parsed.protocol = base.protocol;
195
- } else parsed.protocol = parsed.protocol === "wss:" ? "https:" : "http:";
196
- const fetchUrl = parsed.toString();
197
- const wsResponse = await fetch(fetchUrl, { headers: {
198
- ...options?.headers,
199
- Upgrade: "websocket"
200
- } });
201
- const ws = wsResponse.webSocket;
202
- if (!ws) throw new Error(`Failed to establish CDP WebSocket at ${fetchUrl} (status ${wsResponse.status})`);
203
- ws.accept();
204
- return new CdpSession(ws, options?.timeoutMs);
205
- }
206
- //#endregion
207
- //#region src/browser/truncate.ts
208
- const CHARS_PER_TOKEN = 4;
209
- const MAX_TOKENS = 6e3;
210
- const MAX_CHARS = CHARS_PER_TOKEN * MAX_TOKENS;
211
- function truncateResponse(content) {
212
- const text = typeof content === "string" ? content : JSON.stringify(content, null, 2) ?? "null";
213
- if (text.length <= MAX_CHARS) return text;
214
- const estimatedTokens = Math.ceil(text.length / CHARS_PER_TOKEN);
215
- return `${text.slice(0, MAX_CHARS)}\n\n--- TRUNCATED ---\nResponse was ~${estimatedTokens.toLocaleString()} tokens (limit: ${MAX_TOKENS.toLocaleString()}). Use more specific queries to reduce response size.`;
216
- }
217
- //#endregion
218
- //#region src/browser/shared.ts
219
- const specCache = /* @__PURE__ */ new Map();
220
- const CACHE_TTL_MS = 300 * 1e3;
221
- const SEARCH_DESCRIPTION = `Search the Chrome DevTools Protocol spec using JavaScript code.
222
-
223
- Available in your code:
224
-
225
- declare const spec: {
226
- get(): Promise<{
227
- domains: Array<{
228
- name: string;
229
- description?: string;
230
- commands: Array<{ name: string; method: string; description?: string }>;
231
- events: Array<{ name: string; event: string; description?: string }>;
232
- types: Array<{ id: string; name: string; description?: string }>;
233
- }>;
234
- }>;
235
- };
236
-
237
- Write an async arrow function in JavaScript. Do NOT use TypeScript syntax.
238
-
239
- Example:
240
- async () => {
241
- const s = await spec.get();
242
- return s.domains
243
- .find(d => d.name === "Network")
244
- .commands.filter(c => c.description?.toLowerCase().includes("intercept"))
245
- .map(c => ({ method: c.method, description: c.description }));
246
- }`;
247
- function normalizeCdpSpec(spec) {
248
- return { domains: (spec.domains ?? []).map((domain) => ({
249
- name: domain.domain,
250
- description: domain.description,
251
- commands: (domain.commands ?? []).map((command) => ({
252
- name: command.name,
253
- method: `${domain.domain}.${command.name}`,
254
- description: command.description
255
- })),
256
- events: (domain.events ?? []).map((event) => ({
257
- name: event.name,
258
- event: `${domain.domain}.${event.name}`,
259
- description: event.description
260
- })),
261
- types: (domain.types ?? []).map((type) => ({
262
- id: type.id,
263
- name: `${domain.domain}.${type.id}`,
264
- description: type.description
265
- }))
266
- })) };
267
- }
268
- function getSpecCacheKey(source, headers) {
269
- const headerEntries = Object.entries(headers ?? {}).sort(([a], [b]) => a.localeCompare(b));
270
- return `${source}:${JSON.stringify(headerEntries)}`;
271
- }
272
- async function getCachedSpec(key, load) {
273
- const cached = specCache.get(key);
274
- if (cached && Date.now() - cached.cachedAt < CACHE_TTL_MS) return cached.spec;
275
- const spec = normalizeCdpSpec(await load());
276
- specCache.set(key, {
277
- spec,
278
- cachedAt: Date.now()
279
- });
280
- return spec;
281
- }
282
- async function fetchCdpSpecFromUrl(cdpBaseUrl, headers) {
283
- const endpoint = new URL("/json/protocol", cdpBaseUrl).toString();
284
- return getCachedSpec(getSpecCacheKey(endpoint, headers), async () => {
285
- const response = await fetch(endpoint, { headers });
286
- if (!response.ok) throw new Error(`Failed to fetch CDP spec from ${endpoint}: ${response.status}`);
287
- return await response.json();
288
- });
289
- }
290
- async function fetchCdpSpecFromBrowser(browser) {
291
- return getCachedSpec("browser-binding", async () => {
292
- const createResponse = await browser.fetch("https://localhost/v1/devtools/browser", { method: "POST" });
293
- if (!createResponse.ok) throw new Error(`Failed to create Browser Rendering session for protocol fetch: ${createResponse.status}`);
294
- const sessionId = (await createResponse.json()).sessionId;
295
- if (!sessionId) throw new Error("Browser Rendering session response did not include a sessionId");
296
- try {
297
- const response = await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}/json/protocol`);
298
- if (!response.ok) throw new Error(`Failed to fetch CDP spec from Browser Rendering: ${response.status}`);
299
- return await response.json();
300
- } finally {
301
- try {
302
- await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}`, { method: "DELETE" });
303
- } catch {}
304
- }
305
- });
306
- }
307
- const EXECUTE_DESCRIPTION = `Execute CDP commands against a live browser session using JavaScript code.
308
-
309
- Available in your code:
310
-
311
- declare const cdp: {
312
- send(method: string, params?: unknown, options?: {
313
- timeoutMs?: number;
314
- sessionId?: string;
315
- }): Promise<unknown>;
316
- attachToTarget(targetId: string, options?: {
317
- timeoutMs?: number;
318
- }): Promise<string>;
319
- getDebugLog(limit?: number): Promise<unknown[]>;
320
- clearDebugLog(): Promise<void>;
321
- };
322
-
323
- Write an async arrow function in JavaScript. Do NOT use TypeScript syntax.
324
-
325
- For page-scoped commands such as Page.*, Runtime.*, and DOM.*, first create or select a target, call cdp.attachToTarget(targetId), and pass the returned sessionId in command options.
326
-
327
- Example:
328
- async () => {
329
- return await cdp.send("Browser.getVersion");
330
- }
331
-
332
- Page example:
333
- async () => {
334
- const { targetId } = await cdp.send("Target.createTarget", {
335
- url: "about:blank"
336
- });
337
- const sessionId = await cdp.attachToTarget(targetId);
338
- await cdp.send("Page.enable", {}, { sessionId });
339
- await cdp.send(
340
- "Page.navigate",
341
- { url: "https://example.com" },
342
- { sessionId }
343
- );
344
- const { result } = await cdp.send(
345
- "Runtime.evaluate",
346
- { expression: "document.title" },
347
- { sessionId }
348
- );
349
- return result.value;
350
- }`;
351
- function formatError(error) {
352
- return error instanceof Error ? error.message : String(error);
353
- }
354
- let didWarnExperimental = false;
355
- function createBrowserToolHandlers(options) {
356
- if (!didWarnExperimental) {
357
- didWarnExperimental = true;
358
- console.warn("[agents/browser] Browser tools are experimental and may change in a future release.");
359
- }
360
- const executor = new DynamicWorkerExecutor({
361
- loader: options.loader,
362
- timeout: options.timeout
363
- });
364
- async function search(code) {
365
- try {
366
- let specSource;
367
- if (options.cdpUrl) specSource = await fetchCdpSpecFromUrl(options.cdpUrl, options.cdpHeaders);
368
- else if (options.browser) specSource = await fetchCdpSpecFromBrowser(options.browser);
369
- else return {
370
- text: "Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided",
371
- isError: true
372
- };
373
- const result = await executor.execute(code, [{
374
- name: "spec",
375
- fns: { get: async () => specSource }
376
- }]);
377
- if (result.error) return {
378
- text: result.error,
379
- isError: true
380
- };
381
- return { text: truncateResponse(result.result) };
382
- } catch (error) {
383
- return {
384
- text: formatError(error),
385
- isError: true
386
- };
387
- }
388
- }
389
- async function execute(code) {
390
- let session;
391
- try {
392
- if (options.cdpUrl) session = await connectUrl(options.cdpUrl, {
393
- timeoutMs: options.timeout,
394
- headers: options.cdpHeaders
395
- });
396
- else if (options.browser) session = await connectBrowser(options.browser, options.timeout);
397
- else return {
398
- text: "Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided",
399
- isError: true
400
- };
401
- const result = await executor.execute(code, [{
402
- name: "cdp",
403
- fns: {
404
- send: async (method, params, opts) => session.send(method, params, opts),
405
- attachToTarget: async (targetId, opts) => session.attachToTarget(targetId, opts),
406
- getDebugLog: async (limit) => session.getDebugLog(limit),
407
- clearDebugLog: async () => session.clearDebugLog()
408
- }
409
- }]);
410
- if (result.error) return {
411
- text: result.error,
412
- isError: true
413
- };
414
- return { text: truncateResponse(result.result) };
415
- } catch (error) {
416
- return {
417
- text: formatError(error),
418
- isError: true
419
- };
420
- } finally {
421
- session?.close();
422
- }
423
- }
424
- return {
425
- search,
426
- execute
427
- };
428
- }
429
- //#endregion
430
- export { connectBrowser as a, CdpSession as i, SEARCH_DESCRIPTION as n, connectUrl as o, createBrowserToolHandlers as r, EXECUTE_DESCRIPTION as t };
431
-
432
- //# sourceMappingURL=shared-wyII629d.js.map