agents 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/{agent-tool-types-CzGGB-20.d.ts → agent-routing-CnkaHb-v.d.ts} +2921 -3057
- package/dist/agent-routing.d.ts +14 -0
- package/dist/agent-routing.js +187 -0
- package/dist/agent-routing.js.map +1 -0
- package/dist/agent-tool-types.d.ts +26 -26
- package/dist/{agent-tools-zR2d5uij.d.ts → agent-tools-C0XJqWzB.d.ts} +7 -7
- package/dist/agent-tools.d.ts +21 -21
- package/dist/agent-tools.js +2 -1
- package/dist/agent-tools.js.map +1 -1
- package/dist/browser/ai.js +2 -1
- package/dist/browser/ai.js.map +1 -1
- package/dist/capability-BjSKYpzg.js +42 -0
- package/dist/capability-BjSKYpzg.js.map +1 -0
- package/dist/capability-runner-CvHGZqUu.d.ts +150 -0
- package/dist/chat/index.d.ts +22 -15
- package/dist/chat/index.js +4 -4
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +14 -1
- package/dist/chat/react.js +82 -52
- package/dist/chat/react.js.map +1 -1
- package/dist/chat/transport.js +1 -1
- package/dist/chat-sdk/index.d.ts +4 -4
- package/dist/chat-sdk/index.js +1 -1
- package/dist/{client-zqKcsyFa.js → client-jagG8a9_.js} +129 -37
- package/dist/client-jagG8a9_.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/{cloudflare-BduZwmYK.js → cloudflare-Dzvc7V2N.js} +10 -3
- package/dist/{cloudflare-BduZwmYK.js.map → cloudflare-Dzvc7V2N.js.map} +1 -1
- package/dist/current-agent-CuMErtly.d.ts +283 -0
- package/dist/current-agent-DhoDkSnH.js +51 -0
- package/dist/current-agent-DhoDkSnH.js.map +1 -0
- package/dist/diagnostics-CaBjfz4J.js +41 -0
- package/dist/diagnostics-CaBjfz4J.js.map +1 -0
- package/dist/{do-oauth-client-provider-VTZj2VtM.d.ts → do-oauth-client-provider-Tmf1vgKz.d.ts} +2 -2
- package/dist/durable-object-lifecycle-D6nNQJJd.js +862 -0
- package/dist/durable-object-lifecycle-D6nNQJJd.js.map +1 -0
- package/dist/{email-CL27preh.d.ts → email-7TatiTnl.d.ts} +38 -9
- package/dist/email-send.d.ts +15 -0
- package/dist/email-send.js +32 -0
- package/dist/email-send.js.map +1 -0
- package/dist/email.d.ts +14 -10
- package/dist/email.js.map +1 -1
- package/dist/experimental/memory/session/index.d.ts +3 -2
- package/dist/experimental/memory/session/index.js +15 -10
- package/dist/experimental/memory/session/index.js.map +1 -1
- package/dist/{handler-stateless-C_bo-Ytq.d.ts → handler-stateless-DxYpJ_XF.d.ts} +3 -3
- package/dist/{handler-stateless-CIkKPETH.js → handler-stateless-VvrWSAVA.js} +5 -5
- package/dist/handler-stateless-VvrWSAVA.js.map +1 -0
- package/dist/{index-BRnybD6X.d.ts → index-DcSAZKsB.d.ts} +19 -31
- package/dist/index.d.ts +98 -95
- package/dist/index.js +10 -7234
- package/dist/internal_context-BlxFEWfn.d.ts +19 -0
- package/dist/internal_context.d.ts +10 -4
- package/dist/internal_context.js +1 -10
- package/dist/{client-invoker-BNSZxAkv.d.ts → invoker-CG0_p_Wq.d.ts} +2 -2
- package/dist/{client-invoker-VNZ7X0nn.js → invoker-CHMnoxIA.js} +2 -2
- package/dist/invoker-CHMnoxIA.js.map +1 -0
- package/dist/lifecycle/index.d.ts +48 -0
- package/dist/lifecycle/index.js +4 -0
- package/dist/mcp/{do-oauth-client-provider.d.ts → client/do-oauth-client-provider.d.ts} +1 -1
- package/dist/mcp/{do-oauth-client-provider.js → client/do-oauth-client-provider.js} +1 -1
- package/dist/mcp/client/do-oauth-client-provider.js.map +1 -0
- package/dist/mcp/client/index.d.ts +42 -0
- package/dist/mcp/{client.js → client/index.js} +1 -1
- package/dist/mcp/{x402.d.ts → client/x402.d.ts} +2 -2
- package/dist/mcp/{x402.js → client/x402.js} +2 -2
- package/dist/mcp/client/x402.js.map +1 -0
- package/dist/mcp/index.d.ts +36 -36
- package/dist/mcp/index.js +14 -16
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/{server.d.ts → server/index.d.ts} +1 -1
- package/dist/mcp/{server.js → server/index.js} +1 -1
- package/dist/observability/ai/index.js +50 -35
- package/dist/observability/ai/index.js.map +1 -1
- package/dist/observability/index.d.ts +4 -4
- package/dist/observability/index.js +3 -50
- package/dist/observability/index.js.map +1 -1
- package/dist/{protocol-Dqc2MQxo.js → protocol-B0nh6KNf.js} +19 -21
- package/dist/protocol-B0nh6KNf.js.map +1 -0
- package/dist/react.d.ts +4 -4
- package/dist/react.js +1 -1
- package/dist/schedule.d.ts +25 -94
- package/dist/schedule.js +1 -98
- package/dist/schedule.js.map +1 -1
- package/dist/scheduler-CR9RHGos.js +857 -0
- package/dist/scheduler-CR9RHGos.js.map +1 -0
- package/dist/scheduler-DQoTGoAW.d.ts +224 -0
- package/dist/schedules/index.d.ts +22 -0
- package/dist/schedules/index.js +2 -0
- package/dist/schedules/parser.d.ts +79 -0
- package/dist/schedules/parser.js +103 -0
- package/dist/schedules/parser.js.map +1 -0
- package/dist/serializable.d.ts +1 -1
- package/dist/sql-error-CPY-GXyI.d.ts +12 -0
- package/dist/sql-error.d.ts +2 -0
- package/dist/sql-error.js +16 -0
- package/dist/sql-error.js.map +1 -0
- package/dist/src-5W6JNKVb.js +6613 -0
- package/dist/src-5W6JNKVb.js.map +1 -0
- package/dist/sub-routing.d.ts +12 -12
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflows.d.ts +22 -22
- package/dist/workflows.js +2 -1
- package/dist/workflows.js.map +1 -1
- package/dist/{ws-chat-transport-CIoOBbO7.js → ws-chat-transport-rWwta645.js} +152 -15
- package/dist/ws-chat-transport-rWwta645.js.map +1 -0
- package/docs/agent-class.md +28 -86
- package/docs/chat-agents.md +13 -12
- package/docs/durable-execution.md +1 -1
- package/docs/http-websockets.md +1 -11
- package/docs/human-in-the-loop.md +1 -1
- package/docs/index.md +1 -0
- package/docs/lifecycle.md +323 -0
- package/docs/long-running-agents.md +2 -4
- package/docs/mcp-client.md +55 -0
- package/docs/observability.md +11 -11
- package/docs/resumable-streaming.md +1 -1
- package/docs/scheduling.md +175 -15
- package/docs/server-driven-messages.md +1 -1
- package/docs/sub-agents.md +1 -1
- package/package.json +30 -21
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +0 -26
- package/dist/cli/index.js.map +0 -1
- package/dist/client-invoker-VNZ7X0nn.js.map +0 -1
- package/dist/client-zqKcsyFa.js.map +0 -1
- package/dist/handler-stateless-CIkKPETH.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal_context-Dg4Cgjcu.d.ts +0 -37
- package/dist/internal_context.js.map +0 -1
- package/dist/mcp/client.d.ts +0 -42
- package/dist/mcp/do-oauth-client-provider.js.map +0 -1
- package/dist/mcp/x402.js.map +0 -1
- package/dist/protocol-Dqc2MQxo.js.map +0 -1
- package/dist/ws-chat-transport-CIoOBbO7.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
a as
|
|
3
|
-
i as
|
|
2
|
+
a as subscribe,
|
|
3
|
+
i as genericObservability,
|
|
4
4
|
n as Observability,
|
|
5
|
-
o as
|
|
5
|
+
o as channels,
|
|
6
6
|
r as ObservabilityEvent,
|
|
7
7
|
t as ChannelEventMap
|
|
8
|
-
} from "../index-
|
|
8
|
+
} from "../index-DcSAZKsB.js";
|
|
9
9
|
export {
|
|
10
10
|
ChannelEventMap,
|
|
11
11
|
Observability,
|
|
@@ -1,67 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as publishDiagnosticsEvent, t as channels } from "../diagnostics-CaBjfz4J.js";
|
|
2
|
+
import { subscribe as subscribe$1, unsubscribe } from "node:diagnostics_channel";
|
|
2
3
|
//#region src/observability/index.ts
|
|
3
4
|
/**
|
|
4
|
-
* Diagnostics channels for agent observability.
|
|
5
|
-
*
|
|
6
|
-
* Events are published to named channels using the Node.js diagnostics_channel API.
|
|
7
|
-
* By default, publishing to a channel with no subscribers is a no-op (zero overhead).
|
|
8
|
-
*
|
|
9
|
-
* To observe events, subscribe to the channels you care about:
|
|
10
|
-
* ```ts
|
|
11
|
-
* import { subscribe } from "node:diagnostics_channel";
|
|
12
|
-
* subscribe("agents:rpc", (event) => console.log(event));
|
|
13
|
-
* ```
|
|
14
|
-
*
|
|
15
|
-
* In production, all published messages are automatically forwarded to
|
|
16
|
-
* Tail Workers via `event.diagnosticsChannelEvents` — no subscription needed.
|
|
17
|
-
*/
|
|
18
|
-
const channels = {
|
|
19
|
-
state: channel("agents:state"),
|
|
20
|
-
rpc: channel("agents:rpc"),
|
|
21
|
-
message: channel("agents:message"),
|
|
22
|
-
chat: channel("agents:chat"),
|
|
23
|
-
transcript: channel("agents:transcript"),
|
|
24
|
-
fiber: channel("agents:fiber"),
|
|
25
|
-
agentTool: channel("agents:agent_tool"),
|
|
26
|
-
schedule: channel("agents:schedule"),
|
|
27
|
-
lifecycle: channel("agents:lifecycle"),
|
|
28
|
-
workflow: channel("agents:workflow"),
|
|
29
|
-
mcp: channel("agents:mcp"),
|
|
30
|
-
email: channel("agents:email"),
|
|
31
|
-
channel: channel("agents:channel")
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
5
|
* Channel keys whose diagnostics channel name differs from `agents:${key}`.
|
|
35
6
|
* Keep this in sync with {@link channels} for any camelCase key that maps to a
|
|
36
7
|
* snake_case diagnostics channel.
|
|
37
8
|
*/
|
|
38
9
|
const CHANNEL_DIAGNOSTIC_NAME_OVERRIDES = { agentTool: "agents:agent_tool" };
|
|
39
10
|
/**
|
|
40
|
-
* Map event type prefixes to their diagnostics channel.
|
|
41
|
-
*/
|
|
42
|
-
function getChannel(type) {
|
|
43
|
-
if (type.startsWith("mcp:")) return channels.mcp;
|
|
44
|
-
if (type.startsWith("workflow:")) return channels.workflow;
|
|
45
|
-
if (type.startsWith("fiber:")) return channels.fiber;
|
|
46
|
-
if (type.startsWith("transcript:") || type.startsWith("chat:transcript:")) return channels.transcript;
|
|
47
|
-
if (type.startsWith("chat:")) return channels.chat;
|
|
48
|
-
if (type.startsWith("agent_tool:")) return channels.agentTool;
|
|
49
|
-
if (type.startsWith("schedule:") || type.startsWith("queue:")) return channels.schedule;
|
|
50
|
-
if (type.startsWith("message:") || type.startsWith("tool:") || type.startsWith("submission:") || type.startsWith("action:")) return channels.message;
|
|
51
|
-
if (type === "rpc" || type.startsWith("rpc:")) return channels.rpc;
|
|
52
|
-
if (type.startsWith("state:")) return channels.state;
|
|
53
|
-
if (type.startsWith("email:")) return channels.email;
|
|
54
|
-
if (type.startsWith("channel:") || type.startsWith("notice:")) return channels.channel;
|
|
55
|
-
return channels.lifecycle;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
11
|
* The default observability implementation.
|
|
59
12
|
*
|
|
60
13
|
* Publishes events to diagnostics_channel. Events are silent unless
|
|
61
14
|
* a subscriber is registered or a Tail Worker is attached.
|
|
62
15
|
*/
|
|
63
16
|
const genericObservability = { emit(event) {
|
|
64
|
-
|
|
17
|
+
publishDiagnosticsEvent(event);
|
|
65
18
|
} };
|
|
66
19
|
/**
|
|
67
20
|
* Subscribe to a typed observability channel.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["dcUnsubscribe"],"sources":["../../src/observability/index.ts"],"sourcesContent":["import {\n
|
|
1
|
+
{"version":3,"file":"index.js","names":["dcUnsubscribe"],"sources":["../../src/observability/index.ts"],"sourcesContent":["import {\n subscribe as dcSubscribe,\n unsubscribe as dcUnsubscribe\n} from \"node:diagnostics_channel\";\nimport type { AgentObservabilityEvent } from \"./agent\";\nimport type { MCPObservabilityEvent } from \"./mcp\";\nimport { publishDiagnosticsEvent } from \"./diagnostics\";\nexport { channels } from \"./diagnostics\";\n\n/**\n * Union of all observability event types from different domains\n */\nexport type ObservabilityEvent =\n | AgentObservabilityEvent\n | MCPObservabilityEvent;\n\nexport interface Observability {\n /**\n * Emit an event for the Agent's observability implementation to handle.\n * @param event - The event to emit\n */\n emit(event: ObservabilityEvent): void;\n}\n\n/**\n * Channel keys whose diagnostics channel name differs from `agents:${key}`.\n * Keep this in sync with {@link channels} for any camelCase key that maps to a\n * snake_case diagnostics channel.\n */\nconst CHANNEL_DIAGNOSTIC_NAME_OVERRIDES: Partial<Record<string, string>> = {\n agentTool: \"agents:agent_tool\"\n};\n\n/**\n * The default observability implementation.\n *\n * Publishes events to diagnostics_channel. Events are silent unless\n * a subscriber is registered or a Tail Worker is attached.\n */\nexport const genericObservability: Observability = {\n emit(event) {\n publishDiagnosticsEvent(event);\n }\n};\n\n/**\n * Maps each channel key to the observability events it carries.\n */\nexport type ChannelEventMap = {\n state: Extract<ObservabilityEvent, { type: `state:${string}` }>;\n rpc: Extract<ObservabilityEvent, { type: \"rpc\" | `rpc:${string}` }>;\n message: Extract<\n ObservabilityEvent,\n {\n type:\n | `message:${string}`\n | `tool:${string}`\n | `submission:${string}`\n | `action:${string}`;\n }\n >;\n chat: Exclude<\n Extract<ObservabilityEvent, { type: `chat:${string}` }>,\n { type: `chat:transcript:${string}` }\n >;\n transcript: Extract<\n ObservabilityEvent,\n { type: `transcript:${string}` | `chat:transcript:${string}` }\n >;\n fiber: Extract<ObservabilityEvent, { type: `fiber:${string}` }>;\n agentTool: Extract<ObservabilityEvent, { type: `agent_tool:${string}` }>;\n schedule: Extract<\n ObservabilityEvent,\n { type: `schedule:${string}` | `queue:${string}` }\n >;\n lifecycle: Extract<\n ObservabilityEvent,\n { type: \"connect\" | \"disconnect\" | \"destroy\" }\n >;\n workflow: Extract<ObservabilityEvent, { type: `workflow:${string}` }>;\n mcp: Extract<ObservabilityEvent, { type: `mcp:${string}` }>;\n email: Extract<ObservabilityEvent, { type: `email:${string}` }>;\n channel: Extract<\n ObservabilityEvent,\n { type: `channel:${string}` | `notice:${string}` }\n >;\n};\n\n/**\n * Subscribe to a typed observability channel.\n *\n * ```ts\n * import { subscribe } from \"agents/observability\";\n *\n * const unsub = subscribe(\"rpc\", (event) => {\n * console.log(event.payload.method); // fully typed\n * });\n * ```\n *\n * @returns A function that unsubscribes the callback.\n */\nexport function subscribe<K extends keyof ChannelEventMap>(\n channelKey: K,\n callback: (event: ChannelEventMap[K]) => void\n): () => void {\n const name =\n CHANNEL_DIAGNOSTIC_NAME_OVERRIDES[channelKey] ?? `agents:${channelKey}`;\n const handler = (message: unknown, _name: string | symbol) =>\n callback(message as ChannelEventMap[K]);\n dcSubscribe(name, handler);\n return () => dcUnsubscribe(name, handler);\n}\n"],"mappings":";;;;;;;;AA6BA,MAAM,oCAAqE,EACzE,WAAW,oBACb;;;;;;;AAQA,MAAa,uBAAsC,EACjD,KAAK,OAAO;CACV,wBAAwB,KAAK;AAC/B,EACF;;;;;;;;;;;;;;AA0DA,SAAgB,UACd,YACA,UACY;CACZ,MAAM,OACJ,kCAAkC,eAAe,UAAU;CAC7D,MAAM,WAAW,SAAkB,UACjC,SAAS,OAA6B;CACxC,YAAY,MAAM,OAAO;CACzB,aAAaA,YAAc,MAAM,OAAO;AAC1C"}
|
|
@@ -9,8 +9,10 @@ var StreamAccumulator = class {
|
|
|
9
9
|
this._isContinuation = options.continuation ?? false;
|
|
10
10
|
this.parts = options.existingParts ? [...options.existingParts] : [];
|
|
11
11
|
this.metadata = options.existingMetadata ? { ...options.existingMetadata } : void 0;
|
|
12
|
+
this._pendingContinuationChunks = this._isContinuation && options.existingParts === void 0 && options.existingMetadata === void 0 ? [] : null;
|
|
12
13
|
}
|
|
13
14
|
applyChunk(chunk) {
|
|
15
|
+
this._pendingContinuationChunks?.push(chunk);
|
|
14
16
|
const handled = applyChunkToParts(this.parts, chunk);
|
|
15
17
|
if (chunk.type === "tool-approval-request" && chunk.toolCallId) return {
|
|
16
18
|
handled,
|
|
@@ -101,7 +103,8 @@ var StreamAccumulator = class {
|
|
|
101
103
|
/**
|
|
102
104
|
* Merge this accumulator's message into an existing message array.
|
|
103
105
|
* Handles continuation (walk backward for last assistant), replacement
|
|
104
|
-
* (update existing by messageId), or append (new message).
|
|
106
|
+
* (update existing by messageId), or append (new message). An unseeded
|
|
107
|
+
* continuation adopts current parts here before applying its queued chunks.
|
|
105
108
|
*/
|
|
106
109
|
mergeInto(messages) {
|
|
107
110
|
let existingIdx = messages.findIndex((m) => m.id === this.messageId);
|
|
@@ -111,6 +114,15 @@ var StreamAccumulator = class {
|
|
|
111
114
|
break;
|
|
112
115
|
}
|
|
113
116
|
}
|
|
117
|
+
if (this._pendingContinuationChunks !== null) {
|
|
118
|
+
const pendingChunks = this._pendingContinuationChunks;
|
|
119
|
+
this._pendingContinuationChunks = null;
|
|
120
|
+
this.parts.splice(0, this.parts.length, ...existingIdx >= 0 ? messages[existingIdx].parts : []);
|
|
121
|
+
const currentMetadata = existingIdx >= 0 ? asMetadata(messages[existingIdx].metadata) : void 0;
|
|
122
|
+
this.metadata = currentMetadata ? { ...currentMetadata } : void 0;
|
|
123
|
+
if (existingIdx >= 0) this.messageId = messages[existingIdx].id;
|
|
124
|
+
for (const chunk of pendingChunks) this.applyChunk(chunk);
|
|
125
|
+
}
|
|
114
126
|
const partialMessage = {
|
|
115
127
|
id: existingIdx >= 0 ? messages[existingIdx].id : this.messageId,
|
|
116
128
|
role: "assistant",
|
|
@@ -147,25 +159,11 @@ function transition(state, event) {
|
|
|
147
159
|
case "response": {
|
|
148
160
|
let accumulator;
|
|
149
161
|
const isReplayedStart = event.replay === true && event.chunkData?.type === "start";
|
|
150
|
-
if (state.status === "idle" || state.streamId !== event.streamId || isReplayedStart) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
for (let i = event.currentMessages.length - 1; i >= 0; i--) if (event.currentMessages[i].role === "assistant") {
|
|
156
|
-
messageId = event.currentMessages[i].id;
|
|
157
|
-
existingParts = [...event.currentMessages[i].parts];
|
|
158
|
-
if (event.currentMessages[i].metadata != null) existingMetadata = { ...event.currentMessages[i].metadata };
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
accumulator = new StreamAccumulator({
|
|
163
|
-
messageId,
|
|
164
|
-
continuation: event.continuation,
|
|
165
|
-
existingParts,
|
|
166
|
-
existingMetadata
|
|
167
|
-
});
|
|
168
|
-
} else accumulator = state.accumulator;
|
|
162
|
+
if (state.status === "idle" || state.streamId !== event.streamId || isReplayedStart) accumulator = new StreamAccumulator({
|
|
163
|
+
messageId: event.messageId,
|
|
164
|
+
continuation: event.continuation
|
|
165
|
+
});
|
|
166
|
+
else accumulator = state.accumulator;
|
|
169
167
|
if (event.chunkData) accumulator.applyChunk(event.chunkData);
|
|
170
168
|
let messagesUpdate;
|
|
171
169
|
if (event.done) {
|
|
@@ -224,4 +222,4 @@ const CHAT_MESSAGE_TYPES = {
|
|
|
224
222
|
//#endregion
|
|
225
223
|
export { StreamAccumulator as i, STREAM_RESUME_NONE_REASONS as n, transition as r, CHAT_MESSAGE_TYPES as t };
|
|
226
224
|
|
|
227
|
-
//# sourceMappingURL=protocol-
|
|
225
|
+
//# sourceMappingURL=protocol-B0nh6KNf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol-B0nh6KNf.js","names":[],"sources":["../src/chat/stream-accumulator.ts","../src/chat/broadcast-state.ts","../src/chat/protocol.ts"],"sourcesContent":["/**\n * StreamAccumulator — unified chunk-to-message builder.\n *\n * Used by @cloudflare/ai-chat (server + client) and @cloudflare/think\n * to incrementally build a UIMessage from stream chunks. Wraps\n * applyChunkToParts and handles the metadata chunk types (start, finish,\n * message-metadata, error) that applyChunkToParts does not cover.\n *\n * The accumulator signals domain-specific concerns (early persistence,\n * cross-message tool updates) via ChunkAction returns — callers handle\n * these according to their context.\n */\n\nimport type { UIMessage } from \"ai\";\nimport { applyChunkToParts, type StreamChunkData } from \"./message-builder\";\n\nfunction asMetadata(value: unknown): Record<string, unknown> | undefined {\n if (value != null && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return undefined;\n}\n\nexport interface StreamAccumulatorOptions {\n messageId: string;\n /** Whether chunks continue the current assistant message when merged. */\n continuation?: boolean;\n /** Eager seed; omitted continuations seed from the messages passed to `mergeInto`. */\n existingParts?: UIMessage[\"parts\"];\n existingMetadata?: Record<string, unknown>;\n}\n\nexport type ChunkAction =\n | {\n type: \"start\";\n messageId?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n type: \"finish\";\n finishReason?: string;\n metadata?: Record<string, unknown>;\n }\n | { type: \"message-metadata\"; metadata: Record<string, unknown> }\n | { type: \"tool-approval-request\"; toolCallId: string }\n | {\n type: \"cross-message-tool-update\";\n updateType: \"output-available\" | \"output-error\";\n toolCallId: string;\n output?: unknown;\n errorText?: string;\n preliminary?: boolean;\n }\n | { type: \"error\"; error: string };\n\nexport interface ChunkResult {\n handled: boolean;\n action?: ChunkAction;\n}\n\nexport class StreamAccumulator {\n messageId: string;\n readonly parts: UIMessage[\"parts\"];\n metadata?: Record<string, unknown>;\n private _isContinuation: boolean;\n // Continuation chunks wait here until mergeInto can seed from current state.\n private _pendingContinuationChunks: StreamChunkData[] | null;\n\n constructor(options: StreamAccumulatorOptions) {\n this.messageId = options.messageId;\n this._isContinuation = options.continuation ?? false;\n this.parts = options.existingParts ? [...options.existingParts] : [];\n this.metadata = options.existingMetadata\n ? { ...options.existingMetadata }\n : undefined;\n this._pendingContinuationChunks =\n this._isContinuation &&\n options.existingParts === undefined &&\n options.existingMetadata === undefined\n ? []\n : null;\n }\n\n applyChunk(chunk: StreamChunkData): ChunkResult {\n this._pendingContinuationChunks?.push(chunk);\n const handled = applyChunkToParts(this.parts, chunk);\n\n // Detect tool-approval-request for early persistence signaling\n if (chunk.type === \"tool-approval-request\" && chunk.toolCallId) {\n return {\n handled,\n action: { type: \"tool-approval-request\", toolCallId: chunk.toolCallId }\n };\n }\n\n // Detect cross-message tool output/error: applyChunkToParts returns true\n // for recognized types but silently does nothing when the toolCallId\n // doesn't exist in the current parts array.\n if (\n (chunk.type === \"tool-output-available\" ||\n chunk.type === \"tool-output-error\") &&\n chunk.toolCallId\n ) {\n const foundInParts = this.parts.some(\n (p) => \"toolCallId\" in p && p.toolCallId === chunk.toolCallId\n );\n if (!foundInParts) {\n return {\n handled,\n action: {\n type: \"cross-message-tool-update\",\n updateType:\n chunk.type === \"tool-output-available\"\n ? \"output-available\"\n : \"output-error\",\n toolCallId: chunk.toolCallId,\n output: chunk.output,\n errorText: chunk.errorText,\n preliminary: chunk.preliminary\n }\n };\n }\n }\n\n if (!handled) {\n switch (chunk.type) {\n case \"start\": {\n if (chunk.messageId != null && !this._isContinuation) {\n this.messageId = chunk.messageId;\n }\n const startMeta = asMetadata(chunk.messageMetadata);\n if (startMeta) {\n this.metadata = this.metadata\n ? { ...this.metadata, ...startMeta }\n : { ...startMeta };\n }\n return {\n handled: true,\n action: {\n type: \"start\",\n messageId: chunk.messageId,\n metadata: startMeta\n }\n };\n }\n case \"finish\": {\n const finishMeta = asMetadata(chunk.messageMetadata);\n if (finishMeta) {\n this.metadata = this.metadata\n ? { ...this.metadata, ...finishMeta }\n : { ...finishMeta };\n }\n const finishReason =\n \"finishReason\" in chunk\n ? (chunk.finishReason as string)\n : undefined;\n return {\n handled: true,\n action: {\n type: \"finish\",\n finishReason,\n metadata: finishMeta\n }\n };\n }\n case \"message-metadata\": {\n const msgMeta = asMetadata(chunk.messageMetadata);\n if (msgMeta) {\n this.metadata = this.metadata\n ? { ...this.metadata, ...msgMeta }\n : { ...msgMeta };\n }\n return {\n handled: true,\n action: {\n type: \"message-metadata\",\n metadata: msgMeta ?? {}\n }\n };\n }\n case \"finish-step\": {\n return { handled: true };\n }\n case \"error\": {\n return {\n handled: true,\n action: {\n type: \"error\",\n error: chunk.errorText ?? JSON.stringify(chunk)\n }\n };\n }\n }\n }\n\n return { handled };\n }\n\n /** Snapshot the current state as a UIMessage. */\n toMessage(): UIMessage {\n return {\n id: this.messageId,\n role: \"assistant\",\n parts: [...this.parts],\n ...(this.metadata != null && { metadata: this.metadata })\n } as UIMessage;\n }\n\n /**\n * Merge this accumulator's message into an existing message array.\n * Handles continuation (walk backward for last assistant), replacement\n * (update existing by messageId), or append (new message). An unseeded\n * continuation adopts current parts here before applying its queued chunks.\n */\n mergeInto(messages: UIMessage[]): UIMessage[] {\n let existingIdx = messages.findIndex((m) => m.id === this.messageId);\n\n if (existingIdx < 0 && this._isContinuation) {\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === \"assistant\") {\n existingIdx = i;\n break;\n }\n }\n }\n\n if (this._pendingContinuationChunks !== null) {\n const pendingChunks = this._pendingContinuationChunks;\n this._pendingContinuationChunks = null;\n this.parts.splice(\n 0,\n this.parts.length,\n ...(existingIdx >= 0 ? messages[existingIdx].parts : [])\n );\n const currentMetadata =\n existingIdx >= 0\n ? asMetadata(messages[existingIdx].metadata)\n : undefined;\n this.metadata = currentMetadata ? { ...currentMetadata } : undefined;\n if (existingIdx >= 0) {\n this.messageId = messages[existingIdx].id;\n }\n for (const chunk of pendingChunks) {\n this.applyChunk(chunk);\n }\n }\n\n const messageId =\n existingIdx >= 0 ? messages[existingIdx].id : this.messageId;\n\n const partialMessage: UIMessage = {\n id: messageId,\n role: \"assistant\",\n parts: [...this.parts],\n ...(this.metadata != null && { metadata: this.metadata })\n } as UIMessage;\n\n if (existingIdx >= 0) {\n const updated = [...messages];\n updated[existingIdx] = partialMessage;\n return updated;\n }\n return [...messages, partialMessage];\n }\n}\n","/**\n * Broadcast stream state machine.\n *\n * Manages the lifecycle of a StreamAccumulator for broadcast/resume\n * streams — the path where this client is *observing* a stream owned\n * by another tab or resumed after reconnect, rather than the transport-\n * owned path that feeds directly into useChat.\n *\n * The transition function is pure (no React, no WebSocket, no side\n * effects). Callers dispatch events and apply the returned state +\n * messagesUpdate. Side effects (sending ACKs, calling onData) stay\n * in the caller.\n */\n\nimport type { UIMessage } from \"ai\";\nimport { StreamAccumulator } from \"./stream-accumulator\";\nimport type { StreamChunkData } from \"./message-builder\";\n\n// ── State ──────────────────────────────────────────────────────────\n\nexport type BroadcastStreamState =\n | { status: \"idle\" }\n | {\n status: \"observing\";\n streamId: string;\n accumulator: StreamAccumulator;\n };\n\n// ── Events ─────────────────────────────────────────────────────────\n\nexport type BroadcastStreamEvent =\n | {\n type: \"response\";\n streamId: string;\n /** Fallback message ID for a new accumulator (ignored if one exists for this stream). */\n messageId: string;\n chunkData?: unknown;\n done?: boolean;\n error?: boolean;\n replay?: boolean;\n replayComplete?: boolean;\n continuation?: boolean;\n /** @deprecated Continuations now seed from current messages in `messagesUpdate`. */\n currentMessages?: UIMessage[];\n }\n | {\n type: \"resume-fallback\";\n streamId: string;\n messageId: string;\n }\n | { type: \"clear\" };\n\n// ── Result ─────────────────────────────────────────────────────────\n\nexport interface TransitionResult {\n state: BroadcastStreamState;\n messagesUpdate?: (prev: UIMessage[]) => UIMessage[];\n isStreaming: boolean;\n}\n\n// ── Transition ─────────────────────────────────────────────────────\n\nexport function transition(\n state: BroadcastStreamState,\n event: BroadcastStreamEvent\n): TransitionResult {\n switch (event.type) {\n case \"clear\":\n return { state: { status: \"idle\" }, isStreaming: false };\n\n case \"resume-fallback\": {\n const accumulator = new StreamAccumulator({\n messageId: event.messageId\n });\n return {\n state: {\n status: \"observing\",\n streamId: event.streamId,\n accumulator\n },\n isStreaming: true\n };\n }\n\n case \"response\": {\n let accumulator: StreamAccumulator;\n\n // A replayed `start` chunk means the server is re-sending the stream\n // buffer from chunk 0 (resume replay). Re-initialize the accumulator\n // instead of appending into an existing one: replaying into an\n // accumulator that already holds this stream's parts would duplicate\n // them (a second `text-start` unconditionally opens a second text\n // part — #1733). Re-initializing makes replay idempotent under any\n // number of replays, including a second replay triggered by a\n // duplicate STREAM_RESUMING → ACK cycle or a reconnect.\n const isReplayedStart =\n event.replay === true &&\n (event.chunkData as { type?: string } | null | undefined)?.type ===\n \"start\";\n\n if (\n state.status === \"idle\" ||\n state.streamId !== event.streamId ||\n isReplayedStart\n ) {\n accumulator = new StreamAccumulator({\n messageId: event.messageId,\n continuation: event.continuation\n });\n } else {\n accumulator = state.accumulator;\n }\n\n if (event.chunkData) {\n accumulator.applyChunk(event.chunkData as StreamChunkData);\n }\n\n let messagesUpdate: ((prev: UIMessage[]) => UIMessage[]) | undefined;\n\n if (event.done) {\n messagesUpdate = (prev) => accumulator.mergeInto(prev);\n return {\n state: { status: \"idle\" },\n messagesUpdate,\n isStreaming: false\n };\n }\n\n if (event.chunkData && !event.replay) {\n messagesUpdate = (prev) => accumulator.mergeInto(prev);\n } else if (event.replayComplete) {\n messagesUpdate = (prev) => accumulator.mergeInto(prev);\n }\n\n return {\n state: {\n status: \"observing\",\n streamId: event.streamId,\n accumulator\n },\n messagesUpdate,\n isStreaming: true\n };\n }\n }\n}\n","/**\n * Wire protocol message type constants for the cf_agent_chat_* protocol.\n *\n * These are the string values used on the wire between agent servers and\n * clients. Both @cloudflare/ai-chat (via its MessageType enum) and\n * @cloudflare/think use these values.\n */\nexport const STREAM_RESUME_NONE_REASONS = {\n /** No active, pending, or terminal stream exists for this agent. */\n IDLE: \"idle\",\n /** An active tool continuation is owned by another live connection. */\n CONTINUATION_OWNED: \"continuation-owned\"\n} as const;\n\nexport type StreamResumeNoneReason =\n (typeof STREAM_RESUME_NONE_REASONS)[keyof typeof STREAM_RESUME_NONE_REASONS];\n\nexport const CHAT_MESSAGE_TYPES = {\n CHAT_MESSAGES: \"cf_agent_chat_messages\",\n USE_CHAT_REQUEST: \"cf_agent_use_chat_request\",\n USE_CHAT_RESPONSE: \"cf_agent_use_chat_response\",\n CHAT_CLEAR: \"cf_agent_chat_clear\",\n CHAT_REQUEST_CANCEL: \"cf_agent_chat_request_cancel\",\n STREAM_RESUMING: \"cf_agent_stream_resuming\",\n STREAM_RESUME_ACK: \"cf_agent_stream_resume_ack\",\n STREAM_RESUME_REQUEST: \"cf_agent_stream_resume_request\",\n STREAM_RESUME_NONE: \"cf_agent_stream_resume_none\",\n // Server→client: a turn has been accepted but its resumable stream has not\n // started yet (queued, debouncing, waiting on MCP setup, or running async\n // work in `onChatMessage`). Sent in response to a resume request (or on\n // connect) so a reconnecting/re-mounting client keeps its expectation instead\n // of resolving its resume probe to \"no stream\" and then false-timing-out the\n // turn. Resolved by a later `STREAM_RESUMING` (stream started) or\n // `STREAM_RESUME_NONE` (turn settled without streaming). Backward-compatible —\n // clients that don't understand it ignore it. See issue #1784.\n STREAM_PENDING: \"cf_agent_stream_pending\",\n TOOL_RESULT: \"cf_agent_tool_result\",\n TOOL_APPROVAL: \"cf_agent_tool_approval\",\n MESSAGE_UPDATED: \"cf_agent_message_updated\",\n // Server→client: a durable chat turn is being recovered (interrupted by a\n // deploy/eviction or a stream-stall watchdog abort and now resuming). Sent\n // when a recovery continuation is scheduled and cleared on every terminal\n // outcome; `@cloudflare/think` also replays it on connect so a client that\n // joins mid-recovery learns it. Purely a progress hint — backward-compatible\n // (clients that don't understand it ignore it). See issue #1620.\n CHAT_RECOVERING: \"cf_agent_chat_recovering\"\n} as const;\n"],"mappings":"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"}
|
package/dist/react.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from "./agent-
|
|
2
|
+
$ as AgentToolRunPart,
|
|
3
|
+
et as AgentToolRunState,
|
|
4
|
+
w as MCPServersState
|
|
5
|
+
} from "./agent-routing-CnkaHb-v.js";
|
|
6
6
|
import { ClientParameters } from "./serializable.js";
|
|
7
7
|
import {
|
|
8
8
|
AgentConnectionError,
|
package/dist/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./types.js";
|
|
2
1
|
import { camelCaseToKebabCase } from "./utils.js";
|
|
2
|
+
import "./types.js";
|
|
3
3
|
import { AgentConnectionError, createStubProxy, isTerminalCloseEvent } from "./client.js";
|
|
4
4
|
import { buildSubAgentPathUnchecked } from "./sub-routing.js";
|
|
5
5
|
import { n as applyAgentToolEvent, r as createAgentToolEventState } from "./agent-tools-y7zLfw4Q.js";
|
package/dist/schedule.d.ts
CHANGED
|
@@ -1,130 +1,61 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ParsedSchedule,
|
|
3
|
+
getSchedulePrompt,
|
|
4
|
+
scheduleSchema
|
|
5
|
+
} from "./schedules/parser.js";
|
|
2
6
|
|
|
3
7
|
//#region src/schedule.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Get the schedule prompt for a given event
|
|
6
|
-
* @param event - The event to get the schedule prompt for
|
|
7
|
-
* @returns The schedule prompt
|
|
8
|
-
*/
|
|
9
|
-
declare function getSchedulePrompt(event: { date: Date }): string;
|
|
10
8
|
/**
|
|
11
9
|
* @deprecated this has been renamed to getSchedulePrompt, and unstable_getSchedulePrompt will be removed in the next major version
|
|
12
10
|
* @param event - The event to get the schedule prompt for
|
|
13
11
|
* @returns The schedule prompt
|
|
14
12
|
*/
|
|
15
13
|
declare function unstable_getSchedulePrompt(event: { date: Date }): string;
|
|
16
|
-
/**
|
|
17
|
-
* The schema for parsing natural language scheduling requests.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* import { generateObject } from "ai";
|
|
22
|
-
* import { scheduleSchema, getSchedulePrompt } from "agents/schedule";
|
|
23
|
-
*
|
|
24
|
-
* const result = await generateObject({
|
|
25
|
-
* model,
|
|
26
|
-
* prompt: `${getSchedulePrompt({ date: new Date() })} Input: "${userInput}"`,
|
|
27
|
-
* schema: scheduleSchema,
|
|
28
|
-
* // Required for OpenAI to avoid strict JSON schema validation errors
|
|
29
|
-
* providerOptions: {
|
|
30
|
-
* openai: { strictJsonSchema: false }
|
|
31
|
-
* }
|
|
32
|
-
* });
|
|
33
|
-
* ```
|
|
34
|
-
*
|
|
35
|
-
* @remarks
|
|
36
|
-
* When using this schema with OpenAI models via the AI SDK, you must pass
|
|
37
|
-
* `providerOptions: { openai: { strictJsonSchema: false } }` to `generateObject`.
|
|
38
|
-
* This is because the schema uses a discriminated union which is not compatible
|
|
39
|
-
* with OpenAI's strict structured outputs mode.
|
|
40
|
-
*/
|
|
41
|
-
declare const scheduleSchema: z.ZodObject<
|
|
42
|
-
{
|
|
43
|
-
description: z.ZodString;
|
|
44
|
-
when: z.ZodDiscriminatedUnion<
|
|
45
|
-
[
|
|
46
|
-
z.ZodObject<
|
|
47
|
-
{
|
|
48
|
-
type: z.ZodLiteral<"scheduled">;
|
|
49
|
-
date: z.ZodString;
|
|
50
|
-
},
|
|
51
|
-
z.core.$strip
|
|
52
|
-
>,
|
|
53
|
-
z.ZodObject<
|
|
54
|
-
{
|
|
55
|
-
type: z.ZodLiteral<"delayed">;
|
|
56
|
-
delayInSeconds: z.ZodNumber;
|
|
57
|
-
},
|
|
58
|
-
z.core.$strip
|
|
59
|
-
>,
|
|
60
|
-
z.ZodObject<
|
|
61
|
-
{
|
|
62
|
-
type: z.ZodLiteral<"cron">;
|
|
63
|
-
cron: z.ZodString;
|
|
64
|
-
},
|
|
65
|
-
z.core.$strip
|
|
66
|
-
>,
|
|
67
|
-
z.ZodObject<
|
|
68
|
-
{
|
|
69
|
-
type: z.ZodLiteral<"no-schedule">;
|
|
70
|
-
},
|
|
71
|
-
z.core.$strip
|
|
72
|
-
>
|
|
73
|
-
],
|
|
74
|
-
"type"
|
|
75
|
-
>;
|
|
76
|
-
},
|
|
77
|
-
z.core.$strip
|
|
78
|
-
>;
|
|
79
|
-
/**
|
|
80
|
-
* The type for the schedule prompt
|
|
81
|
-
*/
|
|
82
|
-
type Schedule = z.infer<typeof scheduleSchema>;
|
|
83
14
|
/**
|
|
84
15
|
* @deprecated this has been renamed to scheduleSchema, and unstable_scheduleSchema will be removed in the next major version
|
|
85
16
|
* @returns The schedule schema
|
|
86
17
|
*/
|
|
87
|
-
declare const unstable_scheduleSchema:
|
|
18
|
+
declare const unstable_scheduleSchema: import("zod").ZodObject<
|
|
88
19
|
{
|
|
89
|
-
description:
|
|
90
|
-
when:
|
|
20
|
+
description: import("zod").ZodString;
|
|
21
|
+
when: import("zod").ZodDiscriminatedUnion<
|
|
91
22
|
[
|
|
92
|
-
|
|
23
|
+
import("zod").ZodObject<
|
|
93
24
|
{
|
|
94
|
-
type:
|
|
95
|
-
date:
|
|
25
|
+
type: import("zod").ZodLiteral<"scheduled">;
|
|
26
|
+
date: import("zod").ZodString;
|
|
96
27
|
},
|
|
97
|
-
|
|
28
|
+
import("zod/v4/core").$strip
|
|
98
29
|
>,
|
|
99
|
-
|
|
30
|
+
import("zod").ZodObject<
|
|
100
31
|
{
|
|
101
|
-
type:
|
|
102
|
-
delayInSeconds:
|
|
32
|
+
type: import("zod").ZodLiteral<"delayed">;
|
|
33
|
+
delayInSeconds: import("zod").ZodNumber;
|
|
103
34
|
},
|
|
104
|
-
|
|
35
|
+
import("zod/v4/core").$strip
|
|
105
36
|
>,
|
|
106
|
-
|
|
37
|
+
import("zod").ZodObject<
|
|
107
38
|
{
|
|
108
|
-
type:
|
|
109
|
-
cron:
|
|
39
|
+
type: import("zod").ZodLiteral<"cron">;
|
|
40
|
+
cron: import("zod").ZodString;
|
|
110
41
|
},
|
|
111
|
-
|
|
42
|
+
import("zod/v4/core").$strip
|
|
112
43
|
>,
|
|
113
|
-
|
|
44
|
+
import("zod").ZodObject<
|
|
114
45
|
{
|
|
115
|
-
type:
|
|
46
|
+
type: import("zod").ZodLiteral<"no-schedule">;
|
|
116
47
|
},
|
|
117
|
-
|
|
48
|
+
import("zod/v4/core").$strip
|
|
118
49
|
>
|
|
119
50
|
],
|
|
120
51
|
"type"
|
|
121
52
|
>;
|
|
122
53
|
},
|
|
123
|
-
|
|
54
|
+
import("zod/v4/core").$strip
|
|
124
55
|
>;
|
|
125
56
|
//#endregion
|
|
126
57
|
export {
|
|
127
|
-
Schedule,
|
|
58
|
+
type ParsedSchedule as Schedule,
|
|
128
59
|
getSchedulePrompt,
|
|
129
60
|
scheduleSchema,
|
|
130
61
|
unstable_getSchedulePrompt,
|
package/dist/schedule.js
CHANGED
|
@@ -1,59 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getSchedulePrompt, scheduleSchema } from "./schedules/parser.js";
|
|
2
2
|
//#region src/schedule.ts
|
|
3
|
-
/**
|
|
4
|
-
* Get the schedule prompt for a given event
|
|
5
|
-
* @param event - The event to get the schedule prompt for
|
|
6
|
-
* @returns The schedule prompt
|
|
7
|
-
*/
|
|
8
|
-
function getSchedulePrompt(event) {
|
|
9
|
-
return `
|
|
10
|
-
[Schedule Parser Component]
|
|
11
|
-
|
|
12
|
-
Current time: ${event.date.toUTCString()}
|
|
13
|
-
|
|
14
|
-
This component parses natural language scheduling requests into a structured format. It extracts:
|
|
15
|
-
1. A clean task description (without timing information)
|
|
16
|
-
2. Scheduling details in one of these formats:
|
|
17
|
-
- scheduled: Specific date/time events
|
|
18
|
-
- delayed: Relative time delays (in seconds)
|
|
19
|
-
- cron: Recurring patterns
|
|
20
|
-
- no-schedule: Tasks without timing
|
|
21
|
-
|
|
22
|
-
Rules:
|
|
23
|
-
- Task descriptions should be clean and focused on the action
|
|
24
|
-
- Use numbers (0-6) for days in cron patterns (0=Sunday)
|
|
25
|
-
- For recurring tasks, use standard cron syntax
|
|
26
|
-
- For relative times, convert to seconds
|
|
27
|
-
- For specific dates, use the current time as reference
|
|
28
|
-
|
|
29
|
-
Example outputs:
|
|
30
|
-
{
|
|
31
|
-
"description": "meeting with team",
|
|
32
|
-
"when": {
|
|
33
|
-
"type": "scheduled",
|
|
34
|
-
"date": "tomorrow at 14:00"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
{
|
|
39
|
-
"description": "backup database",
|
|
40
|
-
"when": {
|
|
41
|
-
"type": "cron",
|
|
42
|
-
"cron": "0 0 * * *"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
{
|
|
47
|
-
"description": "send report",
|
|
48
|
-
"when": {
|
|
49
|
-
"type": "delayed",
|
|
50
|
-
"delayInSeconds": 1800
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
[End Schedule Parser Component]
|
|
55
|
-
`;
|
|
56
|
-
}
|
|
57
3
|
let didWarnAboutUnstableGetSchedulePrompt = false;
|
|
58
4
|
/**
|
|
59
5
|
* @deprecated this has been renamed to getSchedulePrompt, and unstable_getSchedulePrompt will be removed in the next major version
|
|
@@ -68,49 +14,6 @@ function unstable_getSchedulePrompt(event) {
|
|
|
68
14
|
return getSchedulePrompt(event);
|
|
69
15
|
}
|
|
70
16
|
/**
|
|
71
|
-
* The schema for parsing natural language scheduling requests.
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* ```typescript
|
|
75
|
-
* import { generateObject } from "ai";
|
|
76
|
-
* import { scheduleSchema, getSchedulePrompt } from "agents/schedule";
|
|
77
|
-
*
|
|
78
|
-
* const result = await generateObject({
|
|
79
|
-
* model,
|
|
80
|
-
* prompt: `${getSchedulePrompt({ date: new Date() })} Input: "${userInput}"`,
|
|
81
|
-
* schema: scheduleSchema,
|
|
82
|
-
* // Required for OpenAI to avoid strict JSON schema validation errors
|
|
83
|
-
* providerOptions: {
|
|
84
|
-
* openai: { strictJsonSchema: false }
|
|
85
|
-
* }
|
|
86
|
-
* });
|
|
87
|
-
* ```
|
|
88
|
-
*
|
|
89
|
-
* @remarks
|
|
90
|
-
* When using this schema with OpenAI models via the AI SDK, you must pass
|
|
91
|
-
* `providerOptions: { openai: { strictJsonSchema: false } }` to `generateObject`.
|
|
92
|
-
* This is because the schema uses a discriminated union which is not compatible
|
|
93
|
-
* with OpenAI's strict structured outputs mode.
|
|
94
|
-
*/
|
|
95
|
-
const scheduleSchema = z.object({
|
|
96
|
-
description: z.string().describe("A description of the task"),
|
|
97
|
-
when: z.discriminatedUnion("type", [
|
|
98
|
-
z.object({
|
|
99
|
-
type: z.literal("scheduled"),
|
|
100
|
-
date: z.string().describe("Execute task at the specified date and time in ISO 8601 format")
|
|
101
|
-
}),
|
|
102
|
-
z.object({
|
|
103
|
-
type: z.literal("delayed"),
|
|
104
|
-
delayInSeconds: z.number().describe("Execute task after a delay in seconds")
|
|
105
|
-
}),
|
|
106
|
-
z.object({
|
|
107
|
-
type: z.literal("cron"),
|
|
108
|
-
cron: z.string().describe("Execute task on a recurring interval specified as cron syntax")
|
|
109
|
-
}),
|
|
110
|
-
z.object({ type: z.literal("no-schedule") })
|
|
111
|
-
])
|
|
112
|
-
});
|
|
113
|
-
/**
|
|
114
17
|
* @deprecated this has been renamed to scheduleSchema, and unstable_scheduleSchema will be removed in the next major version
|
|
115
18
|
* @returns The schedule schema
|
|
116
19
|
*/
|
package/dist/schedule.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.js","names":[],"sources":["../src/schedule.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"schedule.js","names":[],"sources":["../src/schedule.ts"],"sourcesContent":["/**\n * @deprecated Import schedule parsing helpers from `agents/schedules/parser`.\n * This compatibility entry point will be removed in a future major release.\n */\nexport { getSchedulePrompt, scheduleSchema } from \"./schedules/parser\";\n/**\n * @deprecated Import `ParsedSchedule` from `agents/schedules/parser`.\n */\nexport type { ParsedSchedule as Schedule } from \"./schedules/parser\";\n\nimport { getSchedulePrompt, scheduleSchema } from \"./schedules/parser\";\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 * @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":";;AAYA,IAAI,wCAAwC;;;;;;AAO5C,SAAgB,2BAA2B,OAAuB;CAChE,IAAI,CAAC,uCAAuC;EAC1C,wCAAwC;EACxC,QAAQ,KACN,gJACF;CACF;CACA,OAAO,kBAAkB,KAAK;AAChC;;;;;AAMA,MAAa,0BAA0B"}
|