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/dist/ai.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ type GenerationStartedPayload = {
|
|
|
49
49
|
responseMessageId: string;
|
|
50
50
|
attempt: number;
|
|
51
51
|
model: string;
|
|
52
|
+
promptThroughIndex?: number;
|
|
52
53
|
};
|
|
53
54
|
type GenerationProgressPayload = {
|
|
54
55
|
requestId: string;
|
|
@@ -65,6 +66,7 @@ type GenerationCompletedPayload = {
|
|
|
65
66
|
responseMessageId: string;
|
|
66
67
|
finishReason?: FinishReason;
|
|
67
68
|
usage?: LanguageModelUsage;
|
|
69
|
+
inputTokenEstimate?: number;
|
|
68
70
|
};
|
|
69
71
|
type GenerationFailedPayload = {
|
|
70
72
|
requestId: string;
|
|
@@ -137,15 +139,38 @@ type InputRespondedPayload = {
|
|
|
137
139
|
name: string;
|
|
138
140
|
value: JSONValue;
|
|
139
141
|
};
|
|
142
|
+
type ModelLimits = {
|
|
143
|
+
contextWindow: number;
|
|
144
|
+
maxOutputTokens: number;
|
|
145
|
+
};
|
|
146
|
+
type ModelMetadataRequestedPayload = {
|
|
147
|
+
modelId: string;
|
|
148
|
+
};
|
|
149
|
+
type ModelMetadataResolvedPayload = {
|
|
150
|
+
modelId: string;
|
|
151
|
+
limits: ModelLimits | null;
|
|
152
|
+
};
|
|
153
|
+
type ModelMetadataState = {
|
|
154
|
+
status: "pending";
|
|
155
|
+
} | {
|
|
156
|
+
status: "resolved";
|
|
157
|
+
limits: ModelLimits;
|
|
158
|
+
} | {
|
|
159
|
+
status: "unavailable";
|
|
160
|
+
};
|
|
140
161
|
type CompactionRequestedPayload = {
|
|
141
162
|
generationId: string;
|
|
142
163
|
throughMessageId: string;
|
|
164
|
+
throughIndex?: number;
|
|
143
165
|
};
|
|
144
166
|
type CompactionCompletedPayload<M extends UIMessage> = {
|
|
145
167
|
generationId: string;
|
|
146
168
|
throughMessageId: string;
|
|
169
|
+
throughIndex?: number;
|
|
147
170
|
messages: M[];
|
|
148
171
|
retainedMessageIds?: string[];
|
|
172
|
+
summary?: string;
|
|
173
|
+
usage?: LanguageModelUsage;
|
|
149
174
|
};
|
|
150
175
|
type AIEventDefs<M extends UIMessage = UIMessage> = {
|
|
151
176
|
"ai.session.created": StandardSchemaV1<SessionCreatedPayload>;
|
|
@@ -167,6 +192,8 @@ type AIEventDefs<M extends UIMessage = UIMessage> = {
|
|
|
167
192
|
"ai.input.responded": StandardSchemaV1<InputRespondedPayload>;
|
|
168
193
|
"ai.compaction.requested": StandardSchemaV1<CompactionRequestedPayload>;
|
|
169
194
|
"ai.compaction.completed": StandardSchemaV1<CompactionCompletedPayload<M>>;
|
|
195
|
+
"ai.model.metadata.requested": StandardSchemaV1<ModelMetadataRequestedPayload>;
|
|
196
|
+
"ai.model.metadata.resolved": StandardSchemaV1<ModelMetadataResolvedPayload>;
|
|
170
197
|
};
|
|
171
198
|
type ActiveGeneration = GenerationStartedPayload;
|
|
172
199
|
type ActiveGenerationProjection<M extends UIMessage = UIMessage> = {
|
|
@@ -226,8 +253,11 @@ type CompactionState<M extends UIMessage> = {
|
|
|
226
253
|
status: "running" | "completed";
|
|
227
254
|
generationId: string;
|
|
228
255
|
throughMessageId: string;
|
|
256
|
+
throughIndex?: number;
|
|
229
257
|
messages?: M[];
|
|
230
258
|
retainedMessageIds?: string[];
|
|
259
|
+
summary?: string;
|
|
260
|
+
usage?: LanguageModelUsage;
|
|
231
261
|
};
|
|
232
262
|
type GenerationUsage = {
|
|
233
263
|
generationId: string;
|
|
@@ -251,6 +281,7 @@ type AIState<M extends UIMessage = UIMessage> = {
|
|
|
251
281
|
pendingInputs: PendingInput[];
|
|
252
282
|
tools: ToolActivity[];
|
|
253
283
|
compaction: CompactionState<M> | null;
|
|
284
|
+
modelMetadata: Record<string, ModelMetadataState>;
|
|
254
285
|
usage: GenerationUsage[];
|
|
255
286
|
error: string | null;
|
|
256
287
|
};
|
|
@@ -330,5 +361,5 @@ declare function handlerContext<D extends AgentToolEventDefs>(agentOrContract: C
|
|
|
330
361
|
*/
|
|
331
362
|
declare function agent<M extends UIMessage = UIMessage, E extends EventDefs = Record<never, never>>(options: AgentOptions<M, E>): AgentDefinition<M, AIEventDefs<M> & E>;
|
|
332
363
|
//#endregion
|
|
333
|
-
export { AIEventDefs, AIInputs, AIState, ActiveGeneration, ActiveGenerationProjection, AgentDefinition, AgentOptions, AgentStatus, AgentToolContext, AgentToolEventDefs, ApprovalRequestedPayload, ApprovalRespondedPayload, CompactionCompletedPayload, CompactionRequestedPayload, CompactionState, type FinishReason, GenerationCompletedPayload, GenerationFailedPayload, GenerationProgressPayload, GenerationReason, GenerationRequestedPayload, GenerationStartedPayload, GenerationUsage, InputRequestedPayload, InputRespondedPayload, type JSONValue, type LanguageModelUsage, MessageCompletedPayload, MessageCreatedPayload, MessageInterruptedPayload, PendingApproval, PendingInput, RetryGenerationOptions, RetryRequestedPayload, SessionClosedPayload, SessionCreatedPayload, ToolActivity, ToolCalledPayload, ToolResultPayload, type UIMessage, type UIMessageChunk, agent, createEvents, createReducer, deriveUIMessages, events, handlerContext, inputs, reduceAIState };
|
|
364
|
+
export { AIEventDefs, AIInputs, AIState, ActiveGeneration, ActiveGenerationProjection, AgentDefinition, AgentOptions, AgentStatus, AgentToolContext, AgentToolEventDefs, ApprovalRequestedPayload, ApprovalRespondedPayload, CompactionCompletedPayload, CompactionRequestedPayload, CompactionState, type FinishReason, GenerationCompletedPayload, GenerationFailedPayload, GenerationProgressPayload, GenerationReason, GenerationRequestedPayload, GenerationStartedPayload, GenerationUsage, InputRequestedPayload, InputRespondedPayload, type JSONValue, type LanguageModelUsage, MessageCompletedPayload, MessageCreatedPayload, MessageInterruptedPayload, ModelLimits, ModelMetadataRequestedPayload, ModelMetadataResolvedPayload, ModelMetadataState, PendingApproval, PendingInput, RetryGenerationOptions, RetryRequestedPayload, SessionClosedPayload, SessionCreatedPayload, ToolActivity, ToolCalledPayload, ToolResultPayload, type UIMessage, type UIMessageChunk, agent, createEvents, createReducer, deriveUIMessages, events, handlerContext, inputs, reduceAIState };
|
|
334
365
|
//# sourceMappingURL=ai.d.ts.map
|
package/dist/ai.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.d.ts","names":[],"sources":["../src/ai.ts"],"mappings":";;;;KAwBY;KAGA;KAEA;EAA0B,WAAW;;KACrC;EAAyB;;KACzB,sBAAsB,UAAU;EAC1C,SAAS;;EAET;;KAEU;EAA4B;;KACnC;EACH;EACA;;EAEA;;KAEU,4BAA4B;EAEhC;EAAsB;;EACtB;EAAmB;;KAEf;EACV;EACA,QAAQ;EACR;;KAEU;EACV;EACA;EACA;;KAEU,wBAAwB;KACxB;EACV;EACA;EACA;EACA;EACA;EACA;;KAEU;EACV;EACA;EACA;EACA;EACA;EACA,QAAQ;;KAEE;EACV;EACA;EACA;EACA;EACA,eAAe;EACf,QAAQ;;
|
|
1
|
+
{"version":3,"file":"ai.d.ts","names":[],"sources":["../src/ai.ts"],"mappings":"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"}
|
package/dist/ai.js
CHANGED
|
@@ -419,6 +419,7 @@ const jsonObject = (label, check) => schema(label, (value) => {
|
|
|
419
419
|
return { value };
|
|
420
420
|
});
|
|
421
421
|
const stringField = (value, key) => typeof value[key] === "string" && value[key].length > 0;
|
|
422
|
+
const optionalIndexField = (value, key) => value[key] === void 0 || typeof value[key] === "number" && Number.isSafeInteger(value[key]) && value[key] >= 0;
|
|
422
423
|
const optionalStringField = (value, key) => value[key] === void 0 || typeof value[key] === "string";
|
|
423
424
|
const messageValue = (value) => isRecord(value) && typeof value["id"] === "string" && (value["role"] === "user" || value["role"] === "assistant" || value["role"] === "system") && Array.isArray(value["parts"]) && value["parts"].every((part) => isRecord(part) && typeof part["type"] === "string") && isJSONCompatible(value);
|
|
424
425
|
const validateMessage = (value, messageSchema) => {
|
|
@@ -442,11 +443,11 @@ const progressPayloadSchema = schema("ai.generation.progress", (value) => {
|
|
|
442
443
|
return { value };
|
|
443
444
|
});
|
|
444
445
|
const completedPayloadSchema = schema("ai.generation.completed", (value) => {
|
|
445
|
-
if (!isRecord(value) || !isJSONCompatible(value) || !stringField(value, "requestId") || !stringField(value, "messageId") || !stringField(value, "generationId") || !stringField(value, "responseMessageId") || !optionalStringField(value, "finishReason")) return issue("invalid ai.generation.completed payload");
|
|
446
|
+
if (!isRecord(value) || !isJSONCompatible(value) || !stringField(value, "requestId") || !stringField(value, "messageId") || !stringField(value, "generationId") || !stringField(value, "responseMessageId") || !optionalIndexField(value, "inputTokenEstimate") || !optionalStringField(value, "finishReason")) return issue("invalid ai.generation.completed payload");
|
|
446
447
|
return { value };
|
|
447
448
|
});
|
|
448
449
|
const compactionPayloadSchema = (messageSchema) => schema("ai.compaction.completed", (value) => {
|
|
449
|
-
if (!isRecord(value) || !isJSONCompatible(value) || !stringField(value, "generationId") || !stringField(value, "throughMessageId") || !Array.isArray(value["messages"]) || value["retainedMessageIds"] !== void 0 && (!Array.isArray(value["retainedMessageIds"]) || !value["retainedMessageIds"].every((candidate) => typeof candidate === "string"))) return issue("invalid ai.compaction.completed payload");
|
|
450
|
+
if (!isRecord(value) || !isJSONCompatible(value) || !stringField(value, "generationId") || !stringField(value, "throughMessageId") || !optionalIndexField(value, "throughIndex") || !optionalStringField(value, "summary") || !Array.isArray(value["messages"]) || value["retainedMessageIds"] !== void 0 && (!Array.isArray(value["retainedMessageIds"]) || !value["retainedMessageIds"].every((candidate) => typeof candidate === "string"))) return issue("invalid ai.compaction.completed payload");
|
|
450
451
|
const messages = [];
|
|
451
452
|
for (const candidate of value["messages"]) {
|
|
452
453
|
const result = validateMessage(candidate, messageSchema);
|
|
@@ -456,7 +457,10 @@ const compactionPayloadSchema = (messageSchema) => schema("ai.compaction.complet
|
|
|
456
457
|
return { value: {
|
|
457
458
|
generationId: value["generationId"],
|
|
458
459
|
throughMessageId: value["throughMessageId"],
|
|
460
|
+
...value["throughIndex"] === void 0 ? {} : { throughIndex: value["throughIndex"] },
|
|
459
461
|
messages,
|
|
462
|
+
...value["summary"] === void 0 ? {} : { summary: value["summary"] },
|
|
463
|
+
...value["usage"] === void 0 ? {} : { usage: value["usage"] },
|
|
460
464
|
...value["retainedMessageIds"] === void 0 ? {} : { retainedMessageIds: value["retainedMessageIds"] }
|
|
461
465
|
} };
|
|
462
466
|
});
|
|
@@ -471,7 +475,7 @@ function createEvents(options) {
|
|
|
471
475
|
"ai.message.interrupted": jsonObject("ai.message.interrupted", (value) => stringField(value, "messageId") && (stringField(value, "generationId") && value["requestId"] === void 0 || stringField(value, "requestId") && value["generationId"] === void 0) && optionalStringField(value, "reason") && (value["lastSeenIndex"] === void 0 || typeof value["lastSeenIndex"] === "number" && Number.isInteger(value["lastSeenIndex"]) && value["lastSeenIndex"] >= 0)),
|
|
472
476
|
"ai.generation.requested": jsonObject("ai.generation.requested", (value) => stringField(value, "messageId") && optionalStringField(value, "responseMessageId") && (value["reason"] === "message" || value["reason"] === "tool" || value["reason"] === "input" || value["reason"] === "retry")),
|
|
473
477
|
"ai.retry.requested": jsonObject("ai.retry.requested", (value) => stringField(value, "messageId") && stringField(value, "responseMessageId") && stringField(value, "retryId")),
|
|
474
|
-
"ai.generation.started": jsonObject("ai.generation.started", (value) => stringField(value, "requestId") && stringField(value, "messageId") && stringField(value, "generationId") && stringField(value, "responseMessageId") && typeof value["attempt"] === "number" && Number.isInteger(value["attempt"]) && value["attempt"] > 0 && stringField(value, "model")),
|
|
478
|
+
"ai.generation.started": jsonObject("ai.generation.started", (value) => stringField(value, "requestId") && stringField(value, "messageId") && stringField(value, "generationId") && stringField(value, "responseMessageId") && typeof value["attempt"] === "number" && Number.isInteger(value["attempt"]) && value["attempt"] > 0 && stringField(value, "model") && optionalIndexField(value, "promptThroughIndex")),
|
|
475
479
|
"ai.generation.progress": progressPayloadSchema,
|
|
476
480
|
"ai.generation.completed": completedPayloadSchema,
|
|
477
481
|
"ai.generation.failed": jsonObject("ai.generation.failed", (value) => stringField(value, "requestId") && stringField(value, "messageId") && stringField(value, "generationId") && stringField(value, "responseMessageId") && stringField(value, "error") && (value["superseded"] === void 0 || typeof value["superseded"] === "boolean") && (value["stepLimit"] === void 0 || typeof value["stepLimit"] === "boolean")),
|
|
@@ -481,8 +485,10 @@ function createEvents(options) {
|
|
|
481
485
|
"ai.approval.responded": jsonObject("ai.approval.responded", (value) => stringField(value, "messageId") && stringField(value, "generationId") && stringField(value, "approvalId") && typeof value["approved"] === "boolean" && optionalStringField(value, "reason")),
|
|
482
486
|
"ai.input.requested": jsonObject("ai.input.requested", (value) => stringField(value, "messageId") && stringField(value, "generationId") && stringField(value, "inputId") && stringField(value, "name")),
|
|
483
487
|
"ai.input.responded": jsonObject("ai.input.responded", (value) => stringField(value, "messageId") && stringField(value, "generationId") && stringField(value, "inputId") && stringField(value, "name")),
|
|
484
|
-
"ai.compaction.requested": jsonObject("ai.compaction.requested", (value) => stringField(value, "generationId") && stringField(value, "throughMessageId")),
|
|
485
|
-
"ai.compaction.completed": compactionPayloadSchema(messageSchema)
|
|
488
|
+
"ai.compaction.requested": jsonObject("ai.compaction.requested", (value) => stringField(value, "generationId") && stringField(value, "throughMessageId") && optionalIndexField(value, "throughIndex")),
|
|
489
|
+
"ai.compaction.completed": compactionPayloadSchema(messageSchema),
|
|
490
|
+
"ai.model.metadata.requested": jsonObject("ai.model.metadata.requested", (value) => stringField(value, "modelId")),
|
|
491
|
+
"ai.model.metadata.resolved": jsonObject("ai.model.metadata.resolved", (value) => stringField(value, "modelId") && (value["limits"] === null || isRecord(value["limits"]) && typeof value["limits"]["contextWindow"] === "number" && Number.isSafeInteger(value["limits"]["contextWindow"]) && value["limits"]["contextWindow"] > 0 && typeof value["limits"]["maxOutputTokens"] === "number" && Number.isSafeInteger(value["limits"]["maxOutputTokens"]) && value["limits"]["maxOutputTokens"] > 0))
|
|
486
492
|
};
|
|
487
493
|
}
|
|
488
494
|
const events = createEvents();
|
|
@@ -499,6 +505,7 @@ const initialState = () => ({
|
|
|
499
505
|
pendingInputs: [],
|
|
500
506
|
tools: [],
|
|
501
507
|
compaction: null,
|
|
508
|
+
modelMetadata: {},
|
|
502
509
|
usage: [],
|
|
503
510
|
error: null
|
|
504
511
|
});
|
|
@@ -707,6 +714,30 @@ const terminalGenerationReason = (state, generationId) => {
|
|
|
707
714
|
function reduceAIState(state, event) {
|
|
708
715
|
if (state.status === "closed") return state;
|
|
709
716
|
switch (event.type) {
|
|
717
|
+
case "ai.model.metadata.requested": {
|
|
718
|
+
const { modelId } = event.payload;
|
|
719
|
+
if (Object.hasOwn(state.modelMetadata, modelId)) return state;
|
|
720
|
+
return {
|
|
721
|
+
...state,
|
|
722
|
+
modelMetadata: {
|
|
723
|
+
...state.modelMetadata,
|
|
724
|
+
[modelId]: { status: "pending" }
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
case "ai.model.metadata.resolved": {
|
|
729
|
+
const { modelId, limits } = event.payload;
|
|
730
|
+
return {
|
|
731
|
+
...state,
|
|
732
|
+
modelMetadata: {
|
|
733
|
+
...state.modelMetadata,
|
|
734
|
+
[modelId]: limits === null ? { status: "unavailable" } : {
|
|
735
|
+
status: "resolved",
|
|
736
|
+
limits
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
}
|
|
710
741
|
case "ai.session.created": {
|
|
711
742
|
const payload = event.payload;
|
|
712
743
|
return {
|
|
@@ -720,6 +751,7 @@ function reduceAIState(state, event) {
|
|
|
720
751
|
case "ai.session.closed": return {
|
|
721
752
|
...state,
|
|
722
753
|
status: "closed",
|
|
754
|
+
compaction: state.compaction?.status === "running" ? state.activeProjection?.baseCompaction ?? null : state.compaction,
|
|
723
755
|
activeGeneration: null,
|
|
724
756
|
activeRequestId: null,
|
|
725
757
|
activeResponseMessageId: null,
|
|
@@ -1147,7 +1179,7 @@ function deriveUIMessages(history) {
|
|
|
1147
1179
|
/** Build the standard AI state projection for any contract containing the protocol. */
|
|
1148
1180
|
function createReducer(options) {
|
|
1149
1181
|
return options.contract.reducer({
|
|
1150
|
-
name: options.name ?? "a2.ai.state.
|
|
1182
|
+
name: options.name ?? "a2.ai.state.v10",
|
|
1151
1183
|
initialState: initialState()
|
|
1152
1184
|
}).fold((state, event) => reduceAIState(state, event));
|
|
1153
1185
|
}
|
|
@@ -1236,7 +1268,7 @@ function agent(options) {
|
|
|
1236
1268
|
return {
|
|
1237
1269
|
contract: agentContract,
|
|
1238
1270
|
reducer: agentContract.reducer({
|
|
1239
|
-
name: options.reducerName ?? "a2.ai.state.
|
|
1271
|
+
name: options.reducerName ?? "a2.ai.state.v10",
|
|
1240
1272
|
initialState: initialState()
|
|
1241
1273
|
}).fold((state, event) => reduceAIState(state, event))
|
|
1242
1274
|
};
|