stitchkit 0.77.0 → 0.79.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 (99) 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 +20 -93
  4. package/dist/agent-runtime-openrouter.js +1 -1
  5. package/dist/agent-runtime.js +65 -61
  6. package/dist/application/decisions.d.ts +28 -25
  7. package/dist/application/decisions.d.ts.map +1 -1
  8. package/dist/application/kernel.d.ts +2 -0
  9. package/dist/application/kernel.d.ts.map +1 -1
  10. package/dist/application/keyspace.d.ts +11 -1
  11. package/dist/application/keyspace.d.ts.map +1 -1
  12. package/dist/application/schedule.d.ts.map +1 -1
  13. package/dist/application/schemas.d.ts +2 -0
  14. package/dist/application/schemas.d.ts.map +1 -1
  15. package/dist/application/server-resource.d.ts.map +1 -1
  16. package/dist/application/watch-hub.d.ts.map +1 -1
  17. package/dist/application-diagnostic-journal.d.ts +21 -0
  18. package/dist/application-diagnostic-journal.d.ts.map +1 -0
  19. package/dist/application-diagnostic-journal.js +632 -0
  20. package/dist/application-opentelemetry.js +3 -2
  21. package/dist/application-schemas.js +14 -98
  22. package/dist/application.d.ts +1 -2
  23. package/dist/application.d.ts.map +1 -1
  24. package/dist/application.js +155 -882
  25. package/dist/cli.js +13 -11
  26. package/dist/contract/index.js +15 -10
  27. package/dist/files/boundary.d.ts.map +1 -1
  28. package/dist/files.js +1 -1
  29. package/dist/{index-7b188kmz.js → index-2qzskm8h.js} +15 -1
  30. package/dist/{index-k2zczx1g.js → index-2rwwmr7v.js} +3 -3
  31. package/dist/{index-8eywc9zv.js → index-3gye9wzb.js} +6 -3
  32. package/dist/index-4fpa9dy2.js +51 -0
  33. package/dist/{index-7qy2ex0m.js → index-5mtc969c.js} +2 -2
  34. package/dist/index-5s3zajp8.js +192 -0
  35. package/dist/{index-3cwck0rm.js → index-6s7n2v50.js} +60 -374
  36. package/dist/{index-s4c8wy8m.js → index-758zx2ha.js} +11 -90
  37. package/dist/{index-qyrqwr4c.js → index-77fekveh.js} +4 -1
  38. package/dist/{index-58jzmnn4.js → index-7ag81v2f.js} +355 -34
  39. package/dist/index-7gnkny4z.js +326 -0
  40. package/dist/index-7zbps32p.js +89 -0
  41. package/dist/index-85vfqd7m.js +135 -0
  42. package/dist/{index-m668wzyc.js → index-9s6z8vgf.js} +17 -141
  43. package/dist/{index-bfcpjw20.js → index-actkayzn.js} +7 -3
  44. package/dist/index-b9aefrqd.js +20 -0
  45. package/dist/index-dre2ywck.js +48 -0
  46. package/dist/{index-nemjkxjp.js → index-dwf1f2ap.js} +16 -12
  47. package/dist/{index-wwst0td5.js → index-dx9xehwt.js} +1 -1
  48. package/dist/{index-ezmn6ac6.js → index-dxesg10d.js} +4 -4
  49. package/dist/{index-aczggrty.js → index-dxjjv399.js} +2 -2
  50. package/dist/{index-jqtsc9mj.js → index-egaabxkz.js} +3 -3
  51. package/dist/{index-vc1b0b1b.js → index-evcnmsc3.js} +49 -8
  52. package/dist/{index-nt1mp8km.js → index-fxz0v7vg.js} +84 -84
  53. package/dist/index-h4pj6fta.js +87 -0
  54. package/dist/{index-1rxswfbv.js → index-hb5pf3s4.js} +1 -1
  55. package/dist/{index-t8qyvrvg.js → index-k9ay6v6d.js} +21 -272
  56. package/dist/index-kzfs85xp.js +9 -0
  57. package/dist/{index-vbf2p6me.js → index-m9kzax52.js} +91 -89
  58. package/dist/{index-22by16v6.js → index-mgtxfe6b.js} +1 -1
  59. package/dist/index-p7hgdyhb.js +22 -0
  60. package/dist/index-pq95qkbf.js +0 -0
  61. package/dist/index-t0z5p5w6.js +318 -0
  62. package/dist/{index-s2rchahr.js → index-vwp69871.js} +13 -11
  63. package/dist/index-wc4x00bn.js +103 -0
  64. package/dist/{index-da1aqnhb.js → index-xcetq6j3.js} +8 -6
  65. package/dist/{index-f6n5n7nz.js → index-y01f4223.js} +33 -126
  66. package/dist/{index-35z5h2ty.js → index-ywd0y6m1.js} +18 -218
  67. package/dist/index.js +65 -1588
  68. package/dist/internal/deadline.d.ts +17 -0
  69. package/dist/internal/deadline.d.ts.map +1 -0
  70. package/dist/live.js +15 -89
  71. package/dist/node.js +17 -15
  72. package/dist/observability/context.d.ts.map +1 -1
  73. package/dist/observability/index.js +7 -6
  74. package/dist/primitives.js +5 -2
  75. package/dist/react.js +1 -1
  76. package/dist/remote.js +7 -6
  77. package/dist/server/event-bus.d.ts.map +1 -1
  78. package/dist/server/index.js +26 -38
  79. package/dist/telegram.js +1 -1
  80. package/dist/testing.js +86 -97
  81. package/dist/tool-invoker.js +11 -9
  82. package/dist/tools/async-operation-contract.d.ts +61 -0
  83. package/dist/tools/async-operation-contract.d.ts.map +1 -0
  84. package/dist/tools/async-operation.d.ts +2 -47
  85. package/dist/tools/async-operation.d.ts.map +1 -1
  86. package/dist/tools/view-file-contract.d.ts +98 -0
  87. package/dist/tools/view-file-contract.d.ts.map +1 -0
  88. package/dist/tools/view-file.d.ts +4 -83
  89. package/dist/tools/view-file.d.ts.map +1 -1
  90. package/dist/tools-contract.d.ts +29 -0
  91. package/dist/tools-contract.d.ts.map +1 -0
  92. package/dist/tools-contract.js +24 -0
  93. package/dist/tools.d.ts +3 -3
  94. package/dist/tools.d.ts.map +1 -1
  95. package/dist/tools.js +59 -95
  96. package/llms-full.txt +146 -14
  97. package/package.json +14 -7
  98. package/dist/index-ksp6e2ye.js +0 -24
  99. package/dist/index-vj3vvpaa.js +0 -307
@@ -10,33 +10,30 @@ import {
10
10
  createBoundedSinkManager
11
11
  } from "./index-a59da114.js";
12
12
  import {
13
- isAgentToolError
14
- } from "./index-3xnq72rz.js";
15
- import {
16
- ToolExecutionControlError,
17
- isToolExecutionControlError
18
- } from "./index-s4c8wy8m.js";
13
+ AgentRuntimeEventSchema,
14
+ agentDurableEventId
15
+ } from "./index-85vfqd7m.js";
19
16
  import {
20
17
  AgentAssistantPlaceholderSchema,
21
18
  AgentJsonObjectSchema,
22
19
  AgentMessagePartSchema,
23
20
  AgentMessageSchema,
24
21
  AgentProvenanceSchema,
25
- AgentProviderEnvelopeSchema,
26
- AgentRecordIdSchema,
27
- AgentRecordVersionSchema,
28
- AgentRunMetricsSchema,
29
22
  AgentRunSchema,
30
- AgentRunStateSchema,
31
23
  AgentSnapshotSchema,
32
- AgentTerminalReasonSchema,
33
- AgentTimestampSchema,
34
24
  runStateForTerminalReason
35
25
  } from "./index-x1th9s8c.js";
26
+ import {
27
+ isAgentToolError
28
+ } from "./index-3xnq72rz.js";
29
+ import {
30
+ ToolExecutionControlError,
31
+ isToolExecutionControlError
32
+ } from "./index-758zx2ha.js";
36
33
  import {
37
34
  isRecord,
38
35
  transportResult
39
- } from "./index-qyrqwr4c.js";
36
+ } from "./index-77fekveh.js";
40
37
 
41
38
  // src/agent-runtime/context-refusal.ts
42
39
  class AgentContextOverflowError extends Error {
@@ -189,127 +186,6 @@ function createAgentSessionCoordinator() {
189
186
  };
190
187
  }
191
188
 
192
- // src/agent-runtime/event-schema.ts
193
- import { z } from "zod";
194
- var AgentAdmissionEventSchema = z.object({
195
- type: z.literal("admission"),
196
- eventId: AgentRecordIdSchema,
197
- conversationId: AgentRecordIdSchema,
198
- runId: AgentRecordIdSchema,
199
- snapshotVersion: AgentRecordVersionSchema,
200
- input: AgentMessageSchema,
201
- run: AgentRunSchema,
202
- assistant: z.union([AgentAssistantPlaceholderSchema, AgentMessageSchema]),
203
- emittedAt: AgentTimestampSchema
204
- });
205
- var EventIdentitySchema = z.object({
206
- conversationId: AgentRecordIdSchema,
207
- runId: AgentRecordIdSchema,
208
- emittedAt: AgentTimestampSchema
209
- });
210
- var AgentTransientDeltaEventSchema = EventIdentitySchema.extend({
211
- type: z.literal("assistant-delta"),
212
- runtimeEpoch: z.string().min(1),
213
- sequence: z.int().nonnegative(),
214
- textDelta: z.string()
215
- });
216
- var AgentTransientReasoningIdentitySchema = EventIdentitySchema.extend({
217
- runtimeEpoch: z.string().min(1),
218
- sequence: z.int().nonnegative(),
219
- provider: AgentProviderEnvelopeSchema.optional()
220
- });
221
- var AgentReasoningStartEventSchema = AgentTransientReasoningIdentitySchema.extend({
222
- type: z.literal("reasoning-start")
223
- });
224
- var AgentReasoningDeltaEventSchema = AgentTransientReasoningIdentitySchema.extend({
225
- type: z.literal("reasoning-delta"),
226
- textDelta: z.string()
227
- });
228
- var AgentReasoningEndEventSchema = AgentTransientReasoningIdentitySchema.extend({
229
- type: z.literal("reasoning-end")
230
- });
231
- var AgentCheckpointEventSchema = EventIdentitySchema.extend({
232
- type: z.literal("assistant-checkpoint"),
233
- eventId: AgentRecordIdSchema,
234
- snapshotVersion: AgentRecordVersionSchema,
235
- message: AgentMessageSchema,
236
- metrics: AgentRunMetricsSchema.optional()
237
- });
238
- var AgentRunStateEventSchema = EventIdentitySchema.extend({
239
- type: z.literal("run-state"),
240
- eventId: AgentRecordIdSchema,
241
- snapshotVersion: AgentRecordVersionSchema,
242
- state: AgentRunStateSchema
243
- });
244
- var AgentToolStatusEventSchema = EventIdentitySchema.extend({
245
- type: z.literal("tool-status"),
246
- runtimeEpoch: z.string().min(1),
247
- sequence: z.int().nonnegative(),
248
- callId: AgentRecordIdSchema,
249
- toolName: z.string().min(1),
250
- status: z.enum(["started", "completed", "failed", "interrupted"]),
251
- input: z.json().optional(),
252
- output: z.json().optional()
253
- });
254
- var AgentTerminalEventSchema = EventIdentitySchema.extend({
255
- type: z.literal("terminal"),
256
- eventId: AgentRecordIdSchema,
257
- snapshotVersion: AgentRecordVersionSchema,
258
- reason: AgentTerminalReasonSchema,
259
- policyName: z.string().min(1).optional(),
260
- message: AgentMessageSchema,
261
- metrics: AgentRunMetricsSchema.optional()
262
- });
263
- var AgentRuntimeEventSchema = z.discriminatedUnion("type", [
264
- AgentAdmissionEventSchema,
265
- AgentTransientDeltaEventSchema,
266
- AgentReasoningStartEventSchema,
267
- AgentReasoningDeltaEventSchema,
268
- AgentReasoningEndEventSchema,
269
- AgentCheckpointEventSchema,
270
- AgentRunStateEventSchema,
271
- AgentToolStatusEventSchema,
272
- AgentTerminalEventSchema
273
- ]);
274
- var AgentRuntimeEventCursorSchema = z.object({
275
- snapshotVersion: AgentRecordVersionSchema.optional(),
276
- durableEventIds: z.array(AgentRecordIdSchema).optional(),
277
- runtimeEpoch: z.string().min(1).optional(),
278
- sequence: z.int().nonnegative().optional()
279
- });
280
- function isDurableEvent(event) {
281
- return event.type === "admission" || event.type === "assistant-checkpoint" || event.type === "run-state" || event.type === "terminal";
282
- }
283
- function advanceAgentRuntimeEventCursor(rawCursor, event) {
284
- const cursor = AgentRuntimeEventCursorSchema.parse(rawCursor);
285
- if (isDurableEvent(event)) {
286
- const previous = cursor.snapshotVersion;
287
- const durableEventIds = previous === event.snapshotVersion ? cursor.durableEventIds ?? [] : [];
288
- if (previous !== undefined && event.snapshotVersion < previous || durableEventIds.includes(event.eventId)) {
289
- return { status: "duplicate", cursor };
290
- }
291
- return {
292
- status: "accepted",
293
- cursor: {
294
- ...cursor,
295
- snapshotVersion: event.snapshotVersion,
296
- durableEventIds: [...durableEventIds, event.eventId]
297
- }
298
- };
299
- }
300
- const previousSequence = cursor.runtimeEpoch === event.runtimeEpoch ? cursor.sequence : undefined;
301
- if (previousSequence !== undefined && event.sequence <= previousSequence) {
302
- return { status: "duplicate", cursor };
303
- }
304
- return {
305
- status: previousSequence !== undefined && event.sequence > previousSequence + 1 ? "gap" : "accepted",
306
- cursor: { ...cursor, runtimeEpoch: event.runtimeEpoch, sequence: event.sequence }
307
- };
308
- }
309
- function agentDurableEventId(type, runId, snapshotVersion) {
310
- return `${runId}:${type}:${snapshotVersion}`;
311
- }
312
-
313
189
  // src/agent-runtime/events.ts
314
190
  function createAgentRuntimeEventSink(config) {
315
191
  const manager = createBoundedSinkManager({
@@ -625,9 +501,9 @@ function createAgentToolFenceLifecycle(config) {
625
501
  }
626
502
 
627
503
  // src/agent-runtime/prompt.ts
628
- import { z as z2 } from "zod";
629
- var AgentTokenCountSchema = z2.object({
630
- value: z2.int().nonnegative().optional(),
504
+ import { z } from "zod";
505
+ var AgentTokenCountSchema = z.object({
506
+ value: z.int().nonnegative().optional(),
631
507
  provenance: AgentProvenanceSchema.extract([
632
508
  "measured",
633
509
  "computed",
@@ -1058,7 +934,7 @@ function repairedSearchCall(toolCall, searchName) {
1058
934
  }
1059
935
 
1060
936
  // src/agent-runtime/runtime-internals.ts
1061
- import { z as z3 } from "zod";
937
+ import { z as z2 } from "zod";
1062
938
  function findRun(runs, runId) {
1063
939
  const run = runs.find((candidate) => candidate.id === runId);
1064
940
  if (!run)
@@ -1066,7 +942,7 @@ function findRun(runs, runId) {
1066
942
  return run;
1067
943
  }
1068
944
  function jsonValue(value) {
1069
- const parsed = z3.json().safeParse(value);
945
+ const parsed = z2.json().safeParse(value);
1070
946
  return parsed.success ? parsed.data : { message: "Non-JSON tool output omitted" };
1071
947
  }
1072
948
  function providerEnvelope(value) {
@@ -2567,4 +2443,4 @@ function createAgentRuntime(config) {
2567
2443
  };
2568
2444
  }
2569
2445
 
2570
- export { AgentContextOverflowError, createAgentSessionCoordinator, registerDeferredToolRepair, registerDeferredToolCatalog, deferredToolCatalog, repairedSearchCall, AgentAdmissionEventSchema, AgentTransientDeltaEventSchema, AgentReasoningStartEventSchema, AgentReasoningDeltaEventSchema, AgentReasoningEndEventSchema, AgentCheckpointEventSchema, AgentRunStateEventSchema, AgentToolStatusEventSchema, AgentTerminalEventSchema, AgentRuntimeEventSchema, AgentRuntimeEventCursorSchema, advanceAgentRuntimeEventCursor, agentDurableEventId, createAgentRuntimeEventSink, projectAgentHistoryDetailed, projectAgentHistory, createAgentToolFenceLifecycle, AgentTokenCountSchema, selectAgentHistory, composeAgentPrompt, AgentRuntimeConflictError, createAgentRuntime };
2446
+ export { AgentContextOverflowError, createAgentSessionCoordinator, registerDeferredToolRepair, registerDeferredToolCatalog, deferredToolCatalog, repairedSearchCall, createAgentRuntimeEventSink, projectAgentHistoryDetailed, projectAgentHistory, createAgentToolFenceLifecycle, AgentTokenCountSchema, selectAgentHistory, composeAgentPrompt, AgentRuntimeConflictError, createAgentRuntime };
@@ -14,7 +14,11 @@ import { basename, dirname, resolve } from "node:path";
14
14
  var DEFAULT_MAX_BYTES = 100 * 1024 * 1024;
15
15
  var DEFAULT_INSPECTION_BYTES = 64 * 1024;
16
16
  var DEFAULT_INSPECTION_TIMEOUT_MS = 15000;
17
- var NOFOLLOW_FLAG = constants.O_NOFOLLOW ?? 0;
17
+ var nofollowFlag;
18
+ var noFollow = () => {
19
+ nofollowFlag ??= constants.O_NOFOLLOW ?? 0;
20
+ return nofollowFlag;
21
+ };
18
22
  var ManagedFileInspectionSchema = ManagedFileRefSchema.pick({
19
23
  mediaType: true,
20
24
  name: true
@@ -273,7 +277,7 @@ async function createManagedFileBoundary(config) {
273
277
  const maxBytes = positiveLimit(options.maxBytes, maxReadBytes, "maxBytes");
274
278
  let handle;
275
279
  try {
276
- handle = await open(realTarget, constants.O_RDONLY | NOFOLLOW_FLAG);
280
+ handle = await open(realTarget, constants.O_RDONLY | noFollow());
277
281
  const info = await handle.stat();
278
282
  if (!info.isFile()) {
279
283
  throw new ManagedFileError("FILE_NOT_REGULAR", "managed path is not a regular file");
@@ -310,7 +314,7 @@ async function createManagedFileBoundary(config) {
310
314
  let committed = false;
311
315
  let size = 0;
312
316
  try {
313
- handle = await open(temporary, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | NOFOLLOW_FLAG, 384);
317
+ handle = await open(temporary, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | noFollow(), 384);
314
318
  const written = await writeSource(handle, source, maxBytes, inspectionBytes, options.signal);
315
319
  size = written.size;
316
320
  if (options.durable)
@@ -0,0 +1,20 @@
1
+ // src/internal/deadline.ts
2
+ async function withDeadline(value, timeoutMs) {
3
+ if (!(value instanceof Promise))
4
+ return { settled: true, value };
5
+ let timer;
6
+ const expiry = new Promise((resolve) => {
7
+ timer = setTimeout(() => resolve({ settled: false }), timeoutMs);
8
+ });
9
+ try {
10
+ return await Promise.race([
11
+ value.then((settledValue) => ({ settled: true, value: settledValue })),
12
+ expiry
13
+ ]);
14
+ } finally {
15
+ if (timer !== undefined)
16
+ clearTimeout(timer);
17
+ }
18
+ }
19
+
20
+ export { withDeadline };
@@ -0,0 +1,48 @@
1
+ import {
2
+ LiveStatePhaseSchema,
3
+ LiveStateStopReasonSchema
4
+ } from "./index-ywd0y6m1.js";
5
+
6
+ // src/live/watch-contract.ts
7
+ import { z } from "zod";
8
+ var WatchKeySchema = z.object({
9
+ service: z.string().min(1),
10
+ action: z.string().min(1),
11
+ digest: z.string().min(1)
12
+ }).strict().readonly();
13
+ var WatchOpenSchema = z.object({ key: WatchKeySchema, args: z.unknown() }).readonly();
14
+ var WatchAcceptedSchema = z.object({
15
+ accepted: z.boolean(),
16
+ reason: z.string().optional()
17
+ }).strict().readonly();
18
+ var WatchValueSchema = z.object({
19
+ key: WatchKeySchema,
20
+ revision: z.number().int().nonnegative(),
21
+ value: z.unknown()
22
+ }).readonly();
23
+ var WatchStateSchema = z.object({
24
+ key: WatchKeySchema,
25
+ phase: LiveStatePhaseSchema,
26
+ reason: LiveStateStopReasonSchema.optional(),
27
+ code: z.string().optional(),
28
+ message: z.string().optional()
29
+ }).readonly();
30
+ var WATCH_OPEN = "stitchkit.watch.open";
31
+ var WATCH_CLOSE = "stitchkit.watch.close";
32
+ var WATCH_VALUE = "stitchkit.watch.value";
33
+ var WATCH_STATE = "stitchkit.watch.state";
34
+ var watchContract = {
35
+ serverToClient: {
36
+ [WATCH_VALUE]: { args: z.tuple([WatchValueSchema]) },
37
+ [WATCH_STATE]: { args: z.tuple([WatchStateSchema]) }
38
+ },
39
+ clientToServer: {
40
+ [WATCH_OPEN]: { args: z.tuple([WatchOpenSchema]), ack: WatchAcceptedSchema },
41
+ [WATCH_CLOSE]: { args: z.tuple([z.object({ key: WatchKeySchema }).readonly()]) }
42
+ }
43
+ };
44
+ function watchKeyString(key) {
45
+ return `${key.service}/${key.action}/${key.digest}`;
46
+ }
47
+
48
+ export { WatchKeySchema, WatchValueSchema, WatchStateSchema, WATCH_OPEN, WATCH_CLOSE, WATCH_VALUE, WATCH_STATE, watchContract, watchKeyString };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  resolveTraceContext
3
- } from "./index-nt1mp8km.js";
3
+ } from "./index-fxz0v7vg.js";
4
4
  import {
5
5
  isUnsafeKey
6
- } from "./index-vj3vvpaa.js";
6
+ } from "./index-kzfs85xp.js";
7
7
  import {
8
8
  isRecord
9
- } from "./index-qyrqwr4c.js";
9
+ } from "./index-77fekveh.js";
10
10
 
11
11
  // src/server/request.ts
12
12
  function generateTraceId() {
@@ -179,38 +179,42 @@ function isPublicIp(value) {
179
179
 
180
180
  // src/observability/context.ts
181
181
  import { AsyncLocalStorage } from "node:async_hooks";
182
- var storage = new AsyncLocalStorage;
182
+ var storage;
183
+ var requestStorage = () => {
184
+ storage ??= new AsyncLocalStorage;
185
+ return storage;
186
+ };
183
187
  function runWithRequestContext(ctx, fn) {
184
- return storage.run(ctx, fn);
188
+ return requestStorage().run(ctx, fn);
185
189
  }
186
190
  function getRequestContext() {
187
- return storage.getStore();
191
+ return requestStorage().getStore();
188
192
  }
189
193
  function getTraceId() {
190
- return storage.getStore()?.trace.traceId;
194
+ return requestStorage().getStore()?.trace.traceId;
191
195
  }
192
196
  function getUserId() {
193
- return storage.getStore()?.userId;
197
+ return requestStorage().getStore()?.userId;
194
198
  }
195
199
  function setRequestUser(userId) {
196
- const ctx = storage.getStore();
200
+ const ctx = requestStorage().getStore();
197
201
  if (ctx)
198
202
  ctx.userId = userId;
199
203
  }
200
204
  function setRequestEndpoint(serviceName, action) {
201
- const ctx = storage.getStore();
205
+ const ctx = requestStorage().getStore();
202
206
  if (ctx) {
203
207
  ctx.serviceName = serviceName;
204
208
  ctx.action = action;
205
209
  }
206
210
  }
207
211
  function setRequestDimensions(dimensions) {
208
- const ctx = storage.getStore();
212
+ const ctx = requestStorage().getStore();
209
213
  if (ctx)
210
214
  ctx.dimensions = { ...ctx.dimensions, ...dimensions };
211
215
  }
212
216
  function setRequestError(error) {
213
- const ctx = storage.getStore();
217
+ const ctx = requestStorage().getStore();
214
218
  if (ctx)
215
219
  ctx.error = error;
216
220
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  projectRuntimeTool
3
- } from "./index-22by16v6.js";
3
+ } from "./index-mgtxfe6b.js";
4
4
 
5
5
  // src/tools/runtime-tool.ts
6
6
  function defineRuntimeTool(definition) {
@@ -3,18 +3,18 @@ import {
3
3
  } from "./index-3xnq72rz.js";
4
4
  import {
5
5
  collectToolSurface
6
- } from "./index-k2zczx1g.js";
6
+ } from "./index-2rwwmr7v.js";
7
7
  import {
8
8
  createToolRunner,
9
9
  formatToolError
10
- } from "./index-7qy2ex0m.js";
10
+ } from "./index-5mtc969c.js";
11
11
  import {
12
12
  isToolExecutionControlError,
13
13
  toolResultFromError
14
- } from "./index-s4c8wy8m.js";
14
+ } from "./index-758zx2ha.js";
15
15
  import {
16
16
  isRecord
17
- } from "./index-qyrqwr4c.js";
17
+ } from "./index-77fekveh.js";
18
18
 
19
19
  // src/tools/agent.ts
20
20
  import { jsonSchema, tool } from "ai";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  isUnsafeKey
3
- } from "./index-vj3vvpaa.js";
3
+ } from "./index-kzfs85xp.js";
4
4
  import {
5
5
  isRecord
6
- } from "./index-qyrqwr4c.js";
6
+ } from "./index-77fekveh.js";
7
7
 
8
8
  // src/observability/sanitize.ts
9
9
  var SENSITIVE_WORDS = new Set([
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  collectTools,
3
3
  createToolRunner
4
- } from "./index-7qy2ex0m.js";
4
+ } from "./index-5mtc969c.js";
5
5
  import {
6
6
  toolErrorFromResult
7
- } from "./index-s4c8wy8m.js";
7
+ } from "./index-758zx2ha.js";
8
8
  import {
9
9
  assertUniqueToolName
10
- } from "./index-22by16v6.js";
10
+ } from "./index-mgtxfe6b.js";
11
11
  import {
12
12
  AppError
13
13
  } from "./index-0w9abg87.js";
@@ -5,7 +5,7 @@ import {
5
5
  ApplicationIdSchema,
6
6
  ApplicationShutdownResultSchema,
7
7
  ApplicationSnapshotSchema
8
- } from "./index-8eywc9zv.js";
8
+ } from "./index-3gye9wzb.js";
9
9
  import {
10
10
  ShutdownOptionsSchema
11
11
  } from "./index-3z73fh2c.js";
@@ -85,7 +85,11 @@ var ApplicationShutdownBudgetSchema = ShutdownOptionsSchema.pick({
85
85
  gracePeriodMs: true,
86
86
  forceTimeoutMs: true
87
87
  });
88
- var ApplicationRestartInputSchema = z.object({ resourceId: z.string().min(1) }).strict().readonly();
88
+ var ApplicationRestartInputSchema = z.object({
89
+ resourceId: z.string().min(1),
90
+ gracePeriodMs: z.number().int().nonnegative().optional(),
91
+ forceTimeoutMs: z.number().int().nonnegative().optional()
92
+ }).strict().readonly();
89
93
  var ApplicationRestartOutcomeSchema = z.enum(["restarted", "failed", "refused"]);
90
94
  var ApplicationRestartResultSchema = z.object({
91
95
  resourceId: z.string(),
@@ -177,6 +181,7 @@ function createApplication(config) {
177
181
  return optionalUnhealthy ? "degraded" : "healthy";
178
182
  };
179
183
  const isReady = () => lifecycle === "ready" && [...records.values()].every((record) => !record.entry.required || record.state === "ready" && record.health === "healthy");
184
+ let restartingIds = [];
180
185
  const snapshot = () => ApplicationSnapshotSchema.parse({
181
186
  id,
182
187
  epoch,
@@ -187,6 +192,7 @@ function createApplication(config) {
187
192
  capturedAt: new Date().toISOString(),
188
193
  changedAt,
189
194
  admission: { accepting, accepted, completed, pending },
195
+ restarting: [...restartingIds],
190
196
  resources: ordered.map((entry) => {
191
197
  const record = records.get(entry.id);
192
198
  if (!record)
@@ -444,13 +450,21 @@ function createApplication(config) {
444
450
  }
445
451
  return ordered.filter((entry) => affected.has(entry.id));
446
452
  };
447
- const closeOne = async (entry, record, signal) => {
448
- const context = () => contextFor(record, { signal });
453
+ const closeOne = async (entry, record, signal, deadlines) => {
454
+ const context = () => contextFor(record, { ...deadlines, signal });
449
455
  if (record.attempted && !record.closed) {
450
- await entry.resource.stopAdmission?.(context());
451
- await entry.resource.drain?.(context());
456
+ const phase = async (work, what) => {
457
+ const settled = await untilDeadline(Promise.resolve(work), signal);
458
+ if (!settled.settled) {
459
+ throw new Error(`[stitchkit] resource "${entry.id}" did not ${what} within the restart budget`);
460
+ }
461
+ if (settled.error !== undefined)
462
+ throw settled.error;
463
+ };
464
+ await phase(entry.resource.stopAdmission?.(context()), "stop admitting");
465
+ await phase(entry.resource.drain?.(context()), "drain");
452
466
  record.closeInvoked = true;
453
- await entry.resource.close?.(context());
467
+ await phase(entry.resource.close?.(context()), "close");
454
468
  }
455
469
  record.closed = false;
456
470
  record.closeInvoked = false;
@@ -484,17 +498,39 @@ function createApplication(config) {
484
498
  if (lifecycle !== "ready") {
485
499
  return refuse(`the application is ${lifecycle}, not ready`);
486
500
  }
501
+ const budget = {
502
+ gracePeriodMs: parsed.gracePeriodMs ?? shutdownBudget.gracePeriodMs,
503
+ forceTimeoutMs: parsed.forceTimeoutMs ?? shutdownBudget.forceTimeoutMs
504
+ };
505
+ const closeDeadlineAt = performance.now() + budget.gracePeriodMs;
506
+ const deadlines = {
507
+ deadlineAt: closeDeadlineAt,
508
+ forceDeadlineAt: closeDeadlineAt + budget.forceTimeoutMs
509
+ };
510
+ restartingIds = affectedIds;
487
511
  const restartAbort = new AbortController;
512
+ const closeTimer = setTimeout(() => restartAbort.abort(), Math.max(0, deadlines.forceDeadlineAt - performance.now()));
513
+ const stillFailed = () => affectedIds.filter((id2) => records.get(id2)?.state === "failed");
488
514
  try {
489
515
  for (const entry of [...affected].reverse()) {
490
516
  const record = records.get(entry.id);
491
517
  if (record)
492
- await closeOne(entry, record, restartAbort.signal);
518
+ await closeOne(entry, record, restartAbort.signal, deadlines);
493
519
  }
494
520
  publish();
495
521
  await startEach(affected, restartAbort.signal);
496
522
  await activateEach(affected, restartAbort.signal);
497
523
  publish();
524
+ const failed = stillFailed();
525
+ if (failed.length > 0) {
526
+ return {
527
+ resourceId: parsed.resourceId,
528
+ affected: affectedIds,
529
+ outcome: "failed",
530
+ reason: `did not come back: ${failed.join(", ")}`,
531
+ durationMs: Date.now() - startedAt
532
+ };
533
+ }
498
534
  return {
499
535
  resourceId: parsed.resourceId,
500
536
  affected: affectedIds,
@@ -502,6 +538,7 @@ function createApplication(config) {
502
538
  durationMs: Date.now() - startedAt
503
539
  };
504
540
  } catch (error) {
541
+ restartAbort.abort();
505
542
  publish();
506
543
  return {
507
544
  resourceId: parsed.resourceId,
@@ -510,6 +547,10 @@ function createApplication(config) {
510
547
  reason: error instanceof Error ? error.message : String(error),
511
548
  durationMs: Date.now() - startedAt
512
549
  };
550
+ } finally {
551
+ restartingIds = [];
552
+ clearTimeout(closeTimer);
553
+ publish();
513
554
  }
514
555
  };
515
556
  const runStart = async () => {