stitchkit 0.56.4 → 0.57.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/dist/agent-runtime/events.d.ts +730 -0
- package/dist/agent-runtime/events.d.ts.map +1 -1
- package/dist/agent-runtime/runtime.d.ts +34 -3
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/schemas.d.ts +73 -0
- package/dist/agent-runtime/schemas.d.ts.map +1 -1
- package/dist/agent-runtime/store-driver.d.ts +406 -0
- package/dist/agent-runtime/store-driver.d.ts.map +1 -0
- package/dist/agent-runtime/store.d.ts +162 -2
- package/dist/agent-runtime/store.d.ts.map +1 -1
- package/dist/agent-runtime.d.ts +4 -3
- package/dist/agent-runtime.d.ts.map +1 -1
- package/dist/agent-runtime.js +851 -445
- package/dist/index-1f4fcj0b.js +160 -0
- package/dist/server/error-hook.d.ts +8 -1
- package/dist/server/error-hook.d.ts.map +1 -1
- package/dist/server/index.js +4 -2
- package/dist/testing/agent-store-conformance.d.ts +7 -0
- package/dist/testing/agent-store-conformance.d.ts.map +1 -0
- package/dist/testing.d.ts +1 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +166 -0
- package/llms-full.txt +102 -23
- package/package.json +1 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// src/agent-runtime/schemas.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var AgentRecordIdSchema = z.string().min(1);
|
|
4
|
+
var AgentRecordVersionSchema = z.int().nonnegative();
|
|
5
|
+
var AgentTimestampSchema = z.iso.datetime({ offset: true });
|
|
6
|
+
var AgentJsonObjectSchema = z.record(z.string(), z.json());
|
|
7
|
+
var AgentProviderEnvelopeSchema = z.object({
|
|
8
|
+
schemaVersion: z.int().positive(),
|
|
9
|
+
provider: z.string().min(1),
|
|
10
|
+
data: AgentJsonObjectSchema
|
|
11
|
+
});
|
|
12
|
+
var AgentTextPartSchema = z.object({
|
|
13
|
+
type: z.literal("text"),
|
|
14
|
+
text: z.string()
|
|
15
|
+
});
|
|
16
|
+
var AgentReasoningPartSchema = z.object({
|
|
17
|
+
type: z.literal("reasoning"),
|
|
18
|
+
text: z.string(),
|
|
19
|
+
provider: AgentProviderEnvelopeSchema.optional()
|
|
20
|
+
});
|
|
21
|
+
var AgentFilePartSchema = z.object({
|
|
22
|
+
type: z.literal("file"),
|
|
23
|
+
mediaType: z.string().min(1),
|
|
24
|
+
reference: z.string().min(1),
|
|
25
|
+
filename: z.string().min(1).optional()
|
|
26
|
+
});
|
|
27
|
+
var AgentSourcePartSchema = z.object({
|
|
28
|
+
type: z.literal("source"),
|
|
29
|
+
sourceId: z.string().min(1),
|
|
30
|
+
url: z.url().optional(),
|
|
31
|
+
title: z.string().optional()
|
|
32
|
+
});
|
|
33
|
+
var AgentToolCallPartSchema = z.object({
|
|
34
|
+
type: z.literal("tool-call"),
|
|
35
|
+
callId: z.string().min(1),
|
|
36
|
+
toolName: z.string().min(1),
|
|
37
|
+
input: z.json(),
|
|
38
|
+
provider: AgentProviderEnvelopeSchema.optional()
|
|
39
|
+
});
|
|
40
|
+
var AgentToolResultPartSchema = z.object({
|
|
41
|
+
type: z.literal("tool-result"),
|
|
42
|
+
callId: z.string().min(1),
|
|
43
|
+
toolName: z.string().min(1),
|
|
44
|
+
outcome: z.enum(["success", "error", "interrupted"]),
|
|
45
|
+
output: z.json().optional()
|
|
46
|
+
});
|
|
47
|
+
var AgentOpaquePartSchema = z.object({
|
|
48
|
+
type: z.literal("provider"),
|
|
49
|
+
envelope: AgentProviderEnvelopeSchema
|
|
50
|
+
});
|
|
51
|
+
var AgentControlPartSchema = z.object({
|
|
52
|
+
type: z.literal("control"),
|
|
53
|
+
reason: z.enum(["run-interrupted", "stale-run"])
|
|
54
|
+
});
|
|
55
|
+
var AgentMessagePartSchema = z.discriminatedUnion("type", [
|
|
56
|
+
AgentTextPartSchema,
|
|
57
|
+
AgentReasoningPartSchema,
|
|
58
|
+
AgentFilePartSchema,
|
|
59
|
+
AgentSourcePartSchema,
|
|
60
|
+
AgentToolCallPartSchema,
|
|
61
|
+
AgentToolResultPartSchema,
|
|
62
|
+
AgentOpaquePartSchema,
|
|
63
|
+
AgentControlPartSchema
|
|
64
|
+
]);
|
|
65
|
+
var AgentMessageRoleSchema = z.enum(["user", "assistant", "system", "summary"]);
|
|
66
|
+
var AgentMessageStatusSchema = z.enum([
|
|
67
|
+
"committed",
|
|
68
|
+
"streaming",
|
|
69
|
+
"completed",
|
|
70
|
+
"interrupted",
|
|
71
|
+
"failed"
|
|
72
|
+
]);
|
|
73
|
+
var AgentMessageSchema = z.object({
|
|
74
|
+
schemaVersion: z.literal(1),
|
|
75
|
+
id: AgentRecordIdSchema,
|
|
76
|
+
conversationId: AgentRecordIdSchema,
|
|
77
|
+
runId: AgentRecordIdSchema.optional(),
|
|
78
|
+
role: AgentMessageRoleSchema,
|
|
79
|
+
status: AgentMessageStatusSchema,
|
|
80
|
+
parts: z.array(AgentMessagePartSchema),
|
|
81
|
+
metadata: AgentJsonObjectSchema.optional(),
|
|
82
|
+
createdAt: AgentTimestampSchema,
|
|
83
|
+
updatedAt: AgentTimestampSchema
|
|
84
|
+
});
|
|
85
|
+
var AgentAssistantPlaceholderSchema = z.object({
|
|
86
|
+
schemaVersion: z.literal(1),
|
|
87
|
+
id: AgentRecordIdSchema,
|
|
88
|
+
conversationId: AgentRecordIdSchema,
|
|
89
|
+
runId: AgentRecordIdSchema,
|
|
90
|
+
status: z.literal("pending"),
|
|
91
|
+
createdAt: AgentTimestampSchema,
|
|
92
|
+
updatedAt: AgentTimestampSchema
|
|
93
|
+
});
|
|
94
|
+
var AgentRunStateSchema = z.enum([
|
|
95
|
+
"queued",
|
|
96
|
+
"running",
|
|
97
|
+
"interrupt_requested",
|
|
98
|
+
"completed",
|
|
99
|
+
"interrupted",
|
|
100
|
+
"failed",
|
|
101
|
+
"cancelled",
|
|
102
|
+
"abandoned"
|
|
103
|
+
]);
|
|
104
|
+
var AgentTerminalReasonSchema = z.enum([
|
|
105
|
+
"success",
|
|
106
|
+
"policy_stop",
|
|
107
|
+
"interrupted",
|
|
108
|
+
"cancelled",
|
|
109
|
+
"timeout",
|
|
110
|
+
"shutdown",
|
|
111
|
+
"provider_failure",
|
|
112
|
+
"tool_failure",
|
|
113
|
+
"abandoned"
|
|
114
|
+
]);
|
|
115
|
+
var AgentRunSchema = z.object({
|
|
116
|
+
schemaVersion: z.literal(1),
|
|
117
|
+
id: AgentRecordIdSchema,
|
|
118
|
+
conversationId: AgentRecordIdSchema,
|
|
119
|
+
inputMessageIds: z.array(AgentRecordIdSchema).min(1),
|
|
120
|
+
assistantMessageId: AgentRecordIdSchema,
|
|
121
|
+
state: AgentRunStateSchema,
|
|
122
|
+
revision: AgentRecordVersionSchema,
|
|
123
|
+
ownerId: z.string().min(1).optional(),
|
|
124
|
+
terminalReason: AgentTerminalReasonSchema.optional(),
|
|
125
|
+
terminalPolicyName: z.string().min(1).optional(),
|
|
126
|
+
createdAt: AgentTimestampSchema,
|
|
127
|
+
updatedAt: AgentTimestampSchema
|
|
128
|
+
});
|
|
129
|
+
var AgentSnapshotSchema = z.object({
|
|
130
|
+
schemaVersion: z.literal(1),
|
|
131
|
+
conversationId: AgentRecordIdSchema,
|
|
132
|
+
version: AgentRecordVersionSchema,
|
|
133
|
+
messages: z.array(AgentMessageSchema),
|
|
134
|
+
runs: z.array(AgentRunSchema)
|
|
135
|
+
});
|
|
136
|
+
var AgentUsageValueSchema = z.object({
|
|
137
|
+
value: z.number().nonnegative().optional(),
|
|
138
|
+
provenance: z.enum(["provider-reported", "computed", "estimated", "unavailable"])
|
|
139
|
+
});
|
|
140
|
+
var AgentCostValueSchema = z.object({
|
|
141
|
+
value: z.number().nonnegative().optional(),
|
|
142
|
+
currency: z.string().length(3).optional(),
|
|
143
|
+
provenance: z.enum(["provider-reported", "computed", "estimated", "unavailable"])
|
|
144
|
+
});
|
|
145
|
+
var AgentUsageSchema = z.object({
|
|
146
|
+
inputTokens: AgentUsageValueSchema,
|
|
147
|
+
outputTokens: AgentUsageValueSchema,
|
|
148
|
+
reasoningTokens: AgentUsageValueSchema.optional(),
|
|
149
|
+
cacheReadTokens: AgentUsageValueSchema.optional(),
|
|
150
|
+
cacheWriteTokens: AgentUsageValueSchema.optional(),
|
|
151
|
+
cost: AgentCostValueSchema.optional()
|
|
152
|
+
});
|
|
153
|
+
var AgentRunMetricsSchema = z.object({
|
|
154
|
+
partial: z.boolean(),
|
|
155
|
+
usage: AgentUsageSchema.optional(),
|
|
156
|
+
durationMs: z.number().nonnegative().optional(),
|
|
157
|
+
ttftMs: z.number().nonnegative().optional()
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
export { AgentRecordIdSchema, AgentRecordVersionSchema, AgentTimestampSchema, AgentJsonObjectSchema, AgentProviderEnvelopeSchema, AgentTextPartSchema, AgentReasoningPartSchema, AgentFilePartSchema, AgentSourcePartSchema, AgentToolCallPartSchema, AgentToolResultPartSchema, AgentOpaquePartSchema, AgentControlPartSchema, AgentMessagePartSchema, AgentMessageRoleSchema, AgentMessageStatusSchema, AgentMessageSchema, AgentAssistantPlaceholderSchema, AgentRunStateSchema, AgentTerminalReasonSchema, AgentRunSchema, AgentSnapshotSchema, AgentUsageValueSchema, AgentCostValueSchema, AgentUsageSchema, AgentRunMetricsSchema };
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* Every project writes the same `onError`: turn a thrown value into one wire
|
|
6
6
|
* shape, mapping stitchkit's own error codes to the app's public codes. The map
|
|
7
7
|
* is partial — list the codes you have an opinion about, and an unlisted one
|
|
8
|
-
* travels as itself
|
|
8
|
+
* travels as itself unless `unmappedCode` supplies one declarative fallback.
|
|
9
|
+
* Codes the project throws on its own always pass through unchanged. A
|
|
9
10
|
* project whose envelope is a published contract adds `satisfies
|
|
10
11
|
* Record<StitchErrorCode, …>` to its own map and buys the stricter deal: a code
|
|
11
12
|
* added by a later release then breaks the build instead of reaching the wire
|
|
@@ -58,6 +59,12 @@ export interface ErrorHookConfig<TWireCode extends string = string> {
|
|
|
58
59
|
* error here. Codes you threw yourself (not stitchkit's) pass through as-is.
|
|
59
60
|
*/
|
|
60
61
|
codeMap?: Partial<Record<StitchErrorCode, TWireCode>>;
|
|
62
|
+
/**
|
|
63
|
+
* Wire code for every unmapped stitchkit code, or a resolver for grouping
|
|
64
|
+
* them. Explicit `codeMap` entries win. Project-owned codes never use this
|
|
65
|
+
* fallback and continue to pass through unchanged.
|
|
66
|
+
*/
|
|
67
|
+
unmappedCode?: TWireCode | ((code: StitchErrorCode) => TWireCode);
|
|
61
68
|
/** Build the response body from the resolved error. */
|
|
62
69
|
/**
|
|
63
70
|
* Build the response body from the resolved error. `ctx` is the request's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-hook.d.ts","sourceRoot":"","sources":["../../src/server/error-hook.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"error-hook.d.ts","sourceRoot":"","sources":["../../src/server/error-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzD,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,+FAA+F;IAC/F,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM;IAChE;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC;IACtD;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE,eAAe,KAAK,SAAS,CAAC,CAAC;IAClE,uDAAuD;IACvD;;;;;OAKG;IACH,MAAM,EAAE,CACN,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,cAAc,EACnB,QAAQ,CAAC,EAAE,SAAS,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,cAAc,EACnB,QAAQ,CAAC,EAAE,SAAS,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AAED,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,EAC/D,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,GACjC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAkCxC"}
|
package/dist/server/index.js
CHANGED
|
@@ -351,8 +351,10 @@ function cacheHeaders(maxAge, scope = "public") {
|
|
|
351
351
|
function createErrorHook(config) {
|
|
352
352
|
return async (ctx, error, endpoint) => {
|
|
353
353
|
const appErr = normalizeError(error);
|
|
354
|
-
const
|
|
355
|
-
const
|
|
354
|
+
const stitchCode = isStitchErrorCode(appErr.code) ? appErr.code : undefined;
|
|
355
|
+
const mapped = stitchCode === undefined ? undefined : config.codeMap?.[stitchCode];
|
|
356
|
+
const fallback = mapped === undefined && stitchCode !== undefined ? typeof config.unmappedCode === "function" ? config.unmappedCode(stitchCode) : config.unmappedCode : undefined;
|
|
357
|
+
const code = mapped ?? fallback ?? appErr.code;
|
|
356
358
|
const info = {
|
|
357
359
|
code,
|
|
358
360
|
status: appErr.status,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentRuntimeStore } from '../agent-runtime/store';
|
|
2
|
+
export interface AgentStoreConformanceConfig {
|
|
3
|
+
createStore(): AgentRuntimeStore | Promise<AgentRuntimeStore>;
|
|
4
|
+
}
|
|
5
|
+
/** Black-box contract shared by memory and third-party durable agent stores. */
|
|
6
|
+
export declare function runAgentStoreConformance(config: AgentStoreConformanceConfig): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=agent-store-conformance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-store-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/agent-store-conformance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,2BAA2B;IAC1C,WAAW,IAAI,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/D;AAwCD,gFAAgF;AAChF,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,IAAI,CAAC,CAuJf"}
|
package/dist/testing.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare function createHandlerTestClient<T extends Record<string, Endpoin
|
|
|
31
31
|
export declare function createHandlerTestClients<T extends Record<string, ContractDef<Record<string, EndpointDef>, string>>, TServer = unknown, const K extends string = never>(config: HandlerTestClientsConfig<T, TServer, K>): {
|
|
32
32
|
[P in keyof T]: ScopedHttpClient<T[P]['endpoints'], ScopedKeys<K>>;
|
|
33
33
|
};
|
|
34
|
+
export { type AgentStoreConformanceConfig, runAgentStoreConformance, } from './testing/agent-store-conformance';
|
|
34
35
|
export { assertSurfaceDiscovery, type ConformanceTransport, type CreateRealtimeProbeDriverConfig, createRealtimeProbeDriver, type DefineRealtimeProbeConfig, defineRealtimeProbe, type RealtimeDisconnectObservation, RealtimeDisconnectObservationSchema, type RealtimeProbeAdapter, type RealtimeProbeFixture, type RealtimeProbeScenario, type RealtimeRejectionObservation, RealtimeRejectionObservationSchema, type RunSurfaceProbesConfig, runSurfaceProbes, type SurfaceDiscoveryObservation, type SurfaceProbe, type SurfaceProbeDriver, type SurfaceRealtimeDiscoveryObservation, type SurfaceToolDiscoveryObservation, type TransportObservation, TransportObservationSchema, } from './testing/surface-conformance';
|
|
35
36
|
export { assertSurfaceManifestSnapshot, buildSurfaceManifest, type IncompatibleSchemaPolicy, type McpSchemaValidationConfig, type SurfaceAgentProjection, type SurfaceManifest, type SurfaceManifestConfig, type SurfaceManifestExtension, SurfaceManifestExtensionSchema, type SurfaceManifestOperation, SurfaceManifestOperationSchema, type SurfaceManifestRealtimeEvent, SurfaceManifestRealtimeEventSchema, SurfaceManifestSchema, type SurfaceManifestTool, SurfaceManifestToolSchema, type SurfaceManifestToolSurface, SurfaceManifestToolSurfaceSchema, type SurfaceMcpPreparation, SurfaceRealtimeSchemaPairSchema, type SurfaceRuntimeToolDefinition, SurfaceSchemaDigestsSchema, type SurfaceToolDefinition, type SurfaceToolExtension, serializeSurfaceValue, } from './testing/surface-manifest';
|
|
36
37
|
//# sourceMappingURL=testing.d.ts.map
|
package/dist/testing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,oBAAoB,EAGzB,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;AAEhF,MAAM,WAAW,0BAA0B,CAAC,OAAO;IACjD,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC/B,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,OAAO,GAAG,OAAO,EACjB,CAAC,SAAS,MAAM,GAAG,KAAK,CACxB,SAAQ,0BAA0B,CAAC,OAAO,CAAC;IAC3C,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,wBAAwB,CACvC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,EAC1E,OAAO,GAAG,OAAO,EACjB,CAAC,SAAS,MAAM,GAAG,KAAK,CACxB,SAAQ,0BAA0B,CAAC,OAAO,CAAC;IAC3C,SAAS,EAAE,CAAC,CAAC;IACb,cAAc,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;CAC1C;AA+BD,gGAAgG;AAChG,wBAAgB,uBAAuB,CACrC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,OAAO,GAAG,OAAO,EACjB,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAC9B,MAAM,EAAE,uBAAuB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAEpF;AAED,2FAA2F;AAC3F,wBAAgB,wBAAwB,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,EAC1E,OAAO,GAAG,OAAO,EACjB,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAE9B,MAAM,EAAE,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAC9C;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CAAE,CAMxE;AAED,OAAO,EACL,KAAK,2BAA2B,EAChC,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,+BAA+B,EACpC,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,mBAAmB,EACnB,KAAK,6BAA6B,EAClC,mCAAmC,EACnC,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,kCAAkC,EAClC,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,KAAK,2BAA2B,EAChC,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,mCAAmC,EACxC,KAAK,+BAA+B,EACpC,KAAK,oBAAoB,EACzB,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,8BAA8B,EAC9B,KAAK,4BAA4B,EACjC,kCAAkC,EAClC,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,gCAAgC,EAChC,KAAK,qBAAqB,EAC1B,+BAA+B,EAC/B,KAAK,4BAA4B,EACjC,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC"}
|
package/dist/testing.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentMessageSchema,
|
|
3
|
+
AgentRunSchema
|
|
4
|
+
} from "./index-1f4fcj0b.js";
|
|
1
5
|
import {
|
|
2
6
|
RealtimeRequestDisconnectedError,
|
|
3
7
|
RealtimeRequestInvalidAcknowledgementError,
|
|
@@ -23,6 +27,167 @@ import {
|
|
|
23
27
|
} from "./index-smpbdg6k.js";
|
|
24
28
|
import"./index-1bx83sw4.js";
|
|
25
29
|
|
|
30
|
+
// src/testing/agent-store-conformance.ts
|
|
31
|
+
function userMessage(conversationId, id) {
|
|
32
|
+
return AgentMessageSchema.parse({
|
|
33
|
+
schemaVersion: 1,
|
|
34
|
+
id,
|
|
35
|
+
conversationId,
|
|
36
|
+
role: "user",
|
|
37
|
+
status: "committed",
|
|
38
|
+
parts: [{ type: "text", text: id }],
|
|
39
|
+
createdAt: "2026-08-22T00:00:00.000Z",
|
|
40
|
+
updatedAt: "2026-08-22T00:00:00.000Z"
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function queuedRun(conversationId, inputMessageId, id) {
|
|
44
|
+
return AgentRunSchema.parse({
|
|
45
|
+
schemaVersion: 1,
|
|
46
|
+
id,
|
|
47
|
+
conversationId,
|
|
48
|
+
inputMessageIds: [inputMessageId],
|
|
49
|
+
assistantMessageId: `${id}-assistant`,
|
|
50
|
+
state: "queued",
|
|
51
|
+
revision: 0,
|
|
52
|
+
createdAt: "2026-08-22T00:00:00.000Z",
|
|
53
|
+
updatedAt: "2026-08-22T00:00:00.000Z"
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function requireOutcome(actual, expected) {
|
|
57
|
+
if (actual.outcome !== expected) {
|
|
58
|
+
throw new Error(`Agent store conformance expected ${expected}, received ${actual.outcome}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function runAgentStoreConformance(config) {
|
|
62
|
+
const store = await config.createStore();
|
|
63
|
+
const conversationId = `conformance-${crypto.randomUUID()}`;
|
|
64
|
+
const firstInput = userMessage(conversationId, "input-1");
|
|
65
|
+
const firstRun = queuedRun(conversationId, firstInput.id, "run-1");
|
|
66
|
+
const accepted = await store.acceptInputAndAssignRun({
|
|
67
|
+
idempotencyKey: "request-1",
|
|
68
|
+
input: firstInput,
|
|
69
|
+
run: firstRun
|
|
70
|
+
});
|
|
71
|
+
requireOutcome(accepted, "applied");
|
|
72
|
+
const duplicate = await store.acceptInputAndAssignRun({
|
|
73
|
+
idempotencyKey: "request-1",
|
|
74
|
+
input: userMessage(conversationId, "discarded-input"),
|
|
75
|
+
run: queuedRun(conversationId, "discarded-input", "discarded-run")
|
|
76
|
+
});
|
|
77
|
+
requireOutcome(duplicate, "duplicate");
|
|
78
|
+
if (duplicate.input.id !== firstInput.id || duplicate.inputMessageId !== firstInput.id || duplicate.runId !== firstRun.id || duplicate.assistantMessageId !== firstRun.assistantMessageId) {
|
|
79
|
+
throw new Error("Duplicate admission did not return its original durable identity");
|
|
80
|
+
}
|
|
81
|
+
const secondInput = userMessage(conversationId, "input-2");
|
|
82
|
+
const coalesced = await store.acceptInputAndAssignRun({
|
|
83
|
+
idempotencyKey: "request-2",
|
|
84
|
+
input: secondInput,
|
|
85
|
+
run: queuedRun(conversationId, secondInput.id, "discarded-coalesced-run"),
|
|
86
|
+
coalesceIntoRunId: firstRun.id
|
|
87
|
+
});
|
|
88
|
+
requireOutcome(coalesced, "applied");
|
|
89
|
+
const assigned = coalesced.snapshot.runs.find((run) => run.id === firstRun.id);
|
|
90
|
+
if (assigned?.inputMessageIds.join(",") !== "input-1,input-2") {
|
|
91
|
+
throw new Error("Coalesced admission did not preserve ordered input identities");
|
|
92
|
+
}
|
|
93
|
+
const collidingInput = userMessage(conversationId, assigned.assistantMessageId);
|
|
94
|
+
await store.acceptInputAndAssignRun({
|
|
95
|
+
idempotencyKey: "request-collision",
|
|
96
|
+
input: collidingInput,
|
|
97
|
+
run: queuedRun(conversationId, collidingInput.id, "discarded-collision-run"),
|
|
98
|
+
coalesceIntoRunId: assigned.id
|
|
99
|
+
}).then(() => {
|
|
100
|
+
throw new Error("Coalesced input reused the reserved assistant identity");
|
|
101
|
+
}, (error) => {
|
|
102
|
+
if (!(error instanceof TypeError))
|
|
103
|
+
throw error;
|
|
104
|
+
});
|
|
105
|
+
await store.replaceCompactedRange({
|
|
106
|
+
conversationId,
|
|
107
|
+
expectedVersion: coalesced.snapshot.version,
|
|
108
|
+
replacedMessageIds: [firstInput.id, secondInput.id],
|
|
109
|
+
summary: AgentMessageSchema.parse({
|
|
110
|
+
schemaVersion: 1,
|
|
111
|
+
id: assigned.assistantMessageId,
|
|
112
|
+
conversationId,
|
|
113
|
+
role: "summary",
|
|
114
|
+
status: "committed",
|
|
115
|
+
parts: [{ type: "text", text: "invalid reserved identity" }],
|
|
116
|
+
createdAt: "2026-08-22T00:00:02.000Z",
|
|
117
|
+
updatedAt: "2026-08-22T00:00:02.000Z"
|
|
118
|
+
})
|
|
119
|
+
}).then(() => {
|
|
120
|
+
throw new Error("Compaction reused a reserved assistant identity");
|
|
121
|
+
}, (error) => {
|
|
122
|
+
if (!(error instanceof TypeError))
|
|
123
|
+
throw error;
|
|
124
|
+
});
|
|
125
|
+
const compacted = await store.replaceCompactedRange({
|
|
126
|
+
conversationId,
|
|
127
|
+
expectedVersion: coalesced.snapshot.version,
|
|
128
|
+
replacedMessageIds: [firstInput.id, secondInput.id],
|
|
129
|
+
summary: AgentMessageSchema.parse({
|
|
130
|
+
schemaVersion: 1,
|
|
131
|
+
id: "summary-1",
|
|
132
|
+
conversationId,
|
|
133
|
+
role: "summary",
|
|
134
|
+
status: "committed",
|
|
135
|
+
parts: [{ type: "text", text: "two inputs" }],
|
|
136
|
+
createdAt: "2026-08-22T00:00:02.000Z",
|
|
137
|
+
updatedAt: "2026-08-22T00:00:02.000Z"
|
|
138
|
+
})
|
|
139
|
+
});
|
|
140
|
+
requireOutcome(compacted, "applied");
|
|
141
|
+
const duplicateAfterCompaction = await store.acceptInputAndAssignRun({
|
|
142
|
+
idempotencyKey: "request-1",
|
|
143
|
+
input: userMessage(conversationId, "discarded-after-compaction"),
|
|
144
|
+
run: queuedRun(conversationId, "discarded-after-compaction", "discarded-run-2")
|
|
145
|
+
});
|
|
146
|
+
requireOutcome(duplicateAfterCompaction, "duplicate");
|
|
147
|
+
if (duplicateAfterCompaction.input.id !== firstInput.id) {
|
|
148
|
+
throw new Error("Compaction discarded the canonical duplicate admission input");
|
|
149
|
+
}
|
|
150
|
+
const acquired = await store.acquireRun({
|
|
151
|
+
conversationId,
|
|
152
|
+
runId: assigned.id,
|
|
153
|
+
expectedRevision: assigned.revision,
|
|
154
|
+
ownerId: "conformance-owner"
|
|
155
|
+
});
|
|
156
|
+
requireOutcome(acquired, "applied");
|
|
157
|
+
const running = acquired.snapshot.runs.find((run) => run.id === assigned.id);
|
|
158
|
+
if (!running)
|
|
159
|
+
throw new Error("Acquired run disappeared");
|
|
160
|
+
const stale = await store.checkpointRunAssistant({
|
|
161
|
+
conversationId,
|
|
162
|
+
runId: running.id,
|
|
163
|
+
expectedRevision: running.revision - 1,
|
|
164
|
+
ownerId: "conformance-owner",
|
|
165
|
+
assistant: AgentMessageSchema.parse({
|
|
166
|
+
schemaVersion: 1,
|
|
167
|
+
id: running.assistantMessageId,
|
|
168
|
+
conversationId,
|
|
169
|
+
runId: running.id,
|
|
170
|
+
role: "assistant",
|
|
171
|
+
status: "streaming",
|
|
172
|
+
parts: [],
|
|
173
|
+
createdAt: "2026-08-22T00:00:00.000Z",
|
|
174
|
+
updatedAt: "2026-08-22T00:00:01.000Z"
|
|
175
|
+
})
|
|
176
|
+
});
|
|
177
|
+
requireOutcome(stale, "conflict");
|
|
178
|
+
const abandoned = await store.recoverRun({
|
|
179
|
+
conversationId,
|
|
180
|
+
runId: running.id,
|
|
181
|
+
expectedRevision: running.revision,
|
|
182
|
+
action: "abandon"
|
|
183
|
+
});
|
|
184
|
+
requireOutcome(abandoned, "applied");
|
|
185
|
+
const terminalRun = abandoned.snapshot.runs.find((run) => run.id === running.id);
|
|
186
|
+
const terminalMessage = abandoned.snapshot.messages.find((message) => message.id === running.assistantMessageId);
|
|
187
|
+
if (terminalRun?.state !== "abandoned" || terminalMessage?.status !== "failed") {
|
|
188
|
+
throw new Error("Abandon recovery did not atomically terminalize its assistant record");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
26
191
|
// src/testing/surface-conformance.ts
|
|
27
192
|
import { z as z2 } from "zod";
|
|
28
193
|
|
|
@@ -744,6 +909,7 @@ export {
|
|
|
744
909
|
createHandlerTestClients,
|
|
745
910
|
createRealtimeProbeDriver,
|
|
746
911
|
defineRealtimeProbe,
|
|
912
|
+
runAgentStoreConformance,
|
|
747
913
|
runSurfaceProbes,
|
|
748
914
|
serializeSurfaceValue
|
|
749
915
|
};
|
package/llms-full.txt
CHANGED
|
@@ -3482,7 +3482,8 @@ const terminal = await ticket.result
|
|
|
3482
3482
|
|
|
3483
3483
|
`recordIds` is optional. Supply stable application record IDs when an accepted-response transport must
|
|
3484
3484
|
return durable placeholders before the run finishes. `ticket.admission` resolves after the store
|
|
3485
|
-
acceptance CAS and reports the
|
|
3485
|
+
acceptance CAS and reports the canonical committed `input`, assigned `run`, a typed `pending`
|
|
3486
|
+
assistant projection, compatibility IDs and snapshot version.
|
|
3486
3487
|
Those assigned IDs can differ from the proposal when an input coalesces into an existing queued
|
|
3487
3488
|
successor. Reuse the same `inputMessageId` for retries carrying the same idempotency key; input
|
|
3488
3489
|
identity is caller-stable, while the receipt reports the run/assistant identities that assignment
|
|
@@ -3490,8 +3491,35 @@ may change. Await `admission` first on the immediate accepted-response path. `ti
|
|
|
3490
3491
|
remains the signal-only compatibility surface and additionally waits for admission publication.
|
|
3491
3492
|
|
|
3492
3493
|
The in-memory store is a reference adapter and has process-local durability
|
|
3493
|
-
only. Production applications
|
|
3494
|
-
database transaction
|
|
3494
|
+
only. Production applications normally call `createAgentRuntimeStore()` and
|
|
3495
|
+
provide one database transaction driver:
|
|
3496
|
+
|
|
3497
|
+
```ts
|
|
3498
|
+
const store = createAgentRuntimeStore({
|
|
3499
|
+
transaction: work => db.transaction(tx => work(tx)),
|
|
3500
|
+
state: {
|
|
3501
|
+
load: (tx, conversationId) => loadRuntimeState(tx, conversationId),
|
|
3502
|
+
compareAndSwap: (tx, operation) => casRuntimeState(tx, operation),
|
|
3503
|
+
},
|
|
3504
|
+
history: {
|
|
3505
|
+
load: (tx, conversationId) => loadCanonicalMessages(tx, conversationId),
|
|
3506
|
+
loadById: (tx, identity) => loadActiveOrArchivedMessage(tx, identity),
|
|
3507
|
+
apply: (tx, mutation) => applyCanonicalHistoryMutation(tx, mutation),
|
|
3508
|
+
},
|
|
3509
|
+
scanRecoverable: page => scanRecoverableRuns(page),
|
|
3510
|
+
})
|
|
3511
|
+
```
|
|
3512
|
+
|
|
3513
|
+
The same opaque `tx` reaches state and history callbacks. The adapter maps rows
|
|
3514
|
+
and supplies atomicity; Stitchkit owns transition validation and revision
|
|
3515
|
+
arithmetic. The executable reference is
|
|
3516
|
+
[`examples/agent-store-prisma/adapter.ts`](../../examples/agent-store-prisma/adapter.ts).
|
|
3517
|
+
`compareAndSwap` returns either `{ outcome: 'applied' }` or
|
|
3518
|
+
`{ outcome: 'conflict', actualVersion }`; on a winning write it also persists the
|
|
3519
|
+
framework-provided `recoverable` descriptors in the same transaction. Recovery
|
|
3520
|
+
scans that bounded index instead of loading every aggregate. Compaction may hide
|
|
3521
|
+
rows from `history.load`, but `history.loadById` must retain canonical admitted
|
|
3522
|
+
inputs for durable duplicate receipts.
|
|
3495
3523
|
|
|
3496
3524
|
## Durable order
|
|
3497
3525
|
|
|
@@ -3533,8 +3561,8 @@ hatch.
|
|
|
3533
3561
|
|
|
3534
3562
|
## Store operations
|
|
3535
3563
|
|
|
3536
|
-
|
|
3537
|
-
|
|
3564
|
+
`AgentRuntimeStore` remains the runtime-facing aggregate. Application adapters
|
|
3565
|
+
implement the smaller `AgentRuntimeStoreDriver`, not these eight transitions:
|
|
3538
3566
|
|
|
3539
3567
|
- `acceptInputAndAssignRun`
|
|
3540
3568
|
- `acquireRun`
|
|
@@ -3549,13 +3577,13 @@ Every mutation carries an expected run revision or snapshot version. Input
|
|
|
3549
3577
|
assignment additionally carries an idempotency identity. A conflict is a
|
|
3550
3578
|
control outcome; stale data is never silently overwritten.
|
|
3551
3579
|
|
|
3552
|
-
On startup, `
|
|
3553
|
-
|
|
3554
|
-
`
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3580
|
+
On startup, `runtime.recover({ resolveContext })` consumes bounded lightweight
|
|
3581
|
+
pages. Its safe default resumes queued runs and reports acquired or
|
|
3582
|
+
`interrupt_requested` runs as skipped. A policy may requeue acquired work only
|
|
3583
|
+
with explicit replay-safe evidence, or abandon it only with stale-owner
|
|
3584
|
+
evidence. Each attempted run returns its own outcome/error; `pageSize`,
|
|
3585
|
+
`maxRuns`, and `signal` bound the pass. `runtime.resume(...)` remains available
|
|
3586
|
+
for one known queued record.
|
|
3559
3587
|
|
|
3560
3588
|
Canonical records currently write `schemaVersion: 1`. A durable adapter owns
|
|
3561
3589
|
read-time migration of older rows: migrate to the current shape at its storage
|
|
@@ -3567,14 +3595,24 @@ or silently accept an unknown future version.
|
|
|
3567
3595
|
|
|
3568
3596
|
`publish` receives event classes with different guarantees:
|
|
3569
3597
|
|
|
3598
|
+
- `admission` follows a successful acceptance CAS and carries the same complete
|
|
3599
|
+
projection as `ticket.admission`;
|
|
3600
|
+
|
|
3570
3601
|
- `assistant-delta` is transient and ordered by
|
|
3571
3602
|
`(runId, runtimeEpoch, sequence)`;
|
|
3603
|
+
- `reasoning-start`, `reasoning-delta` and `reasoning-end` are transient and
|
|
3604
|
+
ordered by the same identity; delta carries only the current text fragment,
|
|
3605
|
+
while provider metadata stays inside a validated canonical envelope;
|
|
3572
3606
|
- `assistant-checkpoint` follows a successful checkpoint CAS;
|
|
3573
3607
|
- `run-state` follows durable queue/acquire/interrupt transitions;
|
|
3574
3608
|
- `tool-status` is transient lifecycle presentation with JSON-safe input on
|
|
3575
3609
|
start and output on completion; internal tool failures remain generic;
|
|
3576
3610
|
- `terminal` follows the winning terminal CAS.
|
|
3577
3611
|
|
|
3612
|
+
These are post-commit notifications, not a transactional outbox: a process can
|
|
3613
|
+
crash between the database commit and `publish`. Reconnect should load canonical
|
|
3614
|
+
state. Exactly-once external delivery remains an application-owned outbox.
|
|
3615
|
+
|
|
3578
3616
|
A named custom stop condition terminalizes with `policy_stop`; its `policyName`
|
|
3579
3617
|
is persisted on the run and included in the terminal event/result. `max-steps`
|
|
3580
3618
|
is the reserved built-in policy name. `loop.prepareStep` is the controlled AI
|
|
@@ -5129,7 +5167,7 @@ never-leak-an-internal-message rule for a raw throw):
|
|
|
5129
5167
|
|
|
5130
5168
|
```ts
|
|
5131
5169
|
const onError = createErrorHook({
|
|
5132
|
-
// Map the codes you have an opinion about
|
|
5170
|
+
// Map the codes you have an opinion about.
|
|
5133
5171
|
codeMap: {
|
|
5134
5172
|
BAD_REQUEST: 'bad_request', VALIDATION_ERROR: 'bad_request',
|
|
5135
5173
|
UNAUTHORIZED: 'unauthenticated', FORBIDDEN: 'forbidden',
|
|
@@ -5137,6 +5175,9 @@ const onError = createErrorHook({
|
|
|
5137
5175
|
CONFLICT: 'conflict', RATE_LIMITED: 'rate_limited',
|
|
5138
5176
|
INTERNAL_SERVER_ERROR: 'internal',
|
|
5139
5177
|
},
|
|
5178
|
+
// Optional: one public vocabulary entry for every other stitchkit code.
|
|
5179
|
+
// A resolver `(code) => ...` is also accepted for grouping code families.
|
|
5180
|
+
unmappedCode: 'framework_error',
|
|
5140
5181
|
// `ctx` is the request's RuntimeContext — read `ctx.traceId` for a
|
|
5141
5182
|
// correlation id in the envelope. Declaring it is optional.
|
|
5142
5183
|
render: (info, ctx) => ({
|
|
@@ -5149,10 +5190,13 @@ const onError = createErrorHook({
|
|
|
5149
5190
|
createServer({ services, hooks: { onError } })
|
|
5150
5191
|
```
|
|
5151
5192
|
|
|
5152
|
-
`codeMap` is partial: map the codes you have an opinion about.
|
|
5153
|
-
you did not list travels as itself
|
|
5154
|
-
|
|
5155
|
-
|
|
5193
|
+
`codeMap` is partial: map the codes you have an opinion about. By default a
|
|
5194
|
+
stitchkit code you did not list travels as itself. Set `unmappedCode` to one
|
|
5195
|
+
wire-code when your public vocabulary has a catch-all, or to a function such as
|
|
5196
|
+
`(code) => code.startsWith('FILE_') ? 'storage_error' : 'framework_error'` when
|
|
5197
|
+
framework code families need different buckets. An explicit `codeMap` entry
|
|
5198
|
+
always wins. Codes your project throws itself do not belong to Stitchkit's
|
|
5199
|
+
vocabulary, so they never pass through this fallback and remain unchanged.
|
|
5156
5200
|
|
|
5157
5201
|
One `satisfies` is the **opt-in** to the stricter deal:
|
|
5158
5202
|
|
|
@@ -5164,9 +5208,7 @@ That makes the map exhaustive on your side, so a release that adds a code stops
|
|
|
5164
5208
|
your build until you decide what the new code is called on your wire. Take it
|
|
5165
5209
|
when your envelope is a published contract and a code surfacing in stitchkit's
|
|
5166
5210
|
spelling would violate it; leave it off when passing one through is fine.
|
|
5167
|
-
Neither choice is silent — the changelog names every added code.
|
|
5168
|
-
catch-all instead of either, decide it in `render`, where `info.code` is the
|
|
5169
|
-
resolved value.
|
|
5211
|
+
Neither choice is silent — the changelog names every added code.
|
|
5170
5212
|
|
|
5171
5213
|
Both `onError` and `render` may be asynchronous and receive the matched endpoint
|
|
5172
5214
|
as their final argument. The observer is awaited before rendering, so it can
|
|
@@ -6503,6 +6545,34 @@ current one *up to* your target, and apply each snippet.
|
|
|
6503
6545
|
runtime): bootstrap the server, one HTTP request, and any feature you rely on
|
|
6504
6546
|
(Socket.IO connect, an MCP tool call, a multipart upload, …).
|
|
6505
6547
|
|
|
6548
|
+
## Unreleased migration: complete agent admission identity
|
|
6549
|
+
|
|
6550
|
+
Custom `AgentRuntimeStore` adapters must persist and return the input and
|
|
6551
|
+
assistant identities associated with an idempotency key:
|
|
6552
|
+
|
|
6553
|
+
```ts
|
|
6554
|
+
// before
|
|
6555
|
+
return { outcome: 'duplicate', runId, snapshot }
|
|
6556
|
+
|
|
6557
|
+
// after
|
|
6558
|
+
return { outcome: 'duplicate', input, inputMessageId, runId, assistantMessageId, snapshot }
|
|
6559
|
+
```
|
|
6560
|
+
|
|
6561
|
+
Prefer replacing the custom aggregate reducer with `createAgentRuntimeStore()`;
|
|
6562
|
+
its `AgentStoredState.admissions` record and transaction driver implement this
|
|
6563
|
+
contract automatically. `history.loadById()` must retain access to compacted
|
|
6564
|
+
admitted inputs so the framework can return the canonical record.
|
|
6565
|
+
|
|
6566
|
+
`AgentRuntimeEvent` also adds a post-commit `admission` variant. Add it to any
|
|
6567
|
+
exhaustive publisher switch. Its `assistant` is either the pending placeholder
|
|
6568
|
+
for a new assignment or the canonical persisted assistant for a duplicate:
|
|
6569
|
+
|
|
6570
|
+
```ts
|
|
6571
|
+
case 'admission':
|
|
6572
|
+
await persistProductProjection(event.input, event.run, event.assistant)
|
|
6573
|
+
break
|
|
6574
|
+
```
|
|
6575
|
+
|
|
6506
6576
|
## Released migration: 0.56.0
|
|
6507
6577
|
|
|
6508
6578
|
### Surface manifests are version 2
|
|
@@ -7816,7 +7886,7 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
7816
7886
|
| `createAuthHook` | function | one scope gate for HTTP `authorize` and tool `beforeHandle` — [guide](../guide/auth-and-errors.md#createauthhook) |
|
|
7817
7887
|
| `composeAuthHooks` | function | route multiple canonical auth domains by owned scope and atomically commit their typed contributions |
|
|
7818
7888
|
| `createErrorHook` | function | an async-capable, endpoint-aware `onError` hook from a code map + envelope renderer — [guide](../guide/auth-and-errors.md#createerrorhook) |
|
|
7819
|
-
| `ErrorHookConfig` | _type_ | async observer/renderer config
|
|
7889
|
+
| `ErrorHookConfig` | _type_ | async observer/renderer config with partial `codeMap` and optional typed `unmappedCode` fallback |
|
|
7820
7890
|
| `ResolvedError` | _type_ | the normalised error handed to `createErrorHook`'s `render` |
|
|
7821
7891
|
| `createBearerResolver` | function | a bearer-token identity resolver |
|
|
7822
7892
|
| `signJwt` | function | sign an HS256 JWT |
|
|
@@ -7942,6 +8012,10 @@ Server-only optional application runtime. See the
|
|
|
7942
8012
|
| `defineAgentProtocol` | function | declare and validate context, input metadata and canonical message parts |
|
|
7943
8013
|
| `AgentMessageSchema` / `AgentRunSchema` / `AgentSnapshotSchema` | schema | versioned canonical engine records |
|
|
7944
8014
|
| `AgentRuntimeStore` | _type_ | aggregate CAS transaction boundary for message, run and compaction mutations |
|
|
8015
|
+
| `createAgentRuntimeStore` | function | build the aggregate store from one coherent transaction driver; framework owns every state transition |
|
|
8016
|
+
| `AgentRuntimeStoreDriver` | _type_ | ORM-neutral transactional state load/exact-version CAS, active-plus-archived history codec and bounded recoverable-run index scan |
|
|
8017
|
+
| `AgentStoredStateSchema` | schema | versioned runs and full idempotency admission identities without duplicated message history |
|
|
8018
|
+
| `AgentHistoryMutationSchema` | schema | typed canonical message mutation applied inside the winning state transaction |
|
|
7945
8019
|
| `RecoverAgentRunSchema` | schema | explicit abandon/requeue recovery decision; acquired runs require replay-safe evidence |
|
|
7946
8020
|
| `createMemoryAgentRuntimeStore` | function | process-local reference adapter, not production durability |
|
|
7947
8021
|
| `projectAgentHistory` | function | asynchronously project canonical records and resolved multimodal files into provider-valid AI SDK messages |
|
|
@@ -7952,11 +8026,14 @@ Server-only optional application runtime. See the
|
|
|
7952
8026
|
| `AgentRuntimeStopPolicy` | _type_ | named custom AI SDK stop condition persisted and published on policy stop |
|
|
7953
8027
|
| `AgentRuntimePrepareStep` | _type_ | per-run controlled step callback with typed domain context and managed run signal/fence |
|
|
7954
8028
|
| `AgentRuntimeRecordIds` | _type_ | optional caller-provided input, run and assistant IDs for stable application records |
|
|
7955
|
-
| `AgentRuntimeAdmission` | _type_ |
|
|
8029
|
+
| `AgentRuntimeAdmission` | _type_ | canonical committed input, assigned run, pending assistant projection, compatibility IDs and snapshot version |
|
|
8030
|
+
| `AgentAdmissionEventSchema` | schema | post-commit admission projection; removes store rereads but does not imply exactly-once delivery |
|
|
8031
|
+
| `AgentRunMetricsSchema` | schema | optional provenance-aware usage and timings; `partial` distinguishes checkpoint from terminal totals |
|
|
8032
|
+
| `AgentRuntimeRecoverOptions` | _type_ | bounded paged startup recovery with context resolver and explicit evidence policy |
|
|
7956
8033
|
| `AgentSessionCloseOptions` | _type_ | natural `drainTimeoutMs` followed by shutdown abort and optional bounded `forceTimeoutMs` settlement wait |
|
|
7957
8034
|
| `AgentHistoryProjectionOptions` | _type_ | storage-neutral file resolver and explicit unresolved-file behavior |
|
|
7958
8035
|
| `createAgentToolFenceLifecycle` | function | pre-effect and post-effect run ownership fence for `mountAgent` |
|
|
7959
|
-
| `AgentRuntimeEventSchema` | schema | transient
|
|
8036
|
+
| `AgentRuntimeEventSchema` | schema | transient stream lifecycle plus post-commit admission/checkpoint/run-state/terminal projections |
|
|
7960
8037
|
| `createAgentObservability` | function | separate agent-run sink over the shared bounded observability lifecycle |
|
|
7961
8038
|
|
|
7962
8039
|
## `stitchkit/agent-runtime/openrouter`
|
|
@@ -8294,6 +8371,8 @@ handler pipeline without opening a TCP port.
|
|
|
8294
8371
|
|--------|------|---------|
|
|
8295
8372
|
| `createHandlerTestClient` | function | one contract client backed by an in-process `FetchHandler` |
|
|
8296
8373
|
| `createHandlerTestClients` | function | exact contract-registry batch form |
|
|
8374
|
+
| `runAgentStoreConformance` | function | reusable black-box duplicate/coalescing/stale/recovery contract for durable agent-store adapters |
|
|
8375
|
+
| `AgentStoreConformanceConfig` | _type_ | factory configuration for running the same contract against a fresh adapter |
|
|
8297
8376
|
| `HandlerTestClientDefaults` | _type_ | ordinary bare-client defaults with handler-owned `baseUrl` and `fetch` removed |
|
|
8298
8377
|
| `HandlerTestClientConfig` | _type_ | handler, contract, path prefix, scoped config and client request defaults |
|
|
8299
8378
|
| `HandlerTestClientsConfig` | _type_ | batch helper configuration |
|