agents 0.22.0 → 0.23.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 +20 -1
- package/dist/{agent-routing-CnkaHb-v.d.ts → agent-routing-DE5zmCQ8.d.ts} +1038 -394
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +26 -26
- package/dist/{agent-tools-C0XJqWzB.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
- package/dist/agent-tools.d.ts +21 -21
- package/dist/browser/ai.js +4 -1
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
- package/dist/callable-decorator.d.ts +18 -0
- package/dist/callable-decorator.js +71 -0
- package/dist/callable-decorator.js.map +1 -0
- package/dist/capability-BjSKYpzg.js.map +1 -1
- package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
- package/dist/channel-Bnm4S7T2.d.ts +491 -0
- package/dist/channels/ai-sdk.d.ts +46 -0
- package/dist/channels/ai-sdk.js +120 -0
- package/dist/channels/ai-sdk.js.map +1 -0
- package/dist/channels/email.d.ts +95 -0
- package/dist/channels/email.js +323 -0
- package/dist/channels/email.js.map +1 -0
- package/dist/channels/index.d.ts +233 -0
- package/dist/channels/index.js +608 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/slack.d.ts +140 -0
- package/dist/channels/slack.js +614 -0
- package/dist/channels/slack.js.map +1 -0
- package/dist/channels/tanstack-ai.d.ts +39 -0
- package/dist/channels/tanstack-ai.js +17 -0
- package/dist/channels/tanstack-ai.js.map +1 -0
- package/dist/channels/telegram.d.ts +106 -0
- package/dist/channels/telegram.js +427 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/voice.d.ts +45 -0
- package/dist/channels/voice.js +122 -0
- package/dist/channels/voice.js.map +1 -0
- package/dist/chat/index.d.ts +2325 -2019
- package/dist/chat/index.js +888 -518
- package/dist/chat/index.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +7 -7
- package/dist/chat-sdk/index.js +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/context/index.d.ts +216 -0
- package/dist/context/index.js +454 -0
- package/dist/context/index.js.map +1 -0
- package/dist/{current-agent-CuMErtly.d.ts → current-agent-Da_C9a3b.d.ts} +90 -107
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/{diagnostics-CaBjfz4J.js → diagnostics-BzvaX2UT.js} +5 -1
- package/dist/diagnostics-BzvaX2UT.js.map +1 -0
- package/dist/diagnostics-C4jcz3VK.js +360 -0
- package/dist/diagnostics-C4jcz3VK.js.map +1 -0
- package/dist/index-BB0kqhIz.d.ts +101 -0
- package/dist/index-BVVgDSdq.d.ts +1 -0
- package/dist/index-XDkuQ7zm.d.ts +89 -0
- package/dist/{index-DcSAZKsB.d.ts → index-YSKgfgg9.d.ts} +3 -1
- package/dist/index.d.ts +91 -82
- package/dist/index.js +3 -2
- package/dist/ingress-BfetZbMO.js +83 -0
- package/dist/ingress-BfetZbMO.js.map +1 -0
- package/dist/internal-CYlgHl1l.js +59 -0
- package/dist/internal-CYlgHl1l.js.map +1 -0
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +35 -17
- package/dist/lifecycle/index.js +1 -1
- package/dist/lifecycle-CMRGjZdw.js +1299 -0
- package/dist/lifecycle-CMRGjZdw.js.map +1 -0
- package/dist/mcp/client/index.d.ts +20 -20
- package/dist/mcp/index.d.ts +35 -35
- package/dist/mcp/index.js +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js +1 -1
- package/dist/react.d.ts +4 -4
- package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
- package/dist/retries.d.ts +8 -6
- package/dist/retries.js +13 -1
- package/dist/retries.js.map +1 -1
- package/dist/routing/index.d.ts +137 -0
- package/dist/routing/index.js +244 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/sanitize-D9TujEK8.js +79 -0
- package/dist/sanitize-D9TujEK8.js.map +1 -0
- package/dist/scheduler-DD9NdYbF.js +665 -0
- package/dist/scheduler-DD9NdYbF.js.map +1 -0
- package/dist/{scheduler-DQoTGoAW.d.ts → scheduler-Dwh85ZGl.d.ts} +21 -22
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
- package/dist/serializable.d.ts +1 -1
- package/dist/sessions/index.d.ts +441 -0
- package/dist/sessions/index.js +2063 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/skills/index.d.ts +99 -0
- package/dist/skills/index.js +254 -5
- package/dist/skills/index.js.map +1 -1
- package/dist/{src-5W6JNKVb.js → src-DlSHshb2.js} +1460 -1110
- package/dist/src-DlSHshb2.js.map +1 -0
- package/dist/streams/index.d.ts +120 -0
- package/dist/streams/index.js +107 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams-D6tJ0NN9.d.ts +370 -0
- package/dist/streams-DZKgAj9b.js +709 -0
- package/dist/streams-DZKgAj9b.js.map +1 -0
- package/dist/sub-routing.d.ts +12 -12
- package/dist/surface-bZZJqBka.js +17 -0
- package/dist/surface-bZZJqBka.js.map +1 -0
- package/dist/tasks/index.d.ts +64 -0
- package/dist/tasks/index.js +2 -0
- package/dist/tasks-BRJ5zgya.d.ts +517 -0
- package/dist/tasks-ylZgBjhj.js +1656 -0
- package/dist/tasks-ylZgBjhj.js.map +1 -0
- package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
- package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
- package/dist/text-stream-CpdiKrJB.js +272 -0
- package/dist/text-stream-CpdiKrJB.js.map +1 -0
- package/dist/tokens-nHAKcN6M.js +52 -0
- package/dist/tokens-nHAKcN6M.js.map +1 -0
- package/dist/tool-schema-CBjGPrsQ.js +31 -0
- package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
- package/dist/types-B7LojTe4.d.ts +202 -0
- package/dist/types-_Faxb570.d.ts +439 -0
- package/dist/voice/client.d.ts +226 -0
- package/dist/voice/client.js +932 -0
- package/dist/voice/client.js.map +1 -0
- package/dist/voice/errors.d.ts +43 -0
- package/dist/voice/errors.js +41 -0
- package/dist/voice/errors.js.map +1 -0
- package/dist/voice/index.d.ts +271 -0
- package/dist/voice/index.js +1812 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/react.d.ts +167 -0
- package/dist/voice/react.js +234 -0
- package/dist/voice/react.js.map +1 -0
- package/dist/voice/sfu.d.ts +71 -0
- package/dist/voice/sfu.js +157 -0
- package/dist/voice/sfu.js.map +1 -0
- package/dist/voice/text.d.ts +6 -0
- package/dist/voice/text.js +2 -0
- package/dist/voice/types.d.ts +58 -0
- package/dist/voice/types.js +18 -0
- package/dist/voice/types.js.map +1 -0
- package/dist/voice/workers-ai.d.ts +136 -0
- package/dist/voice/workers-ai.js +568 -0
- package/dist/voice/workers-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +192 -0
- package/dist/websockets/index.js +2 -0
- package/dist/websockets-DUfRHPRq.js +502 -0
- package/dist/websockets-DUfRHPRq.js.map +1 -0
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflows.d.ts +21 -21
- package/dist/workflows.js +1 -1
- package/docs/agent-class.md +2 -2
- package/docs/agent-tools.md +2 -1
- package/docs/channels.md +323 -0
- package/docs/chat-agents.md +6 -13
- package/docs/context.md +131 -0
- package/docs/index.md +15 -12
- package/docs/lifecycle.md +102 -55
- package/docs/long-running-agents.md +2 -2
- package/docs/mcp-servers.md +5 -1
- package/docs/resumable-streaming.md +1 -1
- package/docs/routing.md +105 -0
- package/docs/sessions.md +237 -871
- package/docs/streams.md +213 -0
- package/docs/sub-agents.md +184 -124
- package/docs/tasks.md +246 -0
- package/docs/voice.md +745 -0
- package/package.json +115 -13
- package/dist/capability-runner-CvHGZqUu.d.ts +0 -150
- package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
- package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
- package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
- package/dist/diagnostics-CaBjfz4J.js.map +0 -1
- package/dist/durable-object-lifecycle-D6nNQJJd.js +0 -862
- package/dist/durable-object-lifecycle-D6nNQJJd.js.map +0 -1
- package/dist/experimental/memory/session/index.d.ts +0 -671
- package/dist/experimental/memory/session/index.js +0 -2379
- package/dist/experimental/memory/session/index.js.map +0 -1
- package/dist/experimental/memory/utils/index.d.ts +0 -96
- package/dist/experimental/memory/utils/index.js +0 -79
- package/dist/experimental/memory/utils/index.js.map +0 -1
- package/dist/scheduler-CR9RHGos.js +0 -857
- package/dist/scheduler-CR9RHGos.js.map +0 -1
- package/dist/src-5W6JNKVb.js.map +0 -1
- package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
- package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
//#region src/channels/identity.d.ts
|
|
2
|
+
type ChannelIdentity = Readonly<{
|
|
3
|
+
/** Configured Channel that observed this identity. */ channelKey: string /** Stable Channel namespace in which `subject` is unique. @default "default" */;
|
|
4
|
+
scope?: string /** Stable Channel subject within `scope`. */;
|
|
5
|
+
subject: string;
|
|
6
|
+
}>;
|
|
7
|
+
/** A Channel-produced identity before its Host stamps the configured key. */
|
|
8
|
+
type ChannelIdentityInput = Readonly<{
|
|
9
|
+
scope?: string;
|
|
10
|
+
subject: string;
|
|
11
|
+
}>;
|
|
12
|
+
/** Build a stable key for comparing or indexing a Channel identity. */
|
|
13
|
+
declare function identityKey(identity: ChannelIdentity): string;
|
|
14
|
+
type UserIdentity = Readonly<{
|
|
15
|
+
/** Opaque identity owned by this store. */ id: string /** Channel identities explicitly linked to this user. */;
|
|
16
|
+
channelIdentities: readonly ChannelIdentity[];
|
|
17
|
+
}>;
|
|
18
|
+
type UserIdentityConflict = Readonly<{
|
|
19
|
+
channelIdentity: ChannelIdentity;
|
|
20
|
+
userId: string;
|
|
21
|
+
}>;
|
|
22
|
+
/** Raised when an operation would join identities already assigned to users. */
|
|
23
|
+
declare class UserIdentityConflictError extends Error {
|
|
24
|
+
readonly conflicts: readonly UserIdentityConflict[];
|
|
25
|
+
readonly attemptedUserId?: string | undefined;
|
|
26
|
+
readonly code = "USER_IDENTITY_CONFLICT";
|
|
27
|
+
constructor(
|
|
28
|
+
conflicts: readonly UserIdentityConflict[],
|
|
29
|
+
attemptedUserId?: string | undefined
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Application-owned user identity links.
|
|
34
|
+
*
|
|
35
|
+
* Implementations never infer links from usernames, email-like values, display
|
|
36
|
+
* names, or message surfaces. Every link is an explicit application decision.
|
|
37
|
+
*/
|
|
38
|
+
interface UserIdentityStore {
|
|
39
|
+
/** Link one Channel identity to a user. Repeating the same link is safe. */
|
|
40
|
+
link(userId: string, identity: ChannelIdentity): Promise<UserIdentity>;
|
|
41
|
+
/** Find the user linked to one Channel identity. */
|
|
42
|
+
findUser(identity: ChannelIdentity): Promise<UserIdentity | null>;
|
|
43
|
+
/** Get a user and all of its linked Channel identities. */
|
|
44
|
+
getUser(userId: string): Promise<UserIdentity | null>;
|
|
45
|
+
/** List every user and its linked Channel identities, ordered by user ID. */
|
|
46
|
+
listUsers(): Promise<UserIdentity[]>;
|
|
47
|
+
/**
|
|
48
|
+
* Atomically join two previously unjoined Channel identities.
|
|
49
|
+
*
|
|
50
|
+
* If one is linked, the other joins that user. If neither is linked, a new
|
|
51
|
+
* user is created. If both are linked, this raises
|
|
52
|
+
* `UserIdentityConflictError`, including when both point to the same user.
|
|
53
|
+
*/
|
|
54
|
+
linkChannelIdentities(
|
|
55
|
+
first: ChannelIdentity,
|
|
56
|
+
second: ChannelIdentity
|
|
57
|
+
): Promise<UserIdentity>;
|
|
58
|
+
}
|
|
59
|
+
type UserIdentitySqlValue = ArrayBuffer | string | number | null;
|
|
60
|
+
/** Structural storage seam satisfied by Durable Object SQLite storage. */
|
|
61
|
+
interface UserIdentityStorage {
|
|
62
|
+
readonly sql: {
|
|
63
|
+
exec<Row extends Record<string, UserIdentitySqlValue>>(
|
|
64
|
+
query: string,
|
|
65
|
+
...bindings: UserIdentitySqlValue[]
|
|
66
|
+
): {
|
|
67
|
+
toArray(): Row[];
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
transactionSync<Result>(closure: () => Result): Result;
|
|
71
|
+
}
|
|
72
|
+
type UserIdentityStoreOptions = {
|
|
73
|
+
/** Generate a new opaque user ID. @default crypto.randomUUID */ createUserId?: () => string;
|
|
74
|
+
};
|
|
75
|
+
/** Build the off-the-shelf user identity store over application-owned SQLite. */
|
|
76
|
+
declare function createUserIdentityStore(
|
|
77
|
+
storage: UserIdentityStorage,
|
|
78
|
+
options?: UserIdentityStoreOptions
|
|
79
|
+
): UserIdentityStore;
|
|
80
|
+
/** Join two Channel identities through a `UserIdentityStore`. */
|
|
81
|
+
declare function linkChannelIdentities(
|
|
82
|
+
store: UserIdentityStore,
|
|
83
|
+
first: ChannelIdentity,
|
|
84
|
+
second: ChannelIdentity
|
|
85
|
+
): Promise<UserIdentity>;
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/channels/surface.d.ts
|
|
88
|
+
/**
|
|
89
|
+
* A JSON value safe to persist across Worker and Durable Object boundaries.
|
|
90
|
+
*
|
|
91
|
+
* The recursive arms are interfaces rather than inline type literals so that
|
|
92
|
+
* TypeScript defers resolving them. Workers RPC checks a return type with
|
|
93
|
+
* `R extends Rpc.Serializable<R>`, which eagerly expands a self-referential
|
|
94
|
+
* type alias and fails with "Type instantiation is excessively deep". Deferred
|
|
95
|
+
* arms let a surface be returned from a Durable Object method.
|
|
96
|
+
*/
|
|
97
|
+
type ChannelSurfaceValue =
|
|
98
|
+
| null
|
|
99
|
+
| boolean
|
|
100
|
+
| number
|
|
101
|
+
| string
|
|
102
|
+
| ChannelSurfaceArray
|
|
103
|
+
| ChannelSurfaceObject;
|
|
104
|
+
interface ChannelSurfaceArray extends ReadonlyArray<ChannelSurfaceValue> {}
|
|
105
|
+
interface ChannelSurfaceObject {
|
|
106
|
+
readonly [key: string]: ChannelSurfaceValue;
|
|
107
|
+
}
|
|
108
|
+
/** A durable configured destination for one outbound message attempt. */
|
|
109
|
+
type ChannelMessageSurface<
|
|
110
|
+
TChannelKey extends string = string,
|
|
111
|
+
TAddress extends ChannelSurfaceValue = ChannelSurfaceValue
|
|
112
|
+
> = Readonly<{
|
|
113
|
+
channelKey: TChannelKey;
|
|
114
|
+
version: 1;
|
|
115
|
+
address: TAddress /** Human-readable destination text captured when the surface is created. */;
|
|
116
|
+
label: string;
|
|
117
|
+
}>;
|
|
118
|
+
/** A Channel-produced destination before its Host stamps the configured key. */
|
|
119
|
+
type ChannelMessageSurfaceInput<
|
|
120
|
+
TAddress extends ChannelSurfaceValue = ChannelSurfaceValue
|
|
121
|
+
> = Readonly<{
|
|
122
|
+
version: 1;
|
|
123
|
+
address: TAddress;
|
|
124
|
+
label: string;
|
|
125
|
+
}>;
|
|
126
|
+
/** Validate the common envelope before provider-specific address parsing. */
|
|
127
|
+
declare function isChannelMessageSurface(
|
|
128
|
+
value: unknown
|
|
129
|
+
): value is ChannelMessageSurface;
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/channels/ingress.d.ts
|
|
132
|
+
/** Serializable provider attachment facts available after ingress returns. */
|
|
133
|
+
type ChannelAttachment = {
|
|
134
|
+
id?: string;
|
|
135
|
+
mediaType?: string;
|
|
136
|
+
name?: string;
|
|
137
|
+
size?: number;
|
|
138
|
+
text?: string;
|
|
139
|
+
url?: string;
|
|
140
|
+
};
|
|
141
|
+
type ChannelActor = {
|
|
142
|
+
readonly id: string /** Stable Channel identity suitable for explicit application linking. */;
|
|
143
|
+
readonly identity?: ChannelIdentity;
|
|
144
|
+
readonly username?: string;
|
|
145
|
+
readonly fullName?: string;
|
|
146
|
+
readonly isBot?: boolean | "unknown";
|
|
147
|
+
readonly isSelf?: boolean;
|
|
148
|
+
};
|
|
149
|
+
/** An actor before the Host stamps its configured Channel key. */
|
|
150
|
+
type ChannelActorInput = Omit<ChannelActor, "identity"> & {
|
|
151
|
+
readonly identity?: ChannelIdentityInput;
|
|
152
|
+
};
|
|
153
|
+
type ChannelEventContext = {
|
|
154
|
+
/** Immutable Channel-scoped identity, independent of application routing. */ readonly eventId: string;
|
|
155
|
+
readonly thread: {
|
|
156
|
+
readonly id: string;
|
|
157
|
+
readonly isDirectMessage: boolean | "unknown";
|
|
158
|
+
} /** Exact provider destination for responding to this inbound event. */;
|
|
159
|
+
readonly replySurface?: ChannelMessageSurface;
|
|
160
|
+
readonly actor?: ChannelActor;
|
|
161
|
+
};
|
|
162
|
+
/** A normalized inbound message from a Channel adapter. */
|
|
163
|
+
type ChannelInboundMessage = ChannelEventContext & {
|
|
164
|
+
readonly type: "message";
|
|
165
|
+
readonly message: {
|
|
166
|
+
readonly id: string;
|
|
167
|
+
readonly text: string;
|
|
168
|
+
readonly title?: string;
|
|
169
|
+
readonly markdown?: string;
|
|
170
|
+
readonly attachments?: readonly ChannelAttachment[];
|
|
171
|
+
readonly isMention?: boolean;
|
|
172
|
+
readonly reply?: {
|
|
173
|
+
readonly id: string;
|
|
174
|
+
readonly text?: string;
|
|
175
|
+
};
|
|
176
|
+
readonly metadata?: {
|
|
177
|
+
/** ISO 8601 timestamp supplied by the provider. */ readonly sentAt?: string;
|
|
178
|
+
readonly edited?: boolean /** ISO 8601 timestamp supplied by the provider. */;
|
|
179
|
+
readonly editedAt?: string;
|
|
180
|
+
readonly autoReply?: boolean;
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
/** A provider-normalized response to an external approval request. */
|
|
185
|
+
type ChannelApprovalResponse = ChannelEventContext & {
|
|
186
|
+
readonly type: "approval-response";
|
|
187
|
+
readonly interactionId: string;
|
|
188
|
+
readonly decision:
|
|
189
|
+
| "approve"
|
|
190
|
+
| "reject" /** Provider reference for this inbound response. */;
|
|
191
|
+
readonly reference: string;
|
|
192
|
+
};
|
|
193
|
+
type ChannelIngressEvent = ChannelInboundMessage | ChannelApprovalResponse;
|
|
194
|
+
/** A normalized message before the Host stamps its configured Channel key. */
|
|
195
|
+
type ChannelEventContextInput = Omit<
|
|
196
|
+
ChannelEventContext,
|
|
197
|
+
"replySurface" | "actor"
|
|
198
|
+
> & {
|
|
199
|
+
readonly replySurface?: ChannelMessageSurfaceInput;
|
|
200
|
+
readonly actor?: ChannelActorInput;
|
|
201
|
+
};
|
|
202
|
+
type ChannelInboundMessageInput = Omit<
|
|
203
|
+
ChannelInboundMessage,
|
|
204
|
+
"replySurface" | "actor"
|
|
205
|
+
> & {
|
|
206
|
+
readonly replySurface?: ChannelMessageSurfaceInput;
|
|
207
|
+
readonly actor?: ChannelActorInput;
|
|
208
|
+
};
|
|
209
|
+
/** A normalized approval before the Host stamps its configured Channel key. */
|
|
210
|
+
type ChannelApprovalResponseInput = Omit<
|
|
211
|
+
ChannelApprovalResponse,
|
|
212
|
+
"replySurface" | "actor"
|
|
213
|
+
> & {
|
|
214
|
+
readonly replySurface?: ChannelMessageSurfaceInput;
|
|
215
|
+
readonly actor?: ChannelActorInput;
|
|
216
|
+
};
|
|
217
|
+
/** Authenticated event produced by a Channel before Host dispatch. */
|
|
218
|
+
type ChannelIngressEventInput =
|
|
219
|
+
| ChannelInboundMessageInput
|
|
220
|
+
| ChannelApprovalResponseInput;
|
|
221
|
+
/** Authenticated adapter output retained only until Host routing completes. */
|
|
222
|
+
type ChannelIngressEnvelope<TRaw = unknown> = {
|
|
223
|
+
event: ChannelIngressEventInput;
|
|
224
|
+
raw: TRaw;
|
|
225
|
+
};
|
|
226
|
+
/** The normalized envelopes and provider acknowledgement produced by ingress. */
|
|
227
|
+
type ChannelIngressResult<TRaw = unknown> = {
|
|
228
|
+
events: readonly ChannelIngressEnvelope<TRaw>[];
|
|
229
|
+
response: Response;
|
|
230
|
+
};
|
|
231
|
+
/** Match an HTTP request to one exact URL pathname. */
|
|
232
|
+
declare function matchesPath(request: Request, path: string): boolean;
|
|
233
|
+
/** Webhook-shaped inbound support owned by a Channel. */
|
|
234
|
+
interface ChannelIngress<TRaw = unknown> {
|
|
235
|
+
/** Return null when this Channel does not own the request. */
|
|
236
|
+
receive(request: Request): Promise<ChannelIngressResult<TRaw> | null>;
|
|
237
|
+
}
|
|
238
|
+
/** Structural input supported by Workers Email and Agent email handlers. */
|
|
239
|
+
type ChannelEmailInput = {
|
|
240
|
+
from: string;
|
|
241
|
+
to: string;
|
|
242
|
+
headers: Headers;
|
|
243
|
+
raw?: ReadableStream<Uint8Array>;
|
|
244
|
+
getRaw?: () => Promise<Uint8Array>;
|
|
245
|
+
};
|
|
246
|
+
type ChannelEmailIngressResult<TRaw = unknown> = {
|
|
247
|
+
events: readonly ChannelIngressEnvelope<TRaw>[];
|
|
248
|
+
};
|
|
249
|
+
/** Non-HTTP ingress for a Workers Email event. */
|
|
250
|
+
interface ChannelEmailIngress<TRaw = unknown> {
|
|
251
|
+
/** Return null when this Channel does not own the email. */
|
|
252
|
+
receive(
|
|
253
|
+
email: ChannelEmailInput
|
|
254
|
+
): Promise<ChannelEmailIngressResult<TRaw> | null>;
|
|
255
|
+
}
|
|
256
|
+
//#endregion
|
|
257
|
+
//#region src/channels/channel.d.ts
|
|
258
|
+
type Awaitable<T> = T | Promise<T>;
|
|
259
|
+
/** A transport-neutral outbound message whose canonical content is Markdown. */
|
|
260
|
+
type ChannelMessage = {
|
|
261
|
+
/** Optional topic. Each transport decides how to represent it. */ title?: string /** Canonical Markdown content. */;
|
|
262
|
+
markdown: string;
|
|
263
|
+
};
|
|
264
|
+
/** A transport failure safe to expose to an AI model. */
|
|
265
|
+
type DeliveryFailure = {
|
|
266
|
+
code: string;
|
|
267
|
+
message: string;
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* The result of a direct delivery attempt, defined by what reached the reader.
|
|
271
|
+
*
|
|
272
|
+
* `delivered` means the whole message reached the reader, not that a person
|
|
273
|
+
* read it. `failed` means none of it did; its `retryable` field says whether
|
|
274
|
+
* the same route can be attempted again. `uncertain` means an unknown amount
|
|
275
|
+
* of the message reached the reader, so another attempt or route could
|
|
276
|
+
* duplicate content. A stream that ends before its answer is complete is
|
|
277
|
+
* `uncertain`, and carries a `reference` when the Channel created something
|
|
278
|
+
* the caller can point at.
|
|
279
|
+
*/
|
|
280
|
+
type DeliveryResult =
|
|
281
|
+
| {
|
|
282
|
+
status: "delivered";
|
|
283
|
+
reference?: string;
|
|
284
|
+
}
|
|
285
|
+
| {
|
|
286
|
+
status: "failed";
|
|
287
|
+
retryable: boolean;
|
|
288
|
+
error: DeliveryFailure;
|
|
289
|
+
}
|
|
290
|
+
| {
|
|
291
|
+
status: "uncertain";
|
|
292
|
+
reference?: string;
|
|
293
|
+
error: DeliveryFailure;
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* One element of a progressively generated answer.
|
|
297
|
+
*
|
|
298
|
+
* The variants describe what an Agent produces, not what a provider renders.
|
|
299
|
+
* Any Channel may ignore any variant, so `text` alone must always be a
|
|
300
|
+
* complete answer; a variant carrying meaning `text` does not is a bug in the
|
|
301
|
+
* variant.
|
|
302
|
+
*/
|
|
303
|
+
type ChannelChunk =
|
|
304
|
+
| {
|
|
305
|
+
type: "text";
|
|
306
|
+
text: string;
|
|
307
|
+
}
|
|
308
|
+
| {
|
|
309
|
+
type: "reasoning";
|
|
310
|
+
text: string;
|
|
311
|
+
}
|
|
312
|
+
| {
|
|
313
|
+
type: "tool" /** Stable identity for one invocation when the producer provides it. */;
|
|
314
|
+
id?: string;
|
|
315
|
+
name: string;
|
|
316
|
+
status: "started" | "completed" | "failed";
|
|
317
|
+
title?: string;
|
|
318
|
+
detail?: string;
|
|
319
|
+
}
|
|
320
|
+
| {
|
|
321
|
+
type: "source";
|
|
322
|
+
url: string;
|
|
323
|
+
title?: string;
|
|
324
|
+
};
|
|
325
|
+
/** The normalized stream shape accepted by `ChannelHost.stream`. */
|
|
326
|
+
type ChannelChunkSource = ReadableStream<ChannelChunk>;
|
|
327
|
+
/** Caller options for one finished delivery. */
|
|
328
|
+
type ChannelDeliveryOptions = {
|
|
329
|
+
/** Caller-owned correlation an Adapter may use where the provider supports it. */ delivery?: ChannelDeliveryContext;
|
|
330
|
+
};
|
|
331
|
+
/** Caller options for one streamed answer. */
|
|
332
|
+
type ChannelStreamOptions = {
|
|
333
|
+
/**
|
|
334
|
+
* Optional topic. It is an option rather than a chunk because it is known
|
|
335
|
+
* before the first token, and a Channel usually needs it in its opening
|
|
336
|
+
* provider call.
|
|
337
|
+
*/
|
|
338
|
+
title?: string /** Caller-owned correlation an Adapter may use where the provider supports it. */;
|
|
339
|
+
delivery?: ChannelDeliveryContext;
|
|
340
|
+
};
|
|
341
|
+
/**
|
|
342
|
+
* Caller-owned correlation supplied to one provider delivery attempt.
|
|
343
|
+
*
|
|
344
|
+
* This is not an idempotency guarantee. An Adapter may map it to a provider
|
|
345
|
+
* idempotency primitive when one exists, or otherwise use it for observability.
|
|
346
|
+
*/
|
|
347
|
+
type ChannelDeliveryContext = {
|
|
348
|
+
deliveryId: string;
|
|
349
|
+
};
|
|
350
|
+
/** Caller-supplied approval links a Channel may include in its rendering. */
|
|
351
|
+
type ChannelApprovalLinks = {
|
|
352
|
+
approve: string;
|
|
353
|
+
reject: string;
|
|
354
|
+
};
|
|
355
|
+
/** The content a Channel needs to render an external approval request. */
|
|
356
|
+
type ChannelApprovalRequest = {
|
|
357
|
+
title?: string;
|
|
358
|
+
summary: string;
|
|
359
|
+
input: unknown;
|
|
360
|
+
};
|
|
361
|
+
type ChannelApprovalRequestOptions = {
|
|
362
|
+
interactionId: string;
|
|
363
|
+
request: ChannelApprovalRequest /** Caller-owned correlation an Adapter may use where the provider supports it. */;
|
|
364
|
+
delivery?: ChannelDeliveryContext /** Lazily obtains approval links supplied and settled by the caller. */;
|
|
365
|
+
getApprovalLinks?: () => Promise<ChannelApprovalLinks>;
|
|
366
|
+
};
|
|
367
|
+
type ChannelRouteContext = {
|
|
368
|
+
/** Lazily resolve the application user explicitly linked to the event actor. */ findUser(): Promise<UserIdentity | null>;
|
|
369
|
+
};
|
|
370
|
+
type ChannelRoute<TRaw = unknown> = (
|
|
371
|
+
event: ChannelIngressEvent,
|
|
372
|
+
raw: TRaw,
|
|
373
|
+
context: ChannelRouteContext
|
|
374
|
+
) => Awaitable<string | null>;
|
|
375
|
+
/** Recursive outbound capability injected into a composite Channel. */
|
|
376
|
+
type OutboundResolver = {
|
|
377
|
+
deliver(
|
|
378
|
+
surface: ChannelMessageSurface,
|
|
379
|
+
message: ChannelMessage,
|
|
380
|
+
options?: ChannelDeliveryOptions
|
|
381
|
+
): Promise<DeliveryResult>;
|
|
382
|
+
stream(
|
|
383
|
+
surface: ChannelMessageSurface,
|
|
384
|
+
chunks: ChannelChunkSource,
|
|
385
|
+
options?: ChannelStreamOptions
|
|
386
|
+
): Promise<DeliveryResult>;
|
|
387
|
+
requestApproval(
|
|
388
|
+
surface: ChannelMessageSurface,
|
|
389
|
+
options: ChannelApprovalRequestOptions
|
|
390
|
+
): Promise<DeliveryResult>;
|
|
391
|
+
isAvailable(surface: ChannelMessageSurface): Promise<boolean>;
|
|
392
|
+
};
|
|
393
|
+
/** A configured delivery route with optional approval and ingress support. */
|
|
394
|
+
interface Channel<TRaw = unknown> {
|
|
395
|
+
/** Select an opaque application route, or return null to ignore the event. */
|
|
396
|
+
route?(
|
|
397
|
+
event: ChannelIngressEvent,
|
|
398
|
+
raw: TRaw,
|
|
399
|
+
context: ChannelRouteContext
|
|
400
|
+
): Awaitable<string | null>;
|
|
401
|
+
/** Derive a direct destination from this configured Channel's identity. */
|
|
402
|
+
contactSurface?(identity: ChannelIdentity): ChannelMessageSurfaceInput | null;
|
|
403
|
+
/**
|
|
404
|
+
* Whether this route can currently be selected without attempting delivery.
|
|
405
|
+
* Absence means the channel should be attempted.
|
|
406
|
+
*/
|
|
407
|
+
isAvailable?(surface: ChannelMessageSurface): Awaitable<boolean>;
|
|
408
|
+
/**
|
|
409
|
+
* Perform one outbound delivery. Absent for inbound-only Channels.
|
|
410
|
+
*/
|
|
411
|
+
deliver?(
|
|
412
|
+
surface: ChannelMessageSurface,
|
|
413
|
+
message: ChannelMessage,
|
|
414
|
+
options?: ChannelDeliveryOptions
|
|
415
|
+
): Promise<DeliveryResult>;
|
|
416
|
+
/**
|
|
417
|
+
* Deliver one progressively generated answer. Absent for Channels that
|
|
418
|
+
* cannot stream, which the Host serves by collecting and calling `deliver`.
|
|
419
|
+
*
|
|
420
|
+
* The Channel owns the consumption loop. It must finalize whether the
|
|
421
|
+
* stream closed or errored, because a model can fail mid-generation, and it
|
|
422
|
+
* must not abandon a terminal provider call on error.
|
|
423
|
+
*/
|
|
424
|
+
stream?(
|
|
425
|
+
surface: ChannelMessageSurface,
|
|
426
|
+
chunks: ReadableStream<ChannelChunk>,
|
|
427
|
+
options: ChannelStreamOptions
|
|
428
|
+
): Promise<DeliveryResult>;
|
|
429
|
+
requestApproval?(
|
|
430
|
+
surface: ChannelMessageSurface,
|
|
431
|
+
options: ChannelApprovalRequestOptions
|
|
432
|
+
): Promise<DeliveryResult>;
|
|
433
|
+
readonly ingress?: ChannelIngress<TRaw>;
|
|
434
|
+
readonly emailIngress?: ChannelEmailIngress<TRaw>;
|
|
435
|
+
}
|
|
436
|
+
//#endregion
|
|
437
|
+
export {
|
|
438
|
+
ChannelIngressEnvelope as A,
|
|
439
|
+
isChannelMessageSurface as B,
|
|
440
|
+
ChannelEmailIngressResult as C,
|
|
441
|
+
ChannelInboundMessage as D,
|
|
442
|
+
ChannelEventContextInput as E,
|
|
443
|
+
ChannelMessageSurface as F,
|
|
444
|
+
UserIdentityConflictError as G,
|
|
445
|
+
ChannelIdentityInput as H,
|
|
446
|
+
ChannelMessageSurfaceInput as I,
|
|
447
|
+
UserIdentityStore as J,
|
|
448
|
+
UserIdentitySqlValue as K,
|
|
449
|
+
ChannelSurfaceArray as L,
|
|
450
|
+
ChannelIngressEventInput as M,
|
|
451
|
+
ChannelIngressResult as N,
|
|
452
|
+
ChannelInboundMessageInput as O,
|
|
453
|
+
matchesPath as P,
|
|
454
|
+
linkChannelIdentities as Q,
|
|
455
|
+
ChannelSurfaceObject as R,
|
|
456
|
+
ChannelEmailIngress as S,
|
|
457
|
+
ChannelEventContext as T,
|
|
458
|
+
UserIdentity as U,
|
|
459
|
+
ChannelIdentity as V,
|
|
460
|
+
UserIdentityConflict as W,
|
|
461
|
+
createUserIdentityStore as X,
|
|
462
|
+
UserIdentityStoreOptions as Y,
|
|
463
|
+
identityKey as Z,
|
|
464
|
+
ChannelActor as _,
|
|
465
|
+
ChannelApprovalRequestOptions as a,
|
|
466
|
+
ChannelApprovalResponseInput as b,
|
|
467
|
+
ChannelDeliveryContext as c,
|
|
468
|
+
ChannelRoute as d,
|
|
469
|
+
ChannelRouteContext as f,
|
|
470
|
+
OutboundResolver as g,
|
|
471
|
+
DeliveryResult as h,
|
|
472
|
+
ChannelApprovalRequest as i,
|
|
473
|
+
ChannelIngressEvent as j,
|
|
474
|
+
ChannelIngress as k,
|
|
475
|
+
ChannelDeliveryOptions as l,
|
|
476
|
+
DeliveryFailure as m,
|
|
477
|
+
Channel as n,
|
|
478
|
+
ChannelChunk as o,
|
|
479
|
+
ChannelStreamOptions as p,
|
|
480
|
+
UserIdentityStorage as q,
|
|
481
|
+
ChannelApprovalLinks as r,
|
|
482
|
+
ChannelChunkSource as s,
|
|
483
|
+
Awaitable as t,
|
|
484
|
+
ChannelMessage as u,
|
|
485
|
+
ChannelActorInput as v,
|
|
486
|
+
ChannelEmailInput as w,
|
|
487
|
+
ChannelAttachment as x,
|
|
488
|
+
ChannelApprovalResponse as y,
|
|
489
|
+
ChannelSurfaceValue as z
|
|
490
|
+
};
|
|
491
|
+
//# sourceMappingURL=channel-Bnm4S7T2.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
F as ChannelMessageSurface,
|
|
3
|
+
h as DeliveryResult,
|
|
4
|
+
o as ChannelChunk,
|
|
5
|
+
u as ChannelMessage
|
|
6
|
+
} from "../channel-Bnm4S7T2.js";
|
|
7
|
+
import { n as ChannelHost } from "../index-BB0kqhIz.js";
|
|
8
|
+
import { TextStreamPart, Tool, ToolSet } from "ai";
|
|
9
|
+
|
|
10
|
+
//#region src/channels/ai-sdk.d.ts
|
|
11
|
+
type SendMessageTool = Tool<ChannelMessage, DeliveryResult>;
|
|
12
|
+
/** Model-facing options controlled by the caller creating the tool. */
|
|
13
|
+
type CreateSendMessageToolOptions = Pick<
|
|
14
|
+
SendMessageTool,
|
|
15
|
+
| "description"
|
|
16
|
+
| "inputExamples"
|
|
17
|
+
| "metadata"
|
|
18
|
+
| "needsApproval"
|
|
19
|
+
| "providerOptions"
|
|
20
|
+
| "strict"
|
|
21
|
+
>;
|
|
22
|
+
/**
|
|
23
|
+
* Adapt one Host-resolved surface to an AI SDK tool.
|
|
24
|
+
*
|
|
25
|
+
* The caller chooses the key used in its ToolSet and owns model-facing policy
|
|
26
|
+
* such as the description, examples, metadata, and approval requirement.
|
|
27
|
+
*/
|
|
28
|
+
declare function createSendMessageTool(
|
|
29
|
+
host: ChannelHost,
|
|
30
|
+
surface: ChannelMessageSurface,
|
|
31
|
+
options?: CreateSendMessageToolOptions
|
|
32
|
+
): Tool<ChannelMessage, DeliveryResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Project an AI SDK `fullStream` onto neutral Channel chunks.
|
|
35
|
+
*
|
|
36
|
+
* Parts a Channel cannot express are dropped, which keeps provider part
|
|
37
|
+
* shapes out of `ChannelChunk`. An `error` or `abort` part errors the returned
|
|
38
|
+
* stream, so a generation that fails part-way reaches a Channel as the
|
|
39
|
+
* abnormal ending it is rather than as a complete answer.
|
|
40
|
+
*/
|
|
41
|
+
declare function toChannelChunks(
|
|
42
|
+
fullStream: AsyncIterable<TextStreamPart<ToolSet>>
|
|
43
|
+
): ReadableStream<ChannelChunk>;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { CreateSendMessageToolOptions, createSendMessageTool, toChannelChunks };
|
|
46
|
+
//# sourceMappingURL=ai-sdk.d.ts.map
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { n as parseChannelMessage, t as channelMessageJsonSchema } from "../tool-schema-CBjGPrsQ.js";
|
|
2
|
+
import { jsonSchema, tool } from "ai";
|
|
3
|
+
//#region src/channels/ai-sdk.ts
|
|
4
|
+
const channelMessageSchema = jsonSchema(channelMessageJsonSchema, { validate(value) {
|
|
5
|
+
try {
|
|
6
|
+
return {
|
|
7
|
+
success: true,
|
|
8
|
+
value: parseChannelMessage(value)
|
|
9
|
+
};
|
|
10
|
+
} catch (error) {
|
|
11
|
+
return {
|
|
12
|
+
success: false,
|
|
13
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
} });
|
|
17
|
+
/**
|
|
18
|
+
* Adapt one Host-resolved surface to an AI SDK tool.
|
|
19
|
+
*
|
|
20
|
+
* The caller chooses the key used in its ToolSet and owns model-facing policy
|
|
21
|
+
* such as the description, examples, metadata, and approval requirement.
|
|
22
|
+
*/
|
|
23
|
+
function createSendMessageTool(host, surface, options = {}) {
|
|
24
|
+
return tool({
|
|
25
|
+
...options,
|
|
26
|
+
inputSchema: channelMessageSchema,
|
|
27
|
+
execute: (message) => host.deliver(surface, message)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function toChannelChunk(part) {
|
|
31
|
+
switch (part.type) {
|
|
32
|
+
case "text-delta": return {
|
|
33
|
+
type: "text",
|
|
34
|
+
text: part.text
|
|
35
|
+
};
|
|
36
|
+
case "reasoning-delta": return {
|
|
37
|
+
type: "reasoning",
|
|
38
|
+
text: part.text
|
|
39
|
+
};
|
|
40
|
+
case "source": return part.sourceType === "url" ? {
|
|
41
|
+
type: "source",
|
|
42
|
+
url: part.url,
|
|
43
|
+
...part.title !== void 0 && { title: part.title }
|
|
44
|
+
} : void 0;
|
|
45
|
+
case "tool-call": return {
|
|
46
|
+
type: "tool",
|
|
47
|
+
id: part.toolCallId,
|
|
48
|
+
name: part.toolName,
|
|
49
|
+
status: "started"
|
|
50
|
+
};
|
|
51
|
+
case "tool-result": return {
|
|
52
|
+
type: "tool",
|
|
53
|
+
id: part.toolCallId,
|
|
54
|
+
name: part.toolName,
|
|
55
|
+
status: "completed"
|
|
56
|
+
};
|
|
57
|
+
case "tool-error": return {
|
|
58
|
+
type: "tool",
|
|
59
|
+
id: part.toolCallId,
|
|
60
|
+
name: part.toolName,
|
|
61
|
+
status: "failed"
|
|
62
|
+
};
|
|
63
|
+
default: return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Project an AI SDK `fullStream` onto neutral Channel chunks.
|
|
68
|
+
*
|
|
69
|
+
* Parts a Channel cannot express are dropped, which keeps provider part
|
|
70
|
+
* shapes out of `ChannelChunk`. An `error` or `abort` part errors the returned
|
|
71
|
+
* stream, so a generation that fails part-way reaches a Channel as the
|
|
72
|
+
* abnormal ending it is rather than as a complete answer.
|
|
73
|
+
*/
|
|
74
|
+
function toChannelChunks(fullStream) {
|
|
75
|
+
const parts = fullStream[Symbol.asyncIterator]();
|
|
76
|
+
let sourceClosed = false;
|
|
77
|
+
async function closeSource(reason) {
|
|
78
|
+
if (sourceClosed) return;
|
|
79
|
+
sourceClosed = true;
|
|
80
|
+
await parts.return?.(reason);
|
|
81
|
+
}
|
|
82
|
+
return new ReadableStream({
|
|
83
|
+
async pull(controller) {
|
|
84
|
+
try {
|
|
85
|
+
while (true) {
|
|
86
|
+
const { done, value } = await parts.next();
|
|
87
|
+
if (done) {
|
|
88
|
+
sourceClosed = true;
|
|
89
|
+
controller.close();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (value.type === "error") {
|
|
93
|
+
const error = value.error instanceof Error ? value.error : new Error(String(value.error));
|
|
94
|
+
await closeSource().catch(() => {});
|
|
95
|
+
controller.error(error);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (value.type === "abort") {
|
|
99
|
+
const error = new Error(value.reason ?? "The generation was aborted");
|
|
100
|
+
await closeSource().catch(() => {});
|
|
101
|
+
controller.error(error);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const chunk = toChannelChunk(value);
|
|
105
|
+
if (!chunk) continue;
|
|
106
|
+
controller.enqueue(chunk);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
await closeSource().catch(() => {});
|
|
111
|
+
controller.error(error);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
cancel: closeSource
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//#endregion
|
|
118
|
+
export { createSendMessageTool, toChannelChunks };
|
|
119
|
+
|
|
120
|
+
//# sourceMappingURL=ai-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk.js","names":[],"sources":["../../src/channels/ai-sdk.ts"],"sourcesContent":["import {\n jsonSchema,\n tool,\n type TextStreamPart,\n type Tool,\n type ToolSet\n} from \"ai\";\nimport type { ChannelChunk, ChannelMessage, DeliveryResult } from \"./channel\";\nimport type { ChannelHost } from \"./host\";\nimport type { ChannelMessageSurface } from \"./surface\";\nimport { channelMessageJsonSchema, parseChannelMessage } from \"./tool-schema\";\n\ntype SendMessageTool = Tool<ChannelMessage, DeliveryResult>;\n\n/** Model-facing options controlled by the caller creating the tool. */\nexport type CreateSendMessageToolOptions = Pick<\n SendMessageTool,\n | \"description\"\n | \"inputExamples\"\n | \"metadata\"\n | \"needsApproval\"\n | \"providerOptions\"\n | \"strict\"\n>;\n\nconst channelMessageSchema = jsonSchema<ChannelMessage>(\n channelMessageJsonSchema,\n {\n validate(value) {\n try {\n return { success: true, value: parseChannelMessage(value) };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error : new Error(String(error))\n };\n }\n }\n }\n);\n\n/**\n * Adapt one Host-resolved surface to an AI SDK tool.\n *\n * The caller chooses the key used in its ToolSet and owns model-facing policy\n * such as the description, examples, metadata, and approval requirement.\n */\nexport function createSendMessageTool(\n host: ChannelHost,\n surface: ChannelMessageSurface,\n options: CreateSendMessageToolOptions = {}\n): Tool<ChannelMessage, DeliveryResult> {\n return tool({\n ...options,\n inputSchema: channelMessageSchema,\n execute: (message) => host.deliver(surface, message)\n });\n}\n\nfunction toChannelChunk(\n part: TextStreamPart<ToolSet>\n): ChannelChunk | undefined {\n switch (part.type) {\n case \"text-delta\":\n return { type: \"text\", text: part.text };\n case \"reasoning-delta\":\n return { type: \"reasoning\", text: part.text };\n case \"source\":\n return part.sourceType === \"url\"\n ? {\n type: \"source\",\n url: part.url,\n ...(part.title !== undefined && { title: part.title })\n }\n : undefined;\n case \"tool-call\":\n return {\n type: \"tool\",\n id: part.toolCallId,\n name: part.toolName,\n status: \"started\"\n };\n case \"tool-result\":\n return {\n type: \"tool\",\n id: part.toolCallId,\n name: part.toolName,\n status: \"completed\"\n };\n case \"tool-error\":\n return {\n type: \"tool\",\n id: part.toolCallId,\n name: part.toolName,\n status: \"failed\"\n };\n default:\n return undefined;\n }\n}\n\n/**\n * Project an AI SDK `fullStream` onto neutral Channel chunks.\n *\n * Parts a Channel cannot express are dropped, which keeps provider part\n * shapes out of `ChannelChunk`. An `error` or `abort` part errors the returned\n * stream, so a generation that fails part-way reaches a Channel as the\n * abnormal ending it is rather than as a complete answer.\n */\nexport function toChannelChunks(\n fullStream: AsyncIterable<TextStreamPart<ToolSet>>\n): ReadableStream<ChannelChunk> {\n const parts = fullStream[Symbol.asyncIterator]();\n let sourceClosed = false;\n\n async function closeSource(reason?: unknown): Promise<void> {\n if (sourceClosed) return;\n sourceClosed = true;\n await parts.return?.(reason);\n }\n\n return new ReadableStream<ChannelChunk>({\n async pull(controller) {\n try {\n while (true) {\n const { done, value } = await parts.next();\n if (done) {\n sourceClosed = true;\n controller.close();\n return;\n }\n if (value.type === \"error\") {\n const error =\n value.error instanceof Error\n ? value.error\n : new Error(String(value.error));\n await closeSource().catch(() => {});\n controller.error(error);\n return;\n }\n if (value.type === \"abort\") {\n const error = new Error(\n value.reason ?? \"The generation was aborted\"\n );\n await closeSource().catch(() => {});\n controller.error(error);\n return;\n }\n const chunk = toChannelChunk(value);\n if (!chunk) continue;\n controller.enqueue(chunk);\n return;\n }\n } catch (error) {\n await closeSource().catch(() => {});\n controller.error(error);\n }\n },\n cancel: closeSource\n });\n}\n"],"mappings":";;;AAyBA,MAAM,uBAAuB,WAC3B,0BACA,EACE,SAAS,OAAO;CACd,IAAI;EACF,OAAO;GAAE,SAAS;GAAM,OAAO,oBAAoB,KAAK;EAAE;CAC5D,SAAS,OAAO;EACd,OAAO;GACL,SAAS;GACT,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;EACjE;CACF;AACF,EACF,CACF;;;;;;;AAQA,SAAgB,sBACd,MACA,SACA,UAAwC,CAAC,GACH;CACtC,OAAO,KAAK;EACV,GAAG;EACH,aAAa;EACb,UAAU,YAAY,KAAK,QAAQ,SAAS,OAAO;CACrD,CAAC;AACH;AAEA,SAAS,eACP,MAC0B;CAC1B,QAAQ,KAAK,MAAb;EACE,KAAK,cACH,OAAO;GAAE,MAAM;GAAQ,MAAM,KAAK;EAAK;EACzC,KAAK,mBACH,OAAO;GAAE,MAAM;GAAa,MAAM,KAAK;EAAK;EAC9C,KAAK,UACH,OAAO,KAAK,eAAe,QACvB;GACE,MAAM;GACN,KAAK,KAAK;GACV,GAAI,KAAK,UAAU,KAAA,KAAa,EAAE,OAAO,KAAK,MAAM;EACtD,IACA,KAAA;EACN,KAAK,aACH,OAAO;GACL,MAAM;GACN,IAAI,KAAK;GACT,MAAM,KAAK;GACX,QAAQ;EACV;EACF,KAAK,eACH,OAAO;GACL,MAAM;GACN,IAAI,KAAK;GACT,MAAM,KAAK;GACX,QAAQ;EACV;EACF,KAAK,cACH,OAAO;GACL,MAAM;GACN,IAAI,KAAK;GACT,MAAM,KAAK;GACX,QAAQ;EACV;EACF,SACE;CACJ;AACF;;;;;;;;;AAUA,SAAgB,gBACd,YAC8B;CAC9B,MAAM,QAAQ,WAAW,OAAO,cAAc,CAAC;CAC/C,IAAI,eAAe;CAEnB,eAAe,YAAY,QAAiC;EAC1D,IAAI,cAAc;EAClB,eAAe;EACf,MAAM,MAAM,SAAS,MAAM;CAC7B;CAEA,OAAO,IAAI,eAA6B;EACtC,MAAM,KAAK,YAAY;GACrB,IAAI;IACF,OAAO,MAAM;KACX,MAAM,EAAE,MAAM,UAAU,MAAM,MAAM,KAAK;KACzC,IAAI,MAAM;MACR,eAAe;MACf,WAAW,MAAM;MACjB;KACF;KACA,IAAI,MAAM,SAAS,SAAS;MAC1B,MAAM,QACJ,MAAM,iBAAiB,QACnB,MAAM,QACN,IAAI,MAAM,OAAO,MAAM,KAAK,CAAC;MACnC,MAAM,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC;MAClC,WAAW,MAAM,KAAK;MACtB;KACF;KACA,IAAI,MAAM,SAAS,SAAS;MAC1B,MAAM,QAAQ,IAAI,MAChB,MAAM,UAAU,4BAClB;MACA,MAAM,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC;MAClC,WAAW,MAAM,KAAK;MACtB;KACF;KACA,MAAM,QAAQ,eAAe,KAAK;KAClC,IAAI,CAAC,OAAO;KACZ,WAAW,QAAQ,KAAK;KACxB;IACF;GACF,SAAS,OAAO;IACd,MAAM,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC;IAClC,WAAW,MAAM,KAAK;GACxB;EACF;EACA,QAAQ;CACV,CAAC;AACH"}
|