@noetic-tools/core 3.2.0 → 5.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 (96) 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 +42 -26
  30. package/dist/harness/agent-harness.js +68 -21
  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/channel-store.d.ts +33 -0
  64. package/dist/runtime/channel-store.js +297 -11
  65. package/dist/runtime/context-deps.d.ts +2 -2
  66. package/dist/runtime/context-deps.js +1 -1
  67. package/dist/runtime/context-impl.d.ts +10 -8
  68. package/dist/runtime/context-impl.js +11 -7
  69. package/dist/runtime/context-type-deps.d.ts +1 -1
  70. package/dist/runtime/durable/checkpoint-store.d.ts +1 -1
  71. package/dist/runtime/durable/harness-checkpoints.d.ts +2 -3
  72. package/dist/runtime/durable/harness-checkpoints.js +2 -3
  73. package/dist/runtime/durable/step-ledger.d.ts +1 -1
  74. package/dist/runtime/durable/step-ledger.js +1 -1
  75. package/dist/runtime/in-memory-storage.d.ts +1 -1
  76. package/dist/runtime/session-runner.d.ts +1 -1
  77. package/dist/runtime/step-registry.d.ts +3 -3
  78. package/dist/runtime/{tool-memory.d.ts → tool-context.d.ts} +1 -2
  79. package/dist/runtime/{tool-memory.js → tool-context.js} +5 -2
  80. package/dist/runtime/tool-ui.d.ts +1 -1
  81. package/dist/runtime/tool-ui.js +1 -1
  82. package/dist/schemas/workflow.d.ts +5 -279
  83. package/dist/schemas/workflow.js +4 -376
  84. package/dist/types/mutable-context.d.ts +2 -2
  85. package/dist/types/step-registrar.d.ts +1 -1
  86. package/dist/unstable.d.ts +5 -5
  87. package/dist/unstable.js +3 -3
  88. package/dist/until/predicates.d.ts +1 -1
  89. package/package.json +4 -4
  90. package/schema/noetic-workflow.schema.json +28 -0
  91. package/dist/builders/memory-builder.d.ts +0 -11
  92. package/dist/builders/memory-builder.js +0 -15
  93. package/dist/patterns/flow.d.ts +0 -2
  94. package/dist/patterns/flow.js +0 -1
  95. package/dist/portable/memory-layers.d.ts +0 -8
  96. package/dist/portable/memory-layers.js +0 -8
@@ -1,4 +1,4 @@
1
- import type { StorageAdapter } from '@noetic-tools/memory';
1
+ import type { StorageAdapter } from '@noetic-tools/context';
2
2
  import type { StepSubprocessRequest, SubprocessHandle } from '@noetic-tools/types';
3
3
  import type { InMemoryStepManifest } from './types.js';
4
4
  export declare function isStepManifest(value: unknown): value is InMemoryStepManifest;
@@ -1,4 +1,4 @@
1
- import type { StorageAdapter } from '@noetic-tools/memory';
1
+ import type { StorageAdapter } from '@noetic-tools/context';
2
2
  import type { ProcessSubprocessRequest, StepSubprocessRequest, SubprocessHandle, SubprocessHandleMetadata, SubprocessRequest } from '@noetic-tools/types';
3
3
  /**
4
4
  * @public
@@ -1,4 +1,4 @@
1
- import type { MemoryLayer } from '@noetic-tools/memory';
1
+ import type { ContextLayer } from '@noetic-tools/context';
2
2
  import type { AgentHarnessContract, Context, Item, LLMResponse, Tool } from '@noetic-tools/types';
3
3
  import type * as OpenRouterAgent from '@openrouter/agent';
4
4
  import type { EmbedFn } from '../types/embed.js';
@@ -42,7 +42,7 @@ export interface ExecuteToolCallParams {
42
42
  tools: ReadonlyArray<Tool>;
43
43
  context: Context;
44
44
  harness: AgentHarnessContract;
45
- layers?: MemoryLayer[];
45
+ layers?: ContextLayer[];
46
46
  /** The model's `function_call` id — keys this call's tool-UI region. */
47
47
  callId?: string;
48
48
  }
@@ -1,6 +1,6 @@
1
1
  import { frameworkCast, isAssistantMessage, NoeticConfigError, SteeringAction, } from '@noetic-tools/types';
2
2
  import { z } from 'zod';
3
- import { buildToolExecutionContext } from '../runtime/tool-memory.js';
3
+ import { buildToolExecutionContext } from '../runtime/tool-context.js';
4
4
  import { emitToolUi } from '../runtime/tool-ui.js';
5
5
  const EmbeddingsResponseSchema = z.object({
6
6
  data: z.array(z.object({
@@ -210,7 +210,7 @@ export async function executeToolCall(params) {
210
210
  // Model sees sanitised tool names (see `sanitizeToolNameForWire`). Match
211
211
  // against both the original and sanitised name so internal identity (e.g.
212
212
  // `plan/updatePrd` used by steering whitelists, skill docs, and the
213
- // `planMemory.beforeToolCall` hook) stays intact while the wire name is
213
+ // `planContext.beforeToolCall` hook) stays intact while the wire name is
214
214
  // provider-compliant.
215
215
  const matchedTool = params.tools.find((t) => t.name === params.toolName || sanitizeToolNameForWire(t.name) === params.toolName);
216
216
  if (!matchedTool) {
@@ -0,0 +1,11 @@
1
+ import type { ContextConfig, ContextLayer } from '@noetic-tools/context';
2
+ /**
3
+ * Creates a type-safe context configuration from a tuple of context layers.
4
+ * The returned config preserves literal layer types for compile-time inference
5
+ * via `InferContext<typeof config>`.
6
+ *
7
+ * @public
8
+ * @param layers - Tuple of context layers to include in the configuration.
9
+ * @returns A `ContextConfig` carrying the inferred context shape as a phantom type.
10
+ */
11
+ export declare function context<const T extends readonly ContextLayer[]>(layers: T): ContextConfig<T>;
@@ -0,0 +1,15 @@
1
+ import { frameworkCast } from '@noetic-tools/types';
2
+ /**
3
+ * Creates a type-safe context configuration from a tuple of context layers.
4
+ * The returned config preserves literal layer types for compile-time inference
5
+ * via `InferContext<typeof config>`.
6
+ *
7
+ * @public
8
+ * @param layers - Tuple of context layers to include in the configuration.
9
+ * @returns A `ContextConfig` carrying the inferred context shape as a phantom type.
10
+ */
11
+ export function context(layers) {
12
+ return frameworkCast({
13
+ layers,
14
+ });
15
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Returns the configured context layers, preferring the current `context` key
3
+ * and falling back to the pre-rename `memory` key.
4
+ *
5
+ * `context` wins when both are set — an explicit new-style key should never be
6
+ * silently overridden by a stale one left behind mid-migration.
7
+ *
8
+ * This is the only place in core that *resolves* `.memory`. Every public entry
9
+ * point that used to take `memory` — `provide`, `spawn`, `tool`, `react`, the
10
+ * `AgentHarness` constructor, `createContext`, `execute`, `restore` — declares
11
+ * the deprecated key alongside its `context` replacement and resolves it
12
+ * through here.
13
+ *
14
+ * Removing the alias at the next major means deleting the `memory?`
15
+ * declarations, this function, and the one place that destructures the key off
16
+ * an options bag before forwarding it (`AgentHarness.createContext`).
17
+ *
18
+ * @internal
19
+ */
20
+ export declare function resolveContextOption<T>(opts: {
21
+ context?: T;
22
+ memory?: T;
23
+ }): T | undefined;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Returns the configured context layers, preferring the current `context` key
3
+ * and falling back to the pre-rename `memory` key.
4
+ *
5
+ * `context` wins when both are set — an explicit new-style key should never be
6
+ * silently overridden by a stale one left behind mid-migration.
7
+ *
8
+ * This is the only place in core that *resolves* `.memory`. Every public entry
9
+ * point that used to take `memory` — `provide`, `spawn`, `tool`, `react`, the
10
+ * `AgentHarness` constructor, `createContext`, `execute`, `restore` — declares
11
+ * the deprecated key alongside its `context` replacement and resolves it
12
+ * through here.
13
+ *
14
+ * Removing the alias at the next major means deleting the `memory?`
15
+ * declarations, this function, and the one place that destructures the key off
16
+ * an options bag before forwarding it (`AgentHarness.createContext`).
17
+ *
18
+ * @internal
19
+ */
20
+ export function resolveContextOption(opts) {
21
+ return opts.context ?? opts.memory;
22
+ }
@@ -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, SettleResult, Step, StepBranch, StepForkAll, StepForkRace, StepForkSettle } from '@noetic-tools/types';
3
3
  /**
4
4
  * Creates a parallel execution step that races paths and returns the first result.
@@ -11,13 +11,13 @@ import type { Context, SettleResult, Step, StepBranch, StepForkAll, StepForkRace
11
11
  * @returns A `StepForkRace` step.
12
12
  * @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
13
13
  */
14
- export declare function fork<TMemory = ContextMemory, I = unknown, O = unknown>(opts: {
14
+ export declare function fork<TContext = ContextData, I = unknown, O = unknown>(opts: {
15
15
  id: string;
16
16
  mode: 'race';
17
- paths: (input: I, ctx: Context<TMemory>) => Step<TMemory, I, O>[];
17
+ paths: (input: I, ctx: Context<TContext>) => Step<TContext, I, O>[];
18
18
  concurrency?: number;
19
- _optimizable?: Step<TMemory>[];
20
- }): StepForkRace<TMemory, I, O>;
19
+ _optimizable?: Step<TContext>[];
20
+ }): StepForkRace<TContext, I, O>;
21
21
  /**
22
22
  * Creates a parallel execution step that waits for all paths and merges results.
23
23
  *
@@ -31,14 +31,14 @@ export declare function fork<TMemory = ContextMemory, I = unknown, O = unknown>(
31
31
  * @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
32
32
  * @throws `NoeticConfigError` with code `MISSING_MERGE_FUNCTION` if `merge` is not provided.
33
33
  */
34
- export declare function fork<TMemory = ContextMemory, I = unknown, O = unknown>(opts: {
34
+ export declare function fork<TContext = ContextData, I = unknown, O = unknown>(opts: {
35
35
  id: string;
36
36
  mode: 'all';
37
- paths: (input: I, ctx: Context<TMemory>) => Step<TMemory, I, O>[];
38
- merge: (results: O[], ctx: Context<TMemory>) => O;
37
+ paths: (input: I, ctx: Context<TContext>) => Step<TContext, I, O>[];
38
+ merge: (results: O[], ctx: Context<TContext>) => O;
39
39
  concurrency?: number;
40
- _optimizable?: Step<TMemory>[];
41
- }): StepForkAll<TMemory, I, O>;
40
+ _optimizable?: Step<TContext>[];
41
+ }): StepForkAll<TContext, I, O>;
42
42
  /**
43
43
  * Creates a parallel execution step that waits for all paths, collecting errors as results.
44
44
  *
@@ -52,14 +52,14 @@ export declare function fork<TMemory = ContextMemory, I = unknown, O = unknown>(
52
52
  * @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
53
53
  * @throws `NoeticConfigError` with code `MISSING_MERGE_FUNCTION` if `merge` is not provided.
54
54
  */
55
- export declare function fork<TMemory = ContextMemory, I = unknown, O = unknown>(opts: {
55
+ export declare function fork<TContext = ContextData, I = unknown, O = unknown>(opts: {
56
56
  id: string;
57
57
  mode: 'settle';
58
- paths: (input: I, ctx: Context<TMemory>) => Step<TMemory, I, O>[];
59
- merge: (results: SettleResult<O>[], ctx: Context<TMemory>) => O;
58
+ paths: (input: I, ctx: Context<TContext>) => Step<TContext, I, O>[];
59
+ merge: (results: SettleResult<O>[], ctx: Context<TContext>) => O;
60
60
  concurrency?: number;
61
- _optimizable?: Step<TMemory>[];
62
- }): StepForkSettle<TMemory, I, O>;
61
+ _optimizable?: Step<TContext>[];
62
+ }): StepForkSettle<TContext, I, O>;
63
63
  /**
64
64
  * Creates a conditional routing step that selects the next step at runtime.
65
65
  *
@@ -71,8 +71,8 @@ export declare function fork<TMemory = ContextMemory, I = unknown, O = unknown>(
71
71
  * @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
72
72
  * @throws `NoeticConfigError` with code `MISSING_ROUTE_FUNCTION` if `route` is not provided.
73
73
  */
74
- export declare function branch<TMemory = ContextMemory, I = unknown, O = unknown>(opts: {
74
+ export declare function branch<TContext = ContextData, I = unknown, O = unknown>(opts: {
75
75
  id: string;
76
- route: (input: I, ctx: Context<TMemory>) => Step<TMemory, I, O> | null | Promise<Step<TMemory, I, O> | null>;
77
- _optimizable?: Step<TMemory>[];
78
- }): StepBranch<TMemory, I, O>;
76
+ route: (input: I, ctx: Context<TContext>) => Step<TContext, I, O> | null | Promise<Step<TContext, I, O> | null>;
77
+ _optimizable?: Step<TContext>[];
78
+ }): StepBranch<TContext, I, 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 { Channel, EveryErrorPolicy, Step, StepEvery } from '@noetic-tools/types';
3
3
  /**
4
4
  * Configuration options accepted by the `every()` builder, excluding the `kind`
@@ -7,11 +7,11 @@ import type { Channel, EveryErrorPolicy, Step, StepEvery } from '@noetic-tools/t
7
7
  *
8
8
  * @public
9
9
  */
10
- export interface EveryOptions<TMemory = ContextMemory, I = unknown, O = unknown> {
10
+ export interface EveryOptions<TContext = ContextData, I = unknown, O = unknown> {
11
11
  /** Unique step identifier used in traces and error messages. */
12
12
  id: string;
13
13
  /** Body step executed on each iteration. */
14
- step: Step<TMemory, I, O>;
14
+ step: Step<TContext, I, O>;
15
15
  /** Park duration between iterations in milliseconds. Must be >= 0. */
16
16
  ms: number;
17
17
  /** Optional channel that wakes the parking interval when any value arrives. */
@@ -41,4 +41,4 @@ export interface EveryOptions<TMemory = ContextMemory, I = unknown, O = unknown>
41
41
  * @throws `NoeticConfigError` with code `INVALID_INTERVAL_MS` if `ms` is negative or not finite.
42
42
  * @throws `NoeticConfigError` with code `INVALID_JITTER` if `jitter` is negative or not finite.
43
43
  */
44
- export declare function every<TMemory = ContextMemory, I = unknown, O = unknown>(opts: EveryOptions<TMemory, I, O>): StepEvery<TMemory, I, O>;
44
+ export declare function every<TContext = ContextData, I = unknown, O = unknown>(opts: EveryOptions<TContext, I, O>): StepEvery<TContext, I, O>;
@@ -1 +1 @@
1
- export { layerData, layerFn } from '@noetic-tools/memory';
1
+ export { layerData, layerFn } from '@noetic-tools/context';
@@ -1 +1 @@
1
- export { layerData, layerFn } from '@noetic-tools/memory';
1
+ export { layerData, layerFn } from '@noetic-tools/context';
@@ -1,7 +1,7 @@
1
- import type { ContextMemory } from '@noetic-tools/memory';
1
+ import type { ContextData } from '@noetic-tools/context';
2
2
  import type { StepLoop } from '@noetic-tools/types';
3
3
  /** @public Configuration options accepted by the `loop()` builder, excluding the `kind` discriminant. */
4
- export type LoopConfig<TMemory = ContextMemory, I = unknown, O = unknown> = Omit<StepLoop<TMemory, I, O>, 'kind'>;
4
+ export type LoopConfig<TContext = ContextData, I = unknown, O = unknown> = Omit<StepLoop<TContext, I, O>, 'kind'>;
5
5
  /**
6
6
  * Creates a loop step that iterates a body step until a termination predicate is satisfied.
7
7
  *
@@ -20,4 +20,4 @@ export type LoopConfig<TMemory = ContextMemory, I = unknown, O = unknown> = Omit
20
20
  * @throws `NoeticConfigError` with code `MISSING_LOOP_BODY` if `steps` is empty.
21
21
  * @throws `NoeticConfigError` with code `MISSING_UNTIL_PREDICATE` if `until` is not provided.
22
22
  */
23
- export declare function loop<TMemory = ContextMemory, I = unknown, O = unknown>(opts: LoopConfig<TMemory, I, O>): StepLoop<TMemory, I, O>;
23
+ export declare function loop<TContext = ContextData, I = unknown, O = unknown>(opts: LoopConfig<TContext, I, O>): StepLoop<TContext, I, O>;
@@ -1,20 +1,27 @@
1
- import type { ContextMemory, MemoryConfig, MemoryLayer } from '@noetic-tools/memory';
1
+ import type { ContextConfig, ContextData, ContextLayer } from '@noetic-tools/context';
2
2
  import type { Step, StepProvide } from '@noetic-tools/types';
3
3
  /**
4
- * Creates a provide step that attaches memory layers to its child without creating an isolated context.
4
+ * Creates a provide step that attaches context layers to its child without creating an isolated context.
5
5
  * Like React's Context.Provider — layers are available to all descendant steps.
6
6
  * Spawn and detachedSpawn break the inheritance chain.
7
7
  *
8
8
  * @public
9
9
  * @param opts.id - Unique step identifier used in traces and error messages.
10
10
  * @param opts.child - Step to execute with the provided layers.
11
- * @param opts.memory - Memory layers to provide to descendant steps.
11
+ * @param opts.context - Context layers to provide to descendant steps.
12
12
  * @returns A `StepProvide` step.
13
13
  * @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
14
14
  * @throws `NoeticConfigError` with code `MISSING_CHILD_STEP` if `child` is not provided.
15
15
  */
16
- export declare function provide<TMemory = ContextMemory, I = unknown, O = unknown>(opts: {
16
+ export declare function provide<TContext = ContextData, I = unknown, O = unknown>(opts: {
17
17
  id: string;
18
- child: Step<TMemory, I, O>;
19
- memory: MemoryConfig | MemoryLayer[];
20
- }): StepProvide<TMemory, I, O>;
18
+ child: Step<TContext, I, O>;
19
+ /**
20
+ * Optional in the type only so the deprecated `memory` spelling remains a
21
+ * valid way to supply the layers. Exactly one of the two is required — the
22
+ * runtime enforces it, the same way `id` and `child` are enforced.
23
+ */
24
+ context?: ContextConfig | ContextLayer[];
25
+ /** @deprecated Renamed to `context`. */
26
+ memory?: ContextConfig | ContextLayer[];
27
+ }): StepProvide<TContext, I, O>;
@@ -1,14 +1,15 @@
1
1
  import { NoeticConfigError } from '@noetic-tools/types';
2
2
  import { getDefaultRegistrar } from '../types/step-registrar.js';
3
+ import { resolveContextOption } from './context-option.js';
3
4
  /**
4
- * Creates a provide step that attaches memory layers to its child without creating an isolated context.
5
+ * Creates a provide step that attaches context layers to its child without creating an isolated context.
5
6
  * Like React's Context.Provider — layers are available to all descendant steps.
6
7
  * Spawn and detachedSpawn break the inheritance chain.
7
8
  *
8
9
  * @public
9
10
  * @param opts.id - Unique step identifier used in traces and error messages.
10
11
  * @param opts.child - Step to execute with the provided layers.
11
- * @param opts.memory - Memory layers to provide to descendant steps.
12
+ * @param opts.context - Context layers to provide to descendant steps.
12
13
  * @returns A `StepProvide` step.
13
14
  * @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
14
15
  * @throws `NoeticConfigError` with code `MISSING_CHILD_STEP` if `child` is not provided.
@@ -25,12 +26,22 @@ export function provide(opts) {
25
26
  throw new NoeticConfigError({
26
27
  code: 'MISSING_CHILD_STEP',
27
28
  message: 'provide() requires a child step.',
28
- hint: 'Provide a child step to execute with the provided memory layers.',
29
+ hint: 'Provide a child step to execute with the provided context layers.',
30
+ });
31
+ }
32
+ const layers = resolveContextOption(opts);
33
+ if (!layers) {
34
+ throw new NoeticConfigError({
35
+ code: 'MISSING_CONTEXT_LAYERS',
36
+ message: 'provide() requires context layers.',
37
+ hint: 'Pass context: [workingMemoryContext()]. The `memory` key is the deprecated spelling of `context`.',
29
38
  });
30
39
  }
31
40
  const built = {
32
41
  kind: 'provide',
33
- ...opts,
42
+ id: opts.id,
43
+ child: opts.child,
44
+ context: layers,
34
45
  };
35
46
  getDefaultRegistrar().register(built);
36
47
  return built;
@@ -1,9 +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 { Step, StepSpawn, SubprocessAdapter } from '@noetic-tools/types';
3
- interface SpawnOpts<TMemory, I, O> {
3
+ interface SpawnOpts<TContext, I, O> {
4
4
  id: string;
5
- child: Step<TMemory, I, O>;
6
- memory?: MemoryConfig | MemoryLayer[];
5
+ child: Step<TContext, I, O>;
6
+ context?: ContextConfig | ContextLayer[];
7
+ /** @deprecated Renamed to `context`. */
8
+ memory?: ContextConfig | ContextLayer[];
7
9
  timeout?: number;
8
10
  /**
9
11
  * Optional per-step subprocess adapter override. The interpreter routes
@@ -18,7 +20,7 @@ interface SpawnOpts<TMemory, I, O> {
18
20
  * @public
19
21
  * @param opts.id - Unique step identifier used in traces and error messages.
20
22
  * @param opts.child - Step to execute in the isolated child context.
21
- * @param opts.memory - Optional memory config or layers for the child context (replaces parent layers entirely).
23
+ * @param opts.context - Optional context config or layers for the child context (replaces parent layers entirely).
22
24
  * @param opts.timeout - Optional execution timeout in ms; the child is aborted if it exceeds this.
23
25
  * @param opts.subprocess - Optional per-step subprocess adapter override.
24
26
  * @returns A `StepSpawn` step. The spawn step and its `child` step are both
@@ -28,5 +30,5 @@ interface SpawnOpts<TMemory, I, O> {
28
30
  * @throws `NoeticConfigError` with code `MISSING_CHILD_STEP` if `child` is not provided.
29
31
  * @throws `NoeticConfigError` with code `DUPLICATE_STEP_ID` if another step with the same id is already registered.
30
32
  */
31
- export declare function spawn<TMemory = ContextMemory, I = unknown, O = unknown>(opts: SpawnOpts<TMemory, I, O>): StepSpawn<TMemory, I, O>;
33
+ export declare function spawn<TContext = ContextData, I = unknown, O = unknown>(opts: SpawnOpts<TContext, I, O>): StepSpawn<TContext, I, O>;
32
34
  export {};
@@ -1,5 +1,6 @@
1
1
  import { NoeticConfigError } from '@noetic-tools/types';
2
2
  import { getDefaultRegistrar } from '../types/step-registrar.js';
3
+ import { resolveContextOption } from './context-option.js';
3
4
  //#endregion
4
5
  //#region Public API
5
6
  /**
@@ -8,7 +9,7 @@ import { getDefaultRegistrar } from '../types/step-registrar.js';
8
9
  * @public
9
10
  * @param opts.id - Unique step identifier used in traces and error messages.
10
11
  * @param opts.child - Step to execute in the isolated child context.
11
- * @param opts.memory - Optional memory config or layers for the child context (replaces parent layers entirely).
12
+ * @param opts.context - Optional context config or layers for the child context (replaces parent layers entirely).
12
13
  * @param opts.timeout - Optional execution timeout in ms; the child is aborted if it exceeds this.
13
14
  * @param opts.subprocess - Optional per-step subprocess adapter override.
14
15
  * @returns A `StepSpawn` step. The spawn step and its `child` step are both
@@ -35,7 +36,11 @@ export function spawn(opts) {
35
36
  }
36
37
  const built = {
37
38
  kind: 'spawn',
38
- ...opts,
39
+ id: opts.id,
40
+ child: opts.child,
41
+ context: resolveContextOption(opts),
42
+ timeout: opts.timeout,
43
+ subprocess: opts.subprocess,
39
44
  };
40
45
  getDefaultRegistrar().register(built);
41
46
  // Ensure the child is addressable by id — builders for `run`/`llm`/`tool`
@@ -1,9 +1,9 @@
1
- import type { ContextMemory } from '@noetic-tools/memory';
1
+ import type { ContextData } from '@noetic-tools/context';
2
2
  import type { Context, Lazy, ModelParams, OutputCodec, RetryPolicy, ServerToolSpec, StepLLM, StepRun, StepSubHarness, StepTool, SubHarness, SubHarnessSessionPolicy, SubHarnessSettings, SubprocessAdapter, Tool } from '@noetic-tools/types';
3
3
  import type { ZodType } from 'zod';
4
- interface StepRunOpts<TMemory, I, O> {
4
+ export interface StepRunOpts<TContext, I, O> {
5
5
  id: string;
6
- execute: (input: I, ctx: Context<TMemory>) => Promise<O>;
6
+ execute: (input: I, ctx: Context<TContext>) => Promise<O>;
7
7
  retry?: RetryPolicy;
8
8
  /**
9
9
  * Optional subprocess adapter override. When set, `execute()` is routed
@@ -12,38 +12,38 @@ interface StepRunOpts<TMemory, I, O> {
12
12
  */
13
13
  subprocess?: SubprocessAdapter;
14
14
  }
15
- interface StepLLMOpts<TMemory, O> {
15
+ export interface StepLLMOpts<TContext, O> {
16
16
  id: string;
17
17
  /** Model id. Eager string or `(ctx) => string` getter (resolved at step execution). */
18
- model: Lazy<string, TMemory>;
18
+ model: Lazy<string, TContext>;
19
19
  /** Optional instructions; eager string or `(ctx) => string | undefined` getter. */
20
- instructions?: Lazy<string | undefined, TMemory>;
20
+ instructions?: Lazy<string | undefined, TContext>;
21
21
  /**
22
22
  * Optional tools; eager array or `(ctx) => (...)[] | undefined` getter. Each
23
23
  * entry is either a client `Tool` or an inline `ServerToolSpec` (an OpenRouter
24
24
  * server tool the provider executes, e.g. web search/fetch).
25
25
  */
26
- tools?: Lazy<(Tool | ServerToolSpec)[] | undefined, TMemory>;
26
+ tools?: Lazy<(Tool | ServerToolSpec)[] | undefined, TContext>;
27
27
  /** Structured output: a Zod schema or a streaming `OutputCodec` (e.g. OpenUI Lang). */
28
28
  output?: ZodType<O> | OutputCodec<O>;
29
29
  params?: ModelParams;
30
30
  emit?: boolean | ((eventType: string, data: Record<string, unknown>) => boolean);
31
31
  }
32
- interface StepToolOpts<I, O> {
32
+ export interface StepToolOpts<I, O> {
33
33
  id: string;
34
34
  tool: Tool<ZodType<I>, ZodType<O>>;
35
35
  args?: Partial<I>;
36
36
  }
37
- interface StepSubHarnessOpts<TMemory, O> {
37
+ export interface StepSubHarnessOpts<TContext, O> {
38
38
  id: string;
39
39
  /** The harness adapter created by a `@noetic-tools/sub-harness-*` factory. Eager or `(ctx) => SubHarness`. */
40
- harness: Lazy<SubHarness, TMemory>;
40
+ harness: Lazy<SubHarness, TContext>;
41
41
  /** Turn prompt. Eager string or `(ctx) => string` getter. */
42
- prompt: Lazy<string, TMemory>;
42
+ prompt: Lazy<string, TContext>;
43
43
  /** Shared harness settings (model, permission mode, …). */
44
44
  settings?: SubHarnessSettings;
45
45
  /** System instructions applied on the first message of a fresh session. */
46
- instructions?: Lazy<string | undefined, TMemory>;
46
+ instructions?: Lazy<string | undefined, TContext>;
47
47
  /** Optional Zod schema; when set the assistant text is JSON-parsed and validated. */
48
48
  output?: ZodType<O>;
49
49
  /** Session reuse + teardown policy across steps. */
@@ -66,7 +66,7 @@ export declare const step: {
66
66
  * @throws `NoeticConfigError` with code `MISSING_EXECUTE_FUNCTION` if `execute` is not provided.
67
67
  * @throws `NoeticConfigError` with code `DUPLICATE_STEP_ID` if another step with the same id is already registered with a different body.
68
68
  */
69
- run<TMemory = ContextMemory, I = unknown, O = unknown>(opts: StepRunOpts<TMemory, I, O>): StepRun<TMemory, I, O>;
69
+ run<TContext = ContextData, I = unknown, O = unknown>(opts: StepRunOpts<TContext, I, O>): StepRun<TContext, I, O>;
70
70
  /**
71
71
  * Creates an LLM model call step with optional tools and structured output.
72
72
  *
@@ -82,7 +82,7 @@ export declare const step: {
82
82
  * @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
83
83
  * @throws `NoeticConfigError` with code `MISSING_MODEL` if an eager `model` string is empty. Function-form models are validated at step execution.
84
84
  */
85
- llm<TMemory = ContextMemory, I = unknown, O = unknown>(opts: StepLLMOpts<TMemory, O>): StepLLM<TMemory, I, O>;
85
+ llm<TContext = ContextData, I = unknown, O = unknown>(opts: StepLLMOpts<TContext, O>): StepLLM<TContext, I, O>;
86
86
  /**
87
87
  * Creates a tool execution step that invokes a typed tool definition.
88
88
  *
@@ -95,7 +95,7 @@ export declare const step: {
95
95
  * @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
96
96
  * @throws `NoeticConfigError` with code `MISSING_TOOL` if `tool` is not provided.
97
97
  */
98
- tool<TMemory = ContextMemory, I = unknown, O = unknown>(opts: StepToolOpts<I, O>): StepTool<TMemory, I, O>;
98
+ tool<TContext = ContextData, I = unknown, O = unknown>(opts: StepToolOpts<I, O>): StepTool<TContext, I, O>;
99
99
  /**
100
100
  * Creates a step that delegates a turn to the Claude Code harness.
101
101
  *
@@ -108,27 +108,26 @@ export declare const step: {
108
108
  * @returns A `StepSubHarness` of kind `claude-code`, auto-registered in the step registry.
109
109
  * @throws `NoeticConfigError` `EMPTY_STEP_ID` / `MISSING_SUB_HARNESS` / `SUB_HARNESS_KIND_MISMATCH`.
110
110
  */
111
- claudeCode<TMemory = ContextMemory, I = unknown, O = unknown>(opts: StepSubHarnessOpts<TMemory, O>): StepSubHarness<TMemory, I, O>;
111
+ claudeCode<TContext = ContextData, I = unknown, O = unknown>(opts: StepSubHarnessOpts<TContext, O>): StepSubHarness<TContext, I, O>;
112
112
  /**
113
113
  * Creates a step that delegates a turn to the Codex harness.
114
114
  * @public
115
115
  * @param opts - See {@link step.claudeCode}; `opts.harness` is a `codex(...)` adapter.
116
116
  * @returns A `StepSubHarness` of kind `codex`.
117
117
  */
118
- codex<TMemory = ContextMemory, I = unknown, O = unknown>(opts: StepSubHarnessOpts<TMemory, O>): StepSubHarness<TMemory, I, O>;
118
+ codex<TContext = ContextData, I = unknown, O = unknown>(opts: StepSubHarnessOpts<TContext, O>): StepSubHarness<TContext, I, O>;
119
119
  /**
120
120
  * Creates a step that delegates a turn to the opencode harness.
121
121
  * @public
122
122
  * @param opts - See {@link step.claudeCode}; `opts.harness` is an `opencode(...)` adapter.
123
123
  * @returns A `StepSubHarness` of kind `opencode`.
124
124
  */
125
- opencode<TMemory = ContextMemory, I = unknown, O = unknown>(opts: StepSubHarnessOpts<TMemory, O>): StepSubHarness<TMemory, I, O>;
125
+ opencode<TContext = ContextData, I = unknown, O = unknown>(opts: StepSubHarnessOpts<TContext, O>): StepSubHarness<TContext, I, O>;
126
126
  /**
127
127
  * Creates a step that delegates a turn to the pi harness.
128
128
  * @public
129
129
  * @param opts - See {@link step.claudeCode}; `opts.harness` is a `pi(...)` adapter.
130
130
  * @returns A `StepSubHarness` of kind `pi`.
131
131
  */
132
- pi<TMemory = ContextMemory, I = unknown, O = unknown>(opts: StepSubHarnessOpts<TMemory, O>): StepSubHarness<TMemory, I, O>;
132
+ pi<TContext = ContextData, I = unknown, O = unknown>(opts: StepSubHarnessOpts<TContext, O>): StepSubHarness<TContext, I, O>;
133
133
  };
134
- export {};
@@ -1,4 +1,4 @@
1
- import type { FunctionCallItem, FunctionCallOutputItem, Item, ItemSchemaExtensions, Tool, ToolExecutionContext, ToolMemoryDeclaration, ToolResultExtensionItem, ToolUiDeclaration } from '@noetic-tools/types';
1
+ import type { FunctionCallItem, FunctionCallOutputItem, Item, ItemSchemaExtensions, Tool, ToolContextDeclaration, ToolExecutionContext, ToolResultExtensionItem, ToolUiDeclaration } from '@noetic-tools/types';
2
2
  import type { ZodTypeAny, z } from 'zod';
3
3
  interface ToolConfig<I extends ZodTypeAny, O extends ZodTypeAny> {
4
4
  name: string;
@@ -16,8 +16,10 @@ interface ToolConfig<I extends ZodTypeAny, O extends ZodTypeAny> {
16
16
  }) => Item | ToolResultExtensionItem;
17
17
  execute: (args: z.infer<I>, toolCtx: ToolExecutionContext) => Promise<z.infer<O>>;
18
18
  needsApproval?: boolean;
19
- /** Optional memory declaration — the runtime generates a MemoryLayer from this via toolMemoryLayer(). */
20
- memory?: ToolMemoryDeclaration;
19
+ /** Optional context declaration — the runtime generates a ContextLayer from this via toolContextLayer(). */
20
+ context?: ToolContextDeclaration;
21
+ /** @deprecated Renamed to `context`. */
22
+ memory?: ToolContextDeclaration;
21
23
  /** Optional UI declaration — the runtime emits the rendered fragments at call/progress/result points. */
22
24
  ui?: ToolUiDeclaration<I, O>;
23
25
  }
@@ -38,8 +40,10 @@ interface GeneratorToolConfig<I extends ZodTypeAny, E extends ZodTypeAny, O exte
38
40
  }) => Item | ToolResultExtensionItem;
39
41
  execute: (args: z.infer<I>, toolCtx: ToolExecutionContext) => AsyncGenerator<z.infer<E>, z.infer<O>>;
40
42
  needsApproval?: boolean;
41
- /** Optional memory declaration — the runtime generates a MemoryLayer from this via toolMemoryLayer(). */
42
- memory?: ToolMemoryDeclaration;
43
+ /** Optional context declaration — the runtime generates a ContextLayer from this via toolContextLayer(). */
44
+ context?: ToolContextDeclaration;
45
+ /** @deprecated Renamed to `context`. */
46
+ memory?: ToolContextDeclaration;
43
47
  /** Optional UI declaration — the runtime emits the rendered fragments at call/progress/result points. */
44
48
  ui?: ToolUiDeclaration<I, O, z.infer<E>>;
45
49
  }
@@ -1,4 +1,5 @@
1
1
  import { NoeticConfigError } from '@noetic-tools/types';
2
+ import { resolveContextOption } from './context-option.js';
2
3
  //#endregion
3
4
  //#region Helpers
4
5
  function validateToolConfig(name, execute) {
@@ -35,7 +36,7 @@ export function tool(config) {
35
36
  decorateResultItem: config.decorateResultItem,
36
37
  execute: config.execute,
37
38
  needsApproval: config.needsApproval,
38
- memory: config.memory,
39
+ context: resolveContextOption(config),
39
40
  ui: config.ui,
40
41
  };
41
42
  }
@@ -56,7 +57,7 @@ export function toolWithGenerator(config) {
56
57
  decorateResultItem: config.decorateResultItem,
57
58
  execute: config.execute,
58
59
  needsApproval: config.needsApproval,
59
- memory: config.memory,
60
+ context: resolveContextOption(config),
60
61
  ui: config.ui,
61
62
  };
62
63
  }
@@ -5,14 +5,14 @@
5
5
  * `loop`, etc.) so hydrated steps are indistinguishable from programmatic
6
6
  * ones — they register in the step registry, carry retry policies, etc.
7
7
  */
8
- import type { ContextMemory, MemoryLayer } from '@noetic-tools/memory';
8
+ import type { ContextData, ContextLayer } from '@noetic-tools/context';
9
9
  import type { ExecuteStepFn, OutputCodec, Step, SubHarness, SubHarnessKind, SubprocessAdapter, Tool } from '@noetic-tools/types';
10
10
  import type { WorkflowDocument, WorkflowNode } from '../schemas/workflow.js';
11
11
  /** @public Context required to hydrate a JSON workflow into live steps. */
12
12
  export interface HydrationContext {
13
13
  tools: ReadonlyMap<string, Tool>;
14
14
  executeStep: ExecuteStepFn;
15
- layers?: ReadonlyMap<string, MemoryLayer>;
15
+ layers?: ReadonlyMap<string, ContextLayer>;
16
16
  /** SubHarness adapters keyed by harness id, resolving `claude-code`/`codex`/… nodes. */
17
17
  subHarnesses?: ReadonlyMap<SubHarnessKind, SubHarness>;
18
18
  /**
@@ -28,6 +28,17 @@ export interface HydrationContext {
28
28
  * `ctx.subprocess` at execution time.
29
29
  */
30
30
  resolveSubprocess?: (ref: string) => SubprocessAdapter | undefined;
31
+ /**
32
+ * Named sub-workflow documents that `subflow` nodes resolve via `ref`.
33
+ * Resolution is lazy (first execution), so a live map view may gain
34
+ * entries after hydration.
35
+ */
36
+ workflows?: ReadonlyMap<string, WorkflowDocument>;
37
+ /**
38
+ * Ancestor ref chain for cycle detection on named sub-workflow references.
39
+ * Threaded internally by the subflow hydrator — callers never set it.
40
+ */
41
+ subflowAncestry?: ReadonlySet<string>;
31
42
  }
32
43
  /**
33
44
  * Hydrates a single `WorkflowNode` into a live `Step`.
@@ -39,8 +50,10 @@ export interface HydrationContext {
39
50
  * @throws `NoeticConfigError` with code `UNKNOWN_NODE_KIND` if the node kind is unrecognised.
40
51
  * @throws `NoeticConfigError` with code `UNKNOWN_TOOL_REFERENCE` if a tool name cannot be resolved.
41
52
  * @throws `NoeticConfigError` with code `UNKNOWN_UNTIL_PREDICATE` if an until predicate kind is unrecognised.
53
+ * @throws `NoeticConfigError` with code `UNKNOWN_WORKFLOW_REFERENCE` (at execution time) if a subflow ref names no registered workflow.
54
+ * @throws `NoeticConfigError` with code `WORKFLOW_CYCLE` (at execution time) if named sub-workflow refs form a cycle.
42
55
  */
43
- export declare function hydrateNode(node: WorkflowNode, ctx: HydrationContext): Step<ContextMemory, string, string>;
56
+ export declare function hydrateNode(node: WorkflowNode, ctx: HydrationContext): Step<ContextData, string, string>;
44
57
  /**
45
58
  * Hydrates a complete `WorkflowDocument` into a live `Step` tree.
46
59
  *
@@ -49,4 +62,4 @@ export declare function hydrateNode(node: WorkflowNode, ctx: HydrationContext):
49
62
  * @param ctx - Hydration context with tool registry and step executor.
50
63
  * @returns The root `Step` of the hydrated workflow.
51
64
  */
52
- export declare function hydrateWorkflow(doc: WorkflowDocument, ctx: HydrationContext): Step<ContextMemory, string, string>;
65
+ export declare function hydrateWorkflow(doc: WorkflowDocument, ctx: HydrationContext): Step<ContextData, string, string>;