stitchkit 0.85.1 → 0.86.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.
Files changed (114) hide show
  1. package/CHANGELOG.md +178 -0
  2. package/README.md +3 -0
  3. package/dist/agent-runtime/agent-tool.d.ts +25 -0
  4. package/dist/agent-runtime/agent-tool.d.ts.map +1 -0
  5. package/dist/agent-runtime/child-tools.d.ts +69 -0
  6. package/dist/agent-runtime/child-tools.d.ts.map +1 -0
  7. package/dist/agent-runtime/children.d.ts +113 -0
  8. package/dist/agent-runtime/children.d.ts.map +1 -0
  9. package/dist/agent-runtime/coding-tool-contract.d.ts +29 -0
  10. package/dist/agent-runtime/coding-tool-contract.d.ts.map +1 -1
  11. package/dist/agent-runtime/coding-tool-refusals.d.ts +2 -0
  12. package/dist/agent-runtime/coding-tool-refusals.d.ts.map +1 -1
  13. package/dist/agent-runtime/coding-tool-shell.d.ts.map +1 -1
  14. package/dist/agent-runtime/coding-tools.d.ts +1 -0
  15. package/dist/agent-runtime/coding-tools.d.ts.map +1 -1
  16. package/dist/agent-runtime/control-schema.d.ts +17 -0
  17. package/dist/agent-runtime/control-schema.d.ts.map +1 -1
  18. package/dist/agent-runtime/event-schema.d.ts +34 -0
  19. package/dist/agent-runtime/event-schema.d.ts.map +1 -1
  20. package/dist/agent-runtime/event-search-tools.d.ts +53 -0
  21. package/dist/agent-runtime/event-search-tools.d.ts.map +1 -0
  22. package/dist/agent-runtime/event-search.d.ts +23 -0
  23. package/dist/agent-runtime/event-search.d.ts.map +1 -0
  24. package/dist/agent-runtime/fault-bench.d.ts +45 -0
  25. package/dist/agent-runtime/fault-bench.d.ts.map +1 -0
  26. package/dist/agent-runtime/observability.d.ts +6 -0
  27. package/dist/agent-runtime/observability.d.ts.map +1 -1
  28. package/dist/agent-runtime/projections.d.ts +69 -0
  29. package/dist/agent-runtime/projections.d.ts.map +1 -0
  30. package/dist/agent-runtime/provider-failure.d.ts +5 -1
  31. package/dist/agent-runtime/provider-failure.d.ts.map +1 -1
  32. package/dist/agent-runtime/provider-origin.d.ts +12 -0
  33. package/dist/agent-runtime/provider-origin.d.ts.map +1 -0
  34. package/dist/agent-runtime/retry-policy.d.ts +27 -0
  35. package/dist/agent-runtime/retry-policy.d.ts.map +1 -0
  36. package/dist/agent-runtime/run-execution.d.ts +0 -9
  37. package/dist/agent-runtime/run-execution.d.ts.map +1 -1
  38. package/dist/agent-runtime/run-mutation-queue.d.ts +21 -0
  39. package/dist/agent-runtime/run-mutation-queue.d.ts.map +1 -0
  40. package/dist/agent-runtime/run-operation-lifecycle.d.ts +3 -0
  41. package/dist/agent-runtime/run-operation-lifecycle.d.ts.map +1 -1
  42. package/dist/agent-runtime/runtime.d.ts +15 -0
  43. package/dist/agent-runtime/runtime.d.ts.map +1 -1
  44. package/dist/agent-runtime/sandbox.d.ts +66 -0
  45. package/dist/agent-runtime/sandbox.d.ts.map +1 -0
  46. package/dist/agent-runtime/schedule-tools.d.ts +35 -0
  47. package/dist/agent-runtime/schedule-tools.d.ts.map +1 -0
  48. package/dist/agent-runtime/schedules.d.ts +63 -0
  49. package/dist/agent-runtime/schedules.d.ts.map +1 -0
  50. package/dist/agent-runtime/schemas.d.ts +9 -0
  51. package/dist/agent-runtime/schemas.d.ts.map +1 -1
  52. package/dist/agent-runtime/spill.d.ts +24 -0
  53. package/dist/agent-runtime/spill.d.ts.map +1 -0
  54. package/dist/agent-runtime/sqlite-purge.d.ts.map +1 -1
  55. package/dist/agent-runtime/sqlite.d.ts +26 -0
  56. package/dist/agent-runtime/sqlite.d.ts.map +1 -1
  57. package/dist/agent-runtime/state-slots.d.ts +48 -0
  58. package/dist/agent-runtime/state-slots.d.ts.map +1 -0
  59. package/dist/agent-runtime/state-tools.d.ts +58 -0
  60. package/dist/agent-runtime/state-tools.d.ts.map +1 -0
  61. package/dist/agent-runtime/store-driver.d.ts +13 -0
  62. package/dist/agent-runtime/store-driver.d.ts.map +1 -1
  63. package/dist/agent-runtime/store-events.d.ts +829 -0
  64. package/dist/agent-runtime/store-events.d.ts.map +1 -0
  65. package/dist/agent-runtime/store-migrations/v1-to-v2.d.ts +6 -0
  66. package/dist/agent-runtime/store-migrations/v1-to-v2.d.ts.map +1 -0
  67. package/dist/agent-runtime/store.d.ts +45 -0
  68. package/dist/agent-runtime/store.d.ts.map +1 -1
  69. package/dist/agent-runtime/terminal-commit.d.ts +1 -1
  70. package/dist/agent-runtime-browser.js +5 -3
  71. package/dist/agent-runtime-coding-tools.js +144 -15
  72. package/dist/agent-runtime-harness.js +12 -10
  73. package/dist/agent-runtime-sqlite-bun.d.ts +1 -1
  74. package/dist/agent-runtime-sqlite-bun.d.ts.map +1 -1
  75. package/dist/agent-runtime-sqlite-bun.js +4 -3
  76. package/dist/agent-runtime-sqlite-node.d.ts +1 -1
  77. package/dist/agent-runtime-sqlite-node.d.ts.map +1 -1
  78. package/dist/agent-runtime-sqlite-node.js +4 -3
  79. package/dist/agent-runtime-testing.d.ts +3 -0
  80. package/dist/agent-runtime-testing.d.ts.map +1 -0
  81. package/dist/agent-runtime-testing.js +156 -0
  82. package/dist/agent-runtime.d.ts +16 -2
  83. package/dist/agent-runtime.d.ts.map +1 -1
  84. package/dist/agent-runtime.js +1591 -154
  85. package/dist/application.js +14 -14
  86. package/dist/cli.js +6 -6
  87. package/dist/{index-fwbkp2jn.js → index-0vfdh685.js} +2 -2
  88. package/dist/{index-5z8tezpx.js → index-0ydchz76.js} +3 -3
  89. package/dist/{index-3ds42w1w.js → index-1szetq6f.js} +33 -4
  90. package/dist/{index-jpp7jd1p.js → index-33xckd7h.js} +898 -425
  91. package/dist/{index-27487ay5.js → index-9hw9eq48.js} +4 -4
  92. package/dist/{index-66nxrgy0.js → index-b7qwhbzq.js} +428 -46
  93. package/dist/index-cnyk6te3.js +77 -0
  94. package/dist/index-gskm1k5a.js +50 -0
  95. package/dist/{index-fq492hg0.js → index-hber83mk.js} +254 -157
  96. package/dist/{index-4hk633vz.js → index-hkm6wysp.js} +9 -2
  97. package/dist/{index-dx9xehwt.js → index-kc6h6hg0.js} +1 -1
  98. package/dist/{index-x15ss2dx.js → index-p1b1y93x.js} +3 -0
  99. package/dist/{index-mgtxfe6b.js → index-r159gjwy.js} +8 -1
  100. package/dist/{index-s4ckmrac.js → index-rcgsnrr6.js} +3 -3
  101. package/dist/index-vfgb58nf.js +252 -0
  102. package/dist/{index-dggwnnjv.js → index-wn9cb82y.js} +1 -1
  103. package/dist/{index-ff0kcqvp.js → index-z2452tsw.js} +3 -3
  104. package/dist/testing/agent-store-conformance.d.ts.map +1 -1
  105. package/dist/testing.js +54 -80
  106. package/dist/tool-invoker.js +4 -4
  107. package/dist/tools/internal/surface-projector.d.ts.map +1 -1
  108. package/dist/tools/manifest.d.ts +16 -0
  109. package/dist/tools/manifest.d.ts.map +1 -1
  110. package/dist/tools.d.ts +1 -1
  111. package/dist/tools.d.ts.map +1 -1
  112. package/dist/tools.js +10 -8
  113. package/llms-full.txt +321 -13
  114. package/package.json +6 -1
@@ -0,0 +1,77 @@
1
+ // src/agent-runtime/testing.ts
2
+ function createAgentRaceBarrier(timeoutMs = 5000) {
3
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1) {
4
+ throw new TypeError("Agent race barrier timeoutMs must be a positive safe integer");
5
+ }
6
+ const reached = Promise.withResolvers();
7
+ const released = Promise.withResolvers();
8
+ let announced = false;
9
+ return {
10
+ reached: reached.promise,
11
+ async wait() {
12
+ if (!announced) {
13
+ announced = true;
14
+ reached.resolve();
15
+ }
16
+ let timer;
17
+ try {
18
+ await Promise.race([
19
+ released.promise,
20
+ new Promise((_resolve, reject) => {
21
+ timer = setTimeout(() => reject(new Error(`Agent race barrier exceeded ${timeoutMs}ms teardown bound`)), timeoutMs);
22
+ })
23
+ ]);
24
+ } finally {
25
+ if (timer !== undefined)
26
+ clearTimeout(timer);
27
+ }
28
+ },
29
+ release: released.resolve
30
+ };
31
+ }
32
+ function createAgentRaceTrace() {
33
+ const recorded = [];
34
+ return {
35
+ record(name) {
36
+ const entry = { name, sequence: recorded.length };
37
+ recorded.push(entry);
38
+ return entry;
39
+ },
40
+ entries: () => recorded.map((entry) => ({ ...entry })),
41
+ assertBefore(first, second) {
42
+ const firstEntry = recorded.find((entry) => entry.name === first);
43
+ const secondEntry = recorded.find((entry) => entry.name === second);
44
+ if (!firstEntry || !secondEntry || firstEntry.sequence >= secondEntry.sequence) {
45
+ throw new Error(`Expected ${first} before ${second}`);
46
+ }
47
+ },
48
+ assertSequence(names) {
49
+ const actual = recorded.map((entry) => entry.name);
50
+ if (actual.length !== names.length || actual.some((name, index) => name !== names[index])) {
51
+ throw new Error(`Expected trace ${names.join(" -> ")}, received ${actual.join(" -> ")}`);
52
+ }
53
+ },
54
+ count: (name) => recorded.filter((entry) => entry.name === name).length
55
+ };
56
+ }
57
+ function createAgentRaceDriver(timeoutMs = 5000) {
58
+ const trace = createAgentRaceTrace();
59
+ const barriers = new Map;
60
+ return {
61
+ trace,
62
+ barrier(name) {
63
+ const existing = barriers.get(name);
64
+ if (existing)
65
+ return existing;
66
+ const created = createAgentRaceBarrier(timeoutMs);
67
+ barriers.set(name, created);
68
+ return created;
69
+ },
70
+ releaseAll() {
71
+ for (const barrier of barriers.values())
72
+ barrier.release();
73
+ }
74
+ };
75
+ }
76
+
77
+ export { createAgentRaceBarrier, createAgentRaceTrace, createAgentRaceDriver };
@@ -0,0 +1,50 @@
1
+ // src/agent-runtime/sandbox.ts
2
+ import { z } from "zod";
3
+ var AgentSandboxRestrictionSchema = z.enum([
4
+ "network-denied",
5
+ "write-contained",
6
+ "secrets-hidden",
7
+ "process-contained"
8
+ ]);
9
+ var AgentSandboxGradeSchema = z.discriminatedUnion("grade", [
10
+ z.object({ grade: z.literal("full"), restrictions: z.array(AgentSandboxRestrictionSchema) }).strict(),
11
+ z.object({
12
+ grade: z.literal("partial"),
13
+ restrictions: z.array(AgentSandboxRestrictionSchema),
14
+ gaps: z.array(AgentSandboxRestrictionSchema)
15
+ }).strict(),
16
+ z.object({ grade: z.literal("unavailable"), reason: z.string().min(1) }).strict()
17
+ ]);
18
+ var probes = new WeakMap;
19
+ function probeAgentProcessSandbox(sandbox, options = {}) {
20
+ if (options.refresh)
21
+ probes.delete(sandbox);
22
+ const present = probes.get(sandbox);
23
+ if (present)
24
+ return present;
25
+ const pending = Promise.resolve(sandbox.probe()).then((grade) => AgentSandboxGradeSchema.parse(grade));
26
+ probes.set(sandbox, pending);
27
+ return pending;
28
+ }
29
+ function missingSandboxRestrictions(grade, required) {
30
+ if (grade.grade === "unavailable")
31
+ return required;
32
+ const present = new Set(grade.restrictions);
33
+ return required.filter((restriction) => !present.has(restriction));
34
+ }
35
+ async function recordAgentSandboxProbe(input) {
36
+ const grade = await probeAgentProcessSandbox(input.sandbox);
37
+ const missing = missingSandboxRestrictions(grade, input.required);
38
+ await input.store.appendEvent({
39
+ conversationId: input.conversationId,
40
+ kind: "sandbox/probed",
41
+ payload: {
42
+ result: grade,
43
+ required: [...input.required],
44
+ missing: [...missing]
45
+ }
46
+ });
47
+ return grade;
48
+ }
49
+
50
+ export { AgentSandboxRestrictionSchema, AgentSandboxGradeSchema, probeAgentProcessSandbox, missingSandboxRestrictions, recordAgentSandboxProbe };
@@ -1,51 +1,51 @@
1
1
  import {
2
2
  assistantStatus
3
3
  } from "./index-y2s6h5bf.js";
4
+ import {
5
+ AcceptInputAndAssignRunSchema,
6
+ AcquireAgentRunSchema,
7
+ AgentRecoverablePageSchema,
8
+ AgentRunViewSchema,
9
+ AgentStoreEventEnvelopeSchema,
10
+ AgentStoreEventPageSchema,
11
+ AgentStoreTransitionSchema,
12
+ AppendAgentStoreEventSchema,
13
+ CheckpointRunAssistantSchema,
14
+ CommitRunTerminalSchema,
15
+ ReadAgentStoreEventsSchema,
16
+ RecordRunOperationSchema,
17
+ RecoverAgentRunSchema,
18
+ ReplaceCompactedRangeSchema,
19
+ RequestRunInterruptSchema,
20
+ agentStoreEventDraft,
21
+ canonicalAgentJson,
22
+ decodeAgentConversationArchive,
23
+ encodeAgentConversationArchive
24
+ } from "./index-vfgb58nf.js";
4
25
  import {
5
26
  AgentMessageSchema,
6
27
  AgentRecordIdSchema,
7
28
  AgentRecordVersionSchema,
8
- AgentRunOperationSchema,
9
29
  AgentRunSchema,
10
30
  AgentSnapshotSchema,
11
- AgentTerminalReasonSchema,
12
- AgentUsageSchema,
13
31
  runStateForTerminalReason
14
- } from "./index-x15ss2dx.js";
15
-
16
- // src/agent-runtime/conversations.ts
17
- import { z } from "zod";
18
- var AgentConversationSummarySchema = z.object({
19
- conversationId: AgentRecordIdSchema,
20
- version: AgentRecordVersionSchema,
21
- updatedAt: z.iso.datetime({ offset: true }),
22
- preview: z.string(),
23
- activeRuns: z.int().nonnegative()
24
- }).strict();
25
- var AgentConversationPageSchema = z.object({
26
- items: z.array(AgentConversationSummarySchema),
27
- nextCursor: z.string().min(1).optional()
28
- }).strict();
29
- var AgentConversationMessagePageSchema = z.object({
30
- items: z.array(AgentMessageSchema),
31
- nextCursor: z.string().min(1).optional()
32
- }).strict();
32
+ } from "./index-p1b1y93x.js";
33
33
 
34
34
  // src/agent-runtime/purge.ts
35
- import { z as z2 } from "zod";
36
- var AgentConversationPurgeInputSchema = z2.strictObject({
35
+ import { z } from "zod";
36
+ var AgentConversationPurgeInputSchema = z.strictObject({
37
37
  conversationId: AgentRecordIdSchema,
38
38
  expectedVersion: AgentRecordVersionSchema.optional()
39
39
  });
40
- var AgentConversationPurgeResultSchema = z2.discriminatedUnion("outcome", [
41
- z2.strictObject({ outcome: z2.literal("purged") }),
42
- z2.strictObject({ outcome: z2.literal("already_purged") }),
43
- z2.strictObject({ outcome: z2.literal("unsupported") }),
44
- z2.strictObject({
45
- outcome: z2.literal("active"),
46
- runIds: z2.array(AgentRecordIdSchema).min(1)
40
+ var AgentConversationPurgeResultSchema = z.discriminatedUnion("outcome", [
41
+ z.strictObject({ outcome: z.literal("purged") }),
42
+ z.strictObject({ outcome: z.literal("already_purged") }),
43
+ z.strictObject({ outcome: z.literal("unsupported") }),
44
+ z.strictObject({
45
+ outcome: z.literal("active"),
46
+ runIds: z.array(AgentRecordIdSchema).min(1)
47
47
  }),
48
- z2.strictObject({ outcome: z2.literal("conflict"), actualVersion: AgentRecordVersionSchema })
48
+ z.strictObject({ outcome: z.literal("conflict"), actualVersion: AgentRecordVersionSchema })
49
49
  ]);
50
50
 
51
51
  class AgentConversationPurgedError extends Error {
@@ -61,112 +61,27 @@ async function purgeAgentConversation(store, input) {
61
61
  return AgentConversationPurgeResultSchema.parse(await store.purgeConversation(parsed));
62
62
  }
63
63
 
64
- // src/agent-runtime/store.ts
65
- import { z as z3 } from "zod";
66
- var AgentStoreConflictSchema = z3.object({
67
- outcome: z3.literal("conflict"),
68
- actualVersion: AgentRecordVersionSchema
69
- });
70
- var AgentStoreNotFoundSchema = z3.object({ outcome: z3.literal("not_found") });
71
- var AgentStoreAppliedSchema = z3.object({
72
- outcome: z3.literal("applied"),
73
- snapshot: AgentSnapshotSchema
74
- });
75
- var AgentStoreDuplicateSchema = z3.object({
76
- outcome: z3.literal("duplicate"),
77
- input: AgentMessageSchema,
78
- inputMessageId: AgentRecordIdSchema,
79
- runId: AgentRecordIdSchema,
80
- assistantMessageId: AgentRecordIdSchema,
81
- run: AgentRunSchema,
82
- assistant: AgentMessageSchema.optional(),
83
- snapshot: AgentSnapshotSchema
84
- });
85
- var AgentStoreMutationResultSchema = z3.discriminatedUnion("outcome", [
86
- AgentStoreAppliedSchema,
87
- AgentStoreDuplicateSchema,
88
- AgentStoreConflictSchema,
89
- AgentStoreNotFoundSchema
90
- ]);
91
- var AgentRunViewSchema = z3.object({
92
- snapshotVersion: AgentRecordVersionSchema,
93
- run: AgentRunSchema,
94
- assistant: AgentMessageSchema.optional()
95
- });
96
- var AcceptInputAndAssignRunSchema = z3.object({
97
- idempotencyKey: z3.string().min(1),
98
- expectedVersion: AgentRecordVersionSchema.optional(),
99
- input: AgentMessageSchema,
100
- run: AgentRunSchema,
101
- coalesceIntoRunId: AgentRecordIdSchema.optional()
102
- });
103
- var AcquireAgentRunSchema = z3.object({
104
- conversationId: AgentRecordIdSchema,
105
- runId: AgentRecordIdSchema,
106
- expectedRevision: AgentRecordVersionSchema,
107
- ownerId: z3.string().min(1)
108
- });
109
- var CheckpointRunAssistantSchema = z3.object({
110
- conversationId: AgentRecordIdSchema,
111
- runId: AgentRecordIdSchema,
112
- expectedRevision: AgentRecordVersionSchema,
113
- ownerId: z3.string().min(1),
114
- fencingToken: AgentRecordVersionSchema.optional(),
115
- assistant: AgentMessageSchema,
116
- usage: AgentUsageSchema.optional()
117
- });
118
- var RecordRunOperationSchema = z3.object({
119
- conversationId: AgentRecordIdSchema,
120
- runId: AgentRecordIdSchema,
121
- expectedRevision: AgentRecordVersionSchema,
122
- ownerId: z3.string().min(1),
123
- fencingToken: AgentRecordVersionSchema.optional(),
124
- operation: AgentRunOperationSchema
125
- });
126
- var CommitRunTerminalSchema = z3.object({
127
- conversationId: AgentRecordIdSchema,
128
- runId: AgentRecordIdSchema,
129
- expectedRevision: AgentRecordVersionSchema,
130
- ownerId: z3.string().min(1),
131
- fencingToken: AgentRecordVersionSchema.optional(),
132
- assistant: AgentMessageSchema,
133
- reason: AgentTerminalReasonSchema,
134
- policyName: z3.string().min(1).optional(),
135
- usage: AgentUsageSchema.optional(),
136
- absorb: z3.array(z3.object({
137
- runId: AgentRecordIdSchema,
138
- inputMessageIds: z3.array(AgentRecordIdSchema).min(1)
139
- })).min(1).optional()
140
- });
141
- var RequestRunInterruptSchema = z3.object({
142
- conversationId: AgentRecordIdSchema,
143
- runId: AgentRecordIdSchema,
144
- expectedRevision: AgentRecordVersionSchema
145
- });
146
- var RecoverAgentRunSchema = z3.object({
147
- conversationId: AgentRecordIdSchema,
148
- runId: AgentRecordIdSchema,
149
- expectedRevision: AgentRecordVersionSchema,
150
- action: z3.enum(["requeue", "abandon"]),
151
- replaySafe: z3.boolean().optional()
152
- });
153
- var ReplaceCompactedRangeSchema = z3.object({
154
- conversationId: AgentRecordIdSchema,
155
- expectedVersion: AgentRecordVersionSchema,
156
- replacedMessageIds: z3.array(AgentRecordIdSchema).min(1),
157
- summary: AgentMessageSchema
158
- });
159
- var AgentRecoverableDescriptorSchema = z3.object({
64
+ // src/agent-runtime/conversations.ts
65
+ import { z as z2 } from "zod";
66
+ var AgentConversationSummarySchema = z2.object({
160
67
  conversationId: AgentRecordIdSchema,
161
- run: AgentRunSchema
162
- });
163
- var AgentRecoverablePageSchema = z3.object({
164
- items: z3.array(AgentRecoverableDescriptorSchema),
165
- nextCursor: z3.string().min(1).optional()
166
- });
68
+ version: AgentRecordVersionSchema,
69
+ updatedAt: z2.iso.datetime({ offset: true }),
70
+ preview: z2.string(),
71
+ activeRuns: z2.int().nonnegative()
72
+ }).strict();
73
+ var AgentConversationPageSchema = z2.object({
74
+ items: z2.array(AgentConversationSummarySchema),
75
+ nextCursor: z2.string().min(1).optional()
76
+ }).strict();
77
+ var AgentConversationMessagePageSchema = z2.object({
78
+ items: z2.array(AgentMessageSchema),
79
+ nextCursor: z2.string().min(1).optional()
80
+ }).strict();
167
81
 
168
82
  // src/agent-runtime/store-driver.ts
169
- import { z as z4 } from "zod";
83
+ import { createHash } from "node:crypto";
84
+ import { z as z3 } from "zod";
170
85
 
171
86
  // src/agent-runtime/store-purge.ts
172
87
  function createStoreConversationPurge(driver, conversations) {
@@ -192,40 +107,59 @@ function createStoreConversationPurge(driver, conversations) {
192
107
  }
193
108
 
194
109
  // src/agent-runtime/store-driver.ts
195
- var AgentRuntimeHeadSchema = z4.object({
196
- schemaVersion: z4.literal(1),
110
+ var AgentRuntimeHeadSchema = z3.object({
111
+ schemaVersion: z3.literal(1),
197
112
  conversationId: AgentRecordIdSchema,
198
113
  version: AgentRecordVersionSchema
199
114
  });
200
- var AgentStoredRunSchema = z4.object({
201
- schemaVersion: z4.literal(1),
115
+ var AgentStoredRunSchema = z3.object({
116
+ schemaVersion: z3.literal(1),
202
117
  run: AgentRunSchema,
203
118
  terminalAssistant: AgentMessageSchema.optional()
204
119
  });
205
- var AgentAdmissionReceiptSchema = z4.object({
206
- schemaVersion: z4.literal(1),
120
+ var AgentAdmissionReceiptSchema = z3.object({
121
+ schemaVersion: z3.literal(1),
207
122
  conversationId: AgentRecordIdSchema,
208
- idempotencyKey: z4.string().min(1),
123
+ idempotencyKey: z3.string().min(1),
209
124
  input: AgentMessageSchema,
210
125
  runId: AgentRecordIdSchema,
211
126
  assistantMessageId: AgentRecordIdSchema
212
127
  });
213
- var AgentHistoryMutationSchema = z4.discriminatedUnion("type", [
214
- z4.object({ type: z4.literal("admit"), input: AgentMessageSchema }),
215
- z4.object({
216
- type: z4.literal("upsert-assistant"),
128
+ var AgentHistoryMutationSchema = z3.discriminatedUnion("type", [
129
+ z3.object({ type: z3.literal("admit"), input: AgentMessageSchema }),
130
+ z3.object({
131
+ type: z3.literal("upsert-assistant"),
217
132
  message: AgentMessageSchema
218
133
  }),
219
- z4.object({
220
- type: z4.literal("replace-compacted-range"),
221
- replacedMessageIds: z4.array(AgentRecordIdSchema).min(1),
134
+ z3.object({
135
+ type: z3.literal("replace-compacted-range"),
136
+ replacedMessageIds: z3.array(AgentRecordIdSchema).min(1),
222
137
  summary: AgentMessageSchema
223
138
  })
224
139
  ]);
225
- var AgentRecoverableScanInputSchema = z4.object({
226
- cursor: z4.string().min(1).optional(),
227
- limit: z4.number().int().min(1).max(1000)
140
+ var AgentRecoverableScanInputSchema = z3.object({
141
+ cursor: z3.string().min(1).optional(),
142
+ limit: z3.number().int().min(1).max(1000)
228
143
  });
144
+ function transitionRecord(operation) {
145
+ if (operation.type !== "checkpoint")
146
+ return operation;
147
+ const { assistant, ...rest } = operation.input;
148
+ const body = canonicalAgentJson(assistant);
149
+ return {
150
+ type: operation.type,
151
+ input: {
152
+ ...rest,
153
+ assistant: {
154
+ id: assistant.id,
155
+ status: assistant.status,
156
+ sha256: createHash("sha256").update(body).digest("hex"),
157
+ parts: assistant.parts.length,
158
+ bytes: Buffer.byteLength(body)
159
+ }
160
+ }
161
+ };
162
+ }
229
163
  function emptyHead(conversationId) {
230
164
  return AgentRuntimeHeadSchema.parse({
231
165
  schemaVersion: 1,
@@ -328,7 +262,7 @@ function validateSnapshot(head, messages, records) {
328
262
  }
329
263
  }
330
264
  }
331
- var RecoverableCursorSchema = z4.tuple([AgentRecordIdSchema, AgentRecordIdSchema]);
265
+ var RecoverableCursorSchema = z3.tuple([AgentRecordIdSchema, AgentRecordIdSchema]);
332
266
  function recoverableCursor(input) {
333
267
  return JSON.stringify([input.conversationId, input.run.id]);
334
268
  }
@@ -650,7 +584,7 @@ function validateAdmissionReceipt(receipt, record, conversationId) {
650
584
  }
651
585
  }
652
586
  function createAgentRuntimeStore(driver) {
653
- const loadSnapshot = (conversationId) => driver.transaction(async (transaction) => {
587
+ const snapshotIn = async (transaction, conversationId) => {
654
588
  const [stored, messages, activeRecords] = await Promise.all([
655
589
  driver.head.load(transaction, conversationId),
656
590
  driver.history.load(transaction, conversationId),
@@ -662,7 +596,10 @@ function createAgentRuntimeStore(driver) {
662
596
  runIds: referencedRunIds(messages)
663
597
  });
664
598
  return snapshotOf(head, messages, mergeRunRecords(activeRecords, referencedRecords));
665
- }, { access: "read" });
599
+ };
600
+ const loadSnapshot = (conversationId) => driver.transaction((transaction) => snapshotIn(transaction, conversationId), {
601
+ access: "read"
602
+ });
666
603
  const loadRun = (input) => driver.transaction(async (transaction) => {
667
604
  const [stored, record] = await Promise.all([
668
605
  driver.head.load(transaction, input.conversationId),
@@ -798,12 +735,142 @@ function createAgentRuntimeStore(driver) {
798
735
  for (const mutation of reduced.historyMutations ?? []) {
799
736
  await driver.history.apply(transaction, mutation);
800
737
  }
738
+ await driver.events.append(transaction, agentStoreEventDraft({
739
+ conversationId,
740
+ kind: "runtime/transition",
741
+ payload: z3.json().parse(transitionRecord(operation))
742
+ }));
801
743
  return { outcome: "applied", snapshot: reduced.snapshot };
802
744
  });
745
+ const appendEvent = (input) => {
746
+ const parsed = AppendAgentStoreEventSchema.parse(input);
747
+ return driver.transaction(async (transaction) => {
748
+ if (await driver.conversations?.isPurged(transaction, parsed.conversationId)) {
749
+ throw new AgentConversationPurgedError;
750
+ }
751
+ return driver.events.append(transaction, agentStoreEventDraft(parsed));
752
+ });
753
+ };
754
+ const readEvents = (input) => {
755
+ const parsed = ReadAgentStoreEventsSchema.parse(input);
756
+ return driver.transaction(async (transaction) => AgentStoreEventPageSchema.parse(await driver.events.list(transaction, parsed)), { access: "read" });
757
+ };
758
+ const exportConversation = (conversationId) => driver.transaction(async (transaction) => {
759
+ const events = [];
760
+ let fromSeq;
761
+ do {
762
+ const page = AgentStoreEventPageSchema.parse(await driver.events.list(transaction, ReadAgentStoreEventsSchema.parse({
763
+ conversationId,
764
+ ...fromSeq && { fromSeq },
765
+ limit: 1e4
766
+ })));
767
+ events.push(...page.items);
768
+ fromSeq = page.nextSeq;
769
+ } while (fromSeq !== undefined);
770
+ const durable = await driver.archive?.export(transaction, conversationId) ?? {
771
+ projections: [],
772
+ spills: []
773
+ };
774
+ const snapshot = await snapshotIn(transaction, conversationId);
775
+ return encodeAgentConversationArchive({
776
+ format: "stitchkit.agent-conversation",
777
+ formatVersion: 1,
778
+ conversationId,
779
+ events,
780
+ projections: [
781
+ { archiveType: "runtime-snapshot", snapshot: z3.json().parse(snapshot) },
782
+ ...durable.projections
783
+ ],
784
+ spills: durable.spills
785
+ });
786
+ }, { access: "read" });
787
+ const importConversation = async (bytes) => {
788
+ const archive = decodeAgentConversationArchive(bytes);
789
+ return driver.transaction(async (transaction) => {
790
+ const existing = await driver.events.list(transaction, {
791
+ conversationId: archive.conversationId,
792
+ limit: 1
793
+ });
794
+ if (existing.items.length > 0) {
795
+ throw new TypeError("Conversation event log must be empty before import");
796
+ }
797
+ for (const event of archive.events) {
798
+ const appended = await driver.events.append(transaction, {
799
+ schemaVersion: event.schemaVersion,
800
+ eventId: event.eventId,
801
+ conversationId: event.conversationId,
802
+ kind: event.kind,
803
+ occurredAt: event.occurredAt,
804
+ payload: event.payload,
805
+ ...event.ignorable && { ignorable: true }
806
+ });
807
+ if (appended.seq !== event.seq) {
808
+ throw new TypeError("Conversation archive event sequence is not contiguous");
809
+ }
810
+ }
811
+ const snapshotEntry = archive.projections.find((entry) => typeof entry === "object" && entry !== null && !Array.isArray(entry) && entry.archiveType === "runtime-snapshot");
812
+ if (snapshotEntry && typeof snapshotEntry === "object" && !Array.isArray(snapshotEntry)) {
813
+ const snapshot = AgentSnapshotSchema.parse(snapshotEntry.snapshot);
814
+ if (snapshot.conversationId !== archive.conversationId) {
815
+ throw new TypeError("Conversation archive snapshot belongs to another conversation");
816
+ }
817
+ if (snapshot.version > 0 || snapshot.messages.length > 0 || snapshot.runs.length > 0) {
818
+ const outcome = await driver.head.compareAndSwap(transaction, {
819
+ conversationId: snapshot.conversationId,
820
+ expectedVersion: 0,
821
+ next: AgentRuntimeHeadSchema.parse({
822
+ schemaVersion: 1,
823
+ conversationId: snapshot.conversationId,
824
+ version: snapshot.version
825
+ })
826
+ });
827
+ if (outcome.outcome !== "applied") {
828
+ throw new TypeError("Conversation archive snapshot target is not empty");
829
+ }
830
+ }
831
+ for (const run of snapshot.runs) {
832
+ const terminalAssistant = snapshot.messages.find((message) => message.id === run.assistantMessageId);
833
+ await driver.runs.save(transaction, AgentStoredRunSchema.parse({
834
+ schemaVersion: 1,
835
+ run,
836
+ ...terminalAssistant && { terminalAssistant }
837
+ }));
838
+ }
839
+ for (const message of snapshot.messages) {
840
+ await driver.history.apply(transaction, { type: "admit", input: message });
841
+ }
842
+ for (const event of archive.events) {
843
+ if (event.kind !== "runtime/transition")
844
+ continue;
845
+ const transition = AgentStoreTransitionSchema.parse(event.payload);
846
+ if (transition.type !== "accept")
847
+ continue;
848
+ const assigned = snapshot.runs.find((run) => run.inputMessageIds.includes(transition.input.input.id));
849
+ if (!assigned) {
850
+ throw new TypeError("Conversation archive admission has no assigned run");
851
+ }
852
+ await driver.admissions.create(transaction, AgentAdmissionReceiptSchema.parse({
853
+ schemaVersion: 1,
854
+ conversationId: archive.conversationId,
855
+ idempotencyKey: transition.input.idempotencyKey,
856
+ input: transition.input.input,
857
+ runId: assigned.id,
858
+ assistantMessageId: assigned.assistantMessageId
859
+ }));
860
+ }
861
+ }
862
+ await driver.archive?.import(transaction, archive);
863
+ return { conversationId: archive.conversationId, events: archive.events.length };
864
+ });
865
+ };
803
866
  return {
804
867
  loadSnapshot,
805
868
  loadRun,
806
869
  listActiveRuns,
870
+ appendEvent,
871
+ readEvents,
872
+ exportConversation,
873
+ importConversation,
807
874
  ...driver.conversations && {
808
875
  purgeConversation: createStoreConversationPurge(driver, driver.conversations)
809
876
  },
@@ -860,6 +927,7 @@ function createMemoryAgentRuntimeStore() {
860
927
  let runs = new Map;
861
928
  let admissions = new Map;
862
929
  let histories = new Map;
930
+ let events = new Map;
863
931
  let transactionTail = Promise.resolve();
864
932
  const driver = {
865
933
  async transaction(work) {
@@ -876,7 +944,11 @@ function createMemoryAgentRuntimeStore() {
876
944
  heads: cloneHeadMap(heads),
877
945
  runs: cloneNestedMap(runs, (record) => AgentStoredRunSchema.parse(structuredClone(record))),
878
946
  admissions: cloneNestedMap(admissions, (receipt) => AgentAdmissionReceiptSchema.parse(structuredClone(receipt))),
879
- histories: cloneHistoryMap(histories)
947
+ histories: cloneHistoryMap(histories),
948
+ events: new Map([...events].map(([conversationId, stored]) => [
949
+ conversationId,
950
+ stored.map((event) => AgentStoreEventEnvelopeSchema.parse(structuredClone(event)))
951
+ ]))
880
952
  };
881
953
  try {
882
954
  const result = await work(transaction);
@@ -885,6 +957,7 @@ function createMemoryAgentRuntimeStore() {
885
957
  runs = transaction.runs;
886
958
  admissions = transaction.admissions;
887
959
  histories = transaction.histories;
960
+ events = transaction.events;
888
961
  return result;
889
962
  } finally {
890
963
  release.resolve();
@@ -900,6 +973,7 @@ function createMemoryAgentRuntimeStore() {
900
973
  transaction.runs.delete(conversationId);
901
974
  transaction.admissions.delete(conversationId);
902
975
  transaction.histories.delete(conversationId);
976
+ transaction.events.delete(conversationId);
903
977
  }
904
978
  },
905
979
  head: {
@@ -995,6 +1069,29 @@ function createMemoryAgentRuntimeStore() {
995
1069
  ]);
996
1070
  }
997
1071
  },
1072
+ events: {
1073
+ async append(transaction, draft) {
1074
+ const current = transaction.events.get(draft.conversationId) ?? [];
1075
+ const event = AgentStoreEventEnvelopeSchema.parse({
1076
+ ...draft,
1077
+ seq: (current.at(-1)?.seq ?? 0) + 1
1078
+ });
1079
+ if (current.some((candidate) => candidate.eventId === event.eventId)) {
1080
+ throw new TypeError("Agent store event identity is already present");
1081
+ }
1082
+ transaction.events.set(draft.conversationId, [...current, event]);
1083
+ return event;
1084
+ },
1085
+ async list(transaction, input) {
1086
+ const selected = (transaction.events.get(input.conversationId) ?? []).filter((event) => (input.fromSeq === undefined || event.seq >= input.fromSeq) && (input.toSeq === undefined || event.seq <= input.toSeq));
1087
+ const items = selected.slice(0, input.limit);
1088
+ const last = items.at(-1);
1089
+ return AgentStoreEventPageSchema.parse({
1090
+ items,
1091
+ ...selected.length > items.length && last ? { nextSeq: last.seq + 1 } : {}
1092
+ });
1093
+ }
1094
+ },
998
1095
  async scanRecoverable(input) {
999
1096
  const descriptors = [...runs].flatMap(([conversationId, conversationRuns]) => [...conversationRuns.values()].filter((record) => isActiveRunState(record.run.state)).map((record) => ({ conversationId, run: record.run }))).sort((left, right) => left.conversationId.localeCompare(right.conversationId) || left.run.id.localeCompare(right.run.id));
1000
1097
  const cursorTuple = input.cursor ? parseRecoverableCursor(input.cursor) : undefined;
@@ -1014,4 +1111,4 @@ function createMemoryAgentRuntimeStore() {
1014
1111
  return createAgentRuntimeStore(driver);
1015
1112
  }
1016
1113
 
1017
- export { AgentConversationSummarySchema, AgentConversationPageSchema, AgentConversationMessagePageSchema, AgentConversationPurgeInputSchema, AgentConversationPurgeResultSchema, AgentConversationPurgedError, purgeAgentConversation, AgentStoreConflictSchema, AgentStoreNotFoundSchema, AgentStoreAppliedSchema, AgentStoreDuplicateSchema, AgentStoreMutationResultSchema, AgentRunViewSchema, AcceptInputAndAssignRunSchema, AcquireAgentRunSchema, CheckpointRunAssistantSchema, RecordRunOperationSchema, CommitRunTerminalSchema, RequestRunInterruptSchema, RecoverAgentRunSchema, ReplaceCompactedRangeSchema, AgentRecoverableDescriptorSchema, AgentRecoverablePageSchema, AgentRuntimeHeadSchema, AgentStoredRunSchema, AgentAdmissionReceiptSchema, AgentHistoryMutationSchema, ACTIVE_AGENT_RUN_STATES, createAgentRuntimeStore, createMemoryAgentRuntimeStore };
1114
+ export { AgentConversationPurgeInputSchema, AgentConversationPurgeResultSchema, AgentConversationPurgedError, purgeAgentConversation, AgentConversationSummarySchema, AgentConversationPageSchema, AgentConversationMessagePageSchema, AgentRuntimeHeadSchema, AgentStoredRunSchema, AgentAdmissionReceiptSchema, AgentHistoryMutationSchema, ACTIVE_AGENT_RUN_STATES, createAgentRuntimeStore, createMemoryAgentRuntimeStore };