@noetic-tools/core 3.2.0 → 4.0.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 (94) hide show
  1. package/dist/adapters/in-memory-subprocess/manifest-persistence.d.ts +1 -1
  2. package/dist/adapters/in-memory-subprocess/types.d.ts +1 -1
  3. package/dist/adapters/openrouter.d.ts +2 -2
  4. package/dist/adapters/openrouter.js +2 -2
  5. package/dist/builders/context-builder.d.ts +11 -0
  6. package/dist/builders/context-builder.js +15 -0
  7. package/dist/builders/context-option.d.ts +23 -0
  8. package/dist/builders/context-option.js +22 -0
  9. package/dist/builders/control-flow-builders.d.ts +19 -19
  10. package/dist/builders/every.d.ts +4 -4
  11. package/dist/builders/layer-provides-builders.d.ts +1 -1
  12. package/dist/builders/layer-provides-builders.js +1 -1
  13. package/dist/builders/loop-builder.d.ts +3 -3
  14. package/dist/builders/provide-builder.d.ts +14 -7
  15. package/dist/builders/provide-builder.js +15 -4
  16. package/dist/builders/spawn-builder.d.ts +8 -6
  17. package/dist/builders/spawn-builder.js +7 -2
  18. package/dist/builders/step-builders.d.ts +19 -20
  19. package/dist/builders/tool-builder.d.ts +9 -5
  20. package/dist/builders/tool-builder.js +3 -2
  21. package/dist/builders/workflow-hydrator.d.ts +17 -4
  22. package/dist/builders/workflow-hydrator.js +87 -8
  23. package/dist/builders/workflow-step.d.ts +61 -0
  24. package/dist/builders/workflow-step.js +126 -0
  25. package/dist/conditions/conditions.d.ts +17 -17
  26. package/dist/conditions/conditions.js +1 -1
  27. package/dist/deprecated.d.ts +30 -0
  28. package/dist/deprecated.js +28 -0
  29. package/dist/harness/agent-harness.d.ts +30 -26
  30. package/dist/harness/agent-harness.js +23 -19
  31. package/dist/harness/deps/{memory.d.ts → context.d.ts} +2 -2
  32. package/dist/harness/deps/{memory.js → context.js} +1 -1
  33. package/dist/harness/deps/types.d.ts +1 -1
  34. package/dist/harness/model-schema.d.ts +2 -2
  35. package/dist/index.d.ts +21 -17
  36. package/dist/index.js +14 -8
  37. package/dist/interpreter/action-deps.d.ts +3 -3
  38. package/dist/interpreter/action-deps.js +2 -2
  39. package/dist/interpreter/action-types.d.ts +1 -1
  40. package/dist/interpreter/collect-tools.d.ts +1 -1
  41. package/dist/interpreter/execute-action.d.ts +10 -10
  42. package/dist/interpreter/execute-action.js +13 -13
  43. package/dist/interpreter/execute-control.d.ts +4 -4
  44. package/dist/interpreter/execute-control.js +1 -1
  45. package/dist/interpreter/execute-sub-harness.d.ts +1 -1
  46. package/dist/interpreter/execute.d.ts +3 -3
  47. package/dist/interpreter/execute.js +78 -31
  48. package/dist/interpreter/step-dispatcher.d.ts +3 -3
  49. package/dist/interpreter/sub-harness-events.d.ts +2 -2
  50. package/dist/interpreter/typeguards.d.ts +4 -4
  51. package/dist/patterns/dynamic-workflow.d.ts +7 -4
  52. package/dist/patterns/dynamic-workflow.js +2 -0
  53. package/dist/patterns/interview.d.ts +2 -2
  54. package/dist/patterns/plans.d.ts +5 -5
  55. package/dist/patterns/ralph-wiggum.d.ts +2 -2
  56. package/dist/patterns/react.d.ts +7 -5
  57. package/dist/patterns/react.js +6 -4
  58. package/dist/portable/builders.js +2 -0
  59. package/dist/portable/context-layers.d.ts +8 -0
  60. package/dist/portable/context-layers.js +8 -0
  61. package/dist/portable.d.ts +2 -2
  62. package/dist/portable.js +2 -2
  63. package/dist/runtime/context-deps.d.ts +2 -2
  64. package/dist/runtime/context-deps.js +1 -1
  65. package/dist/runtime/context-impl.d.ts +10 -8
  66. package/dist/runtime/context-impl.js +11 -7
  67. package/dist/runtime/context-type-deps.d.ts +1 -1
  68. package/dist/runtime/durable/checkpoint-store.d.ts +1 -1
  69. package/dist/runtime/durable/harness-checkpoints.d.ts +2 -3
  70. package/dist/runtime/durable/harness-checkpoints.js +2 -3
  71. package/dist/runtime/durable/step-ledger.d.ts +1 -1
  72. package/dist/runtime/durable/step-ledger.js +1 -1
  73. package/dist/runtime/in-memory-storage.d.ts +1 -1
  74. package/dist/runtime/session-runner.d.ts +1 -1
  75. package/dist/runtime/step-registry.d.ts +3 -3
  76. package/dist/runtime/{tool-memory.d.ts → tool-context.d.ts} +1 -2
  77. package/dist/runtime/{tool-memory.js → tool-context.js} +5 -2
  78. package/dist/runtime/tool-ui.d.ts +1 -1
  79. package/dist/runtime/tool-ui.js +1 -1
  80. package/dist/schemas/workflow.d.ts +5 -279
  81. package/dist/schemas/workflow.js +4 -376
  82. package/dist/types/mutable-context.d.ts +2 -2
  83. package/dist/types/step-registrar.d.ts +1 -1
  84. package/dist/unstable.d.ts +5 -5
  85. package/dist/unstable.js +3 -3
  86. package/dist/until/predicates.d.ts +1 -1
  87. package/package.json +4 -4
  88. package/schema/noetic-workflow.schema.json +28 -0
  89. package/dist/builders/memory-builder.d.ts +0 -11
  90. package/dist/builders/memory-builder.js +0 -15
  91. package/dist/patterns/flow.d.ts +0 -2
  92. package/dist/patterns/flow.js +0 -1
  93. package/dist/portable/memory-layers.d.ts +0 -8
  94. package/dist/portable/memory-layers.js +0 -8
@@ -112,6 +112,65 @@ export async function executeNoAdapter(step, input, ctx) {
112
112
  return execute(step, input, ctx);
113
113
  }
114
114
  }
115
+ /**
116
+ * Resume path: when a previous run recorded this exact step at `ledgerPath`,
117
+ * replay its output instead of re-running. Held as a helper (rather than inline
118
+ * in `execute`) so the resume branch stays flat: it pops the frontier itself —
119
+ * the caller returns before the normal `leaveStep` runs — and emits
120
+ * `step_replayed`. Returns `{ hit: false }` when there is nothing to replay so
121
+ * the caller dispatches the step normally.
122
+ */
123
+ function replayFromLedger(opts) {
124
+ const { ledger, ledgerPath, impl, step, broadcaster, agentName } = opts;
125
+ if (!ledger || ledgerPath === undefined || ledger.isEmpty) {
126
+ return {
127
+ hit: false,
128
+ };
129
+ }
130
+ const replayed = ledger.take(ledgerPath, {
131
+ id: step.id,
132
+ kind: step.kind,
133
+ });
134
+ if (!replayed) {
135
+ return {
136
+ hit: false,
137
+ };
138
+ }
139
+ if (impl && step.id.length > 0) {
140
+ impl.leaveStep(step.id);
141
+ }
142
+ emitFrameworkEvent({
143
+ broadcaster,
144
+ agentName,
145
+ eventType: 'step_replayed',
146
+ data: {
147
+ stepId: step.id,
148
+ kind: step.kind,
149
+ },
150
+ });
151
+ return {
152
+ hit: true,
153
+ output: frameworkCast(replayed.output),
154
+ };
155
+ }
156
+ /**
157
+ * Record a completed step's output so a resumed run replays it rather than
158
+ * re-executing. A no-op without a ledger or ledger path. Only successes reach
159
+ * here — a step that threw skips this call in `execute` and runs again on resume.
160
+ */
161
+ async function recordToLedger(opts) {
162
+ const { ledger, ledgerPath, step, output } = opts;
163
+ if (!ledger || ledgerPath === undefined) {
164
+ return;
165
+ }
166
+ await ledger.record({
167
+ path: ledgerPath,
168
+ stepId: step.id,
169
+ kind: step.kind,
170
+ output,
171
+ completedAt: new Date().toISOString(),
172
+ });
173
+ }
115
174
  //#endregion
116
175
  /**
117
176
  * Executes a step within the interpreter, dispatching to the appropriate handler by step kind.
@@ -173,30 +232,21 @@ export async function execute(step, input, ctx) {
173
232
  });
174
233
  }
175
234
  /* Resume: a previous run that completed this exact step replays its recorded
176
- * output instead of re-running it. Captured before dispatch and held for the
177
- * record below, because `leaveStep` pops the path on the way out. */
235
+ * output instead of re-running it. `ledgerPath`/`ledger` are captured before
236
+ * dispatch and reused by the record below, because `leaveStep` pops the path
237
+ * on the way out. */
178
238
  const ledgerPath = impl && step.id.length > 0 ? impl.currentPath() : undefined;
179
239
  const ledger = impl?.ledger;
180
- if (ledger && ledgerPath !== undefined && !ledger.isEmpty) {
181
- const replayed = ledger.take(ledgerPath, {
182
- id: step.id,
183
- kind: step.kind,
184
- });
185
- if (replayed) {
186
- if (impl && step.id.length > 0) {
187
- impl.leaveStep(step.id);
188
- }
189
- emitFrameworkEvent({
190
- broadcaster,
191
- agentName,
192
- eventType: 'step_replayed',
193
- data: {
194
- stepId: step.id,
195
- kind: step.kind,
196
- },
197
- });
198
- return frameworkCast(replayed.output);
199
- }
240
+ const replay = replayFromLedger({
241
+ ledger,
242
+ ledgerPath,
243
+ impl,
244
+ step,
245
+ broadcaster,
246
+ agentName,
247
+ });
248
+ if (replay.hit) {
249
+ return replay.output;
200
250
  }
201
251
  let result;
202
252
  try {
@@ -272,15 +322,12 @@ export async function execute(step, input, ctx) {
272
322
  /* Record the completed step so a resumed run replays this output rather than
273
323
  * re-running the step. Only successes are recorded: a step that threw must run
274
324
  * again. */
275
- if (ledger && ledgerPath !== undefined) {
276
- await ledger.record({
277
- path: ledgerPath,
278
- stepId: step.id,
279
- kind: step.kind,
280
- output: result,
281
- completedAt: new Date().toISOString(),
282
- });
283
- }
325
+ await recordToLedger({
326
+ ledger,
327
+ ledgerPath,
328
+ step,
329
+ output: result,
330
+ });
284
331
  /* Durability boundary (spec 23): snapshot after each completed step, so a crash
285
332
  * lands on a checkpoint that includes the item-log and layer-state mutations this
286
333
  * step produced. A no-op unless the harness has a CheckpointStore, and a failing
@@ -1,4 +1,4 @@
1
- import type { ContextMemory } from '@noetic-tools/memory';
1
+ import type { ContextData } from '@noetic-tools/context';
2
2
  import type { Context, DetachedHandle, Step, SubprocessAdapter } from '@noetic-tools/types';
3
3
  /**
4
4
  * Resolve the subprocess adapter used for a given step dispatch.
@@ -10,7 +10,7 @@ import type { Context, DetachedHandle, Step, SubprocessAdapter } from '@noetic-t
10
10
  *
11
11
  * @internal
12
12
  */
13
- export declare function resolveStepAdapter<TMemory, I, O>(step: Step<TMemory, I, O>, callOverride: SubprocessAdapter | undefined, fallback: SubprocessAdapter): SubprocessAdapter;
13
+ export declare function resolveStepAdapter<TContext, I, O>(step: Step<TContext, I, O>, callOverride: SubprocessAdapter | undefined, fallback: SubprocessAdapter): SubprocessAdapter;
14
14
  /**
15
15
  * Minimum harness surface the dispatcher needs. `AgentHarness` satisfies
16
16
  * this shape — kept structural so tests can pass a stub.
@@ -55,4 +55,4 @@ export interface DetachedSpawnOverrides {
55
55
  *
56
56
  * @internal
57
57
  */
58
- export declare function dispatchStepThroughAdapter<I, O>(h: StepDispatchHandle, s: Step<ContextMemory, I, O>, input: I, parentCtx: Context, overrides?: DetachedSpawnOverrides): DetachedHandle<O>;
58
+ export declare function dispatchStepThroughAdapter<I, O>(h: StepDispatchHandle, s: Step<ContextData, I, O>, input: I, parentCtx: Context, overrides?: DetachedSpawnOverrides): DetachedHandle<O>;
@@ -12,7 +12,7 @@
12
12
  * a result without streaming any text/tool parts, the result's content is
13
13
  * synthesized into events.
14
14
  */
15
- import type { Context, ContextMemory, StepSubHarness, SubHarnessStreamPart, SubHarnessTurnResult } from '@noetic-tools/types';
15
+ import type { Context, ContextData, StepSubHarness, SubHarnessStreamPart, SubHarnessTurnResult } from '@noetic-tools/types';
16
16
  export declare class SubHarnessEventBridge {
17
17
  private readonly broadcaster?;
18
18
  private readonly agentName;
@@ -25,7 +25,7 @@ export declare class SubHarnessEventBridge {
25
25
  private messageOutputIndex;
26
26
  private sawText;
27
27
  private sawToolCall;
28
- constructor(step: Pick<StepSubHarness, 'id' | 'kind' | 'emit'>, ctx: Context<ContextMemory>);
28
+ constructor(step: Pick<StepSubHarness, 'id' | 'kind' | 'emit'>, ctx: Context<ContextData>);
29
29
  /**
30
30
  * Open the turn on the event surface. Emits `response.created` so every turn
31
31
  * always brackets with a lifecycle marker — even a custom adapter that
@@ -1,17 +1,17 @@
1
- import type { ContextMemory } from '@noetic-tools/memory';
1
+ import type { ContextData } from '@noetic-tools/context';
2
2
  import type { Context, FunctionCallItem, Item } from '@noetic-tools/types';
3
3
  import type { ChannelStore } from '../runtime/channel-store.js';
4
4
  import { ContextImpl } from '../runtime/context-impl.js';
5
5
  import type { MutableContext } from '../types/mutable-context.js';
6
6
  export { isAssistantMessage, isOutputText, isUserMessage } from '@noetic-tools/types';
7
- export declare function isMutableContext(ctx: Context<ContextMemory>): ctx is MutableContext;
8
- export declare function isContextImpl(ctx: Context<ContextMemory>): ctx is ContextImpl;
7
+ export declare function isMutableContext(ctx: Context<ContextData>): ctx is MutableContext;
8
+ export declare function isContextImpl(ctx: Context<ContextData>): ctx is ContextImpl;
9
9
  /**
10
10
  * Co-located with `isContextImpl` so the import of `ContextImpl` flows through
11
11
  * the same module other interpreters pull it from, sidestepping a circular
12
12
  * TDZ when this helper is used by `executeEvery` in `execute-control.ts`.
13
13
  */
14
- export declare function getContextChannelStore<TMemory>(ctx: Context<TMemory>): ChannelStore | undefined;
14
+ export declare function getContextChannelStore<TContext>(ctx: Context<TContext>): ChannelStore | undefined;
15
15
  export declare function isFunctionCall(item: Item): item is FunctionCallItem;
16
16
  declare function assertNever(_value: never): never;
17
17
  export { assertNever };
@@ -2,8 +2,9 @@
2
2
  * Pattern that lets an LLM generate a workflow as JSON during execution,
3
3
  * then hydrates and runs it within the same harness session.
4
4
  */
5
- import type { ContextMemory, MemoryLayer } from '@noetic-tools/memory';
5
+ import type { ContextData, ContextLayer } from '@noetic-tools/context';
6
6
  import type { AgentHarnessContract, Context, Step, Tool } from '@noetic-tools/types';
7
+ import type { WorkflowDocument } from '../schemas/workflow.js';
7
8
  /** @public Options for creating a dynamic workflow step. */
8
9
  export interface DynamicWorkflowOpts {
9
10
  model?: string;
@@ -25,7 +26,7 @@ export interface DynamicWorkflowOpts {
25
26
  * @param opts.maxRevisions - Retries with error feedback on validation failure. Default: 3.
26
27
  * @returns A `Step` that dynamically plans and executes.
27
28
  */
28
- export declare function dynamicWorkflow(opts: DynamicWorkflowOpts): Step<ContextMemory, string, string>;
29
+ export declare function dynamicWorkflow(opts: DynamicWorkflowOpts): Step<ContextData, string, string>;
29
30
  /** @public Options for `parseAndRunWorkflow`. */
30
31
  export interface ParseAndRunWorkflowOpts {
31
32
  json: unknown;
@@ -35,11 +36,13 @@ export interface ParseAndRunWorkflowOpts {
35
36
  input?: string;
36
37
  maxDepth?: number;
37
38
  /**
38
- * Memory layers the document's `provide` / `spawn` nodes may reference by name.
39
+ * Context layers the document's `provide` / `spawn` nodes may reference by name.
39
40
  * Without a registry those nodes resolve to NO layers rather than failing, so a
40
41
  * host that runs layer-bearing workflows must pass its layers here.
41
42
  */
42
- layers?: ReadonlyMap<string, MemoryLayer>;
43
+ layers?: ReadonlyMap<string, ContextLayer>;
44
+ /** Named sub-workflows the document's `subflow` nodes may reference via `ref`. */
45
+ workflows?: ReadonlyMap<string, WorkflowDocument>;
43
46
  }
44
47
  /**
45
48
  * Parses raw JSON into a `WorkflowDocument`, hydrates it into a live step
@@ -28,6 +28,7 @@ A WorkflowNode is one of:
28
28
  - { "kind": "loop", "id": "<unique>", "body": <WorkflowNode>, "until": { "kind": "maxSteps", "n": <number> } }
29
29
  - { "kind": "branch", "id": "<unique>", "routes": [{ "match": "<substring>", "target": <WorkflowNode> }], "default": <WorkflowNode> }
30
30
  - { "kind": "spawn", "id": "<unique>", "child": <WorkflowNode> }
31
+ - { "kind": "subflow", "id": "<unique>", "document": { "version": 1, "root": <WorkflowNode> } } (an inline sub-workflow run as one step; only emit the inline form — named refs require a registry this planner does not provide)
31
32
  - { "kind": "claude-code"|"codex"|"opencode"|"pi", "id": "<unique>", "prompt": "<turn prompt>", "settings": { "model": "<optional>", "permissionMode": "<optional>" } }
32
33
 
33
34
  SubHarness nodes (claude-code, codex, opencode, pi) delegate a turn to an external coding agent; only emit one if a matching harness adapter is registered for the workflow.
@@ -143,6 +144,7 @@ export async function parseAndRunWorkflow(opts) {
143
144
  tools: buildToolMap(opts.tools),
144
145
  executeStep,
145
146
  layers: opts.layers,
147
+ workflows: opts.workflows,
146
148
  };
147
149
  const hydrated = hydrateWorkflow(parseResult.doc, hydrationCtx);
148
150
  const runSpan = beginWorkflowRunSpan(opts.harness, opts.ctx, parseResult.doc);
@@ -1,4 +1,4 @@
1
- import type { ContextMemory } from '@noetic-tools/memory';
1
+ import type { ContextData } from '@noetic-tools/context';
2
2
  import type { Step } from '@noetic-tools/types';
3
3
  import type { ZodType } from 'zod';
4
4
  /** @public Answer captured by the host for a single interview question. */
@@ -50,4 +50,4 @@ export interface InterviewOpts<Q, C> {
50
50
  * @returns A `Step` whose output is `InterviewResult<Q, C>` — either the completion envelope or
51
51
  * `maxQuestions` when the budget is exhausted before the model emits `complete`.
52
52
  */
53
- export declare function interview<Q, C>(opts: InterviewOpts<Q, C>): Step<ContextMemory, string, InterviewResult<Q, C>>;
53
+ export declare function interview<Q, C>(opts: InterviewOpts<Q, C>): Step<ContextData, string, InterviewResult<Q, C>>;
@@ -1,4 +1,4 @@
1
- import type { ContextMemory } from '@noetic-tools/memory';
1
+ import type { ContextData } from '@noetic-tools/context';
2
2
  import type { Context, ExecuteStepFn, Step } from '@noetic-tools/types';
3
3
  import { z } from 'zod';
4
4
  export interface PlanNode {
@@ -26,7 +26,7 @@ export interface PlanConstraints {
26
26
  * @param executeStep - Optional step executor for non-run step kinds.
27
27
  * @returns A compiled `Step` ready for execution.
28
28
  */
29
- export declare function compilePlan<O, A = unknown>(plan: PlanNode, agents: Record<string, (prompt: string) => Step<ContextMemory, string, A>>, constraints?: PlanConstraints, executeStep?: ExecuteStepFn): Step<ContextMemory, string, O>;
29
+ export declare function compilePlan<O, A = unknown>(plan: PlanNode, agents: Record<string, (prompt: string) => Step<ContextData, string, A>>, constraints?: PlanConstraints, executeStep?: ExecuteStepFn): Step<ContextData, string, O>;
30
30
  /**
31
31
  * Creates a step that dynamically generates a plan via a planner step and executes it,
32
32
  * retrying with error feedback up to `maxRevisions` times on failure.
@@ -36,9 +36,9 @@ export declare function compilePlan<O, A = unknown>(plan: PlanNode, agents: Reco
36
36
  * @returns A `Step` that adaptively plans and executes.
37
37
  */
38
38
  export declare function adaptivePlan<O, A = unknown>(opts: {
39
- planner: Step<ContextMemory, string, PlanNode>;
40
- agents: Record<string, (prompt: string) => Step<ContextMemory, string, A>>;
39
+ planner: Step<ContextData, string, PlanNode>;
40
+ agents: Record<string, (prompt: string) => Step<ContextData, string, A>>;
41
41
  constraints?: PlanConstraints;
42
42
  maxRevisions: number;
43
43
  executeStep?: ExecuteStepFn;
44
- }): Step<ContextMemory, string, O>;
44
+ }): Step<ContextData, string, O>;
@@ -1,4 +1,4 @@
1
- import type { ContextMemory } from '@noetic-tools/memory';
1
+ import type { ContextData } from '@noetic-tools/context';
2
2
  import type { StepLoop, Tool } from '@noetic-tools/types';
3
3
  import type { VerifyFn } from '../until/predicates.js';
4
4
  /**
@@ -16,4 +16,4 @@ export declare function ralphWiggum(opts: {
16
16
  verify: VerifyFn;
17
17
  maxIterations?: number;
18
18
  innerMaxSteps?: number;
19
- }): StepLoop<ContextMemory, string, string>;
19
+ }): StepLoop<ContextData, string, string>;
@@ -1,11 +1,11 @@
1
- import type { ContextMemory, MemoryConfig, MemoryLayer } from '@noetic-tools/memory';
1
+ import type { ContextConfig, ContextData, ContextLayer } from '@noetic-tools/context';
2
2
  import type { StepLoop, StepSpawn, Tool } from '@noetic-tools/types';
3
3
  /**
4
4
  * Creates a ReAct (Reason + Act) agent loop: an LLM step with tools iterated until no tool calls or limits are hit.
5
5
  *
6
6
  * @public
7
- * @param opts - Model, tools, optional instructions, step/cost limits, and memory layers.
8
- * @returns A `StepLoop` (no memory) or `StepSpawn` wrapping a loop (with memory).
7
+ * @param opts - Model, tools, optional instructions, step/cost limits, and context layers.
8
+ * @returns A `StepLoop` (no context layers) or `StepSpawn` wrapping a loop (with them).
9
9
  */
10
10
  export declare function react(opts: {
11
11
  model: string;
@@ -13,5 +13,7 @@ export declare function react(opts: {
13
13
  tools: Tool[];
14
14
  maxSteps?: number;
15
15
  maxCost?: number;
16
- memory?: MemoryConfig | MemoryLayer[];
17
- }): StepLoop<ContextMemory, string, string> | StepSpawn<ContextMemory, string, string>;
16
+ context?: ContextConfig | ContextLayer[];
17
+ /** @deprecated Renamed to `context`. */
18
+ memory?: ContextConfig | ContextLayer[];
19
+ }): StepLoop<ContextData, string, string> | StepSpawn<ContextData, string, string>;
@@ -1,3 +1,4 @@
1
+ import { resolveContextOption } from '../builders/context-option.js';
1
2
  import { loop } from '../builders/loop-builder.js';
2
3
  import { spawn } from '../builders/spawn-builder.js';
3
4
  import { step } from '../builders/step-builders.js';
@@ -7,8 +8,8 @@ import { until } from '../until/predicates.js';
7
8
  * Creates a ReAct (Reason + Act) agent loop: an LLM step with tools iterated until no tool calls or limits are hit.
8
9
  *
9
10
  * @public
10
- * @param opts - Model, tools, optional instructions, step/cost limits, and memory layers.
11
- * @returns A `StepLoop` (no memory) or `StepSpawn` wrapping a loop (with memory).
11
+ * @param opts - Model, tools, optional instructions, step/cost limits, and context layers.
12
+ * @returns A `StepLoop` (no context layers) or `StepSpawn` wrapping a loop (with them).
12
13
  */
13
14
  export function react(opts) {
14
15
  const llmStep = step.llm({
@@ -28,12 +29,13 @@ export function react(opts) {
28
29
  ]
29
30
  : [])),
30
31
  });
31
- if (!opts.memory) {
32
+ const layers = resolveContextOption(opts);
33
+ if (!layers) {
32
34
  return loopStep;
33
35
  }
34
36
  return spawn({
35
37
  id: 'react-agent',
36
38
  child: loopStep,
37
- memory: opts.memory,
39
+ context: layers,
38
40
  });
39
41
  }
@@ -6,6 +6,8 @@ export { layerData, layerFn } from '../builders/layer-provides-builders.js';
6
6
  export { loop } from '../builders/loop-builder.js';
7
7
  /** @public */
8
8
  export { spawn } from '../builders/spawn-builder.js';
9
+ // The base namespace, without `step.workflow` — the portable surface stays
10
+ // free of the hydrator so restricted runtimes don't pull it in.
9
11
  /** @public */
10
12
  export { step } from '../builders/step-builders.js';
11
13
  /** @public */
@@ -0,0 +1,8 @@
1
+ /** @public */
2
+ /** @public */
3
+ /** @public */
4
+ /** @public */
5
+ /** @public */
6
+ /** @public */
7
+ /** @public */
8
+ export { durableTaskState, historyWindow, observationalContext, planContext, temporalContext, toolContextLayer, workingMemoryContext, } from '@noetic-tools/context';
@@ -0,0 +1,8 @@
1
+ /** @public */
2
+ /** @public */
3
+ /** @public */
4
+ /** @public */
5
+ /** @public */
6
+ /** @public */
7
+ /** @public */
8
+ export { durableTaskState, historyWindow, observationalContext, planContext, temporalContext, toolContextLayer, workingMemoryContext, } from '@noetic-tools/context';
@@ -1,8 +1,8 @@
1
1
  /** @public */
2
- export { Slot } from '@noetic-tools/memory';
2
+ export { Slot } from '@noetic-tools/context';
3
3
  export * from './portable/adapters.js';
4
4
  export * from './portable/ask-user.js';
5
5
  export * from './portable/builders.js';
6
- export * from './portable/memory-layers.js';
6
+ export * from './portable/context-layers.js';
7
7
  export * from './portable/runtime.js';
8
8
  export * from './portable/until.js';
package/dist/portable.js CHANGED
@@ -1,8 +1,8 @@
1
1
  /** @public */
2
- export { Slot } from '@noetic-tools/memory';
2
+ export { Slot } from '@noetic-tools/context';
3
3
  export * from './portable/adapters.js';
4
4
  export * from './portable/ask-user.js';
5
5
  export * from './portable/builders.js';
6
- export * from './portable/memory-layers.js';
6
+ export * from './portable/context-layers.js';
7
7
  export * from './portable/runtime.js';
8
8
  export * from './portable/until.js';
@@ -1,4 +1,4 @@
1
- export { buildContextMemory } from '@noetic-tools/memory';
1
+ export { buildContextData } from '@noetic-tools/context';
2
2
  export type { ItemSchemaRegistry } from '@noetic-tools/types';
3
3
  export { defaultItemSchemaRegistry } from '@noetic-tools/types';
4
- export type { AgentHarnessContract, Channel, ChannelStore, Context, ContextMemory, CwdState, EventBroadcaster, FrontierFrame, FsAdapter, Item, ItemLog, LastLayerUsage, MemoryLayer, Span, StepMeta, TokenUsage, Tool, } from './context-type-deps.js';
4
+ export type { AgentHarnessContract, Channel, ChannelStore, Context, ContextData, ContextLayer, CwdState, EventBroadcaster, FrontierFrame, FsAdapter, Item, ItemLog, LastLayerUsage, Span, StepMeta, TokenUsage, Tool, } from './context-type-deps.js';
@@ -1,2 +1,2 @@
1
- export { buildContextMemory } from '@noetic-tools/memory';
1
+ export { buildContextData } from '@noetic-tools/context';
2
2
  export { defaultItemSchemaRegistry } from '@noetic-tools/types';
@@ -1,4 +1,4 @@
1
- import type { AgentHarnessContract, Channel, ChannelStore, Context, ContextMemory, CwdState, EventBroadcaster, FrontierFrame, FsAdapter, Item, ItemLog, ItemSchemaRegistry, LastLayerUsage, MemoryLayer, Span, StepMeta, TokenUsage, Tool } from './context-deps.js';
1
+ import type { AgentHarnessContract, Channel, ChannelStore, Context, ContextData, ContextLayer, CwdState, EventBroadcaster, FrontierFrame, FsAdapter, Item, ItemLog, ItemSchemaRegistry, LastLayerUsage, Span, StepMeta, TokenUsage, Tool } from './context-deps.js';
2
2
  import type { StepLedger } from './durable/step-ledger.js';
3
3
  /**
4
4
  * @internal
@@ -7,13 +7,13 @@ import type { StepLedger } from './durable/step-ledger.js';
7
7
  * children, so a foreign `Context` implementation yields just itself.
8
8
  */
9
9
  export declare function collectContextTree(ctx: Context): Context[];
10
- export declare class ContextImpl implements Context<ContextMemory> {
10
+ export declare class ContextImpl implements Context<ContextData> {
11
11
  readonly id: string;
12
12
  stepCount: number;
13
13
  tokens: TokenUsage;
14
14
  cost: number;
15
15
  state: unknown;
16
- readonly parent: Context<ContextMemory> | null;
16
+ readonly parent: Context<ContextData> | null;
17
17
  readonly depth: number;
18
18
  readonly span: Span;
19
19
  readonly threadId: string;
@@ -22,7 +22,7 @@ export declare class ContextImpl implements Context<ContextMemory> {
22
22
  lastStepMeta: StepMeta | null;
23
23
  lastLayerUsage: LastLayerUsage | undefined;
24
24
  readonly harness: AgentHarnessContract;
25
- readonly layers?: MemoryLayer[];
25
+ readonly layers?: ContextLayer[];
26
26
  unifiedTools?: ReadonlyArray<Tool>;
27
27
  readonly itemSchemas?: ItemSchemaRegistry;
28
28
  readonly cwdState: CwdState;
@@ -60,7 +60,7 @@ export declare class ContextImpl implements Context<ContextMemory> {
60
60
  * @internal
61
61
  */
62
62
  private readonly _children;
63
- private _memory?;
63
+ private _contextData?;
64
64
  /**
65
65
  * Stack of steps currently in flight on this context, most-recent last.
66
66
  * Pushed by `enterStep` at the top of `execute()` and popped by
@@ -109,7 +109,7 @@ export declare class ContextImpl implements Context<ContextMemory> {
109
109
  pathPrefix?: string;
110
110
  /** The execution's completion ledger, shared with children by reference. */
111
111
  ledger?: StepLedger;
112
- layers?: MemoryLayer[];
112
+ layers?: ContextLayer[];
113
113
  unifiedTools?: ReadonlyArray<Tool>;
114
114
  itemSchemas?: ItemSchemaRegistry;
115
115
  cwdState?: CwdState;
@@ -118,7 +118,7 @@ export declare class ContextImpl implements Context<ContextMemory> {
118
118
  * Pre-chosen context id. When set, the ContextImpl adopts this id instead
119
119
  * of generating a fresh UUID. Used by `executeSpawn` so the child's
120
120
  * `ctx.id` matches the `executionId` keyed into the layer-state store —
121
- * otherwise writes via `ctx.memory[layerId].state` land on one id while
121
+ * otherwise writes via `ctx.context[layerId].state` land on one id while
122
122
  * spawn's `onReturn` reads from another, silently losing the update.
123
123
  */
124
124
  id?: string;
@@ -149,7 +149,9 @@ export declare class ContextImpl implements Context<ContextMemory> {
149
149
  get fs(): FsAdapter;
150
150
  get shell(): AgentHarnessContract['shell'];
151
151
  get subprocess(): AgentHarnessContract['subprocess'];
152
- get memory(): ContextMemory;
152
+ get context(): ContextData;
153
+ /** @deprecated Renamed to `context`. Returns the same object. */
154
+ get memory(): ContextData;
153
155
  recv<T>(ch: Channel<T>, opts?: {
154
156
  timeout?: number;
155
157
  }): Promise<T>;
@@ -1,6 +1,6 @@
1
- import { buildContextMemory, defaultItemSchemaRegistry } from './context-deps.js';
1
+ import { buildContextData, defaultItemSchemaRegistry } from './context-deps.js';
2
2
  import { ItemLogImpl } from './item-log-impl.js';
3
- const EMPTY_MEMORY = Object.freeze({});
3
+ const EMPTY_CONTEXT = Object.freeze({});
4
4
  class NoopSpan {
5
5
  traceId = crypto.randomUUID();
6
6
  spanId = crypto.randomUUID();
@@ -84,7 +84,7 @@ export class ContextImpl {
84
84
  * @internal
85
85
  */
86
86
  _children = new Set();
87
- _memory;
87
+ _contextData;
88
88
  /**
89
89
  * Stack of steps currently in flight on this context, most-recent last.
90
90
  * Pushed by `enterStep` at the top of `execute()` and popped by
@@ -203,11 +203,15 @@ export class ContextImpl {
203
203
  get subprocess() {
204
204
  return this.harness.subprocess;
205
205
  }
206
- get memory() {
207
- if (!this._memory) {
208
- this._memory = this.layers ? buildContextMemory(this.layers, this) : EMPTY_MEMORY;
206
+ get context() {
207
+ if (!this._contextData) {
208
+ this._contextData = this.layers ? buildContextData(this.layers, this) : EMPTY_CONTEXT;
209
209
  }
210
- return this._memory;
210
+ return this._contextData;
211
+ }
212
+ /** @deprecated Renamed to `context`. Returns the same object. */
213
+ get memory() {
214
+ return this.context;
211
215
  }
212
216
  recv(ch, opts) {
213
217
  if (!this.channelStore) {
@@ -1,4 +1,4 @@
1
- export type { ContextMemory, MemoryLayer } from '@noetic-tools/memory';
1
+ export type { ContextData, ContextLayer } from '@noetic-tools/context';
2
2
  export type { AgentHarnessContract, Channel, Context, CwdState, FsAdapter, Item, ItemLog, LastLayerUsage, Span, StepMeta, TokenUsage, Tool, } from '@noetic-tools/types';
3
3
  export type { FrontierFrame } from '../types/checkpoint.js';
4
4
  export type { ChannelStore } from './channel-store.js';
@@ -1,4 +1,4 @@
1
- import type { StorageAdapter } from '@noetic-tools/memory';
1
+ import type { StorageAdapter } from '@noetic-tools/context';
2
2
  import type { CheckpointSnapshot } from '../../types/checkpoint.js';
3
3
  export declare const CheckpointKeys: {
4
4
  readonly ExecPrefix: "execution:";
@@ -1,4 +1,4 @@
1
- import type { LayerStateStore, MemoryLayer } from '@noetic-tools/memory';
1
+ import type { LayerStateStore } from '@noetic-tools/context';
2
2
  import type { Context, Item, ItemSchemaRegistry, RestoreContextOptions } from '@noetic-tools/types';
3
3
  import type { EventBroadcaster } from '../event-broadcaster.js';
4
4
  import type { CheckpointStore } from './checkpoint-store.js';
@@ -29,7 +29,6 @@ export interface CheckpointHarnessHandle {
29
29
  readonly stepLedgerRetention?: StepLedgerRetention;
30
30
  readonly layerStateStore: LayerStateStore;
31
31
  readonly itemSchemas: ItemSchemaRegistry;
32
- readonly _memory?: MemoryLayer[];
33
32
  createContext(opts?: RestoreCheckpointOptions & {
34
33
  items?: Item[];
35
34
  threadId?: string;
@@ -52,7 +51,7 @@ export declare function captureCheckpoint(h: CheckpointHarnessHandle, ctx: Conte
52
51
  * `null` if no snapshot is recorded for `executionId`. Layer state is
53
52
  * replayed into `layerStateStore` keyed by the original executionId so
54
53
  * the restored context observes the pre-crash state through
55
- * `readLayerState` and the memory projectors.
54
+ * `readLayerState` and the context projectors.
56
55
  *
57
56
  * `opts` carries the host's own context wiring (broadcaster, parent, state,
58
57
  * layer overrides) into the rebuilt context. A snapshot cannot round-trip live
@@ -63,7 +63,7 @@ export async function captureCheckpoint(h, ctx) {
63
63
  * `null` if no snapshot is recorded for `executionId`. Layer state is
64
64
  * replayed into `layerStateStore` keyed by the original executionId so
65
65
  * the restored context observes the pre-crash state through
66
- * `readLayerState` and the memory projectors.
66
+ * `readLayerState` and the context projectors.
67
67
  *
68
68
  * `opts` carries the host's own context wiring (broadcaster, parent, state,
69
69
  * layer overrides) into the rebuilt context. A snapshot cannot round-trip live
@@ -93,7 +93,7 @@ export async function restoreFromCheckpoint(h, executionId, opts) {
93
93
  }
94
94
  const items = h.itemSchemas.parseMany(snapshot.itemLog.items);
95
95
  const cwdInit = snapshot.cwd?.current ?? undefined;
96
- /* Caller wiring first, snapshot second: a host may legitimately swap the memory
96
+ /* Caller wiring first, snapshot second: a host may legitimately swap the context
97
97
  * layers or hang the restored execution under a new parent, but it must never be
98
98
  * able to override the identity/history the snapshot is the record of. */
99
99
  const ctx = h.createContext({
@@ -102,7 +102,6 @@ export async function restoreFromCheckpoint(h, executionId, opts) {
102
102
  threadId: snapshot.threadId,
103
103
  resourceId: snapshot.resourceId,
104
104
  cwdInit,
105
- memory: opts?.memory ?? h._memory,
106
105
  });
107
106
  if (ctx instanceof ContextImpl) {
108
107
  Object.defineProperty(ctx, 'id', {
@@ -17,7 +17,7 @@
17
17
  * construction — a missing entry re-runs its step, which costs work rather than
18
18
  * correctness.
19
19
  */
20
- import type { StorageAdapter } from '@noetic-tools/memory';
20
+ import type { StorageAdapter } from '@noetic-tools/context';
21
21
  import { z } from 'zod';
22
22
  /** @public One completed step, keyed by its execution path. */
23
23
  export declare const StepLedgerEntrySchema: z.ZodObject<{
@@ -17,7 +17,7 @@
17
17
  * construction — a missing entry re-runs its step, which costs work rather than
18
18
  * correctness.
19
19
  */
20
- import { storageGetMany } from '@noetic-tools/memory';
20
+ import { storageGetMany } from '@noetic-tools/context';
21
21
  import { NoeticConfigError } from '@noetic-tools/types';
22
22
  import { z } from 'zod';
23
23
  //#region Entry
@@ -1,4 +1,4 @@
1
- import type { StorageAdapter } from '@noetic-tools/memory';
1
+ import type { StorageAdapter } from '@noetic-tools/context';
2
2
  /**
3
3
  * @public Process-local, Map-backed StorageAdapter.
4
4
  *
@@ -16,7 +16,7 @@ export interface TurnContext {
16
16
  * (so the runner is the single point of ExecuteInput → Item[] conversion),
17
17
  * plus the messages being delivered this turn so the harness can honour
18
18
  * per-turn `ExecuteOptions` (the first message's options establish
19
- * resourceId/state/memory for the turn). */
19
+ * resourceId/state/context for the turn). */
20
20
  export type CreateContextFn = (items: ReadonlyArray<Item>, turnId: string, messages: ReadonlyArray<QueuedMessage>) => Context;
21
21
  export interface SessionRunnerOpts {
22
22
  readonly threadId: string;