stitchkit 0.56.5 → 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 +653 -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 +806 -452
- 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 +99 -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":"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"}
|
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,6 +3595,9 @@ 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)`;
|
|
3572
3603
|
- `reasoning-start`, `reasoning-delta` and `reasoning-end` are transient and
|
|
@@ -3578,6 +3609,10 @@ or silently accept an unknown future version.
|
|
|
3578
3609
|
start and output on completion; internal tool failures remain generic;
|
|
3579
3610
|
- `terminal` follows the winning terminal CAS.
|
|
3580
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
|
+
|
|
3581
3616
|
A named custom stop condition terminalizes with `policy_stop`; its `policyName`
|
|
3582
3617
|
is persisted on the run and included in the terminal event/result. `max-steps`
|
|
3583
3618
|
is the reserved built-in policy name. `loop.prepareStep` is the controlled AI
|
|
@@ -5132,7 +5167,7 @@ never-leak-an-internal-message rule for a raw throw):
|
|
|
5132
5167
|
|
|
5133
5168
|
```ts
|
|
5134
5169
|
const onError = createErrorHook({
|
|
5135
|
-
// Map the codes you have an opinion about
|
|
5170
|
+
// Map the codes you have an opinion about.
|
|
5136
5171
|
codeMap: {
|
|
5137
5172
|
BAD_REQUEST: 'bad_request', VALIDATION_ERROR: 'bad_request',
|
|
5138
5173
|
UNAUTHORIZED: 'unauthenticated', FORBIDDEN: 'forbidden',
|
|
@@ -5140,6 +5175,9 @@ const onError = createErrorHook({
|
|
|
5140
5175
|
CONFLICT: 'conflict', RATE_LIMITED: 'rate_limited',
|
|
5141
5176
|
INTERNAL_SERVER_ERROR: 'internal',
|
|
5142
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',
|
|
5143
5181
|
// `ctx` is the request's RuntimeContext — read `ctx.traceId` for a
|
|
5144
5182
|
// correlation id in the envelope. Declaring it is optional.
|
|
5145
5183
|
render: (info, ctx) => ({
|
|
@@ -5152,10 +5190,13 @@ const onError = createErrorHook({
|
|
|
5152
5190
|
createServer({ services, hooks: { onError } })
|
|
5153
5191
|
```
|
|
5154
5192
|
|
|
5155
|
-
`codeMap` is partial: map the codes you have an opinion about.
|
|
5156
|
-
you did not list travels as itself
|
|
5157
|
-
|
|
5158
|
-
|
|
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.
|
|
5159
5200
|
|
|
5160
5201
|
One `satisfies` is the **opt-in** to the stricter deal:
|
|
5161
5202
|
|
|
@@ -5167,9 +5208,7 @@ That makes the map exhaustive on your side, so a release that adds a code stops
|
|
|
5167
5208
|
your build until you decide what the new code is called on your wire. Take it
|
|
5168
5209
|
when your envelope is a published contract and a code surfacing in stitchkit's
|
|
5169
5210
|
spelling would violate it; leave it off when passing one through is fine.
|
|
5170
|
-
Neither choice is silent — the changelog names every added code.
|
|
5171
|
-
catch-all instead of either, decide it in `render`, where `info.code` is the
|
|
5172
|
-
resolved value.
|
|
5211
|
+
Neither choice is silent — the changelog names every added code.
|
|
5173
5212
|
|
|
5174
5213
|
Both `onError` and `render` may be asynchronous and receive the matched endpoint
|
|
5175
5214
|
as their final argument. The observer is awaited before rendering, so it can
|
|
@@ -6506,6 +6545,34 @@ current one *up to* your target, and apply each snippet.
|
|
|
6506
6545
|
runtime): bootstrap the server, one HTTP request, and any feature you rely on
|
|
6507
6546
|
(Socket.IO connect, an MCP tool call, a multipart upload, …).
|
|
6508
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
|
+
|
|
6509
6576
|
## Released migration: 0.56.0
|
|
6510
6577
|
|
|
6511
6578
|
### Surface manifests are version 2
|
|
@@ -7819,7 +7886,7 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
7819
7886
|
| `createAuthHook` | function | one scope gate for HTTP `authorize` and tool `beforeHandle` — [guide](../guide/auth-and-errors.md#createauthhook) |
|
|
7820
7887
|
| `composeAuthHooks` | function | route multiple canonical auth domains by owned scope and atomically commit their typed contributions |
|
|
7821
7888
|
| `createErrorHook` | function | an async-capable, endpoint-aware `onError` hook from a code map + envelope renderer — [guide](../guide/auth-and-errors.md#createerrorhook) |
|
|
7822
|
-
| `ErrorHookConfig` | _type_ | async observer/renderer config
|
|
7889
|
+
| `ErrorHookConfig` | _type_ | async observer/renderer config with partial `codeMap` and optional typed `unmappedCode` fallback |
|
|
7823
7890
|
| `ResolvedError` | _type_ | the normalised error handed to `createErrorHook`'s `render` |
|
|
7824
7891
|
| `createBearerResolver` | function | a bearer-token identity resolver |
|
|
7825
7892
|
| `signJwt` | function | sign an HS256 JWT |
|
|
@@ -7945,6 +8012,10 @@ Server-only optional application runtime. See the
|
|
|
7945
8012
|
| `defineAgentProtocol` | function | declare and validate context, input metadata and canonical message parts |
|
|
7946
8013
|
| `AgentMessageSchema` / `AgentRunSchema` / `AgentSnapshotSchema` | schema | versioned canonical engine records |
|
|
7947
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 |
|
|
7948
8019
|
| `RecoverAgentRunSchema` | schema | explicit abandon/requeue recovery decision; acquired runs require replay-safe evidence |
|
|
7949
8020
|
| `createMemoryAgentRuntimeStore` | function | process-local reference adapter, not production durability |
|
|
7950
8021
|
| `projectAgentHistory` | function | asynchronously project canonical records and resolved multimodal files into provider-valid AI SDK messages |
|
|
@@ -7955,11 +8026,14 @@ Server-only optional application runtime. See the
|
|
|
7955
8026
|
| `AgentRuntimeStopPolicy` | _type_ | named custom AI SDK stop condition persisted and published on policy stop |
|
|
7956
8027
|
| `AgentRuntimePrepareStep` | _type_ | per-run controlled step callback with typed domain context and managed run signal/fence |
|
|
7957
8028
|
| `AgentRuntimeRecordIds` | _type_ | optional caller-provided input, run and assistant IDs for stable application records |
|
|
7958
|
-
| `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 |
|
|
7959
8033
|
| `AgentSessionCloseOptions` | _type_ | natural `drainTimeoutMs` followed by shutdown abort and optional bounded `forceTimeoutMs` settlement wait |
|
|
7960
8034
|
| `AgentHistoryProjectionOptions` | _type_ | storage-neutral file resolver and explicit unresolved-file behavior |
|
|
7961
8035
|
| `createAgentToolFenceLifecycle` | function | pre-effect and post-effect run ownership fence for `mountAgent` |
|
|
7962
|
-
| `AgentRuntimeEventSchema` | schema | transient
|
|
8036
|
+
| `AgentRuntimeEventSchema` | schema | transient stream lifecycle plus post-commit admission/checkpoint/run-state/terminal projections |
|
|
7963
8037
|
| `createAgentObservability` | function | separate agent-run sink over the shared bounded observability lifecycle |
|
|
7964
8038
|
|
|
7965
8039
|
## `stitchkit/agent-runtime/openrouter`
|
|
@@ -8297,6 +8371,8 @@ handler pipeline without opening a TCP port.
|
|
|
8297
8371
|
|--------|------|---------|
|
|
8298
8372
|
| `createHandlerTestClient` | function | one contract client backed by an in-process `FetchHandler` |
|
|
8299
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 |
|
|
8300
8376
|
| `HandlerTestClientDefaults` | _type_ | ordinary bare-client defaults with handler-owned `baseUrl` and `fetch` removed |
|
|
8301
8377
|
| `HandlerTestClientConfig` | _type_ | handler, contract, path prefix, scoped config and client request defaults |
|
|
8302
8378
|
| `HandlerTestClientsConfig` | _type_ | batch helper configuration |
|