stitchkit 0.78.0 → 0.80.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 (84) hide show
  1. package/dist/agent-runtime-browser.js +53 -581
  2. package/dist/agent-runtime-coding-tools.js +6 -5
  3. package/dist/agent-runtime-harness.js +21 -94
  4. package/dist/agent-runtime-openrouter.js +1 -1
  5. package/dist/agent-runtime.js +68 -64
  6. package/dist/application/kernel.d.ts.map +1 -1
  7. package/dist/application/schemas.d.ts +2 -0
  8. package/dist/application/schemas.d.ts.map +1 -1
  9. package/dist/application/watch-hub.d.ts.map +1 -1
  10. package/dist/application-diagnostic-journal.js +14 -96
  11. package/dist/application-opentelemetry.js +6 -92
  12. package/dist/application-schemas.js +2 -1
  13. package/dist/application.js +158 -1802
  14. package/dist/cli.js +13 -11
  15. package/dist/contract/index.js +7 -4
  16. package/dist/index-2qzskm8h.js +63 -0
  17. package/dist/{index-93xp5tgg.js → index-2rwwmr7v.js} +3 -3
  18. package/dist/{index-kw12fsbc.js → index-3gye9wzb.js} +7 -3
  19. package/dist/{index-1ckavx4h.js → index-3z73fh2c.js} +1 -49
  20. package/dist/index-4fpa9dy2.js +51 -0
  21. package/dist/{index-cwp38wxn.js → index-5mtc969c.js} +2 -2
  22. package/dist/index-5s3zajp8.js +192 -0
  23. package/dist/index-6s7n2v50.js +583 -0
  24. package/dist/{index-qaajjfp6.js → index-758zx2ha.js} +15 -94
  25. package/dist/{index-qyrqwr4c.js → index-77fekveh.js} +4 -1
  26. package/dist/{index-k45qqrdh.js → index-7ag81v2f.js} +13 -166
  27. package/dist/{index-n1g2xm6a.js → index-7gnkny4z.js} +124 -1
  28. package/dist/index-7zbps32p.js +89 -0
  29. package/dist/index-85vfqd7m.js +135 -0
  30. package/dist/{index-4ntp63ps.js → index-9s6z8vgf.js} +18 -142
  31. package/dist/index-a916km3r.js +45 -0
  32. package/dist/index-b9aefrqd.js +20 -0
  33. package/dist/index-dre2ywck.js +48 -0
  34. package/dist/{index-s5tn4kdv.js → index-dwf1f2ap.js} +3 -3
  35. package/dist/{index-wwst0td5.js → index-dx9xehwt.js} +1 -1
  36. package/dist/{index-5r0ak8fr.js → index-dxesg10d.js} +4 -4
  37. package/dist/{index-aczggrty.js → index-dxjjv399.js} +2 -2
  38. package/dist/{index-j6mfaw26.js → index-egaabxkz.js} +3 -3
  39. package/dist/index-evcnmsc3.js +866 -0
  40. package/dist/{index-efm026pw.js → index-fxz0v7vg.js} +86 -86
  41. package/dist/{index-56fm73re.js → index-hb5pf3s4.js} +1 -1
  42. package/dist/{index-n7apa6sy.js → index-k9ay6v6d.js} +24 -275
  43. package/dist/index-kzfs85xp.js +9 -0
  44. package/dist/{index-vbf2p6me.js → index-m9kzax52.js} +91 -89
  45. package/dist/{index-22by16v6.js → index-mgtxfe6b.js} +1 -1
  46. package/dist/index-p7hgdyhb.js +22 -0
  47. package/dist/index-pq95qkbf.js +0 -0
  48. package/dist/index-t0z5p5w6.js +318 -0
  49. package/dist/{index-31k1ns1s.js → index-vwp69871.js} +13 -11
  50. package/dist/index-wc4x00bn.js +103 -0
  51. package/dist/{index-aewy3x5j.js → index-xcetq6j3.js} +10 -8
  52. package/dist/{index-7z69kyrh.js → index-y01f4223.js} +24 -40
  53. package/dist/{index-dmfn9m4x.js → index-ywd0y6m1.js} +20 -341
  54. package/dist/index.js +46 -407
  55. package/dist/live.js +6 -3
  56. package/dist/node.js +17 -14
  57. package/dist/observability/index.js +8 -7
  58. package/dist/primitives.js +4 -2
  59. package/dist/react.js +1 -1
  60. package/dist/remote.js +7 -3
  61. package/dist/server/index.js +32 -45
  62. package/dist/telegram.js +1 -1
  63. package/dist/testing.js +90 -1576
  64. package/dist/tool-invoker.js +11 -9
  65. package/dist/tools/async-operation-contract.d.ts +93 -0
  66. package/dist/tools/async-operation-contract.d.ts.map +1 -0
  67. package/dist/tools/async-operation.d.ts +2 -47
  68. package/dist/tools/async-operation.d.ts.map +1 -1
  69. package/dist/tools/view-file-contract.d.ts +98 -0
  70. package/dist/tools/view-file-contract.d.ts.map +1 -0
  71. package/dist/tools/view-file.d.ts +4 -83
  72. package/dist/tools/view-file.d.ts.map +1 -1
  73. package/dist/tools-contract.d.ts +29 -0
  74. package/dist/tools-contract.d.ts.map +1 -0
  75. package/dist/tools-contract.js +24 -0
  76. package/dist/tools.d.ts +3 -3
  77. package/dist/tools.d.ts.map +1 -1
  78. package/dist/tools.js +61 -140
  79. package/llms-full.txt +86 -3
  80. package/package.json +9 -6
  81. package/dist/index-anyqnqcv.js +0 -79
  82. package/dist/index-ksp6e2ye.js +0 -24
  83. package/dist/index-vj3vvpaa.js +0 -307
  84. package/dist/index-wfq8zerm.js +0 -92
package/dist/cli.js CHANGED
@@ -5,20 +5,22 @@ import {
5
5
  emitResult,
6
6
  parseCliArgs,
7
7
  pollUntilDone
8
- } from "./index-31k1ns1s.js";
9
- import"./index-93xp5tgg.js";
10
- import"./index-wwst0td5.js";
11
- import"./index-cwp38wxn.js";
12
- import"./index-qaajjfp6.js";
8
+ } from "./index-vwp69871.js";
13
9
  import"./index-sbdmyz75.js";
14
- import"./index-22by16v6.js";
10
+ import"./index-2rwwmr7v.js";
11
+ import"./index-dx9xehwt.js";
12
+ import"./index-5mtc969c.js";
13
+ import"./index-758zx2ha.js";
14
+ import"./index-dwf1f2ap.js";
15
+ import"./index-mgtxfe6b.js";
15
16
  import"./index-cby4ar3v.js";
16
- import"./index-s5tn4kdv.js";
17
- import"./index-efm026pw.js";
18
- import"./index-vj3vvpaa.js";
19
- import"./index-qyrqwr4c.js";
20
- import"./index-0w9abg87.js";
17
+ import"./index-7zbps32p.js";
18
+ import"./index-fxz0v7vg.js";
19
+ import"./index-y01f4223.js";
21
20
  import"./index-6k1937bx.js";
21
+ import"./index-0w9abg87.js";
22
+ import"./index-kzfs85xp.js";
23
+ import"./index-77fekveh.js";
22
24
  export {
23
25
  pollUntilDone,
24
26
  parseCliArgs,
@@ -2,15 +2,17 @@ import {
2
2
  ALL_TRANSPORTS,
3
3
  ContractStreamFrameSchema,
4
4
  DEFAULT_CONTRACT_STREAM_FRAME_BYTES,
5
- ManagedFilePathSchema,
6
- ManagedFileRefSchema,
7
5
  createContractFactory,
8
6
  decodeCursor,
9
7
  defineContract,
10
8
  defineErrors,
11
9
  encodeCursor,
12
10
  paginatedSchema
13
- } from "../index-7z69kyrh.js";
11
+ } from "../index-y01f4223.js";
12
+ import {
13
+ ManagedFilePathSchema,
14
+ ManagedFileRefSchema
15
+ } from "../index-6k1937bx.js";
14
16
  import {
15
17
  AppError,
16
18
  STITCH_ERROR_STATUS,
@@ -23,7 +25,8 @@ import {
23
25
  rateLimited,
24
26
  unauthorized
25
27
  } from "../index-0w9abg87.js";
26
- import"../index-ksp6e2ye.js";
28
+ import"../index-kzfs85xp.js";
29
+ import"../index-77fekveh.js";
27
30
  export {
28
31
  unauthorized,
29
32
  rateLimited,
@@ -0,0 +1,63 @@
1
+ // src/realtime/request.ts
2
+ import { z } from "zod";
3
+ var RealtimeRequestPhaseSchema = z.enum([
4
+ "engine-handoff",
5
+ "engine-ack-received",
6
+ "settled",
7
+ "timeout",
8
+ "disconnected"
9
+ ]);
10
+ var RealtimeRequestPhaseEventSchema = z.object({
11
+ requestId: z.string().min(1),
12
+ event: z.string().min(1),
13
+ phase: RealtimeRequestPhaseSchema,
14
+ elapsedMs: z.number().finite().nonnegative()
15
+ }).strict();
16
+
17
+ class RealtimeRequestTimeoutError extends Error {
18
+ code = "REALTIME_REQUEST_TIMEOUT";
19
+ event;
20
+ timeoutMs;
21
+ constructor(event, timeoutMs) {
22
+ super(`Realtime request "${event}" timed out after ${timeoutMs}ms`);
23
+ this.name = "RealtimeRequestTimeoutError";
24
+ this.event = event;
25
+ this.timeoutMs = timeoutMs;
26
+ }
27
+ }
28
+
29
+ class RealtimeRequestDisconnectedError extends Error {
30
+ code = "REALTIME_REQUEST_DISCONNECTED";
31
+ event;
32
+ constructor(event) {
33
+ super(`Realtime request "${event}" was interrupted by disconnect`);
34
+ this.name = "RealtimeRequestDisconnectedError";
35
+ this.event = event;
36
+ }
37
+ }
38
+
39
+ class RealtimeRequestInvalidAcknowledgementError extends Error {
40
+ code = "REALTIME_REQUEST_INVALID_ACKNOWLEDGEMENT";
41
+ event;
42
+ constructor(event, cause) {
43
+ super(`Realtime request "${event}" received an invalid acknowledgement`, { cause });
44
+ this.name = "RealtimeRequestInvalidAcknowledgementError";
45
+ this.event = event;
46
+ }
47
+ }
48
+
49
+ class RealtimeRequestRejectedError extends Error {
50
+ code = "REALTIME_REQUEST_REJECTED";
51
+ event;
52
+ reason;
53
+ issues;
54
+ constructor(event, reason, detail, issues) {
55
+ super(`Realtime request "${event}" was rejected by the peer (${reason}): ${detail}`);
56
+ this.name = "RealtimeRequestRejectedError";
57
+ this.event = event;
58
+ this.reason = reason;
59
+ this.issues = issues;
60
+ }
61
+ }
62
+
63
+ export { RealtimeRequestPhaseSchema, RealtimeRequestPhaseEventSchema, RealtimeRequestTimeoutError, RealtimeRequestDisconnectedError, RealtimeRequestInvalidAcknowledgementError, RealtimeRequestRejectedError };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  runtimeToolMountable
3
- } from "./index-wwst0td5.js";
3
+ } from "./index-dx9xehwt.js";
4
4
  import {
5
5
  contractToolMountable
6
- } from "./index-cwp38wxn.js";
6
+ } from "./index-5mtc969c.js";
7
7
  import {
8
8
  projectToolSurface
9
- } from "./index-22by16v6.js";
9
+ } from "./index-mgtxfe6b.js";
10
10
 
11
11
  // src/tools/surface.ts
12
12
  function collectToolSurface({
@@ -44,7 +44,8 @@ var ApplicationSnapshotSchema = z.object({
44
44
  capturedAt: z.string().datetime({ offset: true }),
45
45
  changedAt: z.string().datetime({ offset: true }),
46
46
  admission: ApplicationAdmissionSnapshotSchema,
47
- resources: z.array(ManagedResourceSnapshotSchema).readonly()
47
+ resources: z.array(ManagedResourceSnapshotSchema).readonly(),
48
+ restarting: z.array(z.string()).readonly()
48
49
  }).readonly();
49
50
  var ApplicationStatusProjectionSchema = z.object({
50
51
  id: ApplicationIdSchema,
@@ -57,7 +58,8 @@ var ApplicationStatusProjectionSchema = z.object({
57
58
  ready: NonNegativeIntegerSchema,
58
59
  degraded: NonNegativeIntegerSchema,
59
60
  failed: NonNegativeIntegerSchema
60
- }).readonly()
61
+ }).readonly(),
62
+ restarting: NonNegativeIntegerSchema
61
63
  }).readonly();
62
64
  function projectApplicationStatus(snapshot) {
63
65
  let ready = 0;
@@ -77,7 +79,8 @@ function projectApplicationStatus(snapshot) {
77
79
  health: snapshot.health,
78
80
  ready: snapshot.ready,
79
81
  capturedAt: snapshot.capturedAt,
80
- resources: { total: snapshot.resources.length, ready, degraded, failed }
82
+ resources: { total: snapshot.resources.length, ready, degraded, failed },
83
+ restarting: snapshot.restarting.length
81
84
  };
82
85
  }
83
86
  var ApplicationResourceShutdownSchema = z.object({
@@ -96,4 +99,5 @@ var ApplicationShutdownResultSchema = z.object({
96
99
  resources: z.array(ApplicationResourceShutdownSchema).readonly(),
97
100
  durationMs: z.number().nonnegative()
98
101
  }).readonly();
102
+
99
103
  export { ApplicationIdSchema, ApplicationLifecycleSchema, ApplicationHealthSchema, ManagedResourceStateSchema, ApplicationAdmissionSnapshotSchema, ManagedResourceSnapshotSchema, ApplicationSnapshotSchema, ApplicationStatusProjectionSchema, projectApplicationStatus, ApplicationResourceShutdownSchema, ApplicationShutdownResultSchema };
@@ -329,52 +329,4 @@ function createServerLifecycle(getAdapter) {
329
329
  };
330
330
  }
331
331
 
332
- // src/realtime/request.ts
333
- import { z as z2 } from "zod";
334
- var RealtimeRequestPhaseSchema = z2.enum([
335
- "engine-handoff",
336
- "engine-ack-received",
337
- "settled",
338
- "timeout",
339
- "disconnected"
340
- ]);
341
- var RealtimeRequestPhaseEventSchema = z2.object({
342
- requestId: z2.string().min(1),
343
- event: z2.string().min(1),
344
- phase: RealtimeRequestPhaseSchema,
345
- elapsedMs: z2.number().finite().nonnegative()
346
- }).strict();
347
-
348
- class RealtimeRequestTimeoutError extends Error {
349
- code = "REALTIME_REQUEST_TIMEOUT";
350
- event;
351
- timeoutMs;
352
- constructor(event, timeoutMs) {
353
- super(`Realtime request "${event}" timed out after ${timeoutMs}ms`);
354
- this.name = "RealtimeRequestTimeoutError";
355
- this.event = event;
356
- this.timeoutMs = timeoutMs;
357
- }
358
- }
359
-
360
- class RealtimeRequestDisconnectedError extends Error {
361
- code = "REALTIME_REQUEST_DISCONNECTED";
362
- event;
363
- constructor(event) {
364
- super(`Realtime request "${event}" was interrupted by disconnect`);
365
- this.name = "RealtimeRequestDisconnectedError";
366
- this.event = event;
367
- }
368
- }
369
-
370
- class RealtimeRequestInvalidAcknowledgementError extends Error {
371
- code = "REALTIME_REQUEST_INVALID_ACKNOWLEDGEMENT";
372
- event;
373
- constructor(event, cause) {
374
- super(`Realtime request "${event}" received an invalid acknowledgement`, { cause });
375
- this.name = "RealtimeRequestInvalidAcknowledgementError";
376
- this.event = event;
377
- }
378
- }
379
-
380
- export { isStreamCancellation, ownHttpStream, settleStreamCleanup, ShutdownStateSchema, ShutdownOptionsSchema, ShutdownStatusSchema, ShutdownResultSchema, createServerLifecycle, RealtimeRequestTimeoutError, RealtimeRequestDisconnectedError, RealtimeRequestInvalidAcknowledgementError };
332
+ export { isStreamCancellation, ownHttpStream, settleStreamCleanup, ShutdownStateSchema, ShutdownOptionsSchema, ShutdownStatusSchema, ShutdownResultSchema, createServerLifecycle };
@@ -0,0 +1,51 @@
1
+ // src/tools/async-operation-contract.ts
2
+ import { z } from "zod";
3
+ var AsyncOperationCancelResultSchema = z.discriminatedUnion("outcome", [
4
+ z.object({ outcome: z.literal("accepted") }),
5
+ z.object({ outcome: z.literal("already_terminal") }),
6
+ z.object({ outcome: z.literal("rejected"), reason: z.string().min(1) })
7
+ ]);
8
+ function createAsyncOperationSnapshotSchema(config) {
9
+ const progress = config.progress ? { progress: config.progress.optional() } : {};
10
+ return z.discriminatedUnion("phase", [
11
+ z.object({ phase: z.literal("pending"), ...progress }),
12
+ z.object({ phase: z.literal("running"), ...progress }),
13
+ z.object({ phase: z.literal("succeeded"), ...progress }),
14
+ z.object({ phase: z.literal("failed"), failure: config.failure, ...progress }),
15
+ z.object({ phase: z.literal("cancelled"), ...progress })
16
+ ]);
17
+ }
18
+ // src/tools/view-file-contract.ts
19
+ import { z as z2 } from "zod";
20
+ var MAX_VIEW_FILES = 20;
21
+ var McpAnnotationsSchema = z2.object({
22
+ audience: z2.array(z2.enum(["user", "assistant"])).optional(),
23
+ priority: z2.number().optional()
24
+ });
25
+ var McpMediaContentSchema = z2.discriminatedUnion("type", [
26
+ z2.object({ type: z2.literal("text"), text: z2.string() }),
27
+ z2.object({
28
+ type: z2.literal("image"),
29
+ data: z2.string(),
30
+ mimeType: z2.string(),
31
+ annotations: McpAnnotationsSchema.optional()
32
+ }),
33
+ z2.object({
34
+ type: z2.literal("audio"),
35
+ data: z2.string(),
36
+ mimeType: z2.string(),
37
+ annotations: McpAnnotationsSchema.optional()
38
+ })
39
+ ]);
40
+ var ViewFileErrorSchema = z2.object({
41
+ path: z2.string(),
42
+ message: z2.string()
43
+ });
44
+ var ViewFileOutputSchema = z2.object({
45
+ content: z2.array(McpMediaContentSchema),
46
+ errors: z2.array(ViewFileErrorSchema)
47
+ });
48
+ var ViewFileInputSchema = z2.object({
49
+ paths: z2.union([z2.string(), z2.array(z2.string()).max(MAX_VIEW_FILES)]).describe("Media URL(s) or file path(s) to view")
50
+ });
51
+ export { AsyncOperationCancelResultSchema, createAsyncOperationSnapshotSchema, McpAnnotationsSchema, McpMediaContentSchema, ViewFileErrorSchema, ViewFileOutputSchema, ViewFileInputSchema };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  executeToolMethod
3
- } from "./index-qaajjfp6.js";
3
+ } from "./index-758zx2ha.js";
4
4
  import {
5
5
  assertToolExtensionCompatible,
6
6
  mergeSchemas,
7
7
  projectToolSurface,
8
8
  rebuildObject
9
- } from "./index-22by16v6.js";
9
+ } from "./index-mgtxfe6b.js";
10
10
 
11
11
  // src/tools/mount.ts
12
12
  import { z } from "zod";
@@ -0,0 +1,192 @@
1
+ import {
2
+ AgentRuntimeEventSchema
3
+ } from "./index-85vfqd7m.js";
4
+ import {
5
+ AgentMessagePartSchema,
6
+ AgentSnapshotSchema
7
+ } from "./index-x1th9s8c.js";
8
+
9
+ // src/agent-runtime/control-schema.ts
10
+ import { z } from "zod";
11
+ var AgentControlIdentitySchema = z.object({ schemaVersion: z.literal(1), requestId: z.string().min(1) }).strict();
12
+ var AgentControlRequestSchema = z.discriminatedUnion("operation", [
13
+ AgentControlIdentitySchema.extend({
14
+ operation: z.literal("attach"),
15
+ conversationId: z.string().min(1),
16
+ access: z.enum(["observe", "control"])
17
+ }),
18
+ AgentControlIdentitySchema.extend({
19
+ operation: z.literal("detach"),
20
+ conversationId: z.string().min(1)
21
+ }),
22
+ AgentControlIdentitySchema.extend({
23
+ operation: z.literal("snapshot"),
24
+ conversationId: z.string().min(1)
25
+ }),
26
+ AgentControlIdentitySchema.extend({
27
+ operation: z.literal("submit"),
28
+ conversationId: z.string().min(1),
29
+ idempotencyKey: z.string().min(1),
30
+ context: z.unknown(),
31
+ parts: z.array(AgentMessagePartSchema).min(1),
32
+ metadata: z.unknown().optional()
33
+ }),
34
+ AgentControlIdentitySchema.extend({
35
+ operation: z.literal("interrupt"),
36
+ conversationId: z.string().min(1),
37
+ runId: z.string().min(1)
38
+ }),
39
+ AgentControlIdentitySchema.extend({
40
+ operation: z.literal("respond-approval"),
41
+ conversationId: z.string().min(1),
42
+ approvalId: z.string().min(1),
43
+ approved: z.boolean(),
44
+ reason: z.string().min(1).optional(),
45
+ context: z.unknown(),
46
+ metadata: z.unknown().optional()
47
+ })
48
+ ]);
49
+ var AgentControlResponseIdentitySchema = z.object({
50
+ schemaVersion: z.literal(1),
51
+ requestId: z.string().min(1)
52
+ });
53
+ var AgentControlResponseSchema = z.discriminatedUnion("outcome", [
54
+ AgentControlResponseIdentitySchema.extend({
55
+ outcome: z.literal("ok"),
56
+ snapshot: AgentSnapshotSchema.optional(),
57
+ runId: z.string().min(1).optional()
58
+ }).strict(),
59
+ AgentControlResponseIdentitySchema.extend({
60
+ outcome: z.literal("error"),
61
+ error: z.object({ code: z.string().min(1), message: z.string().min(1) }).strict()
62
+ }).strict()
63
+ ]);
64
+ var AgentControlDeliverySchema = z.discriminatedUnion("type", [
65
+ z.object({
66
+ schemaVersion: z.literal(1),
67
+ type: z.literal("event"),
68
+ event: AgentRuntimeEventSchema
69
+ }).strict(),
70
+ z.object({
71
+ schemaVersion: z.literal(1),
72
+ type: z.literal("resync-required"),
73
+ conversationId: z.string().min(1),
74
+ reason: z.literal("overflow")
75
+ }).strict()
76
+ ]);
77
+ var AgentMultiSessionCursorSchema = z.object({
78
+ conversations: z.record(z.string(), z.object({
79
+ snapshotVersion: z.int().nonnegative().optional(),
80
+ durableEventIds: z.array(z.string().min(1)).optional(),
81
+ runs: z.record(z.string(), z.object({ runtimeEpoch: z.string().min(1), sequence: z.int().nonnegative() }).strict())
82
+ }).strict())
83
+ }).strict();
84
+ function durable(event) {
85
+ return ["admission", "assistant-checkpoint", "run-state", "terminal"].includes(event.type);
86
+ }
87
+ function advanceAgentMultiSessionCursor(raw, event) {
88
+ const cursor = AgentMultiSessionCursorSchema.parse(raw);
89
+ const previous = cursor.conversations[event.conversationId] ?? { runs: {} };
90
+ if (durable(event)) {
91
+ const ids = previous.snapshotVersion === event.snapshotVersion ? previous.durableEventIds ?? [] : [];
92
+ if (previous.snapshotVersion !== undefined && event.snapshotVersion < previous.snapshotVersion || ids.includes(event.eventId)) {
93
+ return { status: "duplicate", cursor };
94
+ }
95
+ return {
96
+ status: "accepted",
97
+ cursor: {
98
+ conversations: {
99
+ ...cursor.conversations,
100
+ [event.conversationId]: {
101
+ ...previous,
102
+ snapshotVersion: event.snapshotVersion,
103
+ durableEventIds: [...ids, event.eventId]
104
+ }
105
+ }
106
+ }
107
+ };
108
+ }
109
+ const run = previous.runs[event.runId];
110
+ const sequence = run?.runtimeEpoch === event.runtimeEpoch ? run.sequence : undefined;
111
+ if (sequence !== undefined && event.sequence <= sequence)
112
+ return { status: "duplicate", cursor };
113
+ const expected = sequence === undefined ? 1 : sequence + 1;
114
+ return {
115
+ status: event.sequence === expected ? "accepted" : "gap",
116
+ cursor: {
117
+ conversations: {
118
+ ...cursor.conversations,
119
+ [event.conversationId]: {
120
+ ...previous,
121
+ runs: {
122
+ ...previous.runs,
123
+ [event.runId]: { runtimeEpoch: event.runtimeEpoch, sequence: event.sequence }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ };
129
+ }
130
+ function createAgentControlView() {
131
+ return { cursor: { conversations: {} }, conversations: {} };
132
+ }
133
+ function reduceAgentControlSnapshot(view, rawSnapshot) {
134
+ const snapshot = AgentSnapshotSchema.parse(rawSnapshot);
135
+ const previous = view.cursor.conversations[snapshot.conversationId] ?? { runs: {} };
136
+ return {
137
+ cursor: {
138
+ conversations: {
139
+ ...view.cursor.conversations,
140
+ [snapshot.conversationId]: {
141
+ ...previous,
142
+ snapshotVersion: snapshot.version,
143
+ durableEventIds: []
144
+ }
145
+ }
146
+ },
147
+ conversations: {
148
+ ...view.conversations,
149
+ [snapshot.conversationId]: {
150
+ snapshot,
151
+ resyncRequired: false,
152
+ transientByRun: {}
153
+ }
154
+ }
155
+ };
156
+ }
157
+ function reduceAgentControlEvent(view, rawEvent) {
158
+ const event = AgentRuntimeEventSchema.parse(rawEvent);
159
+ const advanced = advanceAgentMultiSessionCursor(view.cursor, event);
160
+ if (advanced.status === "duplicate")
161
+ return view;
162
+ const current = view.conversations[event.conversationId] ?? {
163
+ resyncRequired: false,
164
+ transientByRun: {}
165
+ };
166
+ if (advanced.status === "gap") {
167
+ return {
168
+ cursor: advanced.cursor,
169
+ conversations: {
170
+ ...view.conversations,
171
+ [event.conversationId]: { ...current, resyncRequired: true }
172
+ }
173
+ };
174
+ }
175
+ const transient = current.transientByRun[event.runId] ?? { text: "", reasoning: "" };
176
+ const nextTransient = event.type === "assistant-delta" ? { ...transient, text: transient.text + event.textDelta } : event.type === "reasoning-delta" ? { ...transient, reasoning: transient.reasoning + event.textDelta } : transient;
177
+ const snapshotStale = durable(event) && current.snapshot?.version !== event.snapshotVersion;
178
+ const transientByRun = event.type === "terminal" ? Object.fromEntries(Object.entries(current.transientByRun).filter(([runId]) => runId !== event.runId)) : { ...current.transientByRun, [event.runId]: nextTransient };
179
+ return {
180
+ cursor: advanced.cursor,
181
+ conversations: {
182
+ ...view.conversations,
183
+ [event.conversationId]: {
184
+ ...current,
185
+ resyncRequired: current.resyncRequired || snapshotStale,
186
+ transientByRun
187
+ }
188
+ }
189
+ };
190
+ }
191
+
192
+ export { AgentControlRequestSchema, AgentControlResponseSchema, AgentControlDeliverySchema, AgentMultiSessionCursorSchema, advanceAgentMultiSessionCursor, createAgentControlView, reduceAgentControlSnapshot, reduceAgentControlEvent };