stitchkit 0.110.1 → 0.110.2

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 (81) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/agent-runtime/archive-spill.d.ts +61 -0
  3. package/dist/agent-runtime/archive-spill.d.ts.map +1 -0
  4. package/dist/agent-runtime/branch-contract.d.ts +102 -0
  5. package/dist/agent-runtime/branch-contract.d.ts.map +1 -0
  6. package/dist/agent-runtime/branch-events.d.ts +18 -0
  7. package/dist/agent-runtime/branch-events.d.ts.map +1 -0
  8. package/dist/agent-runtime/branch-identities.d.ts +20 -0
  9. package/dist/agent-runtime/branch-identities.d.ts.map +1 -0
  10. package/dist/agent-runtime/branch-messages.d.ts +32 -0
  11. package/dist/agent-runtime/branch-messages.d.ts.map +1 -0
  12. package/dist/agent-runtime/branch-observations.d.ts +104 -0
  13. package/dist/agent-runtime/branch-observations.d.ts.map +1 -0
  14. package/dist/agent-runtime/branch-provider.d.ts +130 -0
  15. package/dist/agent-runtime/branch-provider.d.ts.map +1 -0
  16. package/dist/agent-runtime/branch-replay.d.ts +426 -0
  17. package/dist/agent-runtime/branch-replay.d.ts.map +1 -0
  18. package/dist/agent-runtime/branch-source.d.ts +16 -0
  19. package/dist/agent-runtime/branch-source.d.ts.map +1 -0
  20. package/dist/agent-runtime/branch-transitions.d.ts +6 -0
  21. package/dist/agent-runtime/branch-transitions.d.ts.map +1 -0
  22. package/dist/agent-runtime/sqlite-history.d.ts.map +1 -1
  23. package/dist/agent-runtime/sqlite-purge.d.ts.map +1 -1
  24. package/dist/agent-runtime/store-archive.d.ts +1 -0
  25. package/dist/agent-runtime/store-archive.d.ts.map +1 -1
  26. package/dist/agent-runtime/store-branch.d.ts +5 -0
  27. package/dist/agent-runtime/store-branch.d.ts.map +1 -0
  28. package/dist/agent-runtime/store-conformance-branch.d.ts +4 -0
  29. package/dist/agent-runtime/store-conformance-branch.d.ts.map +1 -0
  30. package/dist/agent-runtime/store-conformance-support.d.ts +5 -5
  31. package/dist/agent-runtime/store-conformance.d.ts.map +1 -1
  32. package/dist/agent-runtime/store-create.d.ts +1 -1
  33. package/dist/agent-runtime/store-create.d.ts.map +1 -1
  34. package/dist/agent-runtime/store-driver-contract.d.ts +6 -0
  35. package/dist/agent-runtime/store-driver-contract.d.ts.map +1 -1
  36. package/dist/agent-runtime/store-events.d.ts +90 -0
  37. package/dist/agent-runtime/store-events.d.ts.map +1 -1
  38. package/dist/agent-runtime/store-memory-archive.d.ts +8 -0
  39. package/dist/agent-runtime/store-memory-archive.d.ts.map +1 -0
  40. package/dist/agent-runtime/store-memory-events.d.ts +7 -0
  41. package/dist/agent-runtime/store-memory-events.d.ts.map +1 -0
  42. package/dist/agent-runtime/store-memory.d.ts +1 -1
  43. package/dist/agent-runtime/store-memory.d.ts.map +1 -1
  44. package/dist/agent-runtime/store-purge.d.ts +2 -0
  45. package/dist/agent-runtime/store-purge.d.ts.map +1 -1
  46. package/dist/agent-runtime/store-reduce-run.d.ts +2 -2
  47. package/dist/agent-runtime/store-reduce-run.d.ts.map +1 -1
  48. package/dist/agent-runtime/store-reduce-shared.d.ts +1 -0
  49. package/dist/agent-runtime/store-reduce-shared.d.ts.map +1 -1
  50. package/dist/agent-runtime/store-reducer.d.ts +2 -2
  51. package/dist/agent-runtime/store-reducer.d.ts.map +1 -1
  52. package/dist/agent-runtime/store.d.ts +3 -0
  53. package/dist/agent-runtime/store.d.ts.map +1 -1
  54. package/dist/durability/events.d.ts +4 -0
  55. package/dist/durability/events.d.ts.map +1 -1
  56. package/dist/entrypoints/agent-runtime/coding-tools.js +1 -2
  57. package/dist/entrypoints/agent-runtime/harness.js +4 -3
  58. package/dist/entrypoints/agent-runtime/sandbox.js +3 -5
  59. package/dist/entrypoints/agent-runtime/sqlite/bun.js +13 -3
  60. package/dist/entrypoints/agent-runtime/sqlite/node.js +13 -3
  61. package/dist/entrypoints/agent-runtime/testing.js +89 -5
  62. package/dist/entrypoints/agent-runtime.d.ts +1 -0
  63. package/dist/entrypoints/agent-runtime.d.ts.map +1 -1
  64. package/dist/entrypoints/agent-runtime.js +25 -15
  65. package/dist/entrypoints/tools.js +5 -3
  66. package/dist/{index-c17xcx4k.js → index-56yx8dxp.js} +19 -96
  67. package/dist/{index-0gs4ymfj.js → index-6qeqdz0z.js} +7 -1
  68. package/dist/{index-924500c3.js → index-79zxnh52.js} +2 -2
  69. package/dist/{index-8rstkvcf.js → index-7c046kxr.js} +1 -1
  70. package/dist/{index-tjdsyrys.js → index-bm180f2d.js} +203 -83
  71. package/dist/{index-5p55xreg.js → index-e9rbhw1s.js} +67 -29
  72. package/dist/index-s2bgwsyr.js +2280 -0
  73. package/dist/index-snef22zr.js +94 -0
  74. package/dist/{index-c0hffcmj.js → index-zbssway3.js} +19 -2
  75. package/llms/agent-runtime.3.txt +3 -0
  76. package/llms/agent-runtime.txt +60 -0
  77. package/llms-full.txt +63 -0
  78. package/llms.txt +1 -1
  79. package/package.json +1 -1
  80. package/dist/index-8ks9b85e.js +0 -129
  81. package/dist/index-d2h99n7d.js +0 -1071
@@ -0,0 +1,94 @@
1
+ // src/durability/contract.ts
2
+ import { z } from "zod";
3
+ var DURABILITY_STEP_EVENT_KIND2 = "durability/step";
4
+ var DURABILITY_PARK_EVENT_KIND = "durability/park";
5
+ var DURABILITY_EVENT_EVENT_KIND = "durability/event";
6
+ var DURABILITY_EFFECT_EVENT_KIND = "durability/effect";
7
+ var StepEventPayloadSchema = z.object({
8
+ runId: z.string().min(1),
9
+ stepName: z.string().min(1),
10
+ encoded: z.string()
11
+ });
12
+ var SleepParkSchema = z.object({
13
+ runId: z.string().min(1),
14
+ kind: z.literal("sleep"),
15
+ name: z.string().min(1),
16
+ deadline: z.number()
17
+ });
18
+ var WaitParkSchema = z.object({
19
+ runId: z.string().min(1),
20
+ kind: z.literal("wait"),
21
+ event: z.string().min(1),
22
+ id: z.string().min(1)
23
+ });
24
+ var ParkEventPayloadSchema = z.discriminatedUnion("kind", [
25
+ SleepParkSchema,
26
+ WaitParkSchema
27
+ ]);
28
+ var DeliveredEventPayloadSchema = z.object({
29
+ runId: z.string().min(1),
30
+ event: z.string().min(1),
31
+ id: z.string().min(1),
32
+ encoded: z.string()
33
+ });
34
+ var EffectIdentity = { runId: z.string().min(1), effectName: z.string().min(1) };
35
+ var EffectEventPayloadSchema = z.discriminatedUnion("phase", [
36
+ z.object({ ...EffectIdentity, phase: z.literal("intent") }),
37
+ z.object({
38
+ ...EffectIdentity,
39
+ phase: z.literal("accepted"),
40
+ encoded: z.string(),
41
+ via: z.enum(["run", "reconcile"])
42
+ }),
43
+ z.object({ ...EffectIdentity, phase: z.literal("uncertain") })
44
+ ]);
45
+
46
+ class StepResultDecodeError2 extends Error {
47
+ constructor(message, options) {
48
+ super(message, options);
49
+ this.name = "StepResultDecodeError";
50
+ }
51
+ }
52
+
53
+ class StepResultNotSerializableError2 extends Error {
54
+ constructor(stepName, cause) {
55
+ super(`Step "${stepName}" returned a value that is not JSON-serializable`, {
56
+ cause
57
+ });
58
+ this.name = "StepResultNotSerializableError";
59
+ }
60
+ }
61
+
62
+ class StepAbortedError2 extends Error {
63
+ constructor(stepName) {
64
+ super(`Step "${stepName}" was aborted before it started`);
65
+ this.name = "StepAbortedError";
66
+ }
67
+ }
68
+
69
+ class EffectUnresolvedError2 extends Error {
70
+ effectName;
71
+ reason;
72
+ constructor(effectName, reason, options) {
73
+ super(`Effect "${effectName}" is unresolved (${reason}); its intent stands`, options);
74
+ this.effectName = effectName;
75
+ this.reason = reason;
76
+ this.name = "EffectUnresolvedError";
77
+ }
78
+ }
79
+
80
+ class ParkRecordDecodeError2 extends Error {
81
+ constructor(message, options) {
82
+ super(message, options);
83
+ this.name = "ParkRecordDecodeError";
84
+ }
85
+ }
86
+
87
+ class ParkAbortedError2 extends Error {
88
+ constructor(park) {
89
+ super(`Park "${park}" was aborted before it was satisfied`);
90
+ this.name = "ParkAbortedError";
91
+ }
92
+ }
93
+
94
+ export { DURABILITY_STEP_EVENT_KIND2, DURABILITY_PARK_EVENT_KIND, DURABILITY_EVENT_EVENT_KIND, DURABILITY_EFFECT_EVENT_KIND, StepEventPayloadSchema, ParkEventPayloadSchema, DeliveredEventPayloadSchema, EffectEventPayloadSchema, StepResultDecodeError2, StepResultNotSerializableError2, StepAbortedError2, EffectUnresolvedError2, ParkRecordDecodeError2, ParkAbortedError2 };
@@ -5,7 +5,7 @@ import {
5
5
  AgentRecoverableDescriptorSchema2,
6
6
  AgentRecoverablePageSchema2,
7
7
  canonicalAgentJson2
8
- } from "./index-0gs4ymfj.js";
8
+ } from "./index-6qeqdz0z.js";
9
9
  import {
10
10
  AgentMessageSchema2,
11
11
  AgentRunSchema2
@@ -18,7 +18,7 @@ import {
18
18
  AgentHistoryMutationSchema2,
19
19
  appendEventIn,
20
20
  createAgentRuntimeStore2
21
- } from "./index-d2h99n7d.js";
21
+ } from "./index-s2bgwsyr.js";
22
22
  import {
23
23
  AgentConversationPageSchema2,
24
24
  AgentConversationMessagePageSchema2
@@ -63,6 +63,14 @@ function sqliteConversationPurge(database) {
63
63
  if (table === null || table === undefined)
64
64
  return;
65
65
  return {
66
+ async isEmpty(transaction, conversationId) {
67
+ for (const table of OWNED_TABLES) {
68
+ const row = transaction.prepare(`SELECT 1 FROM ${table} WHERE conversation_id = ? LIMIT 1`).get(conversationId);
69
+ if (row !== null && row !== undefined)
70
+ return false;
71
+ }
72
+ return transaction.prepare("SELECT 1 FROM stitchkit_agent_runtime_children WHERE parent_conversation_id = ? OR child_conversation_id = ? LIMIT 1").get(conversationId, conversationId) == null;
73
+ },
66
74
  async isPurged(transaction, conversationId) {
67
75
  const row = transaction.prepare("SELECT conversation_id FROM stitchkit_agent_runtime_purged WHERE conversation_id = ?").get(conversationId);
68
76
  return row !== null && row !== undefined;
@@ -629,6 +637,15 @@ var sqliteArchive = {
629
637
 
630
638
  // src/agent-runtime/sqlite-history.ts
631
639
  var sqliteHistory = {
640
+ async restore(transaction, input) {
641
+ const compacted = new Set(input.compactedMessageIds);
642
+ for (const [position, message] of input.messages.entries()) {
643
+ if (message.conversationId !== input.conversationId)
644
+ throw new TypeError("Restored history has a foreign conversation");
645
+ transaction.prepare(`INSERT INTO stitchkit_agent_runtime_messages
646
+ (conversation_id, id, position, active, payload) VALUES (?, ?, ?, ?, ?)`).run(input.conversationId, message.id, position, compacted.has(message.id) ? 0 : 1, encodeJson(message));
647
+ }
648
+ },
632
649
  async load(transaction, conversationId) {
633
650
  return transaction.prepare(`
634
651
  SELECT payload FROM stitchkit_agent_runtime_messages
@@ -31,6 +31,9 @@ Server-only optional application runtime. See the
31
31
  | `AgentMessageSchema` / `AgentRunSchema` / `AgentSnapshotSchema` | schema | versioned canonical engine records |
32
32
  | `AgentRunQueuePrioritySchema` | schema | durable opt-in priority for queued `interrupt-next` runs |
33
33
  | `AgentRuntimeStore` | _type_ | aggregate CAS transaction boundary for message, run and compaction mutations |
34
+ | `BranchAgentConversationInputSchema` / `BranchAgentConversationInput` | schema / _type_ | strict branch request: stable request key, empty destination, settled conversation boundary or archive bytes, fresh artifact authorization |
35
+ | `AgentConversationBranchReceiptSchema` / `AgentConversationBranchReceipt` | schema / _type_ | durable lineage: request fingerprint, source/destination identities, source sequence/version/digest and creation time |
36
+ | `AgentConversationBranchResultSchema` / `AgentConversationBranchResult` | schema / _type_ | `created` or `duplicate` with the same durable receipt; `AgentRuntimeStore.branchConversation` is optional for hand-written stores |
34
37
  | `createAgentRuntimeStore` | function | build the aggregate store from one coherent transaction driver; framework owns every state transition |
35
38
  | `AgentRuntimeStoreDriver` | _type_ | ORM-neutral transaction over a bounded head, normalized runs/admissions, product history, a **required** `events: { append, list }` ledger table, an optional `archive: { export, import }` for driver-owned durable payloads, and indexed run recovery; optional `{ access: 'read' }` selects a coherent read transaction while absent options remain write-safe |
36
39
  | `recordAgentRetryDecision` / `AgentRetryPolicy` | function / _type_ | `loop.retry` policy and the ledger record of a retry decision: explicit retryability and backoff at a durable provider-step boundary |
@@ -567,6 +567,66 @@ failed attempt's reported usage stays in the run's spend. Transient events —
567
567
  deltas, reasoning, `attempt-reset` — are numbered from 1 per run, counting only
568
568
  what was published, so a cursor sees no gap on an ordinary stream.
569
569
 
570
+ ### Branch or restore with a new identity
571
+
572
+ Use `store.branchConversation()` to create an independent conversation. `importConversation()`
573
+ restores the original identity and is not a fork. The built-in memory and SQLite stores and
574
+ `createAgentRuntimeStore()` expose branching; a hand-written `AgentRuntimeStore` can advertise this
575
+ optional capability. The host authorizes the caller's source/archive access and destination
576
+ creation before calling this trusted store boundary.
577
+
578
+ ```ts
579
+ const copy = await sqlite.store.branchConversation({
580
+ requestKey: 'branch-request-1',
581
+ destinationConversationId: 'new-conversation',
582
+ source: { kind: 'conversation', conversationId: 'original', throughRunId: 'finished-run' },
583
+ // Required when selected history has spills: an explicit policy for this destination.
584
+ artifactAuthorization: { operation: 'read', path: 'approved-destination-workspace' },
585
+ })
586
+
587
+ const restored = await sqlite.store.branchConversation({
588
+ requestKey: 'restore-request-1',
589
+ destinationConversationId: 'restored-as-new',
590
+ source: { kind: 'archive', bytes: archiveBytes },
591
+ })
592
+ ```
593
+
594
+ `throughRunId` selects its exact terminal/abandon event. Omit it to include the settled tip and
595
+ compaction recorded after the last run. The selected prefix must contain no queued or acquired
596
+ runs. A later active source run does not prevent branching an earlier settled prefix. A migrated
597
+ baseline has no earlier per-run event boundary; it can be copied at its settled tip.
598
+
599
+ The result is `{ outcome: 'created' | 'duplicate', receipt }`. Keep the receipt: it binds source
600
+ and destination identity, source kind, exact `sourceSeq`/`sourceVersion`, `sourceDigest`, request
601
+ fingerprint and creation time. A retry with the same destination/key and selector returns the
602
+ original receipt even after the source advances or the destination continues. Changing the
603
+ request conflicts; no existing destination is overwritten. Archive fingerprints bind the supplied
604
+ bytes. The source digest binds the selected canonical events, artifacts and reconstructed snapshot.
605
+ Run update timestamps reconstructed from events use their recorded `occurredAt`. Abandon transitions
606
+ retain the full failed assistant in the same event; a legacy archive must retain that exact assistant
607
+ in its runtime snapshot, otherwise copying refuses instead of inventing historical content or time.
608
+
609
+ No provider or tool runs during copying. The next ordinary runtime `submit` continues the copied
610
+ history. All engine identities and typed references are new, including repeated references to one
611
+ spill. Compacted content stays in the event history and SQLite inactive rows; the model reads the
612
+ same active summaries. A hash-only checkpoint is historical digest evidence, marked
613
+ `sourceSha256`; a later full terminal record must settle its content.
614
+
615
+ A branch grants no source authority. Terminal run owners/fences and approval signatures are
616
+ removed. State, schedules, children, retries, sandbox, approval rejection and durability facts are
617
+ retained as inert `runtime/branch-observation` records; they cannot repopulate operational state
618
+ or pending effects. Spills discard source authorization and require the explicit fresh
619
+ `artifactAuthorization`; normal destination read authorization still applies. No cached projection,
620
+ schedule row or child relation is cloned.
621
+
622
+ The store validates the complete archive before writing: contiguous events, a matching runtime
623
+ snapshot, known typed forms, reference closure, and spill bytes/digests. Unsupported provider
624
+ envelopes, encrypted invocation payloads, unknown event versions, arbitrary cached projections,
625
+ missing artifacts and undocumented reference fields in opaque JSON refuse atomically. They need
626
+ an owner-defined transfer codec; never recursively rewrite internal JSON in the application.
627
+ Third-party drivers must provide atomic write transactions and archive support for spills;
628
+ `history.restore` is required for migrated baselines with inactive rows.
629
+
570
630
  ### Event ledger, projections and durable capabilities
571
631
 
572
632
  `AgentRuntimeStore` exposes bounded `readEvents`, declared `appendEvent`, canonical
package/llms-full.txt CHANGED
@@ -5765,6 +5765,66 @@ failed attempt's reported usage stays in the run's spend. Transient events —
5765
5765
  deltas, reasoning, `attempt-reset` — are numbered from 1 per run, counting only
5766
5766
  what was published, so a cursor sees no gap on an ordinary stream.
5767
5767
 
5768
+ ### Branch or restore with a new identity
5769
+
5770
+ Use `store.branchConversation()` to create an independent conversation. `importConversation()`
5771
+ restores the original identity and is not a fork. The built-in memory and SQLite stores and
5772
+ `createAgentRuntimeStore()` expose branching; a hand-written `AgentRuntimeStore` can advertise this
5773
+ optional capability. The host authorizes the caller's source/archive access and destination
5774
+ creation before calling this trusted store boundary.
5775
+
5776
+ ```ts
5777
+ const copy = await sqlite.store.branchConversation({
5778
+ requestKey: 'branch-request-1',
5779
+ destinationConversationId: 'new-conversation',
5780
+ source: { kind: 'conversation', conversationId: 'original', throughRunId: 'finished-run' },
5781
+ // Required when selected history has spills: an explicit policy for this destination.
5782
+ artifactAuthorization: { operation: 'read', path: 'approved-destination-workspace' },
5783
+ })
5784
+
5785
+ const restored = await sqlite.store.branchConversation({
5786
+ requestKey: 'restore-request-1',
5787
+ destinationConversationId: 'restored-as-new',
5788
+ source: { kind: 'archive', bytes: archiveBytes },
5789
+ })
5790
+ ```
5791
+
5792
+ `throughRunId` selects its exact terminal/abandon event. Omit it to include the settled tip and
5793
+ compaction recorded after the last run. The selected prefix must contain no queued or acquired
5794
+ runs. A later active source run does not prevent branching an earlier settled prefix. A migrated
5795
+ baseline has no earlier per-run event boundary; it can be copied at its settled tip.
5796
+
5797
+ The result is `{ outcome: 'created' | 'duplicate', receipt }`. Keep the receipt: it binds source
5798
+ and destination identity, source kind, exact `sourceSeq`/`sourceVersion`, `sourceDigest`, request
5799
+ fingerprint and creation time. A retry with the same destination/key and selector returns the
5800
+ original receipt even after the source advances or the destination continues. Changing the
5801
+ request conflicts; no existing destination is overwritten. Archive fingerprints bind the supplied
5802
+ bytes. The source digest binds the selected canonical events, artifacts and reconstructed snapshot.
5803
+ Run update timestamps reconstructed from events use their recorded `occurredAt`. Abandon transitions
5804
+ retain the full failed assistant in the same event; a legacy archive must retain that exact assistant
5805
+ in its runtime snapshot, otherwise copying refuses instead of inventing historical content or time.
5806
+
5807
+ No provider or tool runs during copying. The next ordinary runtime `submit` continues the copied
5808
+ history. All engine identities and typed references are new, including repeated references to one
5809
+ spill. Compacted content stays in the event history and SQLite inactive rows; the model reads the
5810
+ same active summaries. A hash-only checkpoint is historical digest evidence, marked
5811
+ `sourceSha256`; a later full terminal record must settle its content.
5812
+
5813
+ A branch grants no source authority. Terminal run owners/fences and approval signatures are
5814
+ removed. State, schedules, children, retries, sandbox, approval rejection and durability facts are
5815
+ retained as inert `runtime/branch-observation` records; they cannot repopulate operational state
5816
+ or pending effects. Spills discard source authorization and require the explicit fresh
5817
+ `artifactAuthorization`; normal destination read authorization still applies. No cached projection,
5818
+ schedule row or child relation is cloned.
5819
+
5820
+ The store validates the complete archive before writing: contiguous events, a matching runtime
5821
+ snapshot, known typed forms, reference closure, and spill bytes/digests. Unsupported provider
5822
+ envelopes, encrypted invocation payloads, unknown event versions, arbitrary cached projections,
5823
+ missing artifacts and undocumented reference fields in opaque JSON refuse atomically. They need
5824
+ an owner-defined transfer codec; never recursively rewrite internal JSON in the application.
5825
+ Third-party drivers must provide atomic write transactions and archive support for spills;
5826
+ `history.restore` is required for migrated baselines with inactive rows.
5827
+
5768
5828
  ### Event ledger, projections and durable capabilities
5769
5829
 
5770
5830
  `AgentRuntimeStore` exposes bounded `readEvents`, declared `appendEvent`, canonical
@@ -21702,6 +21762,9 @@ Server-only optional application runtime. See the
21702
21762
  | `AgentMessageSchema` / `AgentRunSchema` / `AgentSnapshotSchema` | schema | versioned canonical engine records |
21703
21763
  | `AgentRunQueuePrioritySchema` | schema | durable opt-in priority for queued `interrupt-next` runs |
21704
21764
  | `AgentRuntimeStore` | _type_ | aggregate CAS transaction boundary for message, run and compaction mutations |
21765
+ | `BranchAgentConversationInputSchema` / `BranchAgentConversationInput` | schema / _type_ | strict branch request: stable request key, empty destination, settled conversation boundary or archive bytes, fresh artifact authorization |
21766
+ | `AgentConversationBranchReceiptSchema` / `AgentConversationBranchReceipt` | schema / _type_ | durable lineage: request fingerprint, source/destination identities, source sequence/version/digest and creation time |
21767
+ | `AgentConversationBranchResultSchema` / `AgentConversationBranchResult` | schema / _type_ | `created` or `duplicate` with the same durable receipt; `AgentRuntimeStore.branchConversation` is optional for hand-written stores |
21705
21768
  | `createAgentRuntimeStore` | function | build the aggregate store from one coherent transaction driver; framework owns every state transition |
21706
21769
  | `AgentRuntimeStoreDriver` | _type_ | ORM-neutral transaction over a bounded head, normalized runs/admissions, product history, a **required** `events: { append, list }` ledger table, an optional `archive: { export, import }` for driver-owned durable payloads, and indexed run recovery; optional `{ access: 'read' }` selects a coherent read transaction while absent options remain write-safe |
21707
21770
  | `recordAgentRetryDecision` / `AgentRetryPolicy` | function / _type_ | `loop.retry` policy and the ledger record of a retry decision: explicit retryability and backoff at a durable provider-step boundary |
package/llms.txt CHANGED
@@ -25,7 +25,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
25
25
  - **stitchkit/primitives**: [llms/primitives.txt](llms/primitives.txt) 11.7 KB
26
26
  - **stitchkit/server**: [llms/server.txt](llms/server.txt) 45.3 KB → [llms/server.2.txt](llms/server.2.txt) 14.6 KB → [llms/server.3.txt](llms/server.3.txt) 45.6 KB → [llms/server.4.txt](llms/server.4.txt) 38.3 KB → [llms/server.5.txt](llms/server.5.txt) 22.1 KB
27
27
  - **stitchkit/observability**: [llms/observability.txt](llms/observability.txt) 45.9 KB
28
- - **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 37.1 KB → [llms/agent-runtime.2.txt](llms/agent-runtime.2.txt) 46.7 KB → [llms/agent-runtime.3.txt](llms/agent-runtime.3.txt) 34.7 KB
28
+ - **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 41.0 KB → [llms/agent-runtime.2.txt](llms/agent-runtime.2.txt) 46.7 KB → [llms/agent-runtime.3.txt](llms/agent-runtime.3.txt) 35.4 KB
29
29
  - **stitchkit/agent-runtime/testing**: [llms/agent-runtime-testing.txt](llms/agent-runtime-testing.txt) 2.6 KB
30
30
  - **stitchkit/agent-runtime/harness**: [llms/agent-runtime-harness.txt](llms/agent-runtime-harness.txt) 11.0 KB
31
31
  - **stitchkit/agent-runtime/coding-tools**: [llms/agent-runtime-coding-tools.txt](llms/agent-runtime-coding-tools.txt) 5.0 KB
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.110.1",
3
+ "version": "0.110.2",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",
@@ -1,129 +0,0 @@
1
- import {
2
- AppError2,
3
- STITCH_ERROR_STATUS2
4
- } from "./index-j9gxbztg.js";
5
-
6
- // src/agent-runtime/sandbox.ts
7
- import { z } from "zod";
8
- var AgentSandboxRestrictionSchema2 = z.enum([
9
- "network-denied",
10
- "write-contained",
11
- "secrets-hidden",
12
- "process-contained"
13
- ]);
14
- var AgentSandboxGradeSchema2 = z.discriminatedUnion("grade", [
15
- z.object({ grade: z.literal("full"), restrictions: z.array(AgentSandboxRestrictionSchema2) }).strict(),
16
- z.object({
17
- grade: z.literal("partial"),
18
- restrictions: z.array(AgentSandboxRestrictionSchema2),
19
- gaps: z.array(AgentSandboxRestrictionSchema2)
20
- }).strict(),
21
- z.object({ grade: z.literal("unavailable"), reason: z.string().min(1) }).strict()
22
- ]);
23
- var probes = new WeakMap;
24
- var PROBE_FAILED = "sandbox probe failed";
25
- var PROBE_INVALID = "sandbox probe returned no valid grade";
26
- async function runProbe(sandbox) {
27
- let value;
28
- try {
29
- value = await sandbox.probe();
30
- } catch (cause) {
31
- return { grade: { grade: "unavailable", reason: PROBE_FAILED }, cause };
32
- }
33
- const parsed = AgentSandboxGradeSchema2.safeParse(value);
34
- if (parsed.success)
35
- return { grade: parsed.data };
36
- return { grade: { grade: "unavailable", reason: PROBE_INVALID }, cause: parsed.error };
37
- }
38
- function probeAgentProcessSandboxOutcome(sandbox, options = {}) {
39
- if (options.refresh)
40
- probes.delete(sandbox);
41
- const present = probes.get(sandbox);
42
- if (present)
43
- return present;
44
- const pending = runProbe(sandbox);
45
- probes.set(sandbox, pending);
46
- return pending;
47
- }
48
- async function probeAgentProcessSandbox2(sandbox, options = {}) {
49
- const fresh = options.refresh === true || !probes.has(sandbox);
50
- const outcome = await probeAgentProcessSandboxOutcome(sandbox, options);
51
- if (fresh && outcome.cause !== undefined) {
52
- process.emitWarning(new Error("Sandbox probe failed", { cause: outcome.cause }));
53
- }
54
- return outcome.grade;
55
- }
56
- function missingSandboxRestrictions2(grade, required) {
57
- if (grade.grade === "unavailable")
58
- return required;
59
- const present = new Set(grade.restrictions);
60
- return required.filter((restriction) => !present.has(restriction));
61
- }
62
- async function recordAgentSandboxProbe2(input) {
63
- const grade = await probeAgentProcessSandbox2(input.sandbox);
64
- const missing = missingSandboxRestrictions2(grade, input.required);
65
- await input.store.appendEvent({
66
- conversationId: input.conversationId,
67
- kind: "sandbox/probed",
68
- payload: {
69
- result: grade,
70
- required: [...input.required],
71
- missing: [...missing]
72
- }
73
- });
74
- return grade;
75
- }
76
-
77
- // src/agent-runtime/coding-tool-refusals.ts
78
- function codingRefusal(code, message, options = {}) {
79
- throw new AppError2(code, {
80
- message,
81
- status: STITCH_ERROR_STATUS2[code],
82
- details: { message, ...options.details },
83
- hint: options.hint,
84
- ..."cause" in options && { cause: options.cause }
85
- });
86
- }
87
- function codingPathRefusal(code, message, path, options = {}) {
88
- codingRefusal(code, message, {
89
- details: { path, ...options.details },
90
- ...options.hint && { hint: options.hint }
91
- });
92
- }
93
- function refuseMissingCodingPath(error, relative) {
94
- const code = error?.code;
95
- if (error instanceof Error && error.message.includes("is not a regular file")) {
96
- codingPathRefusal("BAD_REQUEST", "This path is not a regular file", relative, {
97
- hint: "Use list_directory to see what is here."
98
- });
99
- }
100
- if (code === "ENOENT") {
101
- codingPathRefusal("NOT_FOUND", "This path does not exist", relative, {
102
- hint: "Use list_directory or glob to find the right path."
103
- });
104
- }
105
- if (code === "ENOTDIR") {
106
- codingPathRefusal("BAD_REQUEST", "A segment of this path is not a directory", relative, {
107
- hint: "Check the path with list_directory."
108
- });
109
- }
110
- if (code === "ELOOP") {
111
- codingPathRefusal("FORBIDDEN", "This path is a symlink, which is not followed", relative, {
112
- hint: "Read or write the target directly, by its own workspace-relative path."
113
- });
114
- }
115
- if (code === "EISDIR") {
116
- codingPathRefusal("BAD_REQUEST", "This path is not a regular file", relative, {
117
- hint: "Use list_directory to see what is here."
118
- });
119
- }
120
- throw error;
121
- }
122
- function refuseUnknownSpillReference(reference) {
123
- codingRefusal("SPILL_REFERENCE_UNKNOWN", `No spilled output is held under \`${reference}\``, {
124
- details: { reference },
125
- hint: "Use the reference returned by the command that spilled its output, not a session or call id."
126
- });
127
- }
128
-
129
- export { AgentSandboxRestrictionSchema2, AgentSandboxGradeSchema2, probeAgentProcessSandboxOutcome, probeAgentProcessSandbox2, missingSandboxRestrictions2, recordAgentSandboxProbe2, codingRefusal, codingPathRefusal, refuseMissingCodingPath, refuseUnknownSpillReference };