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/package.json
CHANGED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import type { UIMessage } from 'ai'
|
|
2
|
+
import type { AIState } from './ai.ts'
|
|
3
|
+
import type { ControlCommand, InboxItem } from './ai-control.ts'
|
|
4
|
+
|
|
5
|
+
export type QueueCommand<M extends UIMessage> = Extract<
|
|
6
|
+
ControlCommand<M>,
|
|
7
|
+
{
|
|
8
|
+
action:
|
|
9
|
+
| 'send'
|
|
10
|
+
| 'edit'
|
|
11
|
+
| 'move'
|
|
12
|
+
| 'remove'
|
|
13
|
+
| 'send-now'
|
|
14
|
+
| 'steer'
|
|
15
|
+
| 'pause'
|
|
16
|
+
| 'resume'
|
|
17
|
+
}
|
|
18
|
+
>
|
|
19
|
+
export type PendingQueueCommand<M extends UIMessage> = {
|
|
20
|
+
commandId: string
|
|
21
|
+
command: QueueCommand<M>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const isQueueCommand = <M extends UIMessage>(
|
|
25
|
+
command: ControlCommand<M>,
|
|
26
|
+
): command is QueueCommand<M> =>
|
|
27
|
+
command.action === 'send' ||
|
|
28
|
+
command.action === 'edit' ||
|
|
29
|
+
command.action === 'move' ||
|
|
30
|
+
command.action === 'remove' ||
|
|
31
|
+
command.action === 'send-now' ||
|
|
32
|
+
command.action === 'steer' ||
|
|
33
|
+
command.action === 'pause' ||
|
|
34
|
+
command.action === 'resume'
|
|
35
|
+
|
|
36
|
+
const moveItem = <M extends UIMessage>({
|
|
37
|
+
items,
|
|
38
|
+
inputId,
|
|
39
|
+
beforeId,
|
|
40
|
+
}: {
|
|
41
|
+
items: InboxItem<M>[]
|
|
42
|
+
inputId: string
|
|
43
|
+
beforeId: string | null
|
|
44
|
+
}): InboxItem<M>[] => {
|
|
45
|
+
const from = items.findIndex((item) => item.id === inputId)
|
|
46
|
+
if (
|
|
47
|
+
from < 0 ||
|
|
48
|
+
inputId === beforeId ||
|
|
49
|
+
(beforeId !== null && !items.some((item) => item.id === beforeId))
|
|
50
|
+
)
|
|
51
|
+
return items
|
|
52
|
+
const next = [...items]
|
|
53
|
+
const [item] = next.splice(from, 1)
|
|
54
|
+
const to =
|
|
55
|
+
beforeId === null
|
|
56
|
+
? next.length
|
|
57
|
+
: next.findIndex((entry) => entry.id === beforeId)
|
|
58
|
+
next.splice(to, 0, item!)
|
|
59
|
+
return next
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function projectAIClientState<M extends UIMessage>(
|
|
63
|
+
state: AIState<M>,
|
|
64
|
+
): AIState<M> {
|
|
65
|
+
const pending = state.pendingQueueCommands ?? []
|
|
66
|
+
if (state.status === 'closed') return state
|
|
67
|
+
if (
|
|
68
|
+
pending.length === 0 &&
|
|
69
|
+
!state.inbox.items.some((item) => item.afterStepOf !== undefined)
|
|
70
|
+
)
|
|
71
|
+
return state
|
|
72
|
+
let messages = state.messages
|
|
73
|
+
let { items, paused } = state.inbox
|
|
74
|
+
let turnId = state.active?.turnId ?? null
|
|
75
|
+
let starting = false
|
|
76
|
+
let suspended =
|
|
77
|
+
state.active?.phase === 'paused' || state.active?.phase === 'pausing'
|
|
78
|
+
let messageIds: Set<string> | undefined
|
|
79
|
+
const show = (message: M): void => {
|
|
80
|
+
messageIds ??= new Set(messages.map((item) => item.id))
|
|
81
|
+
if (messageIds.has(message.id)) return
|
|
82
|
+
if (messages === state.messages) messages = state.messages.slice()
|
|
83
|
+
messages.push(message)
|
|
84
|
+
messageIds.add(message.id)
|
|
85
|
+
}
|
|
86
|
+
const admit = (): void => {
|
|
87
|
+
if (turnId !== null || paused || items.length === 0) return
|
|
88
|
+
let count = 0
|
|
89
|
+
for (const item of items) {
|
|
90
|
+
count += 1
|
|
91
|
+
show(item.message)
|
|
92
|
+
if (item.generate) {
|
|
93
|
+
turnId = item.id
|
|
94
|
+
starting = true
|
|
95
|
+
suspended = false
|
|
96
|
+
break
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (count > 0) items = items.slice(count)
|
|
100
|
+
}
|
|
101
|
+
for (const { command } of pending) {
|
|
102
|
+
switch (command.action) {
|
|
103
|
+
case 'send':
|
|
104
|
+
case 'steer': {
|
|
105
|
+
if (
|
|
106
|
+
items.some((item) => item.id === command.message.id) ||
|
|
107
|
+
turnId === command.message.id
|
|
108
|
+
)
|
|
109
|
+
break
|
|
110
|
+
const item = {
|
|
111
|
+
...(command.action === 'steer'
|
|
112
|
+
? { afterStepOf: command.turnId }
|
|
113
|
+
: {}),
|
|
114
|
+
id: command.message.id,
|
|
115
|
+
revision: 0,
|
|
116
|
+
message: command.message,
|
|
117
|
+
generate:
|
|
118
|
+
command.message.role === 'user' &&
|
|
119
|
+
(command.action === 'steer' || command.generate !== false),
|
|
120
|
+
}
|
|
121
|
+
items = command.action === 'steer' ? [item, ...items] : [...items, item]
|
|
122
|
+
break
|
|
123
|
+
}
|
|
124
|
+
case 'edit':
|
|
125
|
+
items = items.map((item) =>
|
|
126
|
+
item.id === command.message.id &&
|
|
127
|
+
item.revision === command.expectedRevision &&
|
|
128
|
+
item.message.role === command.message.role
|
|
129
|
+
? { ...item, message: command.message }
|
|
130
|
+
: item,
|
|
131
|
+
)
|
|
132
|
+
break
|
|
133
|
+
case 'move':
|
|
134
|
+
items = moveItem({
|
|
135
|
+
items,
|
|
136
|
+
inputId: command.inputId,
|
|
137
|
+
beforeId: command.beforeId,
|
|
138
|
+
})
|
|
139
|
+
break
|
|
140
|
+
case 'remove':
|
|
141
|
+
items = items.filter((item) => item.id !== command.inputId)
|
|
142
|
+
break
|
|
143
|
+
case 'send-now': {
|
|
144
|
+
if (turnId !== command.turnId) break
|
|
145
|
+
const selected = items.find((item) => item.id === command.inputId)
|
|
146
|
+
if (!selected || selected.message.role !== 'user') break
|
|
147
|
+
items = items.map((item) =>
|
|
148
|
+
item.id === selected.id
|
|
149
|
+
? {
|
|
150
|
+
...item,
|
|
151
|
+
generate: true,
|
|
152
|
+
...(turnId === null ? {} : { afterStepOf: turnId }),
|
|
153
|
+
}
|
|
154
|
+
: item,
|
|
155
|
+
)
|
|
156
|
+
items = moveItem({
|
|
157
|
+
items,
|
|
158
|
+
inputId: command.inputId,
|
|
159
|
+
beforeId: items[0]?.id ?? null,
|
|
160
|
+
})
|
|
161
|
+
break
|
|
162
|
+
}
|
|
163
|
+
case 'pause':
|
|
164
|
+
paused = true
|
|
165
|
+
if (command.when === 'now') suspended = true
|
|
166
|
+
break
|
|
167
|
+
case 'resume':
|
|
168
|
+
paused = false
|
|
169
|
+
suspended = false
|
|
170
|
+
break
|
|
171
|
+
}
|
|
172
|
+
admit()
|
|
173
|
+
}
|
|
174
|
+
items = items.filter((item) => {
|
|
175
|
+
if (item.afterStepOf === undefined) return true
|
|
176
|
+
show(item.message)
|
|
177
|
+
return false
|
|
178
|
+
})
|
|
179
|
+
return {
|
|
180
|
+
...state,
|
|
181
|
+
messages,
|
|
182
|
+
inbox: { items, paused },
|
|
183
|
+
starting: starting && !suspended,
|
|
184
|
+
}
|
|
185
|
+
}
|