@noetic-tools/core 0.0.1 → 0.1.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 (202) hide show
  1. package/dist/adapters/in-memory-fs-adapter.js +1 -1
  2. package/dist/adapters/in-memory-subprocess/manifest-persistence.d.ts +8 -0
  3. package/dist/adapters/in-memory-subprocess/manifest-persistence.js +56 -0
  4. package/dist/adapters/in-memory-subprocess/metadata.d.ts +12 -0
  5. package/dist/adapters/in-memory-subprocess/metadata.js +58 -0
  6. package/dist/adapters/in-memory-subprocess/step-completion.d.ts +3 -0
  7. package/dist/adapters/in-memory-subprocess/step-completion.js +86 -0
  8. package/dist/adapters/in-memory-subprocess/types.d.ts +88 -0
  9. package/dist/adapters/in-memory-subprocess/types.js +2 -0
  10. package/dist/adapters/in-memory-subprocess-adapter.d.ts +12 -4
  11. package/dist/adapters/in-memory-subprocess-adapter.js +164 -55
  12. package/dist/adapters/openrouter.d.ts +11 -2
  13. package/dist/adapters/openrouter.js +66 -5
  14. package/dist/builders/control-flow-builders.js +8 -3
  15. package/dist/builders/every.js +4 -1
  16. package/dist/builders/layer-provides-builders.d.ts +1 -32
  17. package/dist/builders/layer-provides-builders.js +1 -33
  18. package/dist/builders/loop-builder.js +4 -1
  19. package/dist/builders/memory-builder.js +1 -1
  20. package/dist/builders/provide-builder.js +4 -1
  21. package/dist/builders/spawn-builder.d.ts +20 -7
  22. package/dist/builders/spawn-builder.js +16 -2
  23. package/dist/builders/step-builders.d.ts +49 -28
  24. package/dist/builders/step-builders.js +30 -11
  25. package/dist/builders/tool-builder.d.ts +5 -1
  26. package/dist/builders/tool-builder.js +2 -0
  27. package/dist/builders/workflow-hydrator.d.ts +38 -0
  28. package/dist/builders/workflow-hydrator.js +336 -0
  29. package/dist/conditions/conditions.js +1 -1
  30. package/dist/errors/noetic-error.js +2 -0
  31. package/dist/{runtime → harness}/agent-harness.d.ts +65 -45
  32. package/dist/harness/agent-harness.js +576 -0
  33. package/dist/harness/deps/adapters.d.ts +4 -0
  34. package/dist/harness/deps/adapters.js +4 -0
  35. package/dist/harness/deps/interpreter.d.ts +5 -0
  36. package/dist/harness/deps/interpreter.js +4 -0
  37. package/dist/harness/deps/memory.d.ts +5 -0
  38. package/dist/harness/deps/memory.js +4 -0
  39. package/dist/harness/deps/runtime.d.ts +10 -0
  40. package/dist/harness/deps/runtime.js +7 -0
  41. package/dist/harness/deps/types.d.ts +17 -0
  42. package/dist/harness/deps/types.js +1 -0
  43. package/dist/harness/model-call.d.ts +50 -0
  44. package/dist/harness/model-call.js +694 -0
  45. package/dist/harness/model-schema.d.ts +19 -0
  46. package/dist/harness/model-schema.js +46 -0
  47. package/dist/harness/step-bootstrap.d.ts +25 -0
  48. package/dist/harness/step-bootstrap.js +170 -0
  49. package/dist/index.d.ts +48 -12
  50. package/dist/index.js +29 -7
  51. package/dist/interpreter/action-deps.d.ts +12 -0
  52. package/dist/interpreter/action-deps.js +10 -0
  53. package/dist/interpreter/action-types.d.ts +8 -0
  54. package/dist/interpreter/action-types.js +1 -0
  55. package/dist/interpreter/collect-tools.d.ts +1 -1
  56. package/dist/interpreter/collect-tools.js +6 -2
  57. package/dist/interpreter/execute-action.d.ts +22 -0
  58. package/dist/interpreter/execute-action.js +527 -0
  59. package/dist/interpreter/{execute-every.d.ts → execute-control.d.ts} +7 -1
  60. package/dist/interpreter/execute-control.js +530 -0
  61. package/dist/interpreter/execute.d.ts +13 -0
  62. package/dist/interpreter/execute.js +151 -48
  63. package/dist/interpreter/message-helpers.d.ts +1 -9
  64. package/dist/interpreter/message-helpers.js +1 -42
  65. package/dist/interpreter/step-dispatcher.d.ts +61 -0
  66. package/dist/interpreter/step-dispatcher.js +67 -0
  67. package/dist/interpreter/typeguards.d.ts +3 -10
  68. package/dist/interpreter/typeguards.js +3 -20
  69. package/dist/{runtime → memory}/exec-context-factory.js +1 -1
  70. package/dist/memory/flow-schema.d.ts +52 -0
  71. package/dist/memory/flow-schema.js +102 -0
  72. package/dist/memory/function-call-utils.js +4 -2
  73. package/dist/memory/layer-api.d.ts +1 -1
  74. package/dist/memory/layer-api.js +2 -2
  75. package/dist/memory/layer-lifecycle.d.ts +1 -1
  76. package/dist/memory/layer-lifecycle.js +2 -2
  77. package/dist/memory/layer-provides.d.ts +32 -0
  78. package/dist/memory/layer-provides.js +33 -0
  79. package/dist/memory/layer-usage.d.ts +3 -2
  80. package/dist/memory/layer-usage.js +9 -3
  81. package/dist/memory/layers/durable-task-state.js +1 -1
  82. package/dist/memory/layers/file-reference.js +302 -246
  83. package/dist/memory/layers/history-window.js +1 -1
  84. package/dist/memory/layers/observational-memory.js +1 -2
  85. package/dist/memory/layers/plan.d.ts +1 -1
  86. package/dist/memory/layers/plan.js +13 -8
  87. package/dist/memory/layers/steering.js +1 -1
  88. package/dist/memory/layers/tool-memory-layer.d.ts +1 -1
  89. package/dist/memory/layers/working-memory.js +2 -2
  90. package/dist/patterns/dynamic-workflow.d.ts +55 -0
  91. package/dist/patterns/dynamic-workflow.js +194 -0
  92. package/dist/patterns/flow.d.ts +2 -52
  93. package/dist/patterns/flow.js +1 -103
  94. package/dist/patterns/interview.js +1 -1
  95. package/dist/patterns/plans.d.ts +3 -3
  96. package/dist/patterns/plans.js +3 -3
  97. package/dist/patterns/ralph-wiggum.d.ts +1 -1
  98. package/dist/patterns/react.d.ts +1 -1
  99. package/dist/portable/adapters.d.ts +6 -0
  100. package/dist/portable/adapters.js +6 -0
  101. package/dist/portable/ask-user.d.ts +4 -0
  102. package/dist/portable/ask-user.js +2 -0
  103. package/dist/portable/builders.d.ts +12 -0
  104. package/dist/portable/builders.js +12 -0
  105. package/dist/portable/memory-layers.d.ts +12 -0
  106. package/dist/portable/memory-layers.js +12 -0
  107. package/dist/portable/runtime.d.ts +4 -0
  108. package/dist/portable/runtime.js +4 -0
  109. package/dist/portable/until.d.ts +4 -0
  110. package/dist/portable/until.js +4 -0
  111. package/dist/portable.d.ts +8 -26
  112. package/dist/portable.js +8 -34
  113. package/dist/runtime/broadcaster-utils.d.ts +5 -1
  114. package/dist/runtime/broadcaster-utils.js +11 -6
  115. package/dist/runtime/channel-store.js +1 -1
  116. package/dist/runtime/context-deps.d.ts +4 -0
  117. package/dist/runtime/context-deps.js +2 -0
  118. package/dist/runtime/context-impl.d.ts +42 -12
  119. package/dist/runtime/context-impl.js +51 -4
  120. package/dist/runtime/context-type-deps.d.ts +14 -0
  121. package/dist/runtime/context-type-deps.js +1 -0
  122. package/dist/runtime/detached-handle.d.ts +50 -2
  123. package/dist/runtime/detached-handle.js +216 -12
  124. package/dist/runtime/durable/checkpoint-store.d.ts +38 -0
  125. package/dist/runtime/durable/checkpoint-store.js +101 -0
  126. package/dist/runtime/durable/detached-signal.d.ts +37 -0
  127. package/dist/runtime/durable/detached-signal.js +52 -0
  128. package/dist/runtime/durable/harness-checkpoints.d.ts +51 -0
  129. package/dist/runtime/durable/harness-checkpoints.js +104 -0
  130. package/dist/runtime/durable/index.d.ts +10 -0
  131. package/dist/runtime/durable/index.js +5 -0
  132. package/dist/runtime/durable/runnable-loop.d.ts +100 -0
  133. package/dist/runtime/durable/runnable-loop.js +90 -0
  134. package/dist/runtime/durable/session-seed.d.ts +28 -0
  135. package/dist/runtime/durable/session-seed.js +27 -0
  136. package/dist/runtime/durable/stall-nudge.d.ts +82 -0
  137. package/dist/runtime/durable/stall-nudge.js +87 -0
  138. package/dist/runtime/in-memory-storage.js +1 -1
  139. package/dist/runtime/item-log-impl.d.ts +1 -1
  140. package/dist/runtime/step-registry.d.ts +42 -0
  141. package/dist/runtime/step-registry.js +77 -0
  142. package/dist/schemas/workflow.d.ts +139 -0
  143. package/dist/schemas/workflow.js +232 -0
  144. package/dist/types/ask-user-types.d.ts +57 -0
  145. package/dist/types/ask-user-types.js +74 -0
  146. package/dist/types/checkpoint.d.ts +98 -0
  147. package/dist/types/checkpoint.js +81 -0
  148. package/dist/types/common.d.ts +1 -50
  149. package/dist/types/context-parts/item-log.d.ts +6 -0
  150. package/dist/types/context-parts/item-log.js +1 -0
  151. package/dist/types/context-parts/layer-usage.d.ts +18 -0
  152. package/dist/types/context-parts/layer-usage.js +1 -0
  153. package/dist/types/context.d.ts +135 -26
  154. package/dist/types/error.d.ts +15 -0
  155. package/dist/types/harness-result.d.ts +1 -1
  156. package/dist/types/items.d.ts +18 -2
  157. package/dist/types/memory-context.d.ts +39 -0
  158. package/dist/types/memory-context.js +1 -0
  159. package/dist/types/memory.d.ts +35 -65
  160. package/dist/types/runtime.d.ts +2 -1
  161. package/dist/types/steering.d.ts +1 -1
  162. package/dist/types/step-registrar.d.ts +46 -0
  163. package/dist/types/step-registrar.js +56 -0
  164. package/dist/types/step.d.ts +30 -5
  165. package/dist/types/subprocess-adapter.d.ts +119 -3
  166. package/dist/types/subprocess-adapter.js +2 -0
  167. package/dist/types/tool.d.ts +64 -0
  168. package/dist/types/tool.js +1 -0
  169. package/dist/unstable.d.ts +2 -2
  170. package/dist/unstable.js +2 -2
  171. package/dist/until/predicates.d.ts +9 -0
  172. package/dist/until/predicates.js +14 -0
  173. package/dist/util/message-helpers.d.ts +17 -0
  174. package/dist/util/message-helpers.js +64 -0
  175. package/package.json +1 -1
  176. package/dist/adapters/local-fs-adapter.d.ts +0 -3
  177. package/dist/adapters/local-fs-adapter.js +0 -43
  178. package/dist/adapters/local-shell-adapter.d.ts +0 -51
  179. package/dist/adapters/local-shell-adapter.js +0 -167
  180. package/dist/adapters/local-subprocess-adapter.d.ts +0 -16
  181. package/dist/adapters/local-subprocess-adapter.js +0 -187
  182. package/dist/interpreter/execute-branch.d.ts +0 -3
  183. package/dist/interpreter/execute-branch.js +0 -10
  184. package/dist/interpreter/execute-every.js +0 -143
  185. package/dist/interpreter/execute-fork.d.ts +0 -3
  186. package/dist/interpreter/execute-fork.js +0 -215
  187. package/dist/interpreter/execute-llm.d.ts +0 -4
  188. package/dist/interpreter/execute-llm.js +0 -217
  189. package/dist/interpreter/execute-loop.d.ts +0 -3
  190. package/dist/interpreter/execute-loop.js +0 -171
  191. package/dist/interpreter/execute-provide.d.ts +0 -10
  192. package/dist/interpreter/execute-provide.js +0 -64
  193. package/dist/interpreter/execute-run.d.ts +0 -3
  194. package/dist/interpreter/execute-run.js +0 -39
  195. package/dist/interpreter/execute-spawn.d.ts +0 -11
  196. package/dist/interpreter/execute-spawn.js +0 -113
  197. package/dist/interpreter/execute-tool.d.ts +0 -5
  198. package/dist/interpreter/execute-tool.js +0 -81
  199. package/dist/runtime/agent-harness.js +0 -1170
  200. /package/dist/{runtime → memory}/exec-context-factory.d.ts +0 -0
  201. /package/dist/{interpreter → util}/framework-cast.d.ts +0 -0
  202. /package/dist/{interpreter → util}/framework-cast.js +0 -0
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Wire schemas + types for the ask-user pattern.
3
+ *
4
+ * The "ask-user" shape is a portable, tool-agnostic description of an
5
+ * interactive prompt (questions + options + answers) that any UI — in-process
6
+ * TUI modal, IPC-backed runner, future web renderer — can render and
7
+ * respond to. The schemas live in core so callers on either side of an
8
+ * adapter (tool author, TUI, IPC protocol) validate against the same
9
+ * definitions rather than each package maintaining a drift-prone copy.
10
+ *
11
+ * Kept separate from a concrete tool factory so the TUI can import the
12
+ * types without pulling in a tool that closes over an `AskUserService`.
13
+ */
14
+ import { z } from 'zod';
15
+ export declare const AskUserOptionSchema: z.ZodObject<{
16
+ label: z.ZodString;
17
+ description: z.ZodString;
18
+ preview: z.ZodOptional<z.ZodString>;
19
+ }, z.core.$strip>;
20
+ export declare const AskUserQuestionSchema: z.ZodObject<{
21
+ question: z.ZodString;
22
+ header: z.ZodString;
23
+ options: z.ZodArray<z.ZodObject<{
24
+ label: z.ZodString;
25
+ description: z.ZodString;
26
+ preview: z.ZodOptional<z.ZodString>;
27
+ }, z.core.$strip>>;
28
+ multiSelect: z.ZodDefault<z.ZodBoolean>;
29
+ }, z.core.$strip>;
30
+ export declare const AskUserInputSchema: z.ZodObject<{
31
+ questions: z.ZodArray<z.ZodObject<{
32
+ question: z.ZodString;
33
+ header: z.ZodString;
34
+ options: z.ZodArray<z.ZodObject<{
35
+ label: z.ZodString;
36
+ description: z.ZodString;
37
+ preview: z.ZodOptional<z.ZodString>;
38
+ }, z.core.$strip>>;
39
+ multiSelect: z.ZodDefault<z.ZodBoolean>;
40
+ }, z.core.$strip>>;
41
+ }, z.core.$strip>;
42
+ export declare const AskUserAnnotationSchema: z.ZodObject<{
43
+ notes: z.ZodOptional<z.ZodString>;
44
+ preview: z.ZodOptional<z.ZodString>;
45
+ }, z.core.$strip>;
46
+ export declare const AskUserOutputSchema: z.ZodObject<{
47
+ answers: z.ZodRecord<z.ZodString, z.ZodString>;
48
+ annotations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
49
+ notes: z.ZodOptional<z.ZodString>;
50
+ preview: z.ZodOptional<z.ZodString>;
51
+ }, z.core.$strip>>>;
52
+ }, z.core.$strip>;
53
+ export type AskUserOption = z.infer<typeof AskUserOptionSchema>;
54
+ export type AskUserQuestion = z.infer<typeof AskUserQuestionSchema>;
55
+ export type AskUserInput = z.infer<typeof AskUserInputSchema>;
56
+ export type AskUserAnnotation = z.infer<typeof AskUserAnnotationSchema>;
57
+ export type AskUserOutput = z.infer<typeof AskUserOutputSchema>;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Wire schemas + types for the ask-user pattern.
3
+ *
4
+ * The "ask-user" shape is a portable, tool-agnostic description of an
5
+ * interactive prompt (questions + options + answers) that any UI — in-process
6
+ * TUI modal, IPC-backed runner, future web renderer — can render and
7
+ * respond to. The schemas live in core so callers on either side of an
8
+ * adapter (tool author, TUI, IPC protocol) validate against the same
9
+ * definitions rather than each package maintaining a drift-prone copy.
10
+ *
11
+ * Kept separate from a concrete tool factory so the TUI can import the
12
+ * types without pulling in a tool that closes over an `AskUserService`.
13
+ */
14
+ import { z } from 'zod';
15
+ //#region Schemas
16
+ export const AskUserOptionSchema = z.object({
17
+ label: z.string().min(1).describe('The display text for this option. Concise (1–5 words).'),
18
+ description: z
19
+ .string()
20
+ .describe('Explanation of what this option means or what will happen if chosen.'),
21
+ preview: z
22
+ .string()
23
+ .optional()
24
+ .describe('Optional preview content rendered when this option is focused. Markdown (or HTML fragment) for side-by-side visual comparison.'),
25
+ });
26
+ export const AskUserQuestionSchema = z.object({
27
+ question: z
28
+ .string()
29
+ .min(1)
30
+ .describe('The complete question. Should be clear, specific, and end with a question mark.'),
31
+ header: z
32
+ .string()
33
+ .min(1)
34
+ .max(12)
35
+ .describe('Very short label displayed as a chip/tag (1–12 chars, inclusive).'),
36
+ options: z
37
+ .array(AskUserOptionSchema)
38
+ .min(2)
39
+ .max(4)
40
+ .describe('2–4 distinct choices. An "Other" option is added automatically.'),
41
+ multiSelect: z
42
+ .boolean()
43
+ .default(false)
44
+ .describe('When true, users may select multiple options for this question.'),
45
+ });
46
+ export const AskUserInputSchema = z.object({
47
+ questions: z
48
+ .array(AskUserQuestionSchema)
49
+ .min(1)
50
+ .max(4)
51
+ .describe('1–4 questions to ask the user.')
52
+ // Question text doubles as the answers-map key. Two questions with the
53
+ // same text would silently collapse, so reject duplicates at parse time.
54
+ .refine((qs) => new Set(qs.map((q) => q.question)).size === qs.length, {
55
+ message: 'Question texts must be unique — duplicates would collapse in the answers map.',
56
+ }),
57
+ });
58
+ export const AskUserAnnotationSchema = z.object({
59
+ notes: z.string().optional().describe('Free-text notes the user added to their selection.'),
60
+ preview: z
61
+ .string()
62
+ .optional()
63
+ .describe('The preview content of the selected option, if the question used previews.'),
64
+ });
65
+ export const AskUserOutputSchema = z.object({
66
+ answers: z
67
+ .record(z.string(), z.string())
68
+ .describe('Map from question text to the user\'s answer (label or custom "Other" text).'),
69
+ annotations: z
70
+ .record(z.string(), AskUserAnnotationSchema)
71
+ .optional()
72
+ .describe('Optional per-question annotations (preview content of selected option, notes).'),
73
+ });
74
+ //#endregion
@@ -0,0 +1,98 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * @public
4
+ * Literal schema version stamped on every `CheckpointSnapshot`. Bumped when a
5
+ * backward-incompatible change lands. `restore()` refuses to load snapshots
6
+ * whose version is not recognised and surfaces a typed `NoeticConfigError`
7
+ * (`code === 'CHECKPOINT_SCHEMA_MISMATCH'`) so hosts can discard cleanly.
8
+ */
9
+ export declare const CheckpointSchemaVersion = 1;
10
+ /**
11
+ * @public
12
+ * One entry in the execution frontier — a pointer to a step currently in
13
+ * flight on the parent's stack, plus the input/state snapshot required to
14
+ * resume it.
15
+ *
16
+ * The frontier is intentionally lenient: frame `state` is treated as an
17
+ * opaque JSON value because step `state` is user-defined. Parse/validate at
18
+ * the call site when specific shape guarantees are needed.
19
+ */
20
+ export declare const FrontierFrameSchema: z.ZodObject<{
21
+ stepId: z.ZodString;
22
+ input: z.ZodUnknown;
23
+ state: z.ZodOptional<z.ZodUnknown>;
24
+ }, z.core.$strip>;
25
+ /** @public Shape of a single frontier frame serialised inside a snapshot. */
26
+ export type FrontierFrame = z.infer<typeof FrontierFrameSchema>;
27
+ /**
28
+ * @public
29
+ * Working-directory snapshot captured at checkpoint time. `current` is the
30
+ * active cwd; `previous` records the last value for parity with
31
+ * `CwdState.previousCwd` which tools use for `cd -`.
32
+ */
33
+ export declare const CwdSnapshotSchema: z.ZodObject<{
34
+ current: z.ZodNullable<z.ZodString>;
35
+ previous: z.ZodOptional<z.ZodNullable<z.ZodString>>;
36
+ }, z.core.$strip>;
37
+ /** @public Cwd portion of a checkpoint snapshot. */
38
+ export type CwdSnapshot = z.infer<typeof CwdSnapshotSchema>;
39
+ /**
40
+ * @public
41
+ * Shape of an ask-user record that was pending at snapshot time. The actual
42
+ * schema is owned by the code-agent `AskUserService`; we only need the outer
43
+ * envelope here so the host can replay the queue into a restarted TUI modal.
44
+ */
45
+ export declare const PendingAskUserSnapshotSchema: z.ZodObject<{
46
+ id: z.ZodString;
47
+ input: z.ZodUnknown;
48
+ createdAt: z.ZodNumber;
49
+ }, z.core.$strip>;
50
+ /** @public Pending ask-user record captured in a snapshot. */
51
+ export type PendingAskUserSnapshot = z.infer<typeof PendingAskUserSnapshotSchema>;
52
+ /**
53
+ * @public
54
+ * Item log state captured in a snapshot. We store the ordered list of items
55
+ * directly — the `ItemLogImpl` is append-only so the list is its own cursor.
56
+ *
57
+ * Items are carried as `unknown` here and re-parsed on restore via the
58
+ * harness's `ItemSchemaRegistry`, which is the same gate production traffic
59
+ * passes through.
60
+ */
61
+ export declare const ItemLogSnapshotSchema: z.ZodObject<{
62
+ items: z.ZodArray<z.ZodUnknown>;
63
+ }, z.core.$strip>;
64
+ /** @public Item log portion of a snapshot. */
65
+ export type ItemLogSnapshot = z.infer<typeof ItemLogSnapshotSchema>;
66
+ /**
67
+ * @public
68
+ * Top-level checkpoint payload persisted through a `CheckpointStore`. Carries
69
+ * a schema version so forward-incompatible changes can be rejected cleanly
70
+ * instead of producing a silently corrupt restored context.
71
+ */
72
+ export declare const CheckpointSnapshotSchema: z.ZodObject<{
73
+ schemaVersion: z.ZodLiteral<1>;
74
+ executionId: z.ZodString;
75
+ threadId: z.ZodOptional<z.ZodString>;
76
+ resourceId: z.ZodOptional<z.ZodString>;
77
+ frontier: z.ZodArray<z.ZodObject<{
78
+ stepId: z.ZodString;
79
+ input: z.ZodUnknown;
80
+ state: z.ZodOptional<z.ZodUnknown>;
81
+ }, z.core.$strip>>;
82
+ layers: z.ZodRecord<z.ZodString, z.ZodUnknown>;
83
+ cwd: z.ZodNullable<z.ZodObject<{
84
+ current: z.ZodNullable<z.ZodString>;
85
+ previous: z.ZodOptional<z.ZodNullable<z.ZodString>>;
86
+ }, z.core.$strip>>;
87
+ askUser: z.ZodArray<z.ZodObject<{
88
+ id: z.ZodString;
89
+ input: z.ZodUnknown;
90
+ createdAt: z.ZodNumber;
91
+ }, z.core.$strip>>;
92
+ itemLog: z.ZodObject<{
93
+ items: z.ZodArray<z.ZodUnknown>;
94
+ }, z.core.$strip>;
95
+ capturedAt: z.ZodString;
96
+ }, z.core.$strip>;
97
+ /** @public Snapshot of an execution suitable for `CheckpointStore.save()`. */
98
+ export type CheckpointSnapshot = z.infer<typeof CheckpointSnapshotSchema>;
@@ -0,0 +1,81 @@
1
+ import { z } from 'zod';
2
+ //#region Schema
3
+ /**
4
+ * @public
5
+ * Literal schema version stamped on every `CheckpointSnapshot`. Bumped when a
6
+ * backward-incompatible change lands. `restore()` refuses to load snapshots
7
+ * whose version is not recognised and surfaces a typed `NoeticConfigError`
8
+ * (`code === 'CHECKPOINT_SCHEMA_MISMATCH'`) so hosts can discard cleanly.
9
+ */
10
+ export const CheckpointSchemaVersion = 1;
11
+ /**
12
+ * @public
13
+ * One entry in the execution frontier — a pointer to a step currently in
14
+ * flight on the parent's stack, plus the input/state snapshot required to
15
+ * resume it.
16
+ *
17
+ * The frontier is intentionally lenient: frame `state` is treated as an
18
+ * opaque JSON value because step `state` is user-defined. Parse/validate at
19
+ * the call site when specific shape guarantees are needed.
20
+ */
21
+ export const FrontierFrameSchema = z.object({
22
+ /** Stable id of the step this frame represents. */
23
+ stepId: z.string(),
24
+ /** Serialisable input delivered to the step when it started. */
25
+ input: z.unknown(),
26
+ /** Optional per-frame state snapshot. */
27
+ state: z.unknown().optional(),
28
+ });
29
+ /**
30
+ * @public
31
+ * Working-directory snapshot captured at checkpoint time. `current` is the
32
+ * active cwd; `previous` records the last value for parity with
33
+ * `CwdState.previousCwd` which tools use for `cd -`.
34
+ */
35
+ export const CwdSnapshotSchema = z.object({
36
+ current: z.string().nullable(),
37
+ previous: z.string().nullish(),
38
+ });
39
+ /**
40
+ * @public
41
+ * Shape of an ask-user record that was pending at snapshot time. The actual
42
+ * schema is owned by the code-agent `AskUserService`; we only need the outer
43
+ * envelope here so the host can replay the queue into a restarted TUI modal.
44
+ */
45
+ export const PendingAskUserSnapshotSchema = z.object({
46
+ id: z.string(),
47
+ input: z.unknown(),
48
+ createdAt: z.number(),
49
+ });
50
+ /**
51
+ * @public
52
+ * Item log state captured in a snapshot. We store the ordered list of items
53
+ * directly — the `ItemLogImpl` is append-only so the list is its own cursor.
54
+ *
55
+ * Items are carried as `unknown` here and re-parsed on restore via the
56
+ * harness's `ItemSchemaRegistry`, which is the same gate production traffic
57
+ * passes through.
58
+ */
59
+ export const ItemLogSnapshotSchema = z.object({
60
+ items: z.array(z.unknown()),
61
+ });
62
+ /**
63
+ * @public
64
+ * Top-level checkpoint payload persisted through a `CheckpointStore`. Carries
65
+ * a schema version so forward-incompatible changes can be rejected cleanly
66
+ * instead of producing a silently corrupt restored context.
67
+ */
68
+ export const CheckpointSnapshotSchema = z.object({
69
+ schemaVersion: z.literal(CheckpointSchemaVersion),
70
+ executionId: z.string(),
71
+ threadId: z.string().optional(),
72
+ resourceId: z.string().optional(),
73
+ frontier: z.array(FrontierFrameSchema),
74
+ layers: z.record(z.string(), z.unknown()),
75
+ cwd: CwdSnapshotSchema.nullable(),
76
+ askUser: z.array(PendingAskUserSnapshotSchema),
77
+ itemLog: ItemLogSnapshotSchema,
78
+ /** ISO-8601 timestamp of when the snapshot was taken. */
79
+ capturedAt: z.string(),
80
+ });
81
+ //#endregion
@@ -1,7 +1,4 @@
1
- import type { ZodTypeAny, z } from 'zod';
2
- import type { FunctionCallItem, FunctionCallOutputItem, Item, ItemSchemaExtensions, ToolResultExtensionItem } from './items';
3
- import type { ToolExecutionContext } from './tool-context';
4
- type ToolExecutionResult<O extends ZodTypeAny> = Promise<z.infer<O>> | AsyncGenerator<unknown, z.infer<O>>;
1
+ import type { FunctionCallItem, Item } from './items';
5
2
  /**
6
3
  * Policy controlling automatic retry behavior on step failure.
7
4
  * @public
@@ -30,51 +27,6 @@ export interface ModelParams {
30
27
  /** Sequences that cause the model to stop generating. */
31
28
  stopSequences?: string[];
32
29
  }
33
- /**
34
- * Declares tool-owned memory that the runtime materializes into a MemoryLayer.
35
- * @public
36
- */
37
- export interface ToolMemoryDeclaration<TState = unknown> {
38
- /** Shared id — tools with the same id share state. Defaults to `tool.name`. */
39
- id?: string;
40
- /** Factory for the initial state. */
41
- init: () => TState;
42
- /** Project state into the LLM context. Return null to omit. */
43
- recall: (state: TState) => string | null;
44
- }
45
- /**
46
- * A tool definition that an LLM can invoke during execution.
47
- * @public
48
- */
49
- export interface Tool<I extends ZodTypeAny = ZodTypeAny, O extends ZodTypeAny = ZodTypeAny> {
50
- /** Unique tool name used by the LLM for selection. */
51
- name: string;
52
- /** Human-readable description shown to the LLM. */
53
- description: string;
54
- /** Zod schema validating tool input arguments. */
55
- input: I;
56
- /** Zod schema validating tool return value. */
57
- output: O;
58
- /** Optional Zod schema validating streaming events yielded during execution. */
59
- event?: ZodTypeAny;
60
- /** Optional item schemas contributed by this tool for tool call/result extensions. */
61
- itemSchemas?: Pick<ItemSchemaExtensions, 'toolCalls' | 'toolResults' | 'items'>;
62
- /** Decorate the harness-created tool result item before it is appended/emitted. */
63
- decorateResultItem?(params: {
64
- baseItem: FunctionCallOutputItem;
65
- callItem: FunctionCallItem;
66
- args: z.infer<I>;
67
- result: z.infer<O> | undefined;
68
- output: string;
69
- error?: boolean;
70
- }): Item | ToolResultExtensionItem;
71
- /** Async function that performs the tool's work. */
72
- execute(args: z.infer<I>, toolCtx: ToolExecutionContext): ToolExecutionResult<O>;
73
- /** When true, execution pauses for human approval before running. */
74
- needsApproval?: boolean;
75
- /** Optional memory declaration — the runtime generates a MemoryLayer from this. */
76
- memory?: ToolMemoryDeclaration;
77
- }
78
30
  /** @public Aggregate token counts for an execution (input, output, total, cached). */
79
31
  export interface TokenUsage {
80
32
  input: number;
@@ -108,4 +60,3 @@ export interface LlmProviderConfig {
108
60
  provider: 'openrouter';
109
61
  apiKey?: string;
110
62
  }
111
- export {};
@@ -0,0 +1,6 @@
1
+ import type { Item } from '../items';
2
+ /** @public Append-only log of conversation items accumulated during execution. */
3
+ export interface ItemLog {
4
+ readonly items: ReadonlyArray<Item>;
5
+ append(item: Item): void;
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import type { Item } from '../items';
2
+ /** @public Per-layer contribution to the context window on the most recent LLM call. */
3
+ export interface LayerUsageEntry {
4
+ readonly layerId: string;
5
+ readonly tokenCount: number;
6
+ /** Items this layer contributed to the context view for the last LLM call. */
7
+ readonly items: ReadonlyArray<Item>;
8
+ }
9
+ /** @public Breakdown of the context window as of the most recent LLM call in an execution. */
10
+ export interface LastLayerUsage {
11
+ readonly executionId: string;
12
+ readonly modelId: string;
13
+ readonly layers: ReadonlyArray<LayerUsageEntry>;
14
+ readonly systemPromptTokens: number;
15
+ readonly toolsTokens: number;
16
+ readonly historyTokens: number;
17
+ readonly totalUsedTokens: number;
18
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,18 +1,19 @@
1
+ import type { ZodType } from 'zod';
1
2
  import type { ItemSchemaRegistry } from '../schemas/item';
2
- import type { Channel } from './channel';
3
- import type { StepMeta, TokenUsage, Tool } from './common';
3
+ import type { Channel, ChannelHandle, ExternalChannel } from './channel';
4
+ import type { LLMResponse, ModelParams, StepMeta, TokenUsage } from './common';
5
+ import type { ItemLog } from './context-parts/item-log';
6
+ import type { LastLayerUsage } from './context-parts/layer-usage';
7
+ import type { DetachedHandle } from './detached';
4
8
  import type { FsAdapter } from './fs-adapter';
5
- import type { Item } from './items';
6
- import type { ContextMemory, MemoryLayer } from './memory';
9
+ import type { HarnessResponse, StreamEvent, StreamingItem } from './harness-result';
10
+ import type { ExecuteInput } from './items';
11
+ import type { ContextMemory, MemoryLayer, StorageAdapter } from './memory';
7
12
  import type { Span } from './observability';
8
- import type { AgentHarnessContract } from './runtime';
9
13
  import type { ShellAdapter } from './shell-adapter';
14
+ import type { SteeringDecision } from './steering';
10
15
  import type { SubprocessAdapter } from './subprocess-adapter';
11
- /** @public Append-only log of conversation items accumulated during execution. */
12
- export interface ItemLog {
13
- readonly items: ReadonlyArray<Item>;
14
- append(item: Item): void;
15
- }
16
+ import type { Tool } from './tool';
16
17
  /**
17
18
  * @public Mutable working-directory state shared among the tools attached to a
18
19
  * single Context. The reference is fixed for the Context's lifetime; mutate
@@ -24,22 +25,129 @@ export interface CwdState {
24
25
  cwd: string;
25
26
  previousCwd?: string;
26
27
  }
27
- /** @public Per-layer contribution to the context window on the most recent LLM call. */
28
- export interface LayerUsageEntry {
29
- readonly layerId: string;
30
- readonly tokenCount: number;
31
- /** Items this layer contributed to the context view for the last LLM call. */
32
- readonly items: ReadonlyArray<Item>;
28
+ export type ContextHarnessStatus = {
29
+ readonly kind: 'idle';
30
+ } | {
31
+ readonly kind: 'generating';
32
+ readonly startedAt: number;
33
+ readonly turnId: string;
34
+ } | {
35
+ readonly kind: 'aborting';
36
+ readonly turnId: string;
37
+ };
38
+ interface ContextCallModelRequestBase {
39
+ model: string;
40
+ items: ReadonlyArray<import('./items').Item>;
41
+ instructions?: string;
42
+ params?: ModelParams;
43
+ outputSchema?: ZodType;
44
+ emit?: boolean | ((eventType: string, data: Record<string, unknown>) => boolean);
45
+ signal?: AbortSignal;
46
+ }
47
+ interface ContextCallModelRequestWithTools extends ContextCallModelRequestBase {
48
+ tools: Tool[];
49
+ ctx: Context;
50
+ layers?: MemoryLayer[];
51
+ allowedToolNames?: string[];
52
+ }
53
+ interface ContextCallModelRequestWithoutTools extends ContextCallModelRequestBase {
54
+ tools?: undefined;
55
+ ctx?: undefined;
56
+ layers?: undefined;
57
+ }
58
+ export type ContextCallModelRequest = ContextCallModelRequestWithTools | ContextCallModelRequestWithoutTools;
59
+ export interface ContextDetachedSpawnOverrides {
60
+ threadId?: string;
61
+ resourceId?: string;
62
+ cwdInit?: string;
33
63
  }
34
- /** @public Breakdown of the context window as of the most recent LLM call in an execution. */
35
- export interface LastLayerUsage {
36
- readonly executionId: string;
37
- readonly modelId: string;
38
- readonly layers: ReadonlyArray<LayerUsageEntry>;
39
- readonly systemPromptTokens: number;
40
- readonly toolsTokens: number;
41
- readonly historyTokens: number;
42
- readonly totalUsedTokens: number;
64
+ export interface ContextRerenderRequest {
65
+ layerId: string;
66
+ slot: number;
67
+ timing: 'immediate' | 'batched';
68
+ scope: 'self' | 'slot-after' | 'all';
69
+ }
70
+ export interface ContextAppendPipelineResult {
71
+ readonly items: import('./items').Item[];
72
+ readonly rerenderRequests: ContextRerenderRequest[];
73
+ }
74
+ export interface ContextRecallLayerOutput {
75
+ layerId: string;
76
+ items: import('./items').Item[];
77
+ tokenCount: number;
78
+ }
79
+ export type ContextStep<TMemory = ContextMemory, I = unknown, O = unknown> = {
80
+ readonly kind: 'run';
81
+ readonly id: string;
82
+ readonly execute: (input: I, ctx: Context<TMemory>) => Promise<O>;
83
+ } | {
84
+ readonly kind: 'llm';
85
+ readonly id: string;
86
+ readonly output?: ZodType<O>;
87
+ } | {
88
+ readonly kind: 'loop';
89
+ readonly id: string;
90
+ readonly steps: ReadonlyArray<ContextStep<TMemory, I, O>>;
91
+ readonly prepareNext?: (output: O, verdict: unknown, ctx: Context<TMemory>) => I;
92
+ } | {
93
+ readonly kind: string;
94
+ readonly id: string;
95
+ };
96
+ /** @public Runtime surface exposed on Context without coupling Context's definition to the runtime type module. */
97
+ export interface ContextHarness {
98
+ readonly config: {
99
+ readonly name: string;
100
+ readonly params: Record<string, unknown>;
101
+ };
102
+ readonly fs: FsAdapter;
103
+ readonly shell: ShellAdapter;
104
+ readonly subprocess: SubprocessAdapter;
105
+ readonly rootCwdState: CwdState;
106
+ callModel(request: ContextCallModelRequest): Promise<LLMResponse>;
107
+ execute(input: ExecuteInput, options?: unknown): Promise<void>;
108
+ getAgentResponse(scope?: unknown): Promise<HarnessResponse>;
109
+ getItemStream(scope?: unknown): AsyncIterable<StreamingItem>;
110
+ getTextStream(scope?: unknown): AsyncIterable<string>;
111
+ getReasoningStream(scope?: unknown): AsyncIterable<string>;
112
+ getFullStream(scope?: unknown): AsyncIterable<StreamEvent>;
113
+ run<I, O>(step: ContextStep<ContextMemory, I, O>, input: I, ctx: Context): Promise<O>;
114
+ detachedSpawn<I, O>(step: unknown, input: I, parentCtx: Context, overrides?: ContextDetachedSpawnOverrides): DetachedHandle<O>;
115
+ createContext(opts?: {
116
+ parent?: Context;
117
+ items?: import('./items').Item[];
118
+ state?: unknown;
119
+ threadId?: string;
120
+ resourceId?: string;
121
+ memory?: MemoryLayer[];
122
+ cwdInit?: string;
123
+ }): Context;
124
+ setRootCwd(nextCwd: string): void;
125
+ getLayerState<T>(executionId: string, layerId: string): T | undefined;
126
+ setLayerState<T>(executionId: string, layerId: string, state: T): void;
127
+ beforeToolCall(layers: MemoryLayer[], toolName: string, toolArgs: unknown, ctx: Context): Promise<SteeringDecision>;
128
+ afterModelCall(layers: MemoryLayer[], response: LLMResponse, ctx: Context): Promise<SteeringDecision>;
129
+ runAppendPipeline(layers: MemoryLayer[], items: import('./items').Item[], ctx: Context): Promise<ContextAppendPipelineResult>;
130
+ recallLayers(layers: MemoryLayer[], input: string, ctx: Context): Promise<ContextRecallLayerOutput[]>;
131
+ projectHistory(layers: MemoryLayer[], items: ReadonlyArray<import('./items').Item>, ctx: Context): Promise<ReadonlyArray<import('./items').Item>>;
132
+ storeLayers(layers: MemoryLayer[], response: LLMResponse, ctx: Context): Promise<void>;
133
+ previewRequestItems(scope?: unknown): Promise<ReadonlyArray<import('./items').Item>>;
134
+ send<T>(channel: Channel<T>, value: T, ctx: Context): void;
135
+ recv<T>(channel: Channel<T>, ctx: Context, opts?: {
136
+ timeout?: number;
137
+ }): Promise<T>;
138
+ tryRecv<T>(channel: Channel<T>, ctx: Context): T | null;
139
+ getChannelHandle<T>(channel: ExternalChannel<T>, executionId: string): ChannelHandle<T>;
140
+ initLayers(layers: MemoryLayer[], ctx: Context, storage: StorageAdapter): Promise<void>;
141
+ disposeLayers(layers: MemoryLayer[], ctx: Context): Promise<void>;
142
+ checkpoint(ctx: Context): Promise<void>;
143
+ restore(executionId: string): Promise<Context | null>;
144
+ cancel(ctx: Context, reason?: string): Promise<void>;
145
+ createSpan(name: string, parent: Span | null): Span;
146
+ abort(scope?: unknown): Promise<void>;
147
+ getStatus(scope?: unknown): ContextHarnessStatus;
148
+ getQueueSize(scope?: unknown): number;
149
+ seedSessionHistory(threadId: string, items: ReadonlyArray<import('./items').Item>): void;
150
+ executeRerender(requests: ContextRerenderRequest[], layers: MemoryLayer[], ctx: Context, budgets: Map<string, number>, query?: string): Promise<ContextRecallLayerOutput[]>;
43
151
  }
44
152
  /** @public Execution context threaded through every step, carrying state, metrics, and channels. */
45
153
  export interface Context<TMemory = ContextMemory, TState = unknown> {
@@ -58,7 +166,7 @@ export interface Context<TMemory = ContextMemory, TState = unknown> {
58
166
  readonly lastStepMeta: StepMeta | null;
59
167
  /** Per-layer breakdown of the context window as of the most recent callModel. Undefined until the first LLM call completes. */
60
168
  readonly lastLayerUsage?: LastLayerUsage;
61
- readonly harness: AgentHarnessContract;
169
+ readonly harness: ContextHarness;
62
170
  /** Filesystem adapter for virtual or real filesystem access. */
63
171
  readonly fs: FsAdapter;
64
172
  /** Shell adapter for virtual or real shell command execution. */
@@ -91,3 +199,4 @@ export interface Context<TMemory = ContextMemory, TState = unknown> {
91
199
  readonly abortReason?: string;
92
200
  abort(reason?: string): void;
93
201
  }
202
+ export {};
@@ -48,4 +48,19 @@ export type NoeticError = {
48
48
  } | {
49
49
  kind: 'steering_denied';
50
50
  guidance?: string;
51
+ } | {
52
+ /**
53
+ * Raised by `DetachedHandle.await()` when the adapter persistently
54
+ * returns `null` for a handle that was previously spawned — the
55
+ * handle has been evicted from the adapter's registry, either by
56
+ * a restart-after-stop-without-restore flow or by a storage
57
+ * inconsistency. This guards against an otherwise-infinite poll
58
+ * loop that would hold the promise open forever. A short grace
59
+ * period tolerates transient nulls (e.g. the in-memory adapter
60
+ * briefly returning null between spawn and first microtask yield).
61
+ */
62
+ kind: 'handle_evicted';
63
+ handleId: string;
64
+ stepId: string;
65
+ gracePeriodMs: number;
51
66
  };
@@ -1,4 +1,4 @@
1
- import type { LastLayerUsage } from './context';
1
+ import type { LastLayerUsage } from './context-parts/layer-usage';
2
2
  import type { Item } from './items';
3
3
  /** @public SDK-originated event from the OpenResponses streaming API. */
4
4
  export interface SdkStreamEvent {
@@ -29,12 +29,28 @@ export interface InputTextPart {
29
29
  readonly type: 'input_text';
30
30
  readonly text: string;
31
31
  }
32
+ /** @public User image input content. */
33
+ export interface InputImagePart {
34
+ readonly type: 'input_image';
35
+ readonly imageUrl: string;
36
+ readonly detail?: 'auto' | 'low' | 'high';
37
+ }
38
+ /** @public User file input content. */
39
+ export interface InputFilePart {
40
+ readonly type: 'input_file';
41
+ readonly fileData?: string;
42
+ readonly fileId?: string | null;
43
+ readonly fileUrl?: string;
44
+ readonly filename?: string;
45
+ }
32
46
  /** @public Reasoning trace content. */
33
47
  export type ReasoningTextPart = ReasoningTextContent;
34
48
  /** @public Reasoning summary content. */
35
49
  export type SummaryTextPart = ReasoningSummaryText;
50
+ /** @public User/developer input content variants. */
51
+ export type InputContentPart = InputTextPart | InputImagePart | InputFilePart;
36
52
  /** @public Content part variants for message items. */
37
- export type ContentPart = OutputTextPart | RefusalPart | InputTextPart;
53
+ export type ContentPart = OutputTextPart | RefusalPart | InputContentPart;
38
54
  /** @public Assistant message output item. */
39
55
  export type MessageItem = ResponsesOutputMessage;
40
56
  /** @public Function call requested by the model. */
@@ -68,7 +84,7 @@ export interface InputMessageItem {
68
84
  readonly type: 'message';
69
85
  readonly role: 'user' | 'system' | 'developer';
70
86
  readonly status: 'in_progress' | 'completed' | 'incomplete' | 'failed';
71
- readonly content: InputTextPart[];
87
+ readonly content: InputContentPart[];
72
88
  }
73
89
  /**
74
90
  * @public Tool execution output created by the harness during the tool loop.