experimental-a2 0.12.0 → 0.14.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/CHANGELOG.md +47 -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 +16 -8
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +1322 -475
- package/dist/ai-server.js.map +1 -1
- package/dist/ai.d.ts +2 -334
- package/dist/ai.js +838 -85
- 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 +361 -76
- package/docs/reference/01-api.mdx +159 -27
- package/examples/playground/app/agent/[agentId]/agent-client.tsx +145 -33
- package/examples/playground/app/agent/[agentId]/agent-queue.tsx +289 -0
- package/examples/playground/app/agent/[agentId]/compaction/route.ts +14 -0
- package/examples/playground/app/agent/[agentId]/compaction-event.tsx +38 -0
- package/examples/playground/app/agent/[agentId]/compaction-panel.tsx +294 -0
- package/examples/playground/app/agent/compaction-settings.test.ts +144 -0
- package/examples/playground/app/agent/compaction-settings.ts +49 -0
- package/examples/playground/app/agent/compaction-timeline.test.ts +337 -0
- package/examples/playground/app/agent/compaction-timeline.ts +198 -0
- package/examples/playground/app/agent/model.ts +56 -1
- package/examples/playground/app/agent/server.ts +9 -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 +333 -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-model-metadata.ts +108 -0
- package/src/ai-progress-batches.ts +68 -0
- package/src/ai-projector.ts +76 -15
- package/src/ai-sdk-step.ts +5 -2
- package/src/ai-server.ts +920 -638
- package/src/ai.ts +650 -110
- 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
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { UIMessageChunk } from 'ai'
|
|
2
|
+
|
|
3
|
+
export type ProgressBatch = { index: number; chunks: UIMessageChunk[] }
|
|
4
|
+
type BatchBlock = ProgressBatch[] | { left: BatchBlock; right: BatchBlock }
|
|
5
|
+
|
|
6
|
+
export type ProgressBatches = {
|
|
7
|
+
length: number
|
|
8
|
+
tail: ProgressBatch[]
|
|
9
|
+
blocks: Array<BatchBlock | null>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const PAGE_SIZE = 64
|
|
13
|
+
|
|
14
|
+
export const appendProgressBatch = ({
|
|
15
|
+
batches,
|
|
16
|
+
batch,
|
|
17
|
+
}: {
|
|
18
|
+
batches: ProgressBatches
|
|
19
|
+
batch: ProgressBatch
|
|
20
|
+
}): ProgressBatches => {
|
|
21
|
+
if (batches.tail.length < PAGE_SIZE)
|
|
22
|
+
return {
|
|
23
|
+
...batches,
|
|
24
|
+
length: batches.length + 1,
|
|
25
|
+
tail: [...batches.tail, batch],
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const blocks = [...batches.blocks]
|
|
29
|
+
let block: BatchBlock = batches.tail
|
|
30
|
+
let level = 0
|
|
31
|
+
for (;;) {
|
|
32
|
+
const left = blocks[level]
|
|
33
|
+
if (left == null) break
|
|
34
|
+
block = { left, right: block }
|
|
35
|
+
blocks[level] = null
|
|
36
|
+
level += 1
|
|
37
|
+
}
|
|
38
|
+
blocks[level] = block
|
|
39
|
+
return { length: batches.length + 1, tail: [batch], blocks }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const progressBatches = (
|
|
43
|
+
items: readonly ProgressBatch[] = [],
|
|
44
|
+
): ProgressBatches => {
|
|
45
|
+
let batches: ProgressBatches = { length: 0, tail: [], blocks: [] }
|
|
46
|
+
for (const batch of items) batches = appendProgressBatch({ batches, batch })
|
|
47
|
+
return batches
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const flattenProgressBatches = (
|
|
51
|
+
batches: ProgressBatches,
|
|
52
|
+
): ProgressBatch[] => {
|
|
53
|
+
const items: ProgressBatch[] = []
|
|
54
|
+
const visit = (block: BatchBlock): void => {
|
|
55
|
+
if (Array.isArray(block)) items.push(...block)
|
|
56
|
+
else {
|
|
57
|
+
visit(block.left)
|
|
58
|
+
visit(block.right)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Level n holds 2^n completed pages; higher levels contain older batches.
|
|
62
|
+
for (let level = batches.blocks.length - 1; level >= 0; level -= 1) {
|
|
63
|
+
const block = batches.blocks[level]
|
|
64
|
+
if (block) visit(block)
|
|
65
|
+
}
|
|
66
|
+
items.push(...batches.tail)
|
|
67
|
+
return items
|
|
68
|
+
}
|
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
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
Instructions,
|
|
11
11
|
LanguageModel,
|
|
12
12
|
LanguageModelUsage,
|
|
13
|
+
ModelMessage,
|
|
13
14
|
TextStreamPart,
|
|
14
15
|
ToolSet,
|
|
15
16
|
UIMessage,
|
|
@@ -127,6 +128,7 @@ export type AISDKStepInput<M extends UIMessage, T extends ToolSet> = {
|
|
|
127
128
|
model: LanguageModel
|
|
128
129
|
tools: T
|
|
129
130
|
messages: M[]
|
|
131
|
+
modelMessages?: ModelMessage[]
|
|
130
132
|
responseMessageId: string
|
|
131
133
|
abortSignal: AbortSignal
|
|
132
134
|
instructions?: Instructions
|
|
@@ -201,7 +203,9 @@ export async function generateAISDKStep<M extends UIMessage, T extends ToolSet>(
|
|
|
201
203
|
): Promise<AISDKStepResult<M>> {
|
|
202
204
|
const settings = safeSettings(input.settings)
|
|
203
205
|
const tools = modelToolSet(input.tools)
|
|
204
|
-
const messages =
|
|
206
|
+
const messages =
|
|
207
|
+
input.modelMessages ??
|
|
208
|
+
(await convertToModelMessages(input.messages, { tools }))
|
|
205
209
|
const streamOptions = {
|
|
206
210
|
...settings,
|
|
207
211
|
model: input.model,
|
|
@@ -240,7 +244,6 @@ export async function generateAISDKStep<M extends UIMessage, T extends ToolSet>(
|
|
|
240
244
|
stream: toUIMessageStream<T, M>({
|
|
241
245
|
stream: observed,
|
|
242
246
|
tools,
|
|
243
|
-
originalMessages: input.messages,
|
|
244
247
|
generateMessageId: () => input.responseMessageId,
|
|
245
248
|
onError: errorMessage,
|
|
246
249
|
...(input.messageMetadata === undefined
|