experimental-a2 0.13.0 → 0.14.1
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/CHANGELOG.md +43 -0
- package/dist/{actor-DJi3RsNu.d.ts → actor-BfQSE0KC.d.ts} +4 -4
- package/dist/{actor-DJi3RsNu.d.ts.map → actor-BfQSE0KC.d.ts.map} +1 -1
- package/dist/actor-client.d.ts +1 -1
- package/dist/actor-client.js +1 -1
- package/dist/actor-react.d.ts +3 -3
- package/dist/actor-react.js +2 -2
- package/dist/{actor-shared-DI7J5upy.js → actor-shared-B5tJfzt-.js} +2 -2
- package/dist/{actor-shared-DI7J5upy.js.map → actor-shared-B5tJfzt-.js.map} +1 -1
- package/dist/actor.d.ts +1 -1
- package/dist/actor.js +3 -3
- package/dist/ai-Cai-lCbj.d.ts +580 -0
- package/dist/ai-Cai-lCbj.d.ts.map +1 -0
- package/dist/ai-control-CcD4hh3y.js +119 -0
- package/dist/ai-control-CcD4hh3y.js.map +1 -0
- package/dist/ai-server.d.ts +6 -6
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +1053 -513
- package/dist/ai-server.js.map +1 -1
- package/dist/ai.d.ts +2 -365
- package/dist/ai.js +801 -80
- package/dist/ai.js.map +1 -1
- package/dist/{client-P_NNNRM-.d.ts → client-BAEABRZB.d.ts} +2 -2
- package/dist/{client-P_NNNRM-.d.ts.map → client-BAEABRZB.d.ts.map} +1 -1
- package/dist/{client-Bf6uSEAk.js → client-BYzHjkwU.js} +21 -6
- package/dist/client-BYzHjkwU.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/{contract-48bUMgcL.js → contract-CKRg_E4q.js} +3 -26
- package/dist/contract-CKRg_E4q.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/{reducer-DJKWm3cp.d.ts → reducer-BcS9VDKC.d.ts} +4 -1
- package/dist/{reducer-DJKWm3cp.d.ts.map → reducer-BcS9VDKC.d.ts.map} +1 -1
- package/dist/reducer-DEMjEY_O.js +29 -0
- package/dist/reducer-DEMjEY_O.js.map +1 -0
- package/dist/scheduler-qstash.d.ts +2 -2
- package/dist/scheduler-qstash.js +1 -1
- package/dist/scheduler-vercel.d.ts +2 -2
- package/dist/scheduler-vercel.js +1 -1
- package/dist/{server-DjZZa1wr.d.ts → server-Bp5Nd1pF.d.ts} +3 -3
- package/dist/{server-DjZZa1wr.d.ts.map → server-Bp5Nd1pF.d.ts.map} +1 -1
- package/dist/{server-BeNADlCI.js → server-CjJSGcF7.js} +4 -3
- package/dist/server-CjJSGcF7.js.map +1 -0
- package/dist/server.d.ts +3 -3
- package/dist/server.js +1 -1
- package/dist/{store-DtDOWLSn.d.ts → store-D_yhNdPz.d.ts} +7 -2
- package/dist/{store-DtDOWLSn.d.ts.map → store-D_yhNdPz.d.ts.map} +1 -1
- package/dist/store-N8PXxDAS.js.map +1 -1
- package/dist/store-memory.d.ts +1 -1
- package/dist/store-postgres.d.ts +1 -1
- package/dist/store-postgres.js +19 -0
- package/dist/store-postgres.js.map +1 -1
- package/dist/store-redis-http.d.ts +1 -1
- package/dist/store-redis-http.js +1 -1
- package/dist/{store-redis-notify-BUCyXOn0.js → store-redis-notify-D2EI6gwX.js} +27 -2
- package/dist/store-redis-notify-D2EI6gwX.js.map +1 -0
- package/dist/store-redis.d.ts +1 -1
- package/dist/store-redis.js +1 -1
- package/dist/store-sqlite.d.ts +1 -1
- package/docs/guides/06-ai-agents.mdx +287 -65
- package/docs/reference/01-api.mdx +122 -27
- package/examples/playground/app/agent/[agentId]/agent-client.tsx +118 -21
- package/examples/playground/app/agent/[agentId]/agent-queue.tsx +289 -0
- package/examples/playground/app/agent/compaction-settings.test.ts +22 -6
- package/examples/playground/app/agent/model.ts +11 -2
- package/examples/playground/app/agent/server.ts +8 -2
- package/examples/playground/app/chat/[chatId]/chat-client.tsx +3 -13
- package/examples/playground/app/chat/model.ts +2 -2
- package/examples/playground/app/chat/server.ts +24 -17
- package/examples/playground/app/globals.css +179 -0
- package/examples/playground/package.json +1 -1
- package/package.json +1 -1
- package/src/ai-client-state.ts +185 -0
- package/src/ai-control-server.ts +829 -0
- package/src/ai-control-state.ts +152 -0
- package/src/ai-control.ts +139 -0
- package/src/ai-coordinator.ts +99 -32
- package/src/ai-progress-batches.ts +68 -0
- package/src/ai-projector.ts +76 -15
- package/src/ai-sdk-step.ts +0 -1
- package/src/ai-server.ts +429 -619
- package/src/ai.ts +553 -108
- package/src/client.ts +31 -9
- package/src/licenses/Apache-2.0.txt +55 -0
- package/src/parse-partial-json.ts +441 -0
- package/src/reducer.ts +6 -0
- package/src/server.ts +8 -4
- package/src/store-postgres.ts +27 -0
- package/src/store-redis-core.ts +53 -1
- package/src/store-redis-notify.ts +1 -0
- package/src/store.ts +6 -0
- package/dist/ai.d.ts.map +0 -1
- package/dist/client-Bf6uSEAk.js.map +0 -1
- package/dist/contract-48bUMgcL.js.map +0 -1
- package/dist/server-BeNADlCI.js.map +0 -1
- package/dist/store-redis-notify-BUCyXOn0.js.map +0 -1
package/src/ai-projector.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { UIMessage, UIMessageChunk } from 'ai'
|
|
2
|
+
import { parsePartialJSON } from './parse-partial-json.ts'
|
|
2
3
|
|
|
3
4
|
type MutablePart = Record<string, unknown>
|
|
4
5
|
|
|
@@ -16,7 +17,13 @@ const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
|
16
17
|
typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
17
18
|
|
|
18
19
|
const cloneMessage = <M extends UIMessage>(messageId: string, base?: M): M =>
|
|
19
|
-
|
|
20
|
+
(base === undefined
|
|
21
|
+
? { id: messageId, role: 'assistant', parts: [] }
|
|
22
|
+
: {
|
|
23
|
+
...base,
|
|
24
|
+
id: messageId,
|
|
25
|
+
parts: base.parts.map((part) => ({ ...part })),
|
|
26
|
+
}) as M
|
|
20
27
|
|
|
21
28
|
const currentStepParts = (parts: MutablePart[]): MutablePart[] => {
|
|
22
29
|
let start = parts.length - 1
|
|
@@ -118,26 +125,47 @@ const mergeMetadata = (current: unknown, update: unknown): unknown => {
|
|
|
118
125
|
: update
|
|
119
126
|
}
|
|
120
127
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return undefined
|
|
126
|
-
}
|
|
128
|
+
export type UIMessageCursor = {
|
|
129
|
+
text: Record<string, number>
|
|
130
|
+
reasoning: Record<string, number>
|
|
131
|
+
tools: Record<string, PartialToolCall>
|
|
127
132
|
}
|
|
128
133
|
|
|
129
|
-
/** Internal synchronous counterpart of the AI SDK UI message stream fold. */
|
|
130
134
|
export function projectUIMessage<M extends UIMessage>(options: {
|
|
131
135
|
messageId: string
|
|
132
136
|
base?: M
|
|
133
137
|
chunks: readonly UIMessageChunk[]
|
|
134
138
|
}): M {
|
|
139
|
+
return projectUIMessageStream(options).message
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function projectUIMessageStream<M extends UIMessage>(options: {
|
|
143
|
+
messageId: string
|
|
144
|
+
base?: M
|
|
145
|
+
cursor?: UIMessageCursor
|
|
146
|
+
chunks: readonly UIMessageChunk[]
|
|
147
|
+
}): { message: M; cursor: UIMessageCursor } {
|
|
135
148
|
const message = cloneMessage(options.messageId, options.base)
|
|
136
149
|
const record = message as unknown as Record<string, unknown>
|
|
137
150
|
const parts = message.parts as unknown as MutablePart[]
|
|
138
|
-
const activeText = new Map
|
|
139
|
-
|
|
140
|
-
|
|
151
|
+
const activeText = new Map(
|
|
152
|
+
Object.entries(options.cursor?.text ?? {}).map(([id, index]) => [
|
|
153
|
+
id,
|
|
154
|
+
parts[index]!,
|
|
155
|
+
]),
|
|
156
|
+
)
|
|
157
|
+
const activeReasoning = new Map(
|
|
158
|
+
Object.entries(options.cursor?.reasoning ?? {}).map(([id, index]) => [
|
|
159
|
+
id,
|
|
160
|
+
parts[index]!,
|
|
161
|
+
]),
|
|
162
|
+
)
|
|
163
|
+
const partialTools = new Map(
|
|
164
|
+
Object.entries(options.cursor?.tools ?? {}).map(([id, partial]) => [
|
|
165
|
+
id,
|
|
166
|
+
{ ...partial },
|
|
167
|
+
]),
|
|
168
|
+
)
|
|
141
169
|
|
|
142
170
|
for (const chunk of options.chunks) {
|
|
143
171
|
switch (chunk.type) {
|
|
@@ -291,7 +319,7 @@ export function projectUIMessage<M extends UIMessage>(options: {
|
|
|
291
319
|
toolName: partial.toolName,
|
|
292
320
|
dynamic: partial.dynamic,
|
|
293
321
|
state: 'input-streaming',
|
|
294
|
-
input:
|
|
322
|
+
input: parsePartialJSON(partial.text),
|
|
295
323
|
providerExecuted: partial.providerExecuted,
|
|
296
324
|
providerMetadata: partial.providerMetadata,
|
|
297
325
|
toolMetadata: partial.toolMetadata,
|
|
@@ -424,7 +452,6 @@ export function projectUIMessage<M extends UIMessage>(options: {
|
|
|
424
452
|
activeReasoning.clear()
|
|
425
453
|
break
|
|
426
454
|
case 'start':
|
|
427
|
-
if (chunk.messageId !== undefined) record['id'] = chunk.messageId
|
|
428
455
|
if (
|
|
429
456
|
chunk.messageMetadata !== undefined &&
|
|
430
457
|
chunk.messageMetadata !== null
|
|
@@ -480,7 +507,38 @@ export function projectUIMessage<M extends UIMessage>(options: {
|
|
|
480
507
|
}
|
|
481
508
|
}
|
|
482
509
|
|
|
483
|
-
|
|
510
|
+
const indexes = new Map(parts.map((part, index) => [part, index]))
|
|
511
|
+
return {
|
|
512
|
+
message,
|
|
513
|
+
cursor: {
|
|
514
|
+
text: Object.fromEntries(
|
|
515
|
+
[...activeText].map(([id, part]) => [id, indexes.get(part)!]),
|
|
516
|
+
),
|
|
517
|
+
reasoning: Object.fromEntries(
|
|
518
|
+
[...activeReasoning].map(([id, part]) => [id, indexes.get(part)!]),
|
|
519
|
+
),
|
|
520
|
+
tools: Object.fromEntries(partialTools),
|
|
521
|
+
},
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
export function pauseUIMessage<M extends UIMessage>(options: {
|
|
526
|
+
message: M
|
|
527
|
+
toolCallIds: ReadonlySet<string>
|
|
528
|
+
}): M {
|
|
529
|
+
const next = structuredClone(options.message)
|
|
530
|
+
next.parts = next.parts.filter(
|
|
531
|
+
(part) =>
|
|
532
|
+
!('toolCallId' in part && !options.toolCallIds.has(part.toolCallId)),
|
|
533
|
+
)
|
|
534
|
+
for (const part of next.parts) {
|
|
535
|
+
if (
|
|
536
|
+
(part.type === 'text' || part.type === 'reasoning') &&
|
|
537
|
+
part.state === 'streaming'
|
|
538
|
+
)
|
|
539
|
+
part.state = 'done'
|
|
540
|
+
}
|
|
541
|
+
return next
|
|
484
542
|
}
|
|
485
543
|
|
|
486
544
|
export function interruptUIMessage<M extends UIMessage>(
|
|
@@ -488,6 +546,10 @@ export function interruptUIMessage<M extends UIMessage>(
|
|
|
488
546
|
toolError = 'Tool execution was interrupted.',
|
|
489
547
|
): M {
|
|
490
548
|
const next = structuredClone(message)
|
|
549
|
+
next.parts = next.parts.filter((value) => {
|
|
550
|
+
const part = value as unknown as MutablePart
|
|
551
|
+
return !isToolPart(part) || part['state'] !== 'input-streaming'
|
|
552
|
+
})
|
|
491
553
|
for (const value of next.parts as unknown as MutablePart[]) {
|
|
492
554
|
if (value['type'] === 'text' || value['type'] === 'reasoning') {
|
|
493
555
|
if (value['state'] === 'streaming') value['state'] = 'done'
|
|
@@ -510,7 +572,6 @@ export function interruptUIMessage<M extends UIMessage>(
|
|
|
510
572
|
continue
|
|
511
573
|
}
|
|
512
574
|
if (
|
|
513
|
-
state === 'input-streaming' ||
|
|
514
575
|
state === 'input-available' ||
|
|
515
576
|
state === 'approval-requested' ||
|
|
516
577
|
state === 'approval-responded'
|
package/src/ai-sdk-step.ts
CHANGED
|
@@ -244,7 +244,6 @@ export async function generateAISDKStep<M extends UIMessage, T extends ToolSet>(
|
|
|
244
244
|
stream: toUIMessageStream<T, M>({
|
|
245
245
|
stream: observed,
|
|
246
246
|
tools,
|
|
247
|
-
originalMessages: input.messages,
|
|
248
247
|
generateMessageId: () => input.responseMessageId,
|
|
249
248
|
onError: errorMessage,
|
|
250
249
|
...(input.messageMetadata === undefined
|