experimental-a2 0.12.0 → 0.13.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 +13 -0
- package/dist/ai-server.d.ts +11 -3
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +476 -142
- package/dist/ai-server.js.map +1 -1
- package/dist/ai.d.ts +32 -1
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +39 -7
- package/dist/ai.js.map +1 -1
- package/docs/guides/06-ai-agents.mdx +100 -18
- package/docs/reference/01-api.mdx +41 -4
- package/examples/playground/app/agent/[agentId]/agent-client.tsx +31 -16
- 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 +128 -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 +47 -1
- package/examples/playground/app/agent/server.ts +3 -2
- package/examples/playground/app/globals.css +154 -0
- package/examples/playground/package.json +1 -1
- package/package.json +1 -1
- package/src/ai-model-metadata.ts +108 -0
- package/src/ai-sdk-step.ts +5 -1
- package/src/ai-server.ts +712 -203
- package/src/ai.ts +99 -4
package/src/ai.ts
CHANGED
|
@@ -64,6 +64,7 @@ export type GenerationStartedPayload = {
|
|
|
64
64
|
responseMessageId: string
|
|
65
65
|
attempt: number
|
|
66
66
|
model: string
|
|
67
|
+
promptThroughIndex?: number
|
|
67
68
|
}
|
|
68
69
|
export type GenerationProgressPayload = {
|
|
69
70
|
requestId: string
|
|
@@ -80,6 +81,7 @@ export type GenerationCompletedPayload = {
|
|
|
80
81
|
responseMessageId: string
|
|
81
82
|
finishReason?: FinishReason
|
|
82
83
|
usage?: LanguageModelUsage
|
|
84
|
+
inputTokenEstimate?: number
|
|
83
85
|
}
|
|
84
86
|
export type GenerationFailedPayload = {
|
|
85
87
|
requestId: string
|
|
@@ -152,15 +154,33 @@ export type InputRespondedPayload = {
|
|
|
152
154
|
name: string
|
|
153
155
|
value: JSONValue
|
|
154
156
|
}
|
|
157
|
+
export type ModelLimits = {
|
|
158
|
+
contextWindow: number
|
|
159
|
+
maxOutputTokens: number
|
|
160
|
+
}
|
|
161
|
+
export type ModelMetadataRequestedPayload = { modelId: string }
|
|
162
|
+
export type ModelMetadataResolvedPayload = {
|
|
163
|
+
modelId: string
|
|
164
|
+
limits: ModelLimits | null
|
|
165
|
+
}
|
|
166
|
+
export type ModelMetadataState =
|
|
167
|
+
| { status: 'pending' }
|
|
168
|
+
| { status: 'resolved'; limits: ModelLimits }
|
|
169
|
+
| { status: 'unavailable' }
|
|
170
|
+
|
|
155
171
|
export type CompactionRequestedPayload = {
|
|
156
172
|
generationId: string
|
|
157
173
|
throughMessageId: string
|
|
174
|
+
throughIndex?: number
|
|
158
175
|
}
|
|
159
176
|
export type CompactionCompletedPayload<M extends UIMessage> = {
|
|
160
177
|
generationId: string
|
|
161
178
|
throughMessageId: string
|
|
179
|
+
throughIndex?: number
|
|
162
180
|
messages: M[]
|
|
163
181
|
retainedMessageIds?: string[]
|
|
182
|
+
summary?: string
|
|
183
|
+
usage?: LanguageModelUsage
|
|
164
184
|
}
|
|
165
185
|
|
|
166
186
|
export type AIEventDefs<M extends UIMessage = UIMessage> = {
|
|
@@ -183,6 +203,8 @@ export type AIEventDefs<M extends UIMessage = UIMessage> = {
|
|
|
183
203
|
'ai.input.responded': StandardSchemaV1<InputRespondedPayload>
|
|
184
204
|
'ai.compaction.requested': StandardSchemaV1<CompactionRequestedPayload>
|
|
185
205
|
'ai.compaction.completed': StandardSchemaV1<CompactionCompletedPayload<M>>
|
|
206
|
+
'ai.model.metadata.requested': StandardSchemaV1<ModelMetadataRequestedPayload>
|
|
207
|
+
'ai.model.metadata.resolved': StandardSchemaV1<ModelMetadataResolvedPayload>
|
|
186
208
|
}
|
|
187
209
|
|
|
188
210
|
export type ActiveGeneration = GenerationStartedPayload
|
|
@@ -242,8 +264,11 @@ export type CompactionState<M extends UIMessage> = {
|
|
|
242
264
|
status: 'running' | 'completed'
|
|
243
265
|
generationId: string
|
|
244
266
|
throughMessageId: string
|
|
267
|
+
throughIndex?: number
|
|
245
268
|
messages?: M[]
|
|
246
269
|
retainedMessageIds?: string[]
|
|
270
|
+
summary?: string
|
|
271
|
+
usage?: LanguageModelUsage
|
|
247
272
|
}
|
|
248
273
|
|
|
249
274
|
export type GenerationUsage = {
|
|
@@ -269,6 +294,7 @@ export type AIState<M extends UIMessage = UIMessage> = {
|
|
|
269
294
|
pendingInputs: PendingInput[]
|
|
270
295
|
tools: ToolActivity[]
|
|
271
296
|
compaction: CompactionState<M> | null
|
|
297
|
+
modelMetadata: Record<string, ModelMetadataState>
|
|
272
298
|
usage: GenerationUsage[]
|
|
273
299
|
error: string | null
|
|
274
300
|
}
|
|
@@ -373,6 +399,15 @@ const jsonObject = <T extends object>(
|
|
|
373
399
|
const stringField = (value: Record<string, unknown>, key: string): boolean =>
|
|
374
400
|
typeof value[key] === 'string' && value[key].length > 0
|
|
375
401
|
|
|
402
|
+
const optionalIndexField = (
|
|
403
|
+
value: Record<string, unknown>,
|
|
404
|
+
key: string,
|
|
405
|
+
): boolean =>
|
|
406
|
+
value[key] === undefined ||
|
|
407
|
+
(typeof value[key] === 'number' &&
|
|
408
|
+
Number.isSafeInteger(value[key]) &&
|
|
409
|
+
value[key] >= 0)
|
|
410
|
+
|
|
376
411
|
const optionalStringField = (
|
|
377
412
|
value: Record<string, unknown>,
|
|
378
413
|
key: string,
|
|
@@ -449,6 +484,7 @@ const completedPayloadSchema: StandardSchemaV1<GenerationCompletedPayload> =
|
|
|
449
484
|
!stringField(value, 'messageId') ||
|
|
450
485
|
!stringField(value, 'generationId') ||
|
|
451
486
|
!stringField(value, 'responseMessageId') ||
|
|
487
|
+
!optionalIndexField(value, 'inputTokenEstimate') ||
|
|
452
488
|
!optionalStringField(value, 'finishReason')
|
|
453
489
|
) {
|
|
454
490
|
return issue('invalid ai.generation.completed payload')
|
|
@@ -465,6 +501,8 @@ const compactionPayloadSchema = <M extends UIMessage>(
|
|
|
465
501
|
!isJSONCompatible(value) ||
|
|
466
502
|
!stringField(value, 'generationId') ||
|
|
467
503
|
!stringField(value, 'throughMessageId') ||
|
|
504
|
+
!optionalIndexField(value, 'throughIndex') ||
|
|
505
|
+
!optionalStringField(value, 'summary') ||
|
|
468
506
|
!Array.isArray(value['messages']) ||
|
|
469
507
|
(value['retainedMessageIds'] !== undefined &&
|
|
470
508
|
(!Array.isArray(value['retainedMessageIds']) ||
|
|
@@ -484,7 +522,16 @@ const compactionPayloadSchema = <M extends UIMessage>(
|
|
|
484
522
|
value: {
|
|
485
523
|
generationId: value['generationId'] as string,
|
|
486
524
|
throughMessageId: value['throughMessageId'] as string,
|
|
525
|
+
...(value['throughIndex'] === undefined
|
|
526
|
+
? {}
|
|
527
|
+
: { throughIndex: value['throughIndex'] as number }),
|
|
487
528
|
messages,
|
|
529
|
+
...(value['summary'] === undefined
|
|
530
|
+
? {}
|
|
531
|
+
: { summary: value['summary'] as string }),
|
|
532
|
+
...(value['usage'] === undefined
|
|
533
|
+
? {}
|
|
534
|
+
: { usage: value['usage'] as LanguageModelUsage }),
|
|
488
535
|
...(value['retainedMessageIds'] === undefined
|
|
489
536
|
? {}
|
|
490
537
|
: { retainedMessageIds: value['retainedMessageIds'] as string[] }),
|
|
@@ -547,7 +594,8 @@ export function createEvents<M extends UIMessage = UIMessage>(options?: {
|
|
|
547
594
|
typeof value['attempt'] === 'number' &&
|
|
548
595
|
Number.isInteger(value['attempt']) &&
|
|
549
596
|
value['attempt'] > 0 &&
|
|
550
|
-
stringField(value, 'model')
|
|
597
|
+
stringField(value, 'model') &&
|
|
598
|
+
optionalIndexField(value, 'promptThroughIndex'),
|
|
551
599
|
),
|
|
552
600
|
'ai.generation.progress': progressPayloadSchema,
|
|
553
601
|
'ai.generation.completed': completedPayloadSchema,
|
|
@@ -641,9 +689,27 @@ export function createEvents<M extends UIMessage = UIMessage>(options?: {
|
|
|
641
689
|
'ai.compaction.requested',
|
|
642
690
|
(value) =>
|
|
643
691
|
stringField(value, 'generationId') &&
|
|
644
|
-
stringField(value, 'throughMessageId')
|
|
692
|
+
stringField(value, 'throughMessageId') &&
|
|
693
|
+
optionalIndexField(value, 'throughIndex'),
|
|
645
694
|
),
|
|
646
695
|
'ai.compaction.completed': compactionPayloadSchema(messageSchema),
|
|
696
|
+
'ai.model.metadata.requested': jsonObject(
|
|
697
|
+
'ai.model.metadata.requested',
|
|
698
|
+
(value) => stringField(value, 'modelId'),
|
|
699
|
+
),
|
|
700
|
+
'ai.model.metadata.resolved': jsonObject(
|
|
701
|
+
'ai.model.metadata.resolved',
|
|
702
|
+
(value) =>
|
|
703
|
+
stringField(value, 'modelId') &&
|
|
704
|
+
(value['limits'] === null ||
|
|
705
|
+
(isRecord(value['limits']) &&
|
|
706
|
+
typeof value['limits']['contextWindow'] === 'number' &&
|
|
707
|
+
Number.isSafeInteger(value['limits']['contextWindow']) &&
|
|
708
|
+
value['limits']['contextWindow'] > 0 &&
|
|
709
|
+
typeof value['limits']['maxOutputTokens'] === 'number' &&
|
|
710
|
+
Number.isSafeInteger(value['limits']['maxOutputTokens']) &&
|
|
711
|
+
value['limits']['maxOutputTokens'] > 0)),
|
|
712
|
+
),
|
|
647
713
|
}
|
|
648
714
|
return definition
|
|
649
715
|
}
|
|
@@ -663,6 +729,7 @@ const initialState = <M extends UIMessage>(): AIState<M> => ({
|
|
|
663
729
|
pendingInputs: [],
|
|
664
730
|
tools: [],
|
|
665
731
|
compaction: null,
|
|
732
|
+
modelMetadata: {},
|
|
666
733
|
usage: [],
|
|
667
734
|
error: null,
|
|
668
735
|
})
|
|
@@ -1084,6 +1151,30 @@ export function reduceAIState<M extends UIMessage>(
|
|
|
1084
1151
|
): AIState<M> {
|
|
1085
1152
|
if (state.status === 'closed') return state
|
|
1086
1153
|
switch (event.type) {
|
|
1154
|
+
case 'ai.model.metadata.requested': {
|
|
1155
|
+
const { modelId } = event.payload as ModelMetadataRequestedPayload
|
|
1156
|
+
if (Object.hasOwn(state.modelMetadata, modelId)) return state
|
|
1157
|
+
return {
|
|
1158
|
+
...state,
|
|
1159
|
+
modelMetadata: {
|
|
1160
|
+
...state.modelMetadata,
|
|
1161
|
+
[modelId]: { status: 'pending' },
|
|
1162
|
+
},
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
case 'ai.model.metadata.resolved': {
|
|
1166
|
+
const { modelId, limits } = event.payload as ModelMetadataResolvedPayload
|
|
1167
|
+
return {
|
|
1168
|
+
...state,
|
|
1169
|
+
modelMetadata: {
|
|
1170
|
+
...state.modelMetadata,
|
|
1171
|
+
[modelId]:
|
|
1172
|
+
limits === null
|
|
1173
|
+
? { status: 'unavailable' }
|
|
1174
|
+
: { status: 'resolved', limits },
|
|
1175
|
+
},
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1087
1178
|
case 'ai.session.created': {
|
|
1088
1179
|
const payload = event.payload as SessionCreatedPayload
|
|
1089
1180
|
return {
|
|
@@ -1102,6 +1193,10 @@ export function reduceAIState<M extends UIMessage>(
|
|
|
1102
1193
|
return {
|
|
1103
1194
|
...state,
|
|
1104
1195
|
status: 'closed',
|
|
1196
|
+
compaction:
|
|
1197
|
+
state.compaction?.status === 'running'
|
|
1198
|
+
? (state.activeProjection?.baseCompaction ?? null)
|
|
1199
|
+
: state.compaction,
|
|
1105
1200
|
activeGeneration: null,
|
|
1106
1201
|
activeRequestId: null,
|
|
1107
1202
|
activeResponseMessageId: null,
|
|
@@ -1968,7 +2063,7 @@ export function createReducer<D extends EventDefs>(options: {
|
|
|
1968
2063
|
type M = AIMessageFrom<D>
|
|
1969
2064
|
return options.contract
|
|
1970
2065
|
.reducer({
|
|
1971
|
-
name: options.name ?? 'a2.ai.state.
|
|
2066
|
+
name: options.name ?? 'a2.ai.state.v10',
|
|
1972
2067
|
initialState: initialState<M>(),
|
|
1973
2068
|
})
|
|
1974
2069
|
.fold((state, event) => reduceAIState(state, event))
|
|
@@ -2134,7 +2229,7 @@ export function agent<
|
|
|
2134
2229
|
})
|
|
2135
2230
|
const reducer = agentContract
|
|
2136
2231
|
.reducer({
|
|
2137
|
-
name: options.reducerName ?? 'a2.ai.state.
|
|
2232
|
+
name: options.reducerName ?? 'a2.ai.state.v10',
|
|
2138
2233
|
initialState: initialState<M>(),
|
|
2139
2234
|
})
|
|
2140
2235
|
.fold((state, event) => reduceAIState(state, event))
|