agents 0.12.2 → 0.12.4

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 (83) hide show
  1. package/dist/{agent-tool-types-DSteYkkS.d.ts → agent-tool-types-CM_50fcV.d.ts} +104 -87
  2. package/dist/agent-tool-types.d.ts +1 -1
  3. package/dist/agent-tools-BAdX1vdI.js.map +1 -1
  4. package/dist/{agent-tools-eGTCdVZX.d.ts → agent-tools-BylX6WXG.d.ts} +2 -2
  5. package/dist/agent-tools.d.ts +1 -1
  6. package/dist/agent-tools.js.map +1 -1
  7. package/dist/browser/ai.d.ts +2 -2
  8. package/dist/browser/ai.js +1 -1
  9. package/dist/browser/ai.js.map +1 -1
  10. package/dist/browser/index.d.ts +41 -10
  11. package/dist/browser/index.js +1 -1
  12. package/dist/browser/tanstack-ai.d.ts +2 -2
  13. package/dist/browser/tanstack-ai.js +1 -1
  14. package/dist/browser/tanstack-ai.js.map +1 -1
  15. package/dist/chat/index.d.ts +297 -148
  16. package/dist/chat/index.js +43 -14
  17. package/dist/chat/index.js.map +1 -1
  18. package/dist/{classPrivateFieldGet2-Bqby-AHD.js → classPrivateFieldGet2-CS51BNGR.js} +5 -5
  19. package/dist/cli/index.d.ts +1 -1
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/client-D1kFXo80.js.map +1 -1
  22. package/dist/client.d.ts +11 -10
  23. package/dist/client.js.map +1 -1
  24. package/dist/codemode/ai.d.ts +1 -1
  25. package/dist/{compaction-helpers-CSaqCmdE.js → compaction-helpers-DvcZnvQ1.js} +1 -1
  26. package/dist/{compaction-helpers-CSaqCmdE.js.map → compaction-helpers-DvcZnvQ1.js.map} +1 -1
  27. package/dist/{compaction-helpers-D92Ipstp.d.ts → compaction-helpers-bYvP1o2S.d.ts} +10 -3
  28. package/dist/{do-oauth-client-provider-C38aWbFV.d.ts → do-oauth-client-provider-4OKQU9rT.d.ts} +1 -1
  29. package/dist/{email-X72-zjuq.d.ts → email-J0GGS3sa.d.ts} +1 -1
  30. package/dist/email.d.ts +2 -2
  31. package/dist/email.js.map +1 -1
  32. package/dist/experimental/memory/session/index.d.ts +126 -26
  33. package/dist/experimental/memory/session/index.js +13 -3
  34. package/dist/experimental/memory/session/index.js.map +1 -1
  35. package/dist/experimental/memory/utils/index.d.ts +41 -5
  36. package/dist/experimental/memory/utils/index.js +15 -5
  37. package/dist/experimental/memory/utils/index.js.map +1 -1
  38. package/dist/experimental/webmcp.d.ts +9 -3
  39. package/dist/experimental/webmcp.js.map +1 -1
  40. package/dist/{index-Biv6K70p.d.ts → index-DKey3P4s.d.ts} +26 -2
  41. package/dist/index.d.ts +48 -44
  42. package/dist/index.js +122 -85
  43. package/dist/index.js.map +1 -1
  44. package/dist/{internal_context-BvuGZieY.d.ts → internal_context-BZrMS0B5.d.ts} +1 -1
  45. package/dist/internal_context.d.ts +1 -1
  46. package/dist/mcp/client.d.ts +26 -2
  47. package/dist/mcp/do-oauth-client-provider.d.ts +10 -2
  48. package/dist/mcp/do-oauth-client-provider.js.map +1 -1
  49. package/dist/mcp/index.d.ts +54 -2
  50. package/dist/mcp/index.js +43 -19
  51. package/dist/mcp/index.js.map +1 -1
  52. package/dist/mcp/x402.d.ts +74 -17
  53. package/dist/mcp/x402.js.map +1 -1
  54. package/dist/observability/index.d.ts +16 -2
  55. package/dist/observability/index.js +1 -1
  56. package/dist/observability/index.js.map +1 -1
  57. package/dist/react.d.ts +9 -7
  58. package/dist/react.js +18 -2
  59. package/dist/react.js.map +1 -1
  60. package/dist/{retries-fLD8cGNf.d.ts → retries-BVdRl5ZE.d.ts} +1 -1
  61. package/dist/retries.d.ts +1 -1
  62. package/dist/retries.js.map +1 -1
  63. package/dist/schedule.js.map +1 -1
  64. package/dist/serializable.d.ts +141 -7
  65. package/dist/{shared-Ch9slKdI.d.ts → shared-Cvj92byG.d.ts} +1 -1
  66. package/dist/{shared-C6l4ZKRN.js → shared-DzJYHisH.js} +3 -3
  67. package/dist/{shared-C6l4ZKRN.js.map → shared-DzJYHisH.js.map} +1 -1
  68. package/dist/sub-routing.d.ts +6 -6
  69. package/dist/sub-routing.js.map +1 -1
  70. package/dist/tool-output-truncation-CH-khbZ3.js +98 -0
  71. package/dist/tool-output-truncation-CH-khbZ3.js.map +1 -0
  72. package/dist/{types-DAHCZC_W.d.ts → types-_JjKmv-l.d.ts} +1 -1
  73. package/dist/types.d.ts +1 -1
  74. package/dist/types.js.map +1 -1
  75. package/dist/utils.js.map +1 -1
  76. package/dist/vite.js.map +1 -1
  77. package/dist/{workflow-types-DHs0L0KP.d.ts → workflow-types-Dkzg4hAx.d.ts} +1 -1
  78. package/dist/workflow-types.d.ts +1 -1
  79. package/dist/workflow-types.js.map +1 -1
  80. package/dist/workflows.d.ts +2 -2
  81. package/dist/workflows.js.map +1 -1
  82. package/package.json +9 -9
  83. package/dist/serializable-Brg7fRds.d.ts +0 -131
@@ -1 +1 @@
1
- {"version":3,"file":"schedule.js","names":[],"sources":["../src/schedule.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * Get the schedule prompt for a given event\n * @param event - The event to get the schedule prompt for\n * @returns The schedule prompt\n */\nexport function getSchedulePrompt(event: { date: Date }) {\n return `\n[Schedule Parser Component]\n\nCurrent time: ${event.date.toUTCString()}\n\nThis component parses natural language scheduling requests into a structured format. It extracts:\n1. A clean task description (without timing information)\n2. Scheduling details in one of these formats:\n - scheduled: Specific date/time events\n - delayed: Relative time delays (in seconds)\n - cron: Recurring patterns\n - no-schedule: Tasks without timing\n\nRules:\n- Task descriptions should be clean and focused on the action\n- Use numbers (0-6) for days in cron patterns (0=Sunday)\n- For recurring tasks, use standard cron syntax\n- For relative times, convert to seconds\n- For specific dates, use the current time as reference\n\nExample outputs:\n{\n \"description\": \"meeting with team\",\n \"when\": {\n \"type\": \"scheduled\",\n \"date\": \"tomorrow at 14:00\"\n }\n}\n\n{\n \"description\": \"backup database\",\n \"when\": {\n \"type\": \"cron\",\n \"cron\": \"0 0 * * *\"\n }\n}\n\n{\n \"description\": \"send report\",\n \"when\": {\n \"type\": \"delayed\",\n \"delayInSeconds\": 1800\n }\n}\n\n[End Schedule Parser Component]\n`;\n}\n\nlet didWarnAboutUnstableGetSchedulePrompt = false;\n\n/**\n * @deprecated this has been renamed to getSchedulePrompt, and unstable_getSchedulePrompt will be removed in the next major version\n * @param event - The event to get the schedule prompt for\n * @returns The schedule prompt\n */\nexport function unstable_getSchedulePrompt(event: { date: Date }) {\n if (!didWarnAboutUnstableGetSchedulePrompt) {\n didWarnAboutUnstableGetSchedulePrompt = true;\n console.warn(\n \"unstable_getSchedulePrompt is deprecated, use getSchedulePrompt instead. unstable_getSchedulePrompt will be removed in the next major version.\"\n );\n }\n return getSchedulePrompt(event);\n}\n\n/**\n * The schema for parsing natural language scheduling requests.\n *\n * @example\n * ```typescript\n * import { generateObject } from \"ai\";\n * import { scheduleSchema, getSchedulePrompt } from \"agents/schedule\";\n *\n * const result = await generateObject({\n * model,\n * prompt: `${getSchedulePrompt({ date: new Date() })} Input: \"${userInput}\"`,\n * schema: scheduleSchema,\n * // Required for OpenAI to avoid strict JSON schema validation errors\n * providerOptions: {\n * openai: { strictJsonSchema: false }\n * }\n * });\n * ```\n *\n * @remarks\n * When using this schema with OpenAI models via the AI SDK, you must pass\n * `providerOptions: { openai: { strictJsonSchema: false } }` to `generateObject`.\n * This is because the schema uses a discriminated union which is not compatible\n * with OpenAI's strict structured outputs mode.\n */\nexport const scheduleSchema = z.object({\n description: z.string().describe(\"A description of the task\"),\n when: z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"scheduled\"),\n date: z\n .string()\n .describe(\n \"Execute task at the specified date and time in ISO 8601 format\"\n )\n }),\n z.object({\n type: z.literal(\"delayed\"),\n delayInSeconds: z\n .number()\n .describe(\"Execute task after a delay in seconds\")\n }),\n z.object({\n type: z.literal(\"cron\"),\n cron: z\n .string()\n .describe(\n \"Execute task on a recurring interval specified as cron syntax\"\n )\n }),\n z.object({\n type: z.literal(\"no-schedule\")\n })\n ])\n});\n\n/**\n * The type for the schedule prompt\n */\nexport type Schedule = z.infer<typeof scheduleSchema>;\n\n/**\n * @deprecated this has been renamed to scheduleSchema, and unstable_scheduleSchema will be removed in the next major version\n * @returns The schedule schema\n */\nexport const unstable_scheduleSchema = scheduleSchema;\n"],"mappings":";;;;;;;AAOA,SAAgB,kBAAkB,OAAuB;AACvD,QAAO;;;gBAGO,MAAM,KAAK,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CzC,IAAI,wCAAwC;;;;;;AAO5C,SAAgB,2BAA2B,OAAuB;AAChE,KAAI,CAAC,uCAAuC;AAC1C,0CAAwC;AACxC,UAAQ,KACN,iJACD;;AAEH,QAAO,kBAAkB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BjC,MAAa,iBAAiB,EAAE,OAAO;CACrC,aAAa,EAAE,QAAQ,CAAC,SAAS,4BAA4B;CAC7D,MAAM,EAAE,mBAAmB,QAAQ;EACjC,EAAE,OAAO;GACP,MAAM,EAAE,QAAQ,YAAY;GAC5B,MAAM,EACH,QAAQ,CACR,SACC,iEACD;GACJ,CAAC;EACF,EAAE,OAAO;GACP,MAAM,EAAE,QAAQ,UAAU;GAC1B,gBAAgB,EACb,QAAQ,CACR,SAAS,wCAAwC;GACrD,CAAC;EACF,EAAE,OAAO;GACP,MAAM,EAAE,QAAQ,OAAO;GACvB,MAAM,EACH,QAAQ,CACR,SACC,gEACD;GACJ,CAAC;EACF,EAAE,OAAO,EACP,MAAM,EAAE,QAAQ,cAAc,EAC/B,CAAC;EACH,CAAC;CACH,CAAC;;;;;AAWF,MAAa,0BAA0B"}
1
+ {"version":3,"file":"schedule.js","names":[],"sources":["../src/schedule.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * Get the schedule prompt for a given event\n * @param event - The event to get the schedule prompt for\n * @returns The schedule prompt\n */\nexport function getSchedulePrompt(event: { date: Date }) {\n return `\n[Schedule Parser Component]\n\nCurrent time: ${event.date.toUTCString()}\n\nThis component parses natural language scheduling requests into a structured format. It extracts:\n1. A clean task description (without timing information)\n2. Scheduling details in one of these formats:\n - scheduled: Specific date/time events\n - delayed: Relative time delays (in seconds)\n - cron: Recurring patterns\n - no-schedule: Tasks without timing\n\nRules:\n- Task descriptions should be clean and focused on the action\n- Use numbers (0-6) for days in cron patterns (0=Sunday)\n- For recurring tasks, use standard cron syntax\n- For relative times, convert to seconds\n- For specific dates, use the current time as reference\n\nExample outputs:\n{\n \"description\": \"meeting with team\",\n \"when\": {\n \"type\": \"scheduled\",\n \"date\": \"tomorrow at 14:00\"\n }\n}\n\n{\n \"description\": \"backup database\",\n \"when\": {\n \"type\": \"cron\",\n \"cron\": \"0 0 * * *\"\n }\n}\n\n{\n \"description\": \"send report\",\n \"when\": {\n \"type\": \"delayed\",\n \"delayInSeconds\": 1800\n }\n}\n\n[End Schedule Parser Component]\n`;\n}\n\nlet didWarnAboutUnstableGetSchedulePrompt = false;\n\n/**\n * @deprecated this has been renamed to getSchedulePrompt, and unstable_getSchedulePrompt will be removed in the next major version\n * @param event - The event to get the schedule prompt for\n * @returns The schedule prompt\n */\nexport function unstable_getSchedulePrompt(event: { date: Date }) {\n if (!didWarnAboutUnstableGetSchedulePrompt) {\n didWarnAboutUnstableGetSchedulePrompt = true;\n console.warn(\n \"unstable_getSchedulePrompt is deprecated, use getSchedulePrompt instead. unstable_getSchedulePrompt will be removed in the next major version.\"\n );\n }\n return getSchedulePrompt(event);\n}\n\n/**\n * The schema for parsing natural language scheduling requests.\n *\n * @example\n * ```typescript\n * import { generateObject } from \"ai\";\n * import { scheduleSchema, getSchedulePrompt } from \"agents/schedule\";\n *\n * const result = await generateObject({\n * model,\n * prompt: `${getSchedulePrompt({ date: new Date() })} Input: \"${userInput}\"`,\n * schema: scheduleSchema,\n * // Required for OpenAI to avoid strict JSON schema validation errors\n * providerOptions: {\n * openai: { strictJsonSchema: false }\n * }\n * });\n * ```\n *\n * @remarks\n * When using this schema with OpenAI models via the AI SDK, you must pass\n * `providerOptions: { openai: { strictJsonSchema: false } }` to `generateObject`.\n * This is because the schema uses a discriminated union which is not compatible\n * with OpenAI's strict structured outputs mode.\n */\nexport const scheduleSchema = z.object({\n description: z.string().describe(\"A description of the task\"),\n when: z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"scheduled\"),\n date: z\n .string()\n .describe(\n \"Execute task at the specified date and time in ISO 8601 format\"\n )\n }),\n z.object({\n type: z.literal(\"delayed\"),\n delayInSeconds: z\n .number()\n .describe(\"Execute task after a delay in seconds\")\n }),\n z.object({\n type: z.literal(\"cron\"),\n cron: z\n .string()\n .describe(\n \"Execute task on a recurring interval specified as cron syntax\"\n )\n }),\n z.object({\n type: z.literal(\"no-schedule\")\n })\n ])\n});\n\n/**\n * The type for the schedule prompt\n */\nexport type Schedule = z.infer<typeof scheduleSchema>;\n\n/**\n * @deprecated this has been renamed to scheduleSchema, and unstable_scheduleSchema will be removed in the next major version\n * @returns The schedule schema\n */\nexport const unstable_scheduleSchema = scheduleSchema;\n"],"mappings":";;;;;;;AAOA,SAAgB,kBAAkB,OAAuB;CACvD,OAAO;;;gBAGO,MAAM,KAAK,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CzC,IAAI,wCAAwC;;;;;;AAO5C,SAAgB,2BAA2B,OAAuB;CAChE,IAAI,CAAC,uCAAuC;EAC1C,wCAAwC;EACxC,QAAQ,KACN,iJACD;;CAEH,OAAO,kBAAkB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BjC,MAAa,iBAAiB,EAAE,OAAO;CACrC,aAAa,EAAE,QAAQ,CAAC,SAAS,4BAA4B;CAC7D,MAAM,EAAE,mBAAmB,QAAQ;EACjC,EAAE,OAAO;GACP,MAAM,EAAE,QAAQ,YAAY;GAC5B,MAAM,EACH,QAAQ,CACR,SACC,iEACD;GACJ,CAAC;EACF,EAAE,OAAO;GACP,MAAM,EAAE,QAAQ,UAAU;GAC1B,gBAAgB,EACb,QAAQ,CACR,SAAS,wCAAwC;GACrD,CAAC;EACF,EAAE,OAAO;GACP,MAAM,EAAE,QAAQ,OAAO;GACvB,MAAM,EACH,QAAQ,CACR,SACC,gEACD;GACJ,CAAC;EACF,EAAE,OAAO,EACP,MAAM,EAAE,QAAQ,cAAc,EAC/B,CAAC;EACH,CAAC;CACH,CAAC;;;;;AAWF,MAAa,0BAA0B"}
@@ -1,7 +1,141 @@
1
- import {
2
- i as SerializableValue,
3
- n as RPCMethod,
4
- r as SerializableReturnValue,
5
- t as Method
6
- } from "./serializable-Brg7fRds.js";
7
- export { Method, RPCMethod, SerializableReturnValue, SerializableValue };
1
+ import { W as StreamingResponse } from "./agent-tool-types-CM_50fcV.js";
2
+
3
+ //#region src/serializable.d.ts
4
+ type SerializablePrimitive = undefined | null | string | number | boolean;
5
+ type NonSerializable =
6
+ | Function
7
+ | symbol
8
+ | bigint
9
+ | Date
10
+ | RegExp
11
+ | Map<unknown, unknown>
12
+ | Set<unknown>
13
+ | WeakMap<object, unknown>
14
+ | WeakSet<object>
15
+ | Error
16
+ | ArrayBuffer
17
+ | SharedArrayBuffer
18
+ | DataView
19
+ | Int8Array
20
+ | Uint8Array
21
+ | Uint8ClampedArray
22
+ | Int16Array
23
+ | Uint16Array
24
+ | Int32Array
25
+ | Uint32Array
26
+ | Float32Array
27
+ | Float64Array
28
+ | BigInt64Array
29
+ | BigUint64Array;
30
+ type MaxDepth = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
31
+ type Increment<D extends unknown[]> = [0, ...D];
32
+ type IsMaxDepth<D extends unknown[]> = D["length"] extends MaxDepth["length"]
33
+ ? true
34
+ : false;
35
+ type SerializableValue =
36
+ | undefined
37
+ | null
38
+ | string
39
+ | number
40
+ | boolean
41
+ | {
42
+ [key: string]: SerializableValue;
43
+ }
44
+ | SerializableValue[];
45
+ type CanSerialize<T, Seen = never, Depth extends unknown[] = []> =
46
+ IsMaxDepth<Depth> extends true
47
+ ? true
48
+ : T extends Seen
49
+ ? true
50
+ : T extends SerializablePrimitive
51
+ ? true
52
+ : T extends NonSerializable
53
+ ? false
54
+ : T extends readonly (infer U)[]
55
+ ? CanSerialize<U, Seen | T, Increment<Depth>>
56
+ : T extends object
57
+ ? unknown extends T
58
+ ? true
59
+ : {
60
+ [K in keyof T]: CanSerialize<
61
+ T[K],
62
+ Seen | T,
63
+ Increment<Depth>
64
+ >;
65
+ } extends { [K in keyof T]: true }
66
+ ? true
67
+ : false
68
+ : true;
69
+ type CanSerializeReturn<T> = T extends void
70
+ ? true
71
+ : T extends Promise<infer U>
72
+ ? CanSerialize<U>
73
+ : CanSerialize<T>;
74
+ type SerializableReturnValue =
75
+ | SerializableValue
76
+ | void
77
+ | Promise<SerializableValue>
78
+ | Promise<void>;
79
+ type IsSerializableParam<T, Seen = never, Depth extends unknown[] = []> =
80
+ IsMaxDepth<Depth> extends true
81
+ ? true
82
+ : T extends Seen
83
+ ? true
84
+ : T extends SerializablePrimitive
85
+ ? true
86
+ : T extends NonSerializable
87
+ ? false
88
+ : T extends readonly (infer U)[]
89
+ ? IsSerializableParam<U, Seen | T, Increment<Depth>>
90
+ : T extends object
91
+ ? unknown extends T
92
+ ? true
93
+ : {
94
+ [K in keyof T]: IsSerializableParam<
95
+ T[K],
96
+ Seen | T,
97
+ Increment<Depth>
98
+ >;
99
+ } extends { [K in keyof T]: true }
100
+ ? true
101
+ : false
102
+ : true;
103
+ type AllSerializableValues<A> = A extends [infer First, ...infer Rest]
104
+ ? IsSerializableParam<First> extends true
105
+ ? AllSerializableValues<Rest>
106
+ : false
107
+ : true;
108
+ type Method = (...args: any[]) => any;
109
+ type ClientParameters<T = Method> = T extends (...args: infer A) => unknown
110
+ ? A extends [StreamingResponse, ...infer Rest]
111
+ ? Rest
112
+ : A
113
+ : never;
114
+ type IsUnknown<T> = [unknown] extends [T]
115
+ ? [T] extends [unknown]
116
+ ? true
117
+ : false
118
+ : false;
119
+ type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
120
+ type RPCMethod<T = Method> = T extends Method
121
+ ? T extends (...arg: infer A) => infer R
122
+ ? AllSerializableValues<ClientParameters<T>> extends true
123
+ ? A extends [StreamingResponse, ...unknown[]]
124
+ ? T
125
+ : CanSerializeReturn<R> extends true
126
+ ? T
127
+ : IsUnknown<UnwrapPromise<R>> extends true
128
+ ? T
129
+ : never
130
+ : never
131
+ : never
132
+ : never;
133
+ //#endregion
134
+ export {
135
+ ClientParameters,
136
+ Method,
137
+ RPCMethod,
138
+ SerializableReturnValue,
139
+ SerializableValue
140
+ };
141
+ //# sourceMappingURL=serializable.d.ts.map
@@ -31,4 +31,4 @@ export {
31
31
  SEARCH_DESCRIPTION as r,
32
32
  BrowserToolsOptions as t
33
33
  };
34
- //# sourceMappingURL=shared-Ch9slKdI.d.ts.map
34
+ //# sourceMappingURL=shared-Cvj92byG.d.ts.map
@@ -1,6 +1,6 @@
1
- import { a as _checkPrivateRedeclaration, i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-Bqby-AHD.js";
1
+ import { a as _checkPrivateRedeclaration, i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-CS51BNGR.js";
2
2
  import { DynamicWorkerExecutor } from "@cloudflare/codemode";
3
- //#region \0@oxc-project+runtime@0.127.0/helpers/classPrivateMethodInitSpec.js
3
+ //#region \0@oxc-project+runtime@0.129.0/helpers/classPrivateMethodInitSpec.js
4
4
  function _classPrivateMethodInitSpec(e, a) {
5
5
  _checkPrivateRedeclaration(e, a), a.add(e);
6
6
  }
@@ -434,4 +434,4 @@ function createBrowserToolHandlers(options) {
434
434
  //#endregion
435
435
  export { connectBrowser as a, CdpSession as i, SEARCH_DESCRIPTION as n, connectUrl as o, createBrowserToolHandlers as r, EXECUTE_DESCRIPTION as t };
436
436
 
437
- //# sourceMappingURL=shared-C6l4ZKRN.js.map
437
+ //# sourceMappingURL=shared-DzJYHisH.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-C6l4ZKRN.js","names":[],"sources":["../src/browser/cdp-session.ts","../src/browser/truncate.ts","../src/browser/shared.ts"],"sourcesContent":["interface PendingCommand {\n resolve: (result: unknown) => void;\n reject: (error: Error) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n method: string;\n sessionId?: string;\n startedAt: number;\n}\n\ninterface DebugEntry {\n at: string;\n type: string;\n [key: string]: unknown;\n}\n\nexport interface CdpSendOptions {\n timeoutMs?: number;\n sessionId?: string;\n}\n\nexport interface CdpAttachOptions {\n timeoutMs?: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_DEBUG_ENTRIES = 400;\n\n/**\n * A CDP session over an open WebSocket. Manages command correlation,\n * timeouts, target sessions, and a debug event ring buffer.\n *\n * Used host-side (not in the sandbox) — the sandbox calls into this\n * via DynamicWorkerExecutor's ToolDispatcher RPC.\n */\nexport class CdpSession {\n #socket: WebSocket;\n #nextId = 1;\n #pending = new Map<number, PendingCommand>();\n #debugLog: DebugEntry[] = [];\n #defaultTimeoutMs: number;\n #dispose?: () => void;\n\n constructor(\n socket: WebSocket,\n defaultTimeoutMs = DEFAULT_TIMEOUT_MS,\n dispose?: () => void\n ) {\n this.#socket = socket;\n this.#defaultTimeoutMs = defaultTimeoutMs;\n this.#dispose = dispose;\n\n socket.addEventListener(\"message\", (event) => this.#handleMessage(event));\n socket.addEventListener(\"error\", () => {\n this.#rejectAll(new Error(\"CDP socket error\"));\n });\n socket.addEventListener(\"close\", () => {\n this.#rejectAll(new Error(\"CDP connection closed\"));\n });\n }\n\n send(\n method: string,\n params?: unknown,\n options: CdpSendOptions = {}\n ): Promise<unknown> {\n const id = this.#nextId++;\n const timeoutMs = options.timeoutMs ?? this.#defaultTimeoutMs;\n const sessionId =\n typeof options.sessionId === \"string\" && options.sessionId.length > 0\n ? options.sessionId\n : undefined;\n\n const domain = typeof method === \"string\" ? method.split(\".\")[0] : \"\";\n if (!sessionId && domain && ![\"Browser\", \"Target\"].includes(domain)) {\n this.#recordDebug(\"warning\", {\n id,\n method,\n reason: \"target-scoped method sent without sessionId\"\n });\n }\n\n const result = new Promise<unknown>((resolve, reject) => {\n const startedAt = performance.now();\n const timeoutId = setTimeout(() => {\n this.#pending.delete(id);\n reject(\n new Error(`CDP command timed out after ${timeoutMs}ms: ${method}`)\n );\n }, timeoutMs);\n this.#pending.set(id, {\n resolve,\n reject,\n timeoutId,\n method,\n sessionId,\n startedAt\n });\n });\n\n this.#recordDebug(\"send\", { id, method, sessionId, timeoutMs });\n this.#socket.send(JSON.stringify({ id, method, params, sessionId }));\n return result;\n }\n\n async attachToTarget(\n targetId: string,\n options: CdpAttachOptions = {}\n ): Promise<string> {\n if (typeof targetId !== \"string\" || !targetId) {\n throw new Error(\"attachToTarget requires a targetId\");\n }\n\n const result = (await this.send(\n \"Target.attachToTarget\",\n {\n targetId,\n flatten: true\n },\n { timeoutMs: options.timeoutMs }\n )) as { sessionId?: string };\n\n const sessionId = result?.sessionId ?? \"\";\n if (!sessionId) {\n throw new Error(\n `Target.attachToTarget did not return a sessionId for target ${targetId}`\n );\n }\n\n this.#recordDebug(\"attach\", { targetId, sessionId });\n return sessionId;\n }\n\n getDebugLog(limit = 50): DebugEntry[] {\n const normalized = Number.isFinite(limit)\n ? Math.max(1, Math.floor(limit))\n : 50;\n return this.#debugLog.slice(-normalized);\n }\n\n clearDebugLog(): void {\n this.#debugLog = [];\n }\n\n close(): void {\n this.#rejectAll(new Error(\"CDP session closed\"));\n try {\n this.#socket.close(1000, \"Done\");\n } catch {\n // socket may already be closed\n }\n this.#dispose?.();\n }\n\n #rejectAll(error: Error): void {\n for (const [id, pending] of this.#pending.entries()) {\n clearTimeout(pending.timeoutId);\n this.#pending.delete(id);\n pending.reject(error);\n }\n }\n\n #handleMessage(event: MessageEvent): void {\n if (typeof event.data !== \"string\") {\n return;\n }\n\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(event.data) as Record<string, unknown>;\n } catch {\n return;\n }\n\n this.#recordDebug(\"receive\", {\n id: payload.id,\n method: payload.method,\n sessionId: payload.sessionId,\n hasError: !!payload.error\n });\n\n if (typeof payload.id !== \"number\") {\n return;\n }\n\n const pending = this.#pending.get(payload.id);\n if (!pending) {\n return;\n }\n\n clearTimeout(pending.timeoutId);\n this.#pending.delete(payload.id);\n\n if (payload.error) {\n const err = payload.error as { code?: unknown; message?: string };\n const code = err.code ?? \"unknown\";\n const message = err.message ?? \"CDP error\";\n pending.reject(\n new Error(`CDP error ${code}: ${message} for ${pending.method}`)\n );\n return;\n }\n\n pending.resolve(payload.result);\n }\n\n #recordDebug(type: string, data: Record<string, unknown>): void {\n this.#debugLog.push({\n at: new Date().toISOString(),\n type,\n ...data\n });\n if (this.#debugLog.length > MAX_DEBUG_ENTRIES) {\n this.#debugLog.splice(0, this.#debugLog.length - MAX_DEBUG_ENTRIES);\n }\n }\n}\n\n/**\n * Connect to a browser via the Browser Rendering binding (Fetcher).\n * Establishes a CDP WebSocket through the binding's fetch interface.\n */\nexport async function connectBrowser(\n browser: Fetcher,\n timeoutMs?: number\n): Promise<CdpSession> {\n const response = await browser.fetch(\n \"https://localhost/v1/devtools/browser\",\n {\n headers: { Upgrade: \"websocket\" }\n }\n );\n\n const ws = response.webSocket;\n if (!ws) {\n throw new Error(\n \"Browser Rendering binding did not return a WebSocket. \" +\n \"Ensure the 'browser' binding is configured in wrangler.jsonc.\"\n );\n }\n\n const sessionId = response.headers.get(\"cf-browser-session-id\");\n if (!sessionId) {\n throw new Error(\n \"Browser Rendering binding did not include a session ID when opening the CDP WebSocket\"\n );\n }\n\n ws.accept();\n return new CdpSession(ws, timeoutMs, () => {\n void browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}`, {\n method: \"DELETE\"\n });\n });\n}\n\nconst LOCALHOST_HOSTS = new Set([\n \"localhost\",\n \"127.0.0.1\",\n \"0.0.0.0\",\n \"::1\",\n \"[::1]\"\n]);\n\n/**\n * Connect to a browser via a CDP base URL (e.g. http://localhost:9222).\n * Discovers the WebSocket debugger URL via /json/version,\n * rewrites localhost URLs to the base URL host, and opens the WebSocket.\n *\n * Useful for local development with `chrome --remote-debugging-port=9222`\n * or when connecting through a tunnel.\n */\nexport async function connectUrl(\n baseUrl: string,\n options?: { timeoutMs?: number; headers?: Record<string, string> }\n): Promise<CdpSession> {\n const endpoint = new URL(\"/json/version\", baseUrl).toString();\n const response = await fetch(endpoint, {\n headers: options?.headers\n });\n if (!response.ok) {\n throw new Error(\n `Failed to discover CDP endpoint at ${endpoint}: ${response.status}`\n );\n }\n\n const payload = (await response.json()) as {\n webSocketDebuggerUrl?: string;\n };\n if (!payload.webSocketDebuggerUrl) {\n throw new Error(\"CDP /json/version did not include webSocketDebuggerUrl\");\n }\n\n let wsUrl = payload.webSocketDebuggerUrl;\n const parsed = new URL(wsUrl);\n if (LOCALHOST_HOSTS.has(parsed.hostname)) {\n const base = new URL(baseUrl);\n parsed.hostname = base.hostname;\n parsed.port = base.port;\n parsed.protocol = base.protocol;\n } else {\n // Workers runtime requires fetch + Upgrade header for outbound WebSockets\n parsed.protocol = parsed.protocol === \"wss:\" ? \"https:\" : \"http:\";\n }\n const fetchUrl = parsed.toString();\n\n const wsResponse = await fetch(fetchUrl, {\n headers: { ...options?.headers, Upgrade: \"websocket\" }\n });\n const ws = wsResponse.webSocket;\n if (!ws) {\n throw new Error(\n `Failed to establish CDP WebSocket at ${fetchUrl} (status ${wsResponse.status})`\n );\n }\n ws.accept();\n\n return new CdpSession(ws, options?.timeoutMs);\n}\n","const CHARS_PER_TOKEN = 4;\nconst MAX_TOKENS = 6000;\nconst MAX_CHARS = CHARS_PER_TOKEN * MAX_TOKENS;\n\nexport function truncateResponse(content: unknown): string {\n const text =\n typeof content === \"string\"\n ? content\n : (JSON.stringify(content, null, 2) ?? \"null\");\n if (text.length <= MAX_CHARS) {\n return text;\n }\n\n const estimatedTokens = Math.ceil(text.length / CHARS_PER_TOKEN);\n 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.`;\n}\n","import type { ResolvedProvider } from \"@cloudflare/codemode\";\nimport { DynamicWorkerExecutor } from \"@cloudflare/codemode\";\nimport { CdpSession, connectBrowser, connectUrl } from \"./cdp-session\";\nimport { truncateResponse } from \"./truncate\";\n\nexport interface BrowserToolsOptions {\n /** Browser Rendering binding (Fetcher) — used in production */\n browser?: Fetcher;\n /** Optional CDP base URL override (e.g. http://localhost:9222) */\n cdpUrl?: string;\n /** Headers to send with CDP URL discovery requests (e.g. Access headers) */\n cdpHeaders?: Record<string, string>;\n /** Loader binding for sandboxed code execution */\n loader: WorkerLoader;\n /** Execution timeout in milliseconds (default: 30000) */\n timeout?: number;\n}\n\ninterface RawCdpCommand {\n name: string;\n description?: string;\n}\n\ninterface RawCdpEvent {\n name: string;\n description?: string;\n}\n\ninterface RawCdpType {\n id: string;\n description?: string;\n}\n\n/** Raw CDP protocol domain from `/json/protocol` */\ninterface RawCdpDomain {\n domain: string;\n description?: string;\n commands?: RawCdpCommand[];\n events?: RawCdpEvent[];\n types?: RawCdpType[];\n}\n\ninterface SearchableCdpSpec {\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\nconst specCache = new Map<\n string,\n { spec: SearchableCdpSpec; cachedAt: number }\n>();\n\nconst CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\nexport const SEARCH_DESCRIPTION = `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}`;\n\nfunction normalizeCdpSpec(spec: {\n domains?: RawCdpDomain[];\n}): SearchableCdpSpec {\n return {\n domains: (spec.domains ?? []).map((domain) => ({\n name: domain.domain,\n description: domain.description,\n commands: (domain.commands ?? []).map((command) => ({\n name: command.name,\n method: `${domain.domain}.${command.name}`,\n description: command.description\n })),\n events: (domain.events ?? []).map((event) => ({\n name: event.name,\n event: `${domain.domain}.${event.name}`,\n description: event.description\n })),\n types: (domain.types ?? []).map((type) => ({\n id: type.id,\n name: `${domain.domain}.${type.id}`,\n description: type.description\n }))\n }))\n };\n}\n\nfunction getSpecCacheKey(\n source: string,\n headers?: Record<string, string>\n): string {\n const headerEntries = Object.entries(headers ?? {}).sort(([a], [b]) =>\n a.localeCompare(b)\n );\n return `${source}:${JSON.stringify(headerEntries)}`;\n}\n\nasync function getCachedSpec(\n key: string,\n load: () => Promise<{ domains?: RawCdpDomain[] }>\n): Promise<SearchableCdpSpec> {\n const cached = specCache.get(key);\n if (cached && Date.now() - cached.cachedAt < CACHE_TTL_MS) {\n return cached.spec;\n }\n\n const spec = normalizeCdpSpec(await load());\n specCache.set(key, { spec, cachedAt: Date.now() });\n return spec;\n}\n\nasync function fetchCdpSpecFromUrl(\n cdpBaseUrl: string,\n headers?: Record<string, string>\n): Promise<SearchableCdpSpec> {\n const endpoint = new URL(\"/json/protocol\", cdpBaseUrl).toString();\n\n return getCachedSpec(getSpecCacheKey(endpoint, headers), async () => {\n const response = await fetch(endpoint, { headers });\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch CDP spec from ${endpoint}: ${response.status}`\n );\n }\n\n return (await response.json()) as { domains?: RawCdpDomain[] };\n });\n}\n\nasync function fetchCdpSpecFromBrowser(\n browser: Fetcher\n): Promise<SearchableCdpSpec> {\n return getCachedSpec(\"browser-binding\", async () => {\n const createResponse = await browser.fetch(\n \"https://localhost/v1/devtools/browser\",\n {\n method: \"POST\"\n }\n );\n\n if (!createResponse.ok) {\n throw new Error(\n \"Failed to create Browser Rendering session for protocol fetch: \" +\n `${createResponse.status}`\n );\n }\n\n const payload = (await createResponse.json()) as { sessionId?: string };\n const sessionId = payload.sessionId;\n if (!sessionId) {\n throw new Error(\n \"Browser Rendering session response did not include a sessionId\"\n );\n }\n\n try {\n const response = await browser.fetch(\n `https://localhost/v1/devtools/browser/${sessionId}/json/protocol`\n );\n\n if (!response.ok) {\n throw new Error(\n \"Failed to fetch CDP spec from Browser Rendering: \" +\n `${response.status}`\n );\n }\n\n return (await response.json()) as { domains?: RawCdpDomain[] };\n } finally {\n try {\n await browser.fetch(\n `https://localhost/v1/devtools/browser/${sessionId}`,\n {\n method: \"DELETE\"\n }\n );\n } catch {\n // Cleanup failure should not mask the original result or error\n }\n }\n });\n}\n\nexport const EXECUTE_DESCRIPTION = `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}`;\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport interface ToolResult {\n text: string;\n isError?: boolean;\n}\n\nlet didWarnExperimental = false;\n\nexport function createBrowserToolHandlers(options: BrowserToolsOptions) {\n if (!didWarnExperimental) {\n didWarnExperimental = true;\n console.warn(\n \"[agents/browser] Browser tools are experimental and may change in a future release.\"\n );\n }\n const executor = new DynamicWorkerExecutor({\n loader: options.loader,\n timeout: options.timeout\n });\n\n async function search(code: string): Promise<ToolResult> {\n try {\n let specSource: SearchableCdpSpec;\n\n if (options.cdpUrl) {\n specSource = await fetchCdpSpecFromUrl(\n options.cdpUrl,\n options.cdpHeaders\n );\n } else if (options.browser) {\n specSource = await fetchCdpSpecFromBrowser(options.browser);\n } else {\n return {\n text: \"Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided\",\n isError: true\n };\n }\n\n const providers: ResolvedProvider[] = [\n {\n name: \"spec\",\n fns: { get: async () => specSource }\n }\n ];\n const result = await executor.execute(code, providers);\n if (result.error) {\n return { text: result.error, isError: true };\n }\n return { text: truncateResponse(result.result) };\n } catch (error) {\n return { text: formatError(error), isError: true };\n }\n }\n\n async function execute(code: string): Promise<ToolResult> {\n let session: CdpSession | undefined;\n try {\n if (options.cdpUrl) {\n session = await connectUrl(options.cdpUrl, {\n timeoutMs: options.timeout,\n headers: options.cdpHeaders\n });\n } else if (options.browser) {\n session = await connectBrowser(options.browser, options.timeout);\n } else {\n return {\n text: \"Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided\",\n isError: true\n };\n }\n\n const providers: ResolvedProvider[] = [\n {\n name: \"cdp\",\n fns: {\n send: async (method: unknown, params: unknown, opts: unknown) =>\n session!.send(\n method as string,\n params,\n opts as { timeoutMs?: number; sessionId?: string }\n ),\n attachToTarget: async (targetId: unknown, opts: unknown) =>\n session!.attachToTarget(\n targetId as string,\n opts as { timeoutMs?: number }\n ),\n getDebugLog: async (limit: unknown) =>\n session!.getDebugLog(limit as number | undefined),\n clearDebugLog: async () => session!.clearDebugLog()\n },\n positionalArgs: true\n }\n ];\n\n const result = await executor.execute(code, providers);\n if (result.error) {\n return { text: result.error, isError: true };\n }\n return { text: truncateResponse(result.result) };\n } catch (error) {\n return { text: formatError(error), isError: true };\n } finally {\n session?.close();\n }\n }\n\n return { search, execute };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shared-DzJYHisH.js","names":[],"sources":["../src/browser/cdp-session.ts","../src/browser/truncate.ts","../src/browser/shared.ts"],"sourcesContent":["interface PendingCommand {\n resolve: (result: unknown) => void;\n reject: (error: Error) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n method: string;\n sessionId?: string;\n startedAt: number;\n}\n\ninterface DebugEntry {\n at: string;\n type: string;\n [key: string]: unknown;\n}\n\nexport interface CdpSendOptions {\n timeoutMs?: number;\n sessionId?: string;\n}\n\nexport interface CdpAttachOptions {\n timeoutMs?: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_DEBUG_ENTRIES = 400;\n\n/**\n * A CDP session over an open WebSocket. Manages command correlation,\n * timeouts, target sessions, and a debug event ring buffer.\n *\n * Used host-side (not in the sandbox) — the sandbox calls into this\n * via DynamicWorkerExecutor's ToolDispatcher RPC.\n */\nexport class CdpSession {\n #socket: WebSocket;\n #nextId = 1;\n #pending = new Map<number, PendingCommand>();\n #debugLog: DebugEntry[] = [];\n #defaultTimeoutMs: number;\n #dispose?: () => void;\n\n constructor(\n socket: WebSocket,\n defaultTimeoutMs = DEFAULT_TIMEOUT_MS,\n dispose?: () => void\n ) {\n this.#socket = socket;\n this.#defaultTimeoutMs = defaultTimeoutMs;\n this.#dispose = dispose;\n\n socket.addEventListener(\"message\", (event) => this.#handleMessage(event));\n socket.addEventListener(\"error\", () => {\n this.#rejectAll(new Error(\"CDP socket error\"));\n });\n socket.addEventListener(\"close\", () => {\n this.#rejectAll(new Error(\"CDP connection closed\"));\n });\n }\n\n send(\n method: string,\n params?: unknown,\n options: CdpSendOptions = {}\n ): Promise<unknown> {\n const id = this.#nextId++;\n const timeoutMs = options.timeoutMs ?? this.#defaultTimeoutMs;\n const sessionId =\n typeof options.sessionId === \"string\" && options.sessionId.length > 0\n ? options.sessionId\n : undefined;\n\n const domain = typeof method === \"string\" ? method.split(\".\")[0] : \"\";\n if (!sessionId && domain && ![\"Browser\", \"Target\"].includes(domain)) {\n this.#recordDebug(\"warning\", {\n id,\n method,\n reason: \"target-scoped method sent without sessionId\"\n });\n }\n\n const result = new Promise<unknown>((resolve, reject) => {\n const startedAt = performance.now();\n const timeoutId = setTimeout(() => {\n this.#pending.delete(id);\n reject(\n new Error(`CDP command timed out after ${timeoutMs}ms: ${method}`)\n );\n }, timeoutMs);\n this.#pending.set(id, {\n resolve,\n reject,\n timeoutId,\n method,\n sessionId,\n startedAt\n });\n });\n\n this.#recordDebug(\"send\", { id, method, sessionId, timeoutMs });\n this.#socket.send(JSON.stringify({ id, method, params, sessionId }));\n return result;\n }\n\n async attachToTarget(\n targetId: string,\n options: CdpAttachOptions = {}\n ): Promise<string> {\n if (typeof targetId !== \"string\" || !targetId) {\n throw new Error(\"attachToTarget requires a targetId\");\n }\n\n const result = (await this.send(\n \"Target.attachToTarget\",\n {\n targetId,\n flatten: true\n },\n { timeoutMs: options.timeoutMs }\n )) as { sessionId?: string };\n\n const sessionId = result?.sessionId ?? \"\";\n if (!sessionId) {\n throw new Error(\n `Target.attachToTarget did not return a sessionId for target ${targetId}`\n );\n }\n\n this.#recordDebug(\"attach\", { targetId, sessionId });\n return sessionId;\n }\n\n getDebugLog(limit = 50): DebugEntry[] {\n const normalized = Number.isFinite(limit)\n ? Math.max(1, Math.floor(limit))\n : 50;\n return this.#debugLog.slice(-normalized);\n }\n\n clearDebugLog(): void {\n this.#debugLog = [];\n }\n\n close(): void {\n this.#rejectAll(new Error(\"CDP session closed\"));\n try {\n this.#socket.close(1000, \"Done\");\n } catch {\n // socket may already be closed\n }\n this.#dispose?.();\n }\n\n #rejectAll(error: Error): void {\n for (const [id, pending] of this.#pending.entries()) {\n clearTimeout(pending.timeoutId);\n this.#pending.delete(id);\n pending.reject(error);\n }\n }\n\n #handleMessage(event: MessageEvent): void {\n if (typeof event.data !== \"string\") {\n return;\n }\n\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(event.data) as Record<string, unknown>;\n } catch {\n return;\n }\n\n this.#recordDebug(\"receive\", {\n id: payload.id,\n method: payload.method,\n sessionId: payload.sessionId,\n hasError: !!payload.error\n });\n\n if (typeof payload.id !== \"number\") {\n return;\n }\n\n const pending = this.#pending.get(payload.id);\n if (!pending) {\n return;\n }\n\n clearTimeout(pending.timeoutId);\n this.#pending.delete(payload.id);\n\n if (payload.error) {\n const err = payload.error as { code?: unknown; message?: string };\n const code = err.code ?? \"unknown\";\n const message = err.message ?? \"CDP error\";\n pending.reject(\n new Error(`CDP error ${code}: ${message} for ${pending.method}`)\n );\n return;\n }\n\n pending.resolve(payload.result);\n }\n\n #recordDebug(type: string, data: Record<string, unknown>): void {\n this.#debugLog.push({\n at: new Date().toISOString(),\n type,\n ...data\n });\n if (this.#debugLog.length > MAX_DEBUG_ENTRIES) {\n this.#debugLog.splice(0, this.#debugLog.length - MAX_DEBUG_ENTRIES);\n }\n }\n}\n\n/**\n * Connect to a browser via the Browser Rendering binding (Fetcher).\n * Establishes a CDP WebSocket through the binding's fetch interface.\n */\nexport async function connectBrowser(\n browser: Fetcher,\n timeoutMs?: number\n): Promise<CdpSession> {\n const response = await browser.fetch(\n \"https://localhost/v1/devtools/browser\",\n {\n headers: { Upgrade: \"websocket\" }\n }\n );\n\n const ws = response.webSocket;\n if (!ws) {\n throw new Error(\n \"Browser Rendering binding did not return a WebSocket. \" +\n \"Ensure the 'browser' binding is configured in wrangler.jsonc.\"\n );\n }\n\n const sessionId = response.headers.get(\"cf-browser-session-id\");\n if (!sessionId) {\n throw new Error(\n \"Browser Rendering binding did not include a session ID when opening the CDP WebSocket\"\n );\n }\n\n ws.accept();\n return new CdpSession(ws, timeoutMs, () => {\n void browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}`, {\n method: \"DELETE\"\n });\n });\n}\n\nconst LOCALHOST_HOSTS = new Set([\n \"localhost\",\n \"127.0.0.1\",\n \"0.0.0.0\",\n \"::1\",\n \"[::1]\"\n]);\n\n/**\n * Connect to a browser via a CDP base URL (e.g. http://localhost:9222).\n * Discovers the WebSocket debugger URL via /json/version,\n * rewrites localhost URLs to the base URL host, and opens the WebSocket.\n *\n * Useful for local development with `chrome --remote-debugging-port=9222`\n * or when connecting through a tunnel.\n */\nexport async function connectUrl(\n baseUrl: string,\n options?: { timeoutMs?: number; headers?: Record<string, string> }\n): Promise<CdpSession> {\n const endpoint = new URL(\"/json/version\", baseUrl).toString();\n const response = await fetch(endpoint, {\n headers: options?.headers\n });\n if (!response.ok) {\n throw new Error(\n `Failed to discover CDP endpoint at ${endpoint}: ${response.status}`\n );\n }\n\n const payload = (await response.json()) as {\n webSocketDebuggerUrl?: string;\n };\n if (!payload.webSocketDebuggerUrl) {\n throw new Error(\"CDP /json/version did not include webSocketDebuggerUrl\");\n }\n\n let wsUrl = payload.webSocketDebuggerUrl;\n const parsed = new URL(wsUrl);\n if (LOCALHOST_HOSTS.has(parsed.hostname)) {\n const base = new URL(baseUrl);\n parsed.hostname = base.hostname;\n parsed.port = base.port;\n parsed.protocol = base.protocol;\n } else {\n // Workers runtime requires fetch + Upgrade header for outbound WebSockets\n parsed.protocol = parsed.protocol === \"wss:\" ? \"https:\" : \"http:\";\n }\n const fetchUrl = parsed.toString();\n\n const wsResponse = await fetch(fetchUrl, {\n headers: { ...options?.headers, Upgrade: \"websocket\" }\n });\n const ws = wsResponse.webSocket;\n if (!ws) {\n throw new Error(\n `Failed to establish CDP WebSocket at ${fetchUrl} (status ${wsResponse.status})`\n );\n }\n ws.accept();\n\n return new CdpSession(ws, options?.timeoutMs);\n}\n","const CHARS_PER_TOKEN = 4;\nconst MAX_TOKENS = 6000;\nconst MAX_CHARS = CHARS_PER_TOKEN * MAX_TOKENS;\n\nexport function truncateResponse(content: unknown): string {\n const text =\n typeof content === \"string\"\n ? content\n : (JSON.stringify(content, null, 2) ?? \"null\");\n if (text.length <= MAX_CHARS) {\n return text;\n }\n\n const estimatedTokens = Math.ceil(text.length / CHARS_PER_TOKEN);\n 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.`;\n}\n","import type { ResolvedProvider } from \"@cloudflare/codemode\";\nimport { DynamicWorkerExecutor } from \"@cloudflare/codemode\";\nimport { CdpSession, connectBrowser, connectUrl } from \"./cdp-session\";\nimport { truncateResponse } from \"./truncate\";\n\nexport interface BrowserToolsOptions {\n /** Browser Rendering binding (Fetcher) — used in production */\n browser?: Fetcher;\n /** Optional CDP base URL override (e.g. http://localhost:9222) */\n cdpUrl?: string;\n /** Headers to send with CDP URL discovery requests (e.g. Access headers) */\n cdpHeaders?: Record<string, string>;\n /** Loader binding for sandboxed code execution */\n loader: WorkerLoader;\n /** Execution timeout in milliseconds (default: 30000) */\n timeout?: number;\n}\n\ninterface RawCdpCommand {\n name: string;\n description?: string;\n}\n\ninterface RawCdpEvent {\n name: string;\n description?: string;\n}\n\ninterface RawCdpType {\n id: string;\n description?: string;\n}\n\n/** Raw CDP protocol domain from `/json/protocol` */\ninterface RawCdpDomain {\n domain: string;\n description?: string;\n commands?: RawCdpCommand[];\n events?: RawCdpEvent[];\n types?: RawCdpType[];\n}\n\ninterface SearchableCdpSpec {\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\nconst specCache = new Map<\n string,\n { spec: SearchableCdpSpec; cachedAt: number }\n>();\n\nconst CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\nexport const SEARCH_DESCRIPTION = `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}`;\n\nfunction normalizeCdpSpec(spec: {\n domains?: RawCdpDomain[];\n}): SearchableCdpSpec {\n return {\n domains: (spec.domains ?? []).map((domain) => ({\n name: domain.domain,\n description: domain.description,\n commands: (domain.commands ?? []).map((command) => ({\n name: command.name,\n method: `${domain.domain}.${command.name}`,\n description: command.description\n })),\n events: (domain.events ?? []).map((event) => ({\n name: event.name,\n event: `${domain.domain}.${event.name}`,\n description: event.description\n })),\n types: (domain.types ?? []).map((type) => ({\n id: type.id,\n name: `${domain.domain}.${type.id}`,\n description: type.description\n }))\n }))\n };\n}\n\nfunction getSpecCacheKey(\n source: string,\n headers?: Record<string, string>\n): string {\n const headerEntries = Object.entries(headers ?? {}).sort(([a], [b]) =>\n a.localeCompare(b)\n );\n return `${source}:${JSON.stringify(headerEntries)}`;\n}\n\nasync function getCachedSpec(\n key: string,\n load: () => Promise<{ domains?: RawCdpDomain[] }>\n): Promise<SearchableCdpSpec> {\n const cached = specCache.get(key);\n if (cached && Date.now() - cached.cachedAt < CACHE_TTL_MS) {\n return cached.spec;\n }\n\n const spec = normalizeCdpSpec(await load());\n specCache.set(key, { spec, cachedAt: Date.now() });\n return spec;\n}\n\nasync function fetchCdpSpecFromUrl(\n cdpBaseUrl: string,\n headers?: Record<string, string>\n): Promise<SearchableCdpSpec> {\n const endpoint = new URL(\"/json/protocol\", cdpBaseUrl).toString();\n\n return getCachedSpec(getSpecCacheKey(endpoint, headers), async () => {\n const response = await fetch(endpoint, { headers });\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch CDP spec from ${endpoint}: ${response.status}`\n );\n }\n\n return (await response.json()) as { domains?: RawCdpDomain[] };\n });\n}\n\nasync function fetchCdpSpecFromBrowser(\n browser: Fetcher\n): Promise<SearchableCdpSpec> {\n return getCachedSpec(\"browser-binding\", async () => {\n const createResponse = await browser.fetch(\n \"https://localhost/v1/devtools/browser\",\n {\n method: \"POST\"\n }\n );\n\n if (!createResponse.ok) {\n throw new Error(\n \"Failed to create Browser Rendering session for protocol fetch: \" +\n `${createResponse.status}`\n );\n }\n\n const payload = (await createResponse.json()) as { sessionId?: string };\n const sessionId = payload.sessionId;\n if (!sessionId) {\n throw new Error(\n \"Browser Rendering session response did not include a sessionId\"\n );\n }\n\n try {\n const response = await browser.fetch(\n `https://localhost/v1/devtools/browser/${sessionId}/json/protocol`\n );\n\n if (!response.ok) {\n throw new Error(\n \"Failed to fetch CDP spec from Browser Rendering: \" +\n `${response.status}`\n );\n }\n\n return (await response.json()) as { domains?: RawCdpDomain[] };\n } finally {\n try {\n await browser.fetch(\n `https://localhost/v1/devtools/browser/${sessionId}`,\n {\n method: \"DELETE\"\n }\n );\n } catch {\n // Cleanup failure should not mask the original result or error\n }\n }\n });\n}\n\nexport const EXECUTE_DESCRIPTION = `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}`;\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport interface ToolResult {\n text: string;\n isError?: boolean;\n}\n\nlet didWarnExperimental = false;\n\nexport function createBrowserToolHandlers(options: BrowserToolsOptions) {\n if (!didWarnExperimental) {\n didWarnExperimental = true;\n console.warn(\n \"[agents/browser] Browser tools are experimental and may change in a future release.\"\n );\n }\n const executor = new DynamicWorkerExecutor({\n loader: options.loader,\n timeout: options.timeout\n });\n\n async function search(code: string): Promise<ToolResult> {\n try {\n let specSource: SearchableCdpSpec;\n\n if (options.cdpUrl) {\n specSource = await fetchCdpSpecFromUrl(\n options.cdpUrl,\n options.cdpHeaders\n );\n } else if (options.browser) {\n specSource = await fetchCdpSpecFromBrowser(options.browser);\n } else {\n return {\n text: \"Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided\",\n isError: true\n };\n }\n\n const providers: ResolvedProvider[] = [\n {\n name: \"spec\",\n fns: { get: async () => specSource }\n }\n ];\n const result = await executor.execute(code, providers);\n if (result.error) {\n return { text: result.error, isError: true };\n }\n return { text: truncateResponse(result.result) };\n } catch (error) {\n return { text: formatError(error), isError: true };\n }\n }\n\n async function execute(code: string): Promise<ToolResult> {\n let session: CdpSession | undefined;\n try {\n if (options.cdpUrl) {\n session = await connectUrl(options.cdpUrl, {\n timeoutMs: options.timeout,\n headers: options.cdpHeaders\n });\n } else if (options.browser) {\n session = await connectBrowser(options.browser, options.timeout);\n } else {\n return {\n text: \"Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided\",\n isError: true\n };\n }\n\n const providers: ResolvedProvider[] = [\n {\n name: \"cdp\",\n fns: {\n send: async (method: unknown, params: unknown, opts: unknown) =>\n session!.send(\n method as string,\n params,\n opts as { timeoutMs?: number; sessionId?: string }\n ),\n attachToTarget: async (targetId: unknown, opts: unknown) =>\n session!.attachToTarget(\n targetId as string,\n opts as { timeoutMs?: number }\n ),\n getDebugLog: async (limit: unknown) =>\n session!.getDebugLog(limit as number | undefined),\n clearDebugLog: async () => session!.clearDebugLog()\n },\n positionalArgs: true\n }\n ];\n\n const result = await executor.execute(code, providers);\n if (result.error) {\n return { text: result.error, isError: true };\n }\n return { text: truncateResponse(result.result) };\n } catch (error) {\n return { text: formatError(error), isError: true };\n } finally {\n session?.close();\n }\n }\n\n return { search, execute };\n}\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import {
2
- At as SUB_PREFIX,
3
- Mt as getSubAgentByName,
4
- Nt as parseSubAgentPath,
5
- Pt as routeSubAgentRequest,
6
- jt as SubAgentPathMatch
7
- } from "./agent-tool-types-DSteYkkS.js";
2
+ Ft as parseSubAgentPath,
3
+ It as routeSubAgentRequest,
4
+ Mt as SUB_PREFIX,
5
+ Nt as SubAgentPathMatch,
6
+ Pt as getSubAgentByName
7
+ } from "./agent-tool-types-CM_50fcV.js";
8
8
  export {
9
9
  SUB_PREFIX,
10
10
  SubAgentPathMatch,
@@ -1 +1 @@
1
- {"version":3,"file":"sub-routing.js","names":[],"sources":["../src/sub-routing.ts"],"sourcesContent":["/**\n * Sub-agent routing primitives — external addressability for facets.\n *\n * The public surface:\n * - `routeSubAgentRequest(req, parent, options?)` — the sub-agent\n * analog of `routeAgentRequest`. Use in custom fetch handlers.\n * - `getSubAgentByName(parent, Cls, name)` — the sub-agent analog\n * of `getAgentByName`. Returns a typed RPC stub that proxies\n * method calls through the parent. No `.fetch()` support —\n * external HTTP/WS routing goes through `routeSubAgentRequest`.\n *\n * Internal:\n * - `parseSubAgentPath(url)` — URL → `{ childClass, childName, remainingPath }`.\n * - `forwardToFacet(req, parent, match)` — resolves `ctx.facets.get(...)`\n * on the parent and returns `facetStub.fetch(rewrittenReq)`.\n *\n * @experimental The API surface may change before stabilizing.\n */\n\nimport { camelCaseToKebabCase, isInternalJsStubProp } from \"./utils\";\nimport type { Agent, SubAgentClass, SubAgentStub } from \"./index\";\n\n/**\n * URL segment marking a parent↔child boundary.\n *\n * Exposed as a constant so callers can build URLs symbolically, but\n * not configurable — the routing layer matches on the literal `sub`\n * token everywhere (parent fetch, client, helpers).\n */\nexport const SUB_PREFIX = \"sub\";\n\nexport interface SubAgentPathMatch {\n /** CamelCase class name of the child, as it appears in `ctx.exports`. */\n childClass: string;\n /** URL-decoded child name. */\n childName: string;\n /**\n * Request path to forward to the child, with the\n * `/sub/{class}/{name}` segment stripped. Always begins with `/`;\n * may itself contain further `/sub/...` markers when a\n * recursively nested sub-agent is being routed.\n */\n remainingPath: string;\n}\n\n/**\n * Parse a URL and extract the first `/sub/{class}/{name}` segment,\n * if any. Recursive nesting is handled naturally: callers parse one\n * level at a time; the child then parses its own URL (which still\n * contains any deeper `/sub/...` markers).\n *\n * Names are URL-decoded. Classes are kebab-to-CamelCase converted\n * via a best-effort match against a provided lookup — pass\n * `ctx.exports` keys to get exact CamelCase; pass `undefined` for\n * a tolerant conversion without validation.\n *\n * Returns `null` when the URL doesn't contain the marker at a\n * recognized position, or when the marker has no following\n * class+name pair.\n */\nexport function parseSubAgentPath(\n url: string,\n options?: {\n /** CamelCase class names to match against (usually `ctx.exports` keys). */\n knownClasses?: readonly string[];\n }\n): SubAgentPathMatch | null {\n const pathname = new URL(url).pathname;\n const parts = pathname.split(\"/\").filter(Boolean);\n\n // Walk every occurrence of the `sub` segment — a plain\n // `indexOf(SUB_PREFIX)` would mis-match when the literal token\n // appears earlier in the URL (parent instance name == \"sub\", a\n // `basePath` segment that happens to be \"sub\", etc). We return\n // the first position where `parts[i+1]` resolves to a valid\n // class, which pins the real parent↔child boundary.\n for (let i = 0; i < parts.length; i++) {\n if (parts[i] !== SUB_PREFIX) continue;\n if (i + 2 >= parts.length) continue;\n\n const classSegment = parts[i + 1];\n const nameSegment = parts[i + 2];\n\n const childClass = resolveClassName(classSegment, options?.knownClasses);\n if (!childClass) continue;\n\n let childName: string;\n try {\n childName = decodeURIComponent(nameSegment);\n } catch {\n continue;\n }\n\n const remainingParts = parts.slice(i + 3);\n const remainingPath =\n remainingParts.length > 0 ? \"/\" + remainingParts.join(\"/\") : \"/\";\n\n return { childClass, childName, remainingPath };\n }\n\n return null;\n}\n\n/**\n * Best-effort kebab-to-CamelCase match. If `knownClasses` is\n * provided, returns the matching CamelCase entry (or null if no\n * match). If not, performs a naive kebab→CamelCase conversion.\n */\nfunction resolveClassName(\n segment: string,\n knownClasses?: readonly string[]\n): string | null {\n if (knownClasses) {\n const match = knownClasses.find(\n (name) => camelCaseToKebabCase(name) === segment\n );\n return match ?? null;\n }\n return segment\n .split(\"-\")\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join(\"\");\n}\n\n// ── routeSubAgentRequest ───────────────────────────────────────────\n\n/**\n * Minimal parent-side shape that `routeSubAgentRequest` relies on:\n * something fetchable (a DO stub, a sub-agent stub, etc.).\n *\n * @internal\n */\ninterface FetchableParent {\n fetch(req: Request): Promise<Response>;\n}\n\n/**\n * Route a request into a sub-agent via its parent DO.\n *\n * Use this in a custom fetch handler when your URL shape doesn't\n * match the `/agents/{class}/{name}` default — you identify and\n * fetch the parent yourself, then let this helper parse the\n * `/sub/{child}/...` tail and forward it.\n *\n * Runs `onBeforeSubAgent` on the parent DO (authorization / request\n * mutation / short-circuit response).\n *\n * For the default `/agents/...` URL shape, use `routeAgentRequest`\n * instead — it handles the parent lookup and this dispatch in one\n * call.\n *\n * @example\n * ```ts\n * export default {\n * async fetch(req, env) {\n * const { parentName, rest } = myCustomParse(req.url);\n * const parent = await getAgentByName(env.Inbox, parentName);\n * return routeSubAgentRequest(req, parent, { fromPath: rest });\n * }\n * };\n * ```\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport async function routeSubAgentRequest(\n req: Request,\n parent: unknown,\n options?: {\n /**\n * Path to route on. Defaults to `req.url`'s pathname. Useful\n * when your outer URL is custom (e.g. `/api/v1/...`) and you\n * want to route the sub-agent tail without rewriting the\n * Request first.\n */\n fromPath?: string;\n }\n): Promise<Response> {\n // We don't know the parent's ctx.exports from here, so parse with\n // a permissive resolver. If the class doesn't exist, the parent's\n // bridge will 404. This lets us keep the helper self-contained.\n const pathForParsing = options?.fromPath\n ? `http://placeholder${options.fromPath.startsWith(\"/\") ? \"\" : \"/\"}${options.fromPath}`\n : req.url;\n\n const match = parseSubAgentPath(pathForParsing);\n if (!match) {\n return new Response(\"Sub-agent path not found in request URL\", {\n status: 400\n });\n }\n\n // Hand the request to the parent so `onBeforeSubAgent` fires in\n // the parent's isolate. The parent's `fetch` handler recognizes\n // the marker internally — we preserve the original request URL\n // (possibly rewritten by `fromPath`) so the parent's parse sees\n // the same match.\n //\n // Key subtlety: when rewriting the pathname via `fromPath`, we\n // mutate the *original* URL's pathname instead of constructing a\n // new URL from scratch. `new URL(\"/path\", baseWithQuery)` discards\n // the base's search; we want the caller's query params (e.g. auth\n // tokens, PartySocket's `_pk=...` handshake key) to survive.\n // Mirrors how `_cf_forwardToFacet` rewrites only pathname when\n // handing off to the child facet. If `fromPath` itself contains a\n // `?query` segment, that overrides the original.\n const forwardUrl =\n options?.fromPath !== undefined\n ? rewritePathname(req.url, options.fromPath)\n : req.url;\n const forwardInit: RequestInit = {\n method: req.method,\n headers: new Headers(req.headers)\n };\n if (req.body && req.method !== \"GET\" && req.method !== \"HEAD\") {\n forwardInit.body = await req.arrayBuffer();\n }\n const forwardReq = new Request(forwardUrl, forwardInit);\n\n return (parent as FetchableParent).fetch(forwardReq);\n}\n\n/**\n * Replace a URL's pathname (and optionally its search) while\n * preserving every other component. Matches how `_cf_forwardToFacet`\n * forwards requests — pathname is the only thing that changes by\n * default; if the replacement path carries its own query string,\n * that wins.\n */\nfunction rewritePathname(url: string, fromPath: string): string {\n const normalized = fromPath.startsWith(\"/\") ? fromPath : `/${fromPath}`;\n const queryIdx = normalized.indexOf(\"?\");\n const pathOnly = queryIdx >= 0 ? normalized.slice(0, queryIdx) : normalized;\n const querySuffix = queryIdx >= 0 ? normalized.slice(queryIdx) : \"\";\n\n const rewritten = new URL(url);\n rewritten.pathname = pathOnly;\n if (querySuffix) {\n rewritten.search = querySuffix; // URL setter keeps the `?` prefix\n }\n return rewritten.toString();\n}\n\n// ── getSubAgentByName ──────────────────────────────────────────────\n\n/**\n * Parent-side RPC bridge shape that `getSubAgentByName` relies on.\n *\n * @internal\n */\ninterface SubAgentInvokeEndpoint {\n _cf_invokeSubAgent(\n className: string,\n name: string,\n method: string,\n args: unknown[]\n ): Promise<unknown>;\n}\n\n/**\n * Get a typed RPC stub for a sub-agent from outside the parent DO.\n *\n * The returned stub proxies method calls through the parent via a\n * stateless per-call bridge (caller → parent → facet), so each\n * method invocation costs one extra RPC hop. Works across parent\n * hibernation — no cached references to go stale.\n *\n * Limitations:\n * - RPC methods only. `.fetch()` is not supported (will throw).\n * Use `routeSubAgentRequest` for external HTTP/WS.\n * - Arguments and return values must be structured-cloneable,\n * same as any DO RPC call.\n * - Does not run `onBeforeSubAgent` on the parent — analogous to\n * `getAgentByName` not running `onBeforeConnect`. The caller is\n * assumed to have performed whatever access checks are needed.\n *\n * @example\n * ```ts\n * const inbox = await getAgentByName(env.MyInbox, userId);\n * const chat = await getSubAgentByName(inbox, MyChat, chatId);\n * await chat.addMessage({ role: \"user\", content: \"hi\" });\n * ```\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport async function getSubAgentByName<T extends Agent>(\n parent: unknown,\n cls: SubAgentClass<T>,\n name: string\n): Promise<SubAgentStub<T>> {\n if (name.includes(\"\\0\")) {\n throw new Error(\n `Sub-agent name contains null character (\\\\0), which is reserved.`\n );\n }\n\n const bridge = parent as SubAgentInvokeEndpoint;\n const className = cls?.name;\n if (!className) {\n throw new Error(\n `getSubAgentByName: could not determine class name from ${cls}. ` +\n `Ensure you are passing the class constructor (e.g. getSubAgentByName(parent, MyChat, name)), not a string or undefined.`\n );\n }\n\n return new Proxy(\n {},\n {\n get(_target, prop) {\n // JS / runtime / test-framework probes (thenable check,\n // serialization, inspection, matcher duck-typing) must NOT\n // dispatch an RPC — returning `undefined` is the contract\n // the inner `createStubProxy` uses for `useAgent` stubs.\n // Without this guard, `JSON.stringify(stub)`, `console.log`,\n // Vitest matchers, and `await stub` would all trigger bogus\n // `_cf_invokeSubAgent` calls that fail with \"Method not found\".\n if (isInternalJsStubProp(prop)) return undefined;\n if (typeof prop !== \"string\") return undefined;\n // `.fetch` gets a dedicated error so users who try to use\n // the stub for HTTP/WS get a helpful pointer.\n if (prop === \"fetch\") {\n return () => {\n throw new Error(\n `getSubAgentByName returns an RPC-only stub — .fetch() is ` +\n `not supported. Use routeSubAgentRequest() or the ` +\n `/agents/{parent}/{name}/sub/{child}/{name} URL for ` +\n `external HTTP/WS routing.`\n );\n };\n }\n return async (...args: unknown[]) =>\n bridge._cf_invokeSubAgent(className, name, prop, args);\n }\n }\n ) as SubAgentStub<T>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sub-routing.js","names":[],"sources":["../src/sub-routing.ts"],"sourcesContent":["/**\n * Sub-agent routing primitives — external addressability for facets.\n *\n * The public surface:\n * - `routeSubAgentRequest(req, parent, options?)` — the sub-agent\n * analog of `routeAgentRequest`. Use in custom fetch handlers.\n * - `getSubAgentByName(parent, Cls, name)` — the sub-agent analog\n * of `getAgentByName`. Returns a typed RPC stub that proxies\n * method calls through the parent. No `.fetch()` support —\n * external HTTP/WS routing goes through `routeSubAgentRequest`.\n *\n * Internal:\n * - `parseSubAgentPath(url)` — URL → `{ childClass, childName, remainingPath }`.\n * - `forwardToFacet(req, parent, match)` — resolves `ctx.facets.get(...)`\n * on the parent and returns `facetStub.fetch(rewrittenReq)`.\n *\n * @experimental The API surface may change before stabilizing.\n */\n\nimport { camelCaseToKebabCase, isInternalJsStubProp } from \"./utils\";\nimport type { Agent, SubAgentClass, SubAgentStub } from \"./index\";\n\n/**\n * URL segment marking a parent↔child boundary.\n *\n * Exposed as a constant so callers can build URLs symbolically, but\n * not configurable — the routing layer matches on the literal `sub`\n * token everywhere (parent fetch, client, helpers).\n */\nexport const SUB_PREFIX = \"sub\";\n\nexport interface SubAgentPathMatch {\n /** CamelCase class name of the child, as it appears in `ctx.exports`. */\n childClass: string;\n /** URL-decoded child name. */\n childName: string;\n /**\n * Request path to forward to the child, with the\n * `/sub/{class}/{name}` segment stripped. Always begins with `/`;\n * may itself contain further `/sub/...` markers when a\n * recursively nested sub-agent is being routed.\n */\n remainingPath: string;\n}\n\n/**\n * Parse a URL and extract the first `/sub/{class}/{name}` segment,\n * if any. Recursive nesting is handled naturally: callers parse one\n * level at a time; the child then parses its own URL (which still\n * contains any deeper `/sub/...` markers).\n *\n * Names are URL-decoded. Classes are kebab-to-CamelCase converted\n * via a best-effort match against a provided lookup — pass\n * `ctx.exports` keys to get exact CamelCase; pass `undefined` for\n * a tolerant conversion without validation.\n *\n * Returns `null` when the URL doesn't contain the marker at a\n * recognized position, or when the marker has no following\n * class+name pair.\n */\nexport function parseSubAgentPath(\n url: string,\n options?: {\n /** CamelCase class names to match against (usually `ctx.exports` keys). */\n knownClasses?: readonly string[];\n }\n): SubAgentPathMatch | null {\n const pathname = new URL(url).pathname;\n const parts = pathname.split(\"/\").filter(Boolean);\n\n // Walk every occurrence of the `sub` segment — a plain\n // `indexOf(SUB_PREFIX)` would mis-match when the literal token\n // appears earlier in the URL (parent instance name == \"sub\", a\n // `basePath` segment that happens to be \"sub\", etc). We return\n // the first position where `parts[i+1]` resolves to a valid\n // class, which pins the real parent↔child boundary.\n for (let i = 0; i < parts.length; i++) {\n if (parts[i] !== SUB_PREFIX) continue;\n if (i + 2 >= parts.length) continue;\n\n const classSegment = parts[i + 1];\n const nameSegment = parts[i + 2];\n\n const childClass = resolveClassName(classSegment, options?.knownClasses);\n if (!childClass) continue;\n\n let childName: string;\n try {\n childName = decodeURIComponent(nameSegment);\n } catch {\n continue;\n }\n\n const remainingParts = parts.slice(i + 3);\n const remainingPath =\n remainingParts.length > 0 ? \"/\" + remainingParts.join(\"/\") : \"/\";\n\n return { childClass, childName, remainingPath };\n }\n\n return null;\n}\n\n/**\n * Best-effort kebab-to-CamelCase match. If `knownClasses` is\n * provided, returns the matching CamelCase entry (or null if no\n * match). If not, performs a naive kebab→CamelCase conversion.\n */\nfunction resolveClassName(\n segment: string,\n knownClasses?: readonly string[]\n): string | null {\n if (knownClasses) {\n const match = knownClasses.find(\n (name) => camelCaseToKebabCase(name) === segment\n );\n return match ?? null;\n }\n return segment\n .split(\"-\")\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join(\"\");\n}\n\n// ── routeSubAgentRequest ───────────────────────────────────────────\n\n/**\n * Minimal parent-side shape that `routeSubAgentRequest` relies on:\n * something fetchable (a DO stub, a sub-agent stub, etc.).\n *\n * @internal\n */\ninterface FetchableParent {\n fetch(req: Request): Promise<Response>;\n}\n\n/**\n * Route a request into a sub-agent via its parent DO.\n *\n * Use this in a custom fetch handler when your URL shape doesn't\n * match the `/agents/{class}/{name}` default — you identify and\n * fetch the parent yourself, then let this helper parse the\n * `/sub/{child}/...` tail and forward it.\n *\n * Runs `onBeforeSubAgent` on the parent DO (authorization / request\n * mutation / short-circuit response).\n *\n * For the default `/agents/...` URL shape, use `routeAgentRequest`\n * instead — it handles the parent lookup and this dispatch in one\n * call.\n *\n * @example\n * ```ts\n * export default {\n * async fetch(req, env) {\n * const { parentName, rest } = myCustomParse(req.url);\n * const parent = await getAgentByName(env.Inbox, parentName);\n * return routeSubAgentRequest(req, parent, { fromPath: rest });\n * }\n * };\n * ```\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport async function routeSubAgentRequest(\n req: Request,\n parent: unknown,\n options?: {\n /**\n * Path to route on. Defaults to `req.url`'s pathname. Useful\n * when your outer URL is custom (e.g. `/api/v1/...`) and you\n * want to route the sub-agent tail without rewriting the\n * Request first.\n */\n fromPath?: string;\n }\n): Promise<Response> {\n // We don't know the parent's ctx.exports from here, so parse with\n // a permissive resolver. If the class doesn't exist, the parent's\n // bridge will 404. This lets us keep the helper self-contained.\n const pathForParsing = options?.fromPath\n ? `http://placeholder${options.fromPath.startsWith(\"/\") ? \"\" : \"/\"}${options.fromPath}`\n : req.url;\n\n const match = parseSubAgentPath(pathForParsing);\n if (!match) {\n return new Response(\"Sub-agent path not found in request URL\", {\n status: 400\n });\n }\n\n // Hand the request to the parent so `onBeforeSubAgent` fires in\n // the parent's isolate. The parent's `fetch` handler recognizes\n // the marker internally — we preserve the original request URL\n // (possibly rewritten by `fromPath`) so the parent's parse sees\n // the same match.\n //\n // Key subtlety: when rewriting the pathname via `fromPath`, we\n // mutate the *original* URL's pathname instead of constructing a\n // new URL from scratch. `new URL(\"/path\", baseWithQuery)` discards\n // the base's search; we want the caller's query params (e.g. auth\n // tokens, PartySocket's `_pk=...` handshake key) to survive.\n // Mirrors how `_cf_forwardToFacet` rewrites only pathname when\n // handing off to the child facet. If `fromPath` itself contains a\n // `?query` segment, that overrides the original.\n const forwardUrl =\n options?.fromPath !== undefined\n ? rewritePathname(req.url, options.fromPath)\n : req.url;\n const forwardInit: RequestInit = {\n method: req.method,\n headers: new Headers(req.headers)\n };\n if (req.body && req.method !== \"GET\" && req.method !== \"HEAD\") {\n forwardInit.body = await req.arrayBuffer();\n }\n const forwardReq = new Request(forwardUrl, forwardInit);\n\n return (parent as FetchableParent).fetch(forwardReq);\n}\n\n/**\n * Replace a URL's pathname (and optionally its search) while\n * preserving every other component. Matches how `_cf_forwardToFacet`\n * forwards requests — pathname is the only thing that changes by\n * default; if the replacement path carries its own query string,\n * that wins.\n */\nfunction rewritePathname(url: string, fromPath: string): string {\n const normalized = fromPath.startsWith(\"/\") ? fromPath : `/${fromPath}`;\n const queryIdx = normalized.indexOf(\"?\");\n const pathOnly = queryIdx >= 0 ? normalized.slice(0, queryIdx) : normalized;\n const querySuffix = queryIdx >= 0 ? normalized.slice(queryIdx) : \"\";\n\n const rewritten = new URL(url);\n rewritten.pathname = pathOnly;\n if (querySuffix) {\n rewritten.search = querySuffix; // URL setter keeps the `?` prefix\n }\n return rewritten.toString();\n}\n\n// ── getSubAgentByName ──────────────────────────────────────────────\n\n/**\n * Parent-side RPC bridge shape that `getSubAgentByName` relies on.\n *\n * @internal\n */\ninterface SubAgentInvokeEndpoint {\n _cf_invokeSubAgent(\n className: string,\n name: string,\n method: string,\n args: unknown[]\n ): Promise<unknown>;\n}\n\n/**\n * Get a typed RPC stub for a sub-agent from outside the parent DO.\n *\n * The returned stub proxies method calls through the parent via a\n * stateless per-call bridge (caller → parent → facet), so each\n * method invocation costs one extra RPC hop. Works across parent\n * hibernation — no cached references to go stale.\n *\n * Limitations:\n * - RPC methods only. `.fetch()` is not supported (will throw).\n * Use `routeSubAgentRequest` for external HTTP/WS.\n * - Arguments and return values must be structured-cloneable,\n * same as any DO RPC call.\n * - Does not run `onBeforeSubAgent` on the parent — analogous to\n * `getAgentByName` not running `onBeforeConnect`. The caller is\n * assumed to have performed whatever access checks are needed.\n *\n * @example\n * ```ts\n * const inbox = await getAgentByName(env.MyInbox, userId);\n * const chat = await getSubAgentByName(inbox, MyChat, chatId);\n * await chat.addMessage({ role: \"user\", content: \"hi\" });\n * ```\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport async function getSubAgentByName<T extends Agent>(\n parent: unknown,\n cls: SubAgentClass<T>,\n name: string\n): Promise<SubAgentStub<T>> {\n if (name.includes(\"\\0\")) {\n throw new Error(\n `Sub-agent name contains null character (\\\\0), which is reserved.`\n );\n }\n\n const bridge = parent as SubAgentInvokeEndpoint;\n const className = cls?.name;\n if (!className) {\n throw new Error(\n `getSubAgentByName: could not determine class name from ${cls}. ` +\n `Ensure you are passing the class constructor (e.g. getSubAgentByName(parent, MyChat, name)), not a string or undefined.`\n );\n }\n\n return new Proxy(\n {},\n {\n get(_target, prop) {\n // JS / runtime / test-framework probes (thenable check,\n // serialization, inspection, matcher duck-typing) must NOT\n // dispatch an RPC — returning `undefined` is the contract\n // the inner `createStubProxy` uses for `useAgent` stubs.\n // Without this guard, `JSON.stringify(stub)`, `console.log`,\n // Vitest matchers, and `await stub` would all trigger bogus\n // `_cf_invokeSubAgent` calls that fail with \"Method not found\".\n if (isInternalJsStubProp(prop)) return undefined;\n if (typeof prop !== \"string\") return undefined;\n // `.fetch` gets a dedicated error so users who try to use\n // the stub for HTTP/WS get a helpful pointer.\n if (prop === \"fetch\") {\n return () => {\n throw new Error(\n `getSubAgentByName returns an RPC-only stub — .fetch() is ` +\n `not supported. Use routeSubAgentRequest() or the ` +\n `/agents/{parent}/{name}/sub/{child}/{name} URL for ` +\n `external HTTP/WS routing.`\n );\n };\n }\n return async (...args: unknown[]) =>\n bridge._cf_invokeSubAgent(className, name, prop, args);\n }\n }\n ) as SubAgentStub<T>;\n}\n"],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ //#region src/chat/tool-output-truncation.ts
2
+ const DEFAULT_MAX_DEPTH = 8;
3
+ const TRUNCATED_FLAG = "__truncated";
4
+ const TRUNCATED_CHARS = "__truncatedChars";
5
+ function truncateToolOutput(output, maxChars) {
6
+ const original = stringifyForLength(output);
7
+ if (original.length <= maxChars) return {
8
+ output,
9
+ truncated: false,
10
+ originalLength: original.length
11
+ };
12
+ return {
13
+ output: truncateValue(output, maxChars, original.length, 0),
14
+ truncated: true,
15
+ originalLength: original.length
16
+ };
17
+ }
18
+ function truncatedSuffix(originalLength) {
19
+ return `... [truncated ${originalLength} chars]`;
20
+ }
21
+ function truncateValue(value, maxChars, originalLength, depth) {
22
+ if (typeof value === "string") return truncateString(value, maxChars, value.length);
23
+ if (value === null || typeof value !== "object") return value;
24
+ if (depth >= DEFAULT_MAX_DEPTH) return `[Nested output omitted ${truncatedSuffix(originalLength)}]`;
25
+ if (Array.isArray(value)) return truncateArray(value, maxChars, originalLength, depth);
26
+ return truncateObject(value, maxChars, originalLength, depth);
27
+ }
28
+ function truncateArray(value, maxChars, originalLength, depth) {
29
+ const childBudget = childMaxChars(maxChars, value.length);
30
+ const result = value.map((item) => truncateValue(item, childBudget, stringifyForLength(item).length, depth + 1));
31
+ while (result.length > 1 && stringifyForLength(result).length > maxChars) result.pop();
32
+ if (result.length < value.length) result.push(`Array output truncated ${truncatedSuffix(originalLength)}`);
33
+ if (stringifyForLength(result).length > maxChars) return compactArrayMarker(maxChars, originalLength);
34
+ return result;
35
+ }
36
+ function truncateObject(value, maxChars, originalLength, depth) {
37
+ const entries = Object.entries(value);
38
+ const childBudget = childMaxChars(maxChars, entries.length);
39
+ const result = {};
40
+ for (const [key, entryValue] of entries) result[key] = truncateValue(entryValue, childBudget, stringifyForLength(entryValue).length, depth + 1);
41
+ const resultLength = stringifyForLength(result).length;
42
+ if (resultLength <= maxChars) return result;
43
+ shrinkStringFields(result, maxChars);
44
+ if (stringifyForLength(result).length > maxChars) {
45
+ result[TRUNCATED_FLAG] = true;
46
+ result[TRUNCATED_CHARS] = resultLength;
47
+ }
48
+ if (stringifyForLength(result).length > maxChars) return compactObjectMarker(maxChars, originalLength);
49
+ return result;
50
+ }
51
+ function shrinkStringFields(value, maxChars) {
52
+ const stringEntries = Object.entries(value).filter((entry) => typeof entry[1] === "string").sort((a, b) => b[1].length - a[1].length);
53
+ for (const [key, str] of stringEntries) {
54
+ if (stringifyForLength(value).length <= maxChars) return;
55
+ value[key] = truncateString(str, Math.max(0, Math.floor(maxChars / 4)), str.length);
56
+ }
57
+ }
58
+ function truncateString(value, maxChars, originalLength) {
59
+ if (value.length <= maxChars) return value;
60
+ const suffix = truncatedSuffix(originalLength);
61
+ if (maxChars <= suffix.length) return suffix.slice(0, maxChars);
62
+ return `${value.slice(0, maxChars - suffix.length)}${suffix}`;
63
+ }
64
+ function compactObjectMarker(maxChars, originalLength) {
65
+ const marker = {
66
+ [TRUNCATED_FLAG]: true,
67
+ [TRUNCATED_CHARS]: originalLength,
68
+ note: "Tool output omitted because it was too large to preserve structurally."
69
+ };
70
+ if (stringifyForLength(marker).length <= maxChars) return marker;
71
+ return {
72
+ [TRUNCATED_FLAG]: true,
73
+ [TRUNCATED_CHARS]: originalLength
74
+ };
75
+ }
76
+ function compactArrayMarker(maxChars, originalLength) {
77
+ const structuredMarker = compactObjectMarker(maxChars, originalLength);
78
+ if (stringifyForLength([structuredMarker]).length <= maxChars) return [structuredMarker];
79
+ const marker = [`Array output omitted because it was too large to preserve structurally ${truncatedSuffix(originalLength)}`];
80
+ if (stringifyForLength(marker).length <= maxChars) return marker;
81
+ return [truncatedSuffix(originalLength).slice(0, maxChars)];
82
+ }
83
+ function childMaxChars(maxChars, childCount) {
84
+ if (childCount <= 1) return maxChars;
85
+ return Math.max(80, Math.floor(maxChars / Math.min(childCount, 10)));
86
+ }
87
+ function stringifyForLength(value) {
88
+ try {
89
+ if (typeof value === "string") return value;
90
+ return JSON.stringify(value) ?? String(value);
91
+ } catch {
92
+ return String(value);
93
+ }
94
+ }
95
+ //#endregion
96
+ export { truncateToolOutput as t };
97
+
98
+ //# sourceMappingURL=tool-output-truncation-CH-khbZ3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-output-truncation-CH-khbZ3.js","names":[],"sources":["../src/chat/tool-output-truncation.ts"],"sourcesContent":["export interface TruncatedToolOutput {\n output: unknown;\n truncated: boolean;\n originalLength: number;\n}\n\nconst DEFAULT_MAX_DEPTH = 8;\nconst TRUNCATED_FLAG = \"__truncated\";\nconst TRUNCATED_CHARS = \"__truncatedChars\";\n\nexport function truncateToolOutput(\n output: unknown,\n maxChars: number\n): TruncatedToolOutput {\n const original = stringifyForLength(output);\n if (original.length <= maxChars) {\n return { output, truncated: false, originalLength: original.length };\n }\n\n return {\n output: truncateValue(output, maxChars, original.length, 0),\n truncated: true,\n originalLength: original.length\n };\n}\n\nexport function truncatedSuffix(originalLength: number): string {\n return `... [truncated ${originalLength} chars]`;\n}\n\nfunction truncateValue(\n value: unknown,\n maxChars: number,\n originalLength: number,\n depth: number\n): unknown {\n if (typeof value === \"string\") {\n return truncateString(value, maxChars, value.length);\n }\n\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n\n if (depth >= DEFAULT_MAX_DEPTH) {\n return `[Nested output omitted ${truncatedSuffix(originalLength)}]`;\n }\n\n if (Array.isArray(value)) {\n return truncateArray(value, maxChars, originalLength, depth);\n }\n\n return truncateObject(\n value as Record<string, unknown>,\n maxChars,\n originalLength,\n depth\n );\n}\n\nfunction truncateArray(\n value: unknown[],\n maxChars: number,\n originalLength: number,\n depth: number\n): unknown[] {\n const childBudget = childMaxChars(maxChars, value.length);\n const result = value.map((item) =>\n truncateValue(item, childBudget, stringifyForLength(item).length, depth + 1)\n );\n\n while (result.length > 1 && stringifyForLength(result).length > maxChars) {\n result.pop();\n }\n\n if (result.length < value.length) {\n result.push(`Array output truncated ${truncatedSuffix(originalLength)}`);\n }\n\n if (stringifyForLength(result).length > maxChars) {\n return compactArrayMarker(maxChars, originalLength);\n }\n\n return result;\n}\n\nfunction truncateObject(\n value: Record<string, unknown>,\n maxChars: number,\n originalLength: number,\n depth: number\n): Record<string, unknown> {\n const entries = Object.entries(value);\n const childBudget = childMaxChars(maxChars, entries.length);\n const result: Record<string, unknown> = {};\n\n for (const [key, entryValue] of entries) {\n result[key] = truncateValue(\n entryValue,\n childBudget,\n stringifyForLength(entryValue).length,\n depth + 1\n );\n }\n\n const resultLength = stringifyForLength(result).length;\n if (resultLength <= maxChars) {\n return result;\n }\n\n shrinkStringFields(result, maxChars);\n const shrunkLength = stringifyForLength(result).length;\n if (shrunkLength > maxChars) {\n result[TRUNCATED_FLAG] = true;\n result[TRUNCATED_CHARS] = resultLength;\n }\n\n if (stringifyForLength(result).length > maxChars) {\n return compactObjectMarker(maxChars, originalLength);\n }\n\n return result;\n}\n\nfunction shrinkStringFields(\n value: Record<string, unknown>,\n maxChars: number\n): void {\n const stringEntries = Object.entries(value)\n .filter((entry): entry is [string, string] => typeof entry[1] === \"string\")\n .sort((a, b) => b[1].length - a[1].length);\n\n for (const [key, str] of stringEntries) {\n if (stringifyForLength(value).length <= maxChars) {\n return;\n }\n\n value[key] = truncateString(\n str,\n Math.max(0, Math.floor(maxChars / 4)),\n str.length\n );\n }\n}\n\nfunction truncateString(\n value: string,\n maxChars: number,\n originalLength: number\n): string {\n if (value.length <= maxChars) {\n return value;\n }\n\n const suffix = truncatedSuffix(originalLength);\n if (maxChars <= suffix.length) {\n return suffix.slice(0, maxChars);\n }\n\n return `${value.slice(0, maxChars - suffix.length)}${suffix}`;\n}\n\nfunction compactObjectMarker(\n maxChars: number,\n originalLength: number\n): Record<string, unknown> {\n const marker = {\n [TRUNCATED_FLAG]: true,\n [TRUNCATED_CHARS]: originalLength,\n note: \"Tool output omitted because it was too large to preserve structurally.\"\n };\n\n if (stringifyForLength(marker).length <= maxChars) {\n return marker;\n }\n\n return {\n [TRUNCATED_FLAG]: true,\n [TRUNCATED_CHARS]: originalLength\n };\n}\n\nfunction compactArrayMarker(\n maxChars: number,\n originalLength: number\n): unknown[] {\n const structuredMarker = compactObjectMarker(maxChars, originalLength);\n if (stringifyForLength([structuredMarker]).length <= maxChars) {\n return [structuredMarker];\n }\n\n const marker = [\n `Array output omitted because it was too large to preserve structurally ${truncatedSuffix(originalLength)}`\n ];\n\n if (stringifyForLength(marker).length <= maxChars) {\n return marker;\n }\n\n return [truncatedSuffix(originalLength).slice(0, maxChars)];\n}\n\nfunction childMaxChars(maxChars: number, childCount: number): number {\n if (childCount <= 1) {\n return maxChars;\n }\n\n return Math.max(80, Math.floor(maxChars / Math.min(childCount, 10)));\n}\n\nfunction stringifyForLength(value: unknown): string {\n try {\n if (typeof value === \"string\") {\n return value;\n }\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n"],"mappings":";AAMA,MAAM,oBAAoB;AAC1B,MAAM,iBAAiB;AACvB,MAAM,kBAAkB;AAExB,SAAgB,mBACd,QACA,UACqB;CACrB,MAAM,WAAW,mBAAmB,OAAO;CAC3C,IAAI,SAAS,UAAU,UACrB,OAAO;EAAE;EAAQ,WAAW;EAAO,gBAAgB,SAAS;EAAQ;CAGtE,OAAO;EACL,QAAQ,cAAc,QAAQ,UAAU,SAAS,QAAQ,EAAE;EAC3D,WAAW;EACX,gBAAgB,SAAS;EAC1B;;AAGH,SAAgB,gBAAgB,gBAAgC;CAC9D,OAAO,kBAAkB,eAAe;;AAG1C,SAAS,cACP,OACA,UACA,gBACA,OACS;CACT,IAAI,OAAO,UAAU,UACnB,OAAO,eAAe,OAAO,UAAU,MAAM,OAAO;CAGtD,IAAI,UAAU,QAAQ,OAAO,UAAU,UACrC,OAAO;CAGT,IAAI,SAAS,mBACX,OAAO,0BAA0B,gBAAgB,eAAe,CAAC;CAGnE,IAAI,MAAM,QAAQ,MAAM,EACtB,OAAO,cAAc,OAAO,UAAU,gBAAgB,MAAM;CAG9D,OAAO,eACL,OACA,UACA,gBACA,MACD;;AAGH,SAAS,cACP,OACA,UACA,gBACA,OACW;CACX,MAAM,cAAc,cAAc,UAAU,MAAM,OAAO;CACzD,MAAM,SAAS,MAAM,KAAK,SACxB,cAAc,MAAM,aAAa,mBAAmB,KAAK,CAAC,QAAQ,QAAQ,EAAE,CAC7E;CAED,OAAO,OAAO,SAAS,KAAK,mBAAmB,OAAO,CAAC,SAAS,UAC9D,OAAO,KAAK;CAGd,IAAI,OAAO,SAAS,MAAM,QACxB,OAAO,KAAK,0BAA0B,gBAAgB,eAAe,GAAG;CAG1E,IAAI,mBAAmB,OAAO,CAAC,SAAS,UACtC,OAAO,mBAAmB,UAAU,eAAe;CAGrD,OAAO;;AAGT,SAAS,eACP,OACA,UACA,gBACA,OACyB;CACzB,MAAM,UAAU,OAAO,QAAQ,MAAM;CACrC,MAAM,cAAc,cAAc,UAAU,QAAQ,OAAO;CAC3D,MAAM,SAAkC,EAAE;CAE1C,KAAK,MAAM,CAAC,KAAK,eAAe,SAC9B,OAAO,OAAO,cACZ,YACA,aACA,mBAAmB,WAAW,CAAC,QAC/B,QAAQ,EACT;CAGH,MAAM,eAAe,mBAAmB,OAAO,CAAC;CAChD,IAAI,gBAAgB,UAClB,OAAO;CAGT,mBAAmB,QAAQ,SAAS;CAEpC,IADqB,mBAAmB,OAAO,CAAC,SAC7B,UAAU;EAC3B,OAAO,kBAAkB;EACzB,OAAO,mBAAmB;;CAG5B,IAAI,mBAAmB,OAAO,CAAC,SAAS,UACtC,OAAO,oBAAoB,UAAU,eAAe;CAGtD,OAAO;;AAGT,SAAS,mBACP,OACA,UACM;CACN,MAAM,gBAAgB,OAAO,QAAQ,MAAM,CACxC,QAAQ,UAAqC,OAAO,MAAM,OAAO,SAAS,CAC1E,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,EAAE,GAAG,OAAO;CAE5C,KAAK,MAAM,CAAC,KAAK,QAAQ,eAAe;EACtC,IAAI,mBAAmB,MAAM,CAAC,UAAU,UACtC;EAGF,MAAM,OAAO,eACX,KACA,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,EAAE,CAAC,EACrC,IAAI,OACL;;;AAIL,SAAS,eACP,OACA,UACA,gBACQ;CACR,IAAI,MAAM,UAAU,UAClB,OAAO;CAGT,MAAM,SAAS,gBAAgB,eAAe;CAC9C,IAAI,YAAY,OAAO,QACrB,OAAO,OAAO,MAAM,GAAG,SAAS;CAGlC,OAAO,GAAG,MAAM,MAAM,GAAG,WAAW,OAAO,OAAO,GAAG;;AAGvD,SAAS,oBACP,UACA,gBACyB;CACzB,MAAM,SAAS;GACZ,iBAAiB;GACjB,kBAAkB;EACnB,MAAM;EACP;CAED,IAAI,mBAAmB,OAAO,CAAC,UAAU,UACvC,OAAO;CAGT,OAAO;GACJ,iBAAiB;GACjB,kBAAkB;EACpB;;AAGH,SAAS,mBACP,UACA,gBACW;CACX,MAAM,mBAAmB,oBAAoB,UAAU,eAAe;CACtE,IAAI,mBAAmB,CAAC,iBAAiB,CAAC,CAAC,UAAU,UACnD,OAAO,CAAC,iBAAiB;CAG3B,MAAM,SAAS,CACb,0EAA0E,gBAAgB,eAAe,GAC1G;CAED,IAAI,mBAAmB,OAAO,CAAC,UAAU,UACvC,OAAO;CAGT,OAAO,CAAC,gBAAgB,eAAe,CAAC,MAAM,GAAG,SAAS,CAAC;;AAG7D,SAAS,cAAc,UAAkB,YAA4B;CACnE,IAAI,cAAc,GAChB,OAAO;CAGT,OAAO,KAAK,IAAI,IAAI,KAAK,MAAM,WAAW,KAAK,IAAI,YAAY,GAAG,CAAC,CAAC;;AAGtE,SAAS,mBAAmB,OAAwB;CAClD,IAAI;EACF,IAAI,OAAO,UAAU,UACnB,OAAO;EAET,OAAO,KAAK,UAAU,MAAM,IAAI,OAAO,MAAM;SACvC;EACN,OAAO,OAAO,MAAM"}
@@ -14,4 +14,4 @@ declare enum MessageType {
14
14
  }
15
15
  //#endregion
16
16
  export { MessageType as t };
17
- //# sourceMappingURL=types-DAHCZC_W.d.ts.map
17
+ //# sourceMappingURL=types-_JjKmv-l.d.ts.map
package/dist/types.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { t as MessageType } from "./types-DAHCZC_W.js";
1
+ import { t as MessageType } from "./types-_JjKmv-l.js";
2
2
  export { MessageType };
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["/**\n * Enum for message types to improve type safety and maintainability\n */\nexport enum MessageType {\n CF_AGENT_MCP_SERVERS = \"cf_agent_mcp_servers\",\n CF_MCP_AGENT_EVENT = \"cf_mcp_agent_event\",\n CF_AGENT_STATE = \"cf_agent_state\",\n CF_AGENT_STATE_ERROR = \"cf_agent_state_error\",\n CF_AGENT_IDENTITY = \"cf_agent_identity\",\n CF_AGENT_SESSION = \"cf_agent_session\",\n CF_AGENT_SESSION_ERROR = \"cf_agent_session_error\",\n RPC = \"rpc\"\n}\n"],"mappings":";;;;AAGA,IAAY,cAAL,yBAAA,aAAA;AACL,aAAA,0BAAA;AACA,aAAA,wBAAA;AACA,aAAA,oBAAA;AACA,aAAA,0BAAA;AACA,aAAA,uBAAA;AACA,aAAA,sBAAA;AACA,aAAA,4BAAA;AACA,aAAA,SAAA;;KACD"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["/**\n * Enum for message types to improve type safety and maintainability\n */\nexport enum MessageType {\n CF_AGENT_MCP_SERVERS = \"cf_agent_mcp_servers\",\n CF_MCP_AGENT_EVENT = \"cf_mcp_agent_event\",\n CF_AGENT_STATE = \"cf_agent_state\",\n CF_AGENT_STATE_ERROR = \"cf_agent_state_error\",\n CF_AGENT_IDENTITY = \"cf_agent_identity\",\n CF_AGENT_SESSION = \"cf_agent_session\",\n CF_AGENT_SESSION_ERROR = \"cf_agent_session_error\",\n RPC = \"rpc\"\n}\n"],"mappings":";;;;AAGA,IAAY,cAAL,yBAAA,aAAA;CACL,YAAA,0BAAA;CACA,YAAA,wBAAA;CACA,YAAA,oBAAA;CACA,YAAA,0BAAA;CACA,YAAA,uBAAA;CACA,YAAA,sBAAA;CACA,YAAA,4BAAA;CACA,YAAA,SAAA;;KACD"}
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["/**\n * Property keys that JavaScript runtimes and test frameworks probe\n * on arbitrary objects (serialization, thenable check, inspection,\n * matcher duck-typing). When an RPC-stub Proxy is accessed by\n * `JSON.stringify`, `console.log`, `await`, Vitest matchers, etc.,\n * it hits one of these — we must return `undefined` instead of a\n * call-wrapper to avoid firing a bogus RPC for a method the child\n * doesn't implement.\n *\n * @internal\n */\nexport const INTERNAL_JS_STUB_PROPS: ReadonlySet<string> = new Set([\n \"toJSON\",\n \"then\",\n \"catch\",\n \"finally\",\n \"valueOf\",\n \"toString\",\n \"constructor\",\n \"prototype\",\n \"$$typeof\",\n \"@@toStringTag\",\n \"asymmetricMatch\",\n \"nodeType\"\n]);\n\n/**\n * True when the property access is a JS-internal probe that must\n * NOT dispatch an RPC call. Catches all symbol keys plus the named\n * set above.\n *\n * @internal\n */\nexport function isInternalJsStubProp(prop: string | symbol): boolean {\n return typeof prop === \"symbol\" || INTERNAL_JS_STUB_PROPS.has(prop);\n}\n\n/**\n * Convert a camelCase string to a kebab-case string\n * @param str The string to convert\n * @returns The kebab-case string\n */\nexport function camelCaseToKebabCase(str: string): string {\n // If string is all uppercase, convert to lowercase\n if (str === str.toUpperCase() && str !== str.toLowerCase()) {\n return str.toLowerCase().replace(/_/g, \"-\");\n }\n\n // Otherwise handle camelCase to kebab-case\n let kebabified = str.replace(\n /[A-Z]/g,\n (letter) => `-${letter.toLowerCase()}`\n );\n kebabified = kebabified.startsWith(\"-\") ? kebabified.slice(1) : kebabified;\n // Convert any remaining underscores to hyphens and remove trailing -'s\n return kebabified.replace(/_/g, \"-\").replace(/-$/, \"\");\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,yBAA8C,IAAI,IAAI;CACjE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;AASF,SAAgB,qBAAqB,MAAgC;AACnE,QAAO,OAAO,SAAS,YAAY,uBAAuB,IAAI,KAAK;;;;;;;AAQrE,SAAgB,qBAAqB,KAAqB;AAExD,KAAI,QAAQ,IAAI,aAAa,IAAI,QAAQ,IAAI,aAAa,CACxD,QAAO,IAAI,aAAa,CAAC,QAAQ,MAAM,IAAI;CAI7C,IAAI,aAAa,IAAI,QACnB,WACC,WAAW,IAAI,OAAO,aAAa,GACrC;AACD,cAAa,WAAW,WAAW,IAAI,GAAG,WAAW,MAAM,EAAE,GAAG;AAEhE,QAAO,WAAW,QAAQ,MAAM,IAAI,CAAC,QAAQ,MAAM,GAAG"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["/**\n * Property keys that JavaScript runtimes and test frameworks probe\n * on arbitrary objects (serialization, thenable check, inspection,\n * matcher duck-typing). When an RPC-stub Proxy is accessed by\n * `JSON.stringify`, `console.log`, `await`, Vitest matchers, etc.,\n * it hits one of these — we must return `undefined` instead of a\n * call-wrapper to avoid firing a bogus RPC for a method the child\n * doesn't implement.\n *\n * @internal\n */\nexport const INTERNAL_JS_STUB_PROPS: ReadonlySet<string> = new Set([\n \"toJSON\",\n \"then\",\n \"catch\",\n \"finally\",\n \"valueOf\",\n \"toString\",\n \"constructor\",\n \"prototype\",\n \"$$typeof\",\n \"@@toStringTag\",\n \"asymmetricMatch\",\n \"nodeType\"\n]);\n\n/**\n * True when the property access is a JS-internal probe that must\n * NOT dispatch an RPC call. Catches all symbol keys plus the named\n * set above.\n *\n * @internal\n */\nexport function isInternalJsStubProp(prop: string | symbol): boolean {\n return typeof prop === \"symbol\" || INTERNAL_JS_STUB_PROPS.has(prop);\n}\n\n/**\n * Convert a camelCase string to a kebab-case string\n * @param str The string to convert\n * @returns The kebab-case string\n */\nexport function camelCaseToKebabCase(str: string): string {\n // If string is all uppercase, convert to lowercase\n if (str === str.toUpperCase() && str !== str.toLowerCase()) {\n return str.toLowerCase().replace(/_/g, \"-\");\n }\n\n // Otherwise handle camelCase to kebab-case\n let kebabified = str.replace(\n /[A-Z]/g,\n (letter) => `-${letter.toLowerCase()}`\n );\n kebabified = kebabified.startsWith(\"-\") ? kebabified.slice(1) : kebabified;\n // Convert any remaining underscores to hyphens and remove trailing -'s\n return kebabified.replace(/_/g, \"-\").replace(/-$/, \"\");\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,yBAA8C,IAAI,IAAI;CACjE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;AASF,SAAgB,qBAAqB,MAAgC;CACnE,OAAO,OAAO,SAAS,YAAY,uBAAuB,IAAI,KAAK;;;;;;;AAQrE,SAAgB,qBAAqB,KAAqB;CAExD,IAAI,QAAQ,IAAI,aAAa,IAAI,QAAQ,IAAI,aAAa,EACxD,OAAO,IAAI,aAAa,CAAC,QAAQ,MAAM,IAAI;CAI7C,IAAI,aAAa,IAAI,QACnB,WACC,WAAW,IAAI,OAAO,aAAa,GACrC;CACD,aAAa,WAAW,WAAW,IAAI,GAAG,WAAW,MAAM,EAAE,GAAG;CAEhE,OAAO,WAAW,QAAQ,MAAM,IAAI,CAAC,QAAQ,MAAM,GAAG"}
package/dist/vite.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.js","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import babel from \"@rolldown/plugin-babel\";\nimport type { Plugin } from \"vite\";\n\n/**\n * Vite plugin for Agents SDK projects.\n *\n * Currently handles TC39 decorator transforms (Oxc doesn't support them yet,\n * oxc#9170) so `@callable()` works at runtime. Will grow to cover other\n * Agents-specific build concerns as needed.\n */\nexport default function agents(): Plugin {\n return babel({\n presets: [\n {\n preset: () => ({\n plugins: [\n [\"@babel/plugin-proposal-decorators\", { version: \"2023-11\" }]\n ]\n }),\n rolldown: { filter: { code: \"@\" } }\n }\n ]\n }) as unknown as Plugin;\n}\n"],"mappings":";;;;;;;;;AAUA,SAAwB,SAAiB;AACvC,QAAO,MAAM,EACX,SAAS,CACP;EACE,eAAe,EACb,SAAS,CACP,CAAC,qCAAqC,EAAE,SAAS,WAAW,CAAC,CAC9D,EACF;EACD,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,EAAE;EACpC,CACF,EACF,CAAC"}
1
+ {"version":3,"file":"vite.js","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import babel from \"@rolldown/plugin-babel\";\nimport type { Plugin } from \"vite\";\n\n/**\n * Vite plugin for Agents SDK projects.\n *\n * Currently handles TC39 decorator transforms (Oxc doesn't support them yet,\n * oxc#9170) so `@callable()` works at runtime. Will grow to cover other\n * Agents-specific build concerns as needed.\n */\nexport default function agents(): Plugin {\n return babel({\n presets: [\n {\n preset: () => ({\n plugins: [\n [\"@babel/plugin-proposal-decorators\", { version: \"2023-11\" }]\n ]\n }),\n rolldown: { filter: { code: \"@\" } }\n }\n ]\n }) as unknown as Plugin;\n}\n"],"mappings":";;;;;;;;;AAUA,SAAwB,SAAiB;CACvC,OAAO,MAAM,EACX,SAAS,CACP;EACE,eAAe,EACb,SAAS,CACP,CAAC,qCAAqC,EAAE,SAAS,WAAW,CAAC,CAC9D,EACF;EACD,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,EAAE;EACpC,CACF,EACF,CAAC"}
@@ -257,4 +257,4 @@ export {
257
257
  WorkflowStatus as x,
258
258
  WorkflowQueryCriteria as y
259
259
  };
260
- //# sourceMappingURL=workflow-types-DHs0L0KP.d.ts.map
260
+ //# sourceMappingURL=workflow-types-Dkzg4hAx.d.ts.map
@@ -21,7 +21,7 @@ import {
21
21
  v as WorkflowProgressCallback,
22
22
  x as WorkflowStatus,
23
23
  y as WorkflowQueryCriteria
24
- } from "./workflow-types-DHs0L0KP.js";
24
+ } from "./workflow-types-Dkzg4hAx.js";
25
25
  export {
26
26
  AgentWorkflowEvent,
27
27
  AgentWorkflowInternalParams,