@noetic-tools/core 5.2.0 → 5.4.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 (92) hide show
  1. package/README.md +8 -6
  2. package/dist/adapters/in-memory-subprocess/step-completion.js +1 -1
  3. package/dist/adapters/openrouter.d.ts +20 -2
  4. package/dist/adapters/openrouter.js +102 -6
  5. package/dist/builders/control-flow-builders.d.ts +13 -13
  6. package/dist/builders/control-flow-builders.js +11 -11
  7. package/dist/{patterns → builders}/dynamic-workflow.d.ts +1 -1
  8. package/dist/{patterns → builders}/dynamic-workflow.js +18 -12
  9. package/dist/builders/every.d.ts +14 -14
  10. package/dist/builders/every.js +16 -16
  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/provide-builder.d.ts +5 -12
  14. package/dist/builders/provide-builder.js +9 -10
  15. package/dist/builders/spawn-builder.d.ts +0 -2
  16. package/dist/builders/spawn-builder.js +2 -3
  17. package/dist/builders/step-builders.d.ts +66 -55
  18. package/dist/builders/step-builders.js +118 -111
  19. package/dist/builders/tool-builder.d.ts +18 -22
  20. package/dist/builders/tool-builder.js +6 -4
  21. package/dist/builders/workflow-hydrator.d.ts +3 -3
  22. package/dist/builders/workflow-hydrator.js +59 -63
  23. package/dist/builders/workflow-step.d.ts +13 -25
  24. package/dist/builders/workflow-step.js +13 -18
  25. package/dist/conditions/conditions.d.ts +2 -2
  26. package/dist/conditions/conditions.js +1 -1
  27. package/dist/harness/agent-harness.d.ts +58 -40
  28. package/dist/harness/agent-harness.js +125 -51
  29. package/dist/harness/deps/context.d.ts +1 -1
  30. package/dist/harness/deps/context.js +1 -1
  31. package/dist/harness/deps/interpreter.d.ts +1 -0
  32. package/dist/harness/deps/interpreter.js +1 -0
  33. package/dist/harness/deps/types.d.ts +2 -2
  34. package/dist/harness/model-call.d.ts +1 -1
  35. package/dist/harness/model-call.js +45 -23
  36. package/dist/index.d.ts +23 -35
  37. package/dist/index.js +10 -26
  38. package/dist/interpreter/action-deps.d.ts +2 -2
  39. package/dist/interpreter/action-deps.js +1 -1
  40. package/dist/interpreter/action-types.d.ts +1 -1
  41. package/dist/interpreter/collect-tools.js +7 -7
  42. package/dist/interpreter/context-assembly.d.ts +50 -0
  43. package/dist/interpreter/context-assembly.js +547 -0
  44. package/dist/interpreter/execute-action.d.ts +5 -5
  45. package/dist/interpreter/execute-action.js +337 -208
  46. package/dist/interpreter/execute-control.d.ts +9 -9
  47. package/dist/interpreter/execute-control.js +27 -27
  48. package/dist/interpreter/execute-sub-harness.d.ts +1 -1
  49. package/dist/interpreter/execute-sub-harness.js +7 -26
  50. package/dist/interpreter/execute.d.ts +1 -1
  51. package/dist/interpreter/execute.js +26 -25
  52. package/dist/interpreter/step-dispatcher.d.ts +1 -1
  53. package/dist/interpreter/step-dispatcher.js +3 -3
  54. package/dist/interpreter/structured-output.d.ts +14 -0
  55. package/dist/interpreter/structured-output.js +40 -0
  56. package/dist/interpreter/typeguards.d.ts +1 -1
  57. package/dist/interpreter/typeguards.js +1 -1
  58. package/dist/observability/genai-attributes.d.ts +20 -0
  59. package/dist/observability/genai-attributes.js +20 -0
  60. package/dist/portable/builders.d.ts +3 -3
  61. package/dist/portable/builders.js +6 -5
  62. package/dist/portable/context-layers.d.ts +1 -1
  63. package/dist/portable/context-layers.js +1 -1
  64. package/dist/runtime/broadcaster-utils.d.ts +1 -1
  65. package/dist/runtime/broadcaster-utils.js +1 -1
  66. package/dist/runtime/context-impl.d.ts +8 -10
  67. package/dist/runtime/context-impl.js +8 -12
  68. package/dist/runtime/durable/step-ledger.d.ts +2 -2
  69. package/dist/runtime/durable/step-ledger.js +3 -3
  70. package/dist/runtime/session-runner.d.ts +12 -1
  71. package/dist/runtime/session-runner.js +33 -1
  72. package/dist/runtime/tool-context.js +0 -2
  73. package/dist/schemas/workflow.d.ts +3 -3
  74. package/dist/schemas/workflow.js +2 -2
  75. package/dist/types/checkpoint.d.ts +11 -2
  76. package/dist/types/checkpoint.js +10 -1
  77. package/dist/{runtime → util}/detached-handle.js +1 -1
  78. package/package.json +6 -4
  79. package/schema/noetic-workflow.schema.json +24 -11
  80. package/dist/builders/context-option.d.ts +0 -23
  81. package/dist/builders/context-option.js +0 -22
  82. package/dist/deprecated.d.ts +0 -30
  83. package/dist/deprecated.js +0 -28
  84. package/dist/patterns/interview.d.ts +0 -53
  85. package/dist/patterns/interview.js +0 -113
  86. package/dist/patterns/plans.d.ts +0 -44
  87. package/dist/patterns/plans.js +0 -125
  88. package/dist/patterns/ralph-wiggum.d.ts +0 -19
  89. package/dist/patterns/ralph-wiggum.js +0 -37
  90. package/dist/patterns/react.d.ts +0 -19
  91. package/dist/patterns/react.js +0 -41
  92. /package/dist/{runtime → util}/detached-handle.d.ts +0 -0
@@ -5,4 +5,4 @@
5
5
  /** @public */
6
6
  /** @public */
7
7
  /** @public */
8
- export { durableTaskState, historyWindow, observationalContext, planContext, temporalContext, toolContextLayer, workingMemoryContext, } from '@noetic-tools/context';
8
+ export { history, observations, plan, scratchpad, taskState, temporal, toolCalls, } from '@noetic-tools/context';
@@ -7,7 +7,7 @@ export type EmitOption = boolean | ((eventType: string, data: Record<string, unk
7
7
  *
8
8
  * When `emit` is `undefined` (the default for non-LLM steps where the
9
9
  * field does not exist on the Step type), events are always emitted.
10
- * Only StepLLM exposes `emit` for opt-out or filtering.
10
+ * Only StepCallModel exposes `emit` for opt-out or filtering.
11
11
  *
12
12
  * @internal
13
13
  */
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * When `emit` is `undefined` (the default for non-LLM steps where the
7
7
  * field does not exist on the Step type), events are always emitted.
8
- * Only StepLLM exposes `emit` for opt-out or filtering.
8
+ * Only StepCallModel exposes `emit` for opt-out or filtering.
9
9
  *
10
10
  * @internal
11
11
  */
@@ -31,8 +31,8 @@ export declare class ContextImpl implements Context<ContextData> {
31
31
  private readonly _createdAt;
32
32
  /**
33
33
  * Shared channel store for cross-context communication. Inherited by
34
- * `fork` / `spawn` children so channels published by a sibling are visible
35
- * to peers — see `executeFork` and `executeSpawn` in `interpreter/execute-action.ts`
34
+ * `inParallel` / `spawn` children so channels published by a sibling are visible
35
+ * to peers — see `executeInParallel` and `executeSpawn` in `interpreter/execute-action.ts`
36
36
  * and `interpreter/execute-control.ts`.
37
37
  * @internal
38
38
  */
@@ -46,14 +46,14 @@ export declare class ContextImpl implements Context<ContextData> {
46
46
  * Per-context abort fan-out. `abort()` fires it so operations blocked on
47
47
  * this context (channel `recv` waiters, parked back-pressure senders)
48
48
  * reject promptly with `{ kind: 'cancelled' }` instead of hanging until
49
- * their timeout (spec 09, Cancellation item 2). Each fork/spawn child
49
+ * their timeout (spec 09, Cancellation item 2). Each inParallel/spawn child
50
50
  * constructs its own ContextImpl and therefore its own controller —
51
51
  * aborting a child never rejects the parent's waiters, while aborting a
52
52
  * parent DOES cascade down to every live child (see `_children`).
53
53
  */
54
54
  private readonly _abortController;
55
55
  /**
56
- * Live child contexts (fork paths, spawn children) registered for the abort
56
+ * Live child contexts (inParallel paths, spawn children) registered for the abort
57
57
  * cascade. A child adds itself at construction and removes itself via
58
58
  * `detachFromParent()` when its execution settles, so a long-lived parent
59
59
  * driving a loop of spawns does not accumulate finished children.
@@ -77,7 +77,7 @@ export declare class ContextImpl implements Context<ContextData> {
77
77
  */
78
78
  private readonly _segments;
79
79
  /**
80
- * Path this context's steps hang under. Empty on a root context; a fork/spawn child
80
+ * Path this context's steps hang under. Empty on a root context; an inParallel/spawn child
81
81
  * inherits its parent's current path plus a discriminator, so a path key stays unique
82
82
  * across the whole step tree rather than restarting per child context.
83
83
  * @internal
@@ -91,7 +91,7 @@ export declare class ContextImpl implements Context<ContextData> {
91
91
  private readonly _occurrences;
92
92
  /**
93
93
  * Completion ledger for the execution this context belongs to. Shared by reference
94
- * with fork/spawn children — one execution, one ledger.
94
+ * with inParallel/spawn children — one execution, one ledger.
95
95
  * @internal
96
96
  */
97
97
  readonly ledger?: StepLedger;
@@ -105,7 +105,7 @@ export declare class ContextImpl implements Context<ContextData> {
105
105
  span?: Span;
106
106
  channelStore?: ChannelStore;
107
107
  checkpointFn?: (ctx: Context) => Promise<void>;
108
- /** Path this context's steps hang under (fork/spawn children inherit one). */
108
+ /** Path this context's steps hang under (inParallel/spawn children inherit one). */
109
109
  pathPrefix?: string;
110
110
  /** The execution's completion ledger, shared with children by reference. */
111
111
  ledger?: StepLedger;
@@ -134,7 +134,7 @@ export declare class ContextImpl implements Context<ContextData> {
134
134
  /**
135
135
  * @internal
136
136
  * Leave the parent's abort cascade. Called by the interpreter when a spawn
137
- * child or fork path settles — a finished child has nothing left to cancel,
137
+ * child or inParallel path settles — a finished child has nothing left to cancel,
138
138
  * and holding it would leak for the remaining life of the parent.
139
139
  */
140
140
  detachFromParent(): void;
@@ -150,8 +150,6 @@ export declare class ContextImpl implements Context<ContextData> {
150
150
  get shell(): AgentHarnessContract['shell'];
151
151
  get subprocess(): AgentHarnessContract['subprocess'];
152
152
  get context(): ContextData;
153
- /** @deprecated Renamed to `context`. Returns the same object. */
154
- get memory(): ContextData;
155
153
  recv<T>(ch: Channel<T>, opts?: {
156
154
  timeout?: number;
157
155
  }): Promise<T>;
@@ -55,8 +55,8 @@ export class ContextImpl {
55
55
  _createdAt;
56
56
  /**
57
57
  * Shared channel store for cross-context communication. Inherited by
58
- * `fork` / `spawn` children so channels published by a sibling are visible
59
- * to peers — see `executeFork` and `executeSpawn` in `interpreter/execute-action.ts`
58
+ * `inParallel` / `spawn` children so channels published by a sibling are visible
59
+ * to peers — see `executeInParallel` and `executeSpawn` in `interpreter/execute-action.ts`
60
60
  * and `interpreter/execute-control.ts`.
61
61
  * @internal
62
62
  */
@@ -70,14 +70,14 @@ export class ContextImpl {
70
70
  * Per-context abort fan-out. `abort()` fires it so operations blocked on
71
71
  * this context (channel `recv` waiters, parked back-pressure senders)
72
72
  * reject promptly with `{ kind: 'cancelled' }` instead of hanging until
73
- * their timeout (spec 09, Cancellation item 2). Each fork/spawn child
73
+ * their timeout (spec 09, Cancellation item 2). Each inParallel/spawn child
74
74
  * constructs its own ContextImpl and therefore its own controller —
75
75
  * aborting a child never rejects the parent's waiters, while aborting a
76
76
  * parent DOES cascade down to every live child (see `_children`).
77
77
  */
78
78
  _abortController = new AbortController();
79
79
  /**
80
- * Live child contexts (fork paths, spawn children) registered for the abort
80
+ * Live child contexts (inParallel paths, spawn children) registered for the abort
81
81
  * cascade. A child adds itself at construction and removes itself via
82
82
  * `detachFromParent()` when its execution settles, so a long-lived parent
83
83
  * driving a loop of spawns does not accumulate finished children.
@@ -101,7 +101,7 @@ export class ContextImpl {
101
101
  */
102
102
  _segments = [];
103
103
  /**
104
- * Path this context's steps hang under. Empty on a root context; a fork/spawn child
104
+ * Path this context's steps hang under. Empty on a root context; an inParallel/spawn child
105
105
  * inherits its parent's current path plus a discriminator, so a path key stays unique
106
106
  * across the whole step tree rather than restarting per child context.
107
107
  * @internal
@@ -115,7 +115,7 @@ export class ContextImpl {
115
115
  _occurrences = new Map();
116
116
  /**
117
117
  * Completion ledger for the execution this context belongs to. Shared by reference
118
- * with fork/spawn children — one execution, one ledger.
118
+ * with inParallel/spawn children — one execution, one ledger.
119
119
  * @internal
120
120
  */
121
121
  ledger;
@@ -170,7 +170,7 @@ export class ContextImpl {
170
170
  /**
171
171
  * @internal
172
172
  * Leave the parent's abort cascade. Called by the interpreter when a spawn
173
- * child or fork path settles — a finished child has nothing left to cancel,
173
+ * child or inParallel path settles — a finished child has nothing left to cancel,
174
174
  * and holding it would leak for the remaining life of the parent.
175
175
  */
176
176
  detachFromParent() {
@@ -209,10 +209,6 @@ export class ContextImpl {
209
209
  }
210
210
  return this._contextData;
211
211
  }
212
- /** @deprecated Renamed to `context`. Returns the same object. */
213
- get memory() {
214
- return this.context;
215
- }
216
212
  recv(ch, opts) {
217
213
  if (!this.channelStore) {
218
214
  return Promise.reject(new Error('No channel store configured'));
@@ -265,7 +261,7 @@ export class ContextImpl {
265
261
  // Reject everything blocked on this context (channel recv waiters,
266
262
  // parked back-pressure senders) with { kind: 'cancelled' }.
267
263
  this._abortController.abort(reason ?? 'context aborted');
268
- // Cascade to live children (fork paths, spawn children). The registry is
264
+ // Cascade to live children (inParallel paths, spawn children). The registry is
269
265
  // cleared first so a child's own `detachFromParent()` during its unwind
270
266
  // cannot mutate the set we are iterating.
271
267
  const children = [
@@ -4,7 +4,7 @@
4
4
  * The frontier records which steps were IN FLIGHT at snapshot time; it says nothing
5
5
  * about which ones finished, and a finished step leaves no trace once `leaveStep` pops
6
6
  * it. Resume therefore needs a separate record — and it must carry each step's OUTPUT,
7
- * not merely a "done" flag: steps consume the previous step's value, and an `llm` step
7
+ * not merely a "done" flag: steps consume the previous step's value, and a `callModel` step
8
8
  * re-run to catch up produces a different one than the rest of the run already saw.
9
9
  *
10
10
  * Entries are stored one key per step so appends are O(1). Folding the whole ledger
@@ -124,7 +124,7 @@ export interface StepLedgerStats {
124
124
  * The in-memory ledger a single execution carries: entries recovered from a previous
125
125
  * run (available for replay) plus the sequence counter for newly recorded ones.
126
126
  *
127
- * Shared by reference across fork/spawn children so one execution has one ledger —
127
+ * Shared by reference across inParallel/spawn children so one execution has one ledger —
128
128
  * path keys are globally unique across the step tree, so a flat map is correct. That
129
129
  * sharing is also why retention lives here rather than in the store: the sequence
130
130
  * cursor eviction walks belongs to the execution, not to the harness.
@@ -4,7 +4,7 @@
4
4
  * The frontier records which steps were IN FLIGHT at snapshot time; it says nothing
5
5
  * about which ones finished, and a finished step leaves no trace once `leaveStep` pops
6
6
  * it. Resume therefore needs a separate record — and it must carry each step's OUTPUT,
7
- * not merely a "done" flag: steps consume the previous step's value, and an `llm` step
7
+ * not merely a "done" flag: steps consume the previous step's value, and a `callModel` step
8
8
  * re-run to catch up produces a different one than the rest of the run already saw.
9
9
  *
10
10
  * Entries are stored one key per step so appends are O(1). Folding the whole ledger
@@ -156,7 +156,7 @@ export function createStepLedgerStore(opts) {
156
156
  * The in-memory ledger a single execution carries: entries recovered from a previous
157
157
  * run (available for replay) plus the sequence counter for newly recorded ones.
158
158
  *
159
- * Shared by reference across fork/spawn children so one execution has one ledger —
159
+ * Shared by reference across inParallel/spawn children so one execution has one ledger —
160
160
  * path keys are globally unique across the step tree, so a flat map is correct. That
161
161
  * sharing is also why retention lives here rather than in the store: the sequence
162
162
  * cursor eviction walks belongs to the execution, not to the harness.
@@ -230,7 +230,7 @@ export class StepLedger {
230
230
  if (!this.retainable(entry)) {
231
231
  return;
232
232
  }
233
- /* Reserve the sequence number BEFORE awaiting: concurrent fork legs record through
233
+ /* Reserve the sequence number BEFORE awaiting: concurrent inParallel legs record through
234
234
  * the one shared ledger, and two of them reading the same counter would write the
235
235
  * same key, silently overwriting a sibling's entry. A write that then fails leaves a
236
236
  * gap, which only makes the window below a slight over-estimate of the live count —
@@ -1,4 +1,4 @@
1
- import type { Context, HarnessResponse, HarnessStatus, Item } from '@noetic-tools/types';
1
+ import type { Context, HarnessResponse, HarnessStatus, Item, SessionUsage } from '@noetic-tools/types';
2
2
  import { EventBroadcaster } from './event-broadcaster.js';
3
3
  import type { QueuedMessage } from './message-queue.js';
4
4
  import { MessageQueue } from './message-queue.js';
@@ -46,6 +46,15 @@ export declare class SessionRunner {
46
46
  private readonly runTurn;
47
47
  private readonly createContext;
48
48
  private status;
49
+ /** Cumulative token/cost accounting across every turn this session has run,
50
+ * including turns that failed or were aborted after partial model work. */
51
+ private totalInputTokens;
52
+ private totalOutputTokens;
53
+ /** `undefined` until some turn reports a cache figure, so a provider that
54
+ * explicitly reported 0 cached tokens stays distinguishable from a provider
55
+ * that reports nothing about caching at all (see `SessionUsage`). */
56
+ private totalCachedTokens;
57
+ private totalCost;
49
58
  private currentController?;
50
59
  private currentCtx?;
51
60
  private loopPromise?;
@@ -54,6 +63,8 @@ export declare class SessionRunner {
54
63
  private readonly responseWaiters;
55
64
  constructor(opts: SessionRunnerOpts);
56
65
  getStatus(): HarnessStatus;
66
+ /** Cumulative token usage and cost across all turns this session has run. */
67
+ getUsage(): SessionUsage;
57
68
  /** Resolves once the queue has been drained and the runner is idle with a
58
69
  * response available. If nothing has run yet, waits for the first turn.
59
70
  *
@@ -64,6 +64,15 @@ export class SessionRunner {
64
64
  status = {
65
65
  kind: 'idle',
66
66
  };
67
+ /** Cumulative token/cost accounting across every turn this session has run,
68
+ * including turns that failed or were aborted after partial model work. */
69
+ totalInputTokens = 0;
70
+ totalOutputTokens = 0;
71
+ /** `undefined` until some turn reports a cache figure, so a provider that
72
+ * explicitly reported 0 cached tokens stays distinguishable from a provider
73
+ * that reports nothing about caching at all (see `SessionUsage`). */
74
+ totalCachedTokens;
75
+ totalCost = 0;
67
76
  currentController;
68
77
  currentCtx;
69
78
  loopPromise;
@@ -82,6 +91,15 @@ export class SessionRunner {
82
91
  getStatus() {
83
92
  return this.status;
84
93
  }
94
+ /** Cumulative token usage and cost across all turns this session has run. */
95
+ getUsage() {
96
+ return {
97
+ inputTokens: this.totalInputTokens,
98
+ outputTokens: this.totalOutputTokens,
99
+ cachedTokens: this.totalCachedTokens,
100
+ cost: this.totalCost > 0 ? this.totalCost : undefined,
101
+ };
102
+ }
85
103
  /** Resolves once the queue has been drained and the runner is idle with a
86
104
  * response available. If nothing has run yet, waits for the first turn.
87
105
  *
@@ -227,6 +245,16 @@ export class SessionRunner {
227
245
  this.rejectWaiters(error);
228
246
  }
229
247
  finally {
248
+ // Accumulate the turn's token accounting whatever the outcome — an
249
+ // aborted turn still consumed whatever the model billed before the cut.
250
+ this.totalInputTokens += ctx.tokens.input;
251
+ this.totalOutputTokens += ctx.tokens.output;
252
+ // Only ever leave `undefined` behind when NO turn reported a figure —
253
+ // a turn that reported 0 must surface as 0, not "unreported".
254
+ if (ctx.tokens.cached !== undefined) {
255
+ this.totalCachedTokens = (this.totalCachedTokens ?? 0) + ctx.tokens.cached;
256
+ }
257
+ this.totalCost += ctx.cost;
230
258
  this.currentCtx = undefined;
231
259
  this.currentController = undefined;
232
260
  this.status = {
@@ -255,7 +283,11 @@ function buildResponse(text, ctx) {
255
283
  usage: {
256
284
  inputTokens: ctx.tokens.input,
257
285
  outputTokens: ctx.tokens.output,
258
- cachedTokens: ctx.tokens.cached && ctx.tokens.cached > 0 ? ctx.tokens.cached : undefined,
286
+ // Passed through verbatim: `ctx.tokens.cached` is already
287
+ // undefined-unless-reported, so collapsing a reported 0 to `undefined`
288
+ // here would re-erase the distinction between "nothing was cached" and
289
+ // "this provider says nothing about caching". Matches `SessionUsage`.
290
+ cachedTokens: ctx.tokens.cached,
259
291
  },
260
292
  cost: ctx.cost > 0 ? ctx.cost : undefined,
261
293
  text,
@@ -16,8 +16,6 @@ export function buildToolExecutionContext(ctx, harness, turnContext) {
16
16
  fs: harness.fs,
17
17
  shell: harness.shell,
18
18
  context: toolContext,
19
- // Deprecated alias — same accessor object, not a copy.
20
- memory: toolContext,
21
19
  assembledView: ctx.itemLog.items,
22
20
  lastStepMeta: ctx.lastStepMeta,
23
21
  turnContext,
@@ -1,7 +1,7 @@
1
1
  /**
2
- * The JSON workflow schema lives in `@noetic-tools/types` so the memory
3
- * package (which must not import core) can validate workflow documents.
2
+ * The JSON workflow schema lives in `@noetic-tools/types` so portable
3
+ * consumers can validate workflow documents without importing core.
4
4
  * This barrel keeps core's public and intra-core import paths unchanged.
5
5
  */
6
- export type { BranchRoute, BranchWorkflowNode, EveryWorkflowNode, ForkWorkflowNode, LlmWorkflowNode, LoopWorkflowNode, OutputCodecRef, ProvideWorkflowNode, RunWorkflowNode, SequenceWorkflowNode, SpawnWorkflowNode, SubflowWorkflowNode, SubHarnessWorkflowNode, ToolWorkflowNode, UntilPredicate, WorkflowDocument, WorkflowGraph, WorkflowNode, } from '@noetic-tools/types';
6
+ export type { CallModelWorkflowNode, ConditionalRoute, ConditionalWorkflowNode, InParallelWorkflowNode, InvokeToolWorkflowNode, LoopWorkflowNode, OutputCodecRef, RunCodeWorkflowNode, ScheduleWorkflowNode, SequenceWorkflowNode, SpawnWorkflowNode, SubflowWorkflowNode, SubHarnessWorkflowNode, UntilPredicate, WithContextWorkflowNode, WorkflowDocument, WorkflowGraph, WorkflowNode, } from '@noetic-tools/types';
7
7
  export { MergeStrategy, MergeStrategySchema, UntilPredicateSchema, validateWorkflow, WorkflowDocumentSchema, WorkflowNodeSchema, walkWorkflow, workflowDepth, workflowGraph, } from '@noetic-tools/types';
@@ -1,6 +1,6 @@
1
1
  /**
2
- * The JSON workflow schema lives in `@noetic-tools/types` so the memory
3
- * package (which must not import core) can validate workflow documents.
2
+ * The JSON workflow schema lives in `@noetic-tools/types` so portable
3
+ * consumers can validate workflow documents without importing core.
4
4
  * This barrel keeps core's public and intra-core import paths unchanged.
5
5
  */
6
6
  export { MergeStrategy, MergeStrategySchema, UntilPredicateSchema, validateWorkflow, WorkflowDocumentSchema, WorkflowNodeSchema, walkWorkflow, workflowDepth, workflowGraph, } from '@noetic-tools/types';
@@ -5,8 +5,17 @@ import { z } from 'zod';
5
5
  * backward-incompatible change lands. `restore()` refuses to load snapshots
6
6
  * whose version is not recognised and surfaces a typed `NoeticConfigError`
7
7
  * (`code === 'CHECKPOINT_SCHEMA_MISMATCH'`) so hosts can discard cleanly.
8
+ *
9
+ * Version history:
10
+ * - v1 → v2: built-in layer ids changed (`working-context` → `scratchpad`,
11
+ * `static-content` → `instructions`, `observational-context` →
12
+ * `observations`, `file-reference` → `filesystem`, `history-window` →
13
+ * `history`, and `durable-task-state` → `task-state`). `layers` is keyed by
14
+ * layer id, so a v1 snapshot carries state under ids no current layer reads
15
+ * — restoring it would silently drop that state. There is no migration;
16
+ * discard via `CheckpointStore.clear()` and start fresh.
8
17
  */
9
- export declare const CheckpointSchemaVersion = 1;
18
+ export declare const CheckpointSchemaVersion = 2;
10
19
  /**
11
20
  * @public
12
21
  * One entry in the execution frontier — a pointer to a step currently in
@@ -70,7 +79,7 @@ export type ItemLogSnapshot = z.infer<typeof ItemLogSnapshotSchema>;
70
79
  * instead of producing a silently corrupt restored context.
71
80
  */
72
81
  export declare const CheckpointSnapshotSchema: z.ZodObject<{
73
- schemaVersion: z.ZodLiteral<1>;
82
+ schemaVersion: z.ZodLiteral<2>;
74
83
  executionId: z.ZodString;
75
84
  threadId: z.ZodOptional<z.ZodString>;
76
85
  resourceId: z.ZodOptional<z.ZodString>;
@@ -6,8 +6,17 @@ import { z } from 'zod';
6
6
  * backward-incompatible change lands. `restore()` refuses to load snapshots
7
7
  * whose version is not recognised and surfaces a typed `NoeticConfigError`
8
8
  * (`code === 'CHECKPOINT_SCHEMA_MISMATCH'`) so hosts can discard cleanly.
9
+ *
10
+ * Version history:
11
+ * - v1 → v2: built-in layer ids changed (`working-context` → `scratchpad`,
12
+ * `static-content` → `instructions`, `observational-context` →
13
+ * `observations`, `file-reference` → `filesystem`, `history-window` →
14
+ * `history`, and `durable-task-state` → `task-state`). `layers` is keyed by
15
+ * layer id, so a v1 snapshot carries state under ids no current layer reads
16
+ * — restoring it would silently drop that state. There is no migration;
17
+ * discard via `CheckpointStore.clear()` and start fresh.
9
18
  */
10
- export const CheckpointSchemaVersion = 1;
19
+ export const CheckpointSchemaVersion = 2;
11
20
  /**
12
21
  * @public
13
22
  * One entry in the execution frontier — a pointer to a step currently in
@@ -201,7 +201,7 @@ export class DetachedHandleImpl {
201
201
  kind: 'handle_evicted',
202
202
  handleId: initialHandle.id,
203
203
  stepId: this._stepId,
204
- gracePeriodMs: HANDLE_EVICTED_GRACE_MS,
204
+ gracePeriod: HANDLE_EVICTED_GRACE_MS,
205
205
  });
206
206
  }
207
207
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noetic-tools/core",
3
- "version": "5.2.0",
3
+ "version": "5.4.0",
4
4
  "type": "module",
5
5
  "description": "Step primitives, interpreter, runtime, and context layer contract for Noetic agents.",
6
6
  "license": "Apache-2.0",
@@ -54,7 +54,9 @@
54
54
  },
55
55
  "devDependencies": {
56
56
  "@openrouter/agent": "^0.6.0",
57
- "bun-types": "latest"
57
+ "@valibot/to-json-schema": "1.7.1",
58
+ "bun-types": "latest",
59
+ "valibot": "1.4.2"
58
60
  },
59
61
  "peerDependencies": {
60
62
  "@openrouter/agent": "^0.6.0",
@@ -66,8 +68,8 @@
66
68
  }
67
69
  },
68
70
  "dependencies": {
69
- "@noetic-tools/context": "^1.1.0",
70
- "@noetic-tools/types": "^3.0.0",
71
+ "@noetic-tools/context": "^1.2.1",
72
+ "@noetic-tools/types": "^3.2.1",
71
73
  "@openrouter/agent": "^0.6.0",
72
74
  "zod": "^4.0.0"
73
75
  },
@@ -26,7 +26,7 @@
26
26
  "properties": {
27
27
  "kind": {
28
28
  "type": "string",
29
- "const": "llm"
29
+ "const": "callModel"
30
30
  },
31
31
  "id": {
32
32
  "type": "string",
@@ -118,7 +118,7 @@
118
118
  "properties": {
119
119
  "kind": {
120
120
  "type": "string",
121
- "const": "tool"
121
+ "const": "invokeTool"
122
122
  },
123
123
  "id": {
124
124
  "type": "string",
@@ -148,7 +148,7 @@
148
148
  "properties": {
149
149
  "kind": {
150
150
  "type": "string",
151
- "const": "run"
151
+ "const": "runCode"
152
152
  },
153
153
  "id": {
154
154
  "type": "string",
@@ -207,7 +207,7 @@
207
207
  "properties": {
208
208
  "kind": {
209
209
  "type": "string",
210
- "const": "branch"
210
+ "const": "conditional"
211
211
  },
212
212
  "id": {
213
213
  "type": "string",
@@ -250,7 +250,7 @@
250
250
  "properties": {
251
251
  "kind": {
252
252
  "type": "string",
253
- "const": "fork"
253
+ "const": "inParallel"
254
254
  },
255
255
  "id": {
256
256
  "type": "string",
@@ -338,7 +338,7 @@
338
338
  "properties": {
339
339
  "kind": {
340
340
  "type": "string",
341
- "const": "provide"
341
+ "const": "withContext"
342
342
  },
343
343
  "id": {
344
344
  "type": "string",
@@ -426,7 +426,7 @@
426
426
  "properties": {
427
427
  "kind": {
428
428
  "type": "string",
429
- "const": "every"
429
+ "const": "schedule"
430
430
  },
431
431
  "id": {
432
432
  "type": "string",
@@ -435,7 +435,7 @@
435
435
  "step": {
436
436
  "$ref": "#/$defs/WorkflowNode"
437
437
  },
438
- "ms": {
438
+ "interval": {
439
439
  "type": "number",
440
440
  "minimum": 0
441
441
  },
@@ -451,7 +451,7 @@
451
451
  "kind",
452
452
  "id",
453
453
  "step",
454
- "ms"
454
+ "interval"
455
455
  ],
456
456
  "additionalProperties": false
457
457
  },
@@ -852,14 +852,14 @@
852
852
  "type": "string",
853
853
  "const": "maxDuration"
854
854
  },
855
- "ms": {
855
+ "duration": {
856
856
  "type": "number",
857
857
  "exclusiveMinimum": 0
858
858
  }
859
859
  },
860
860
  "required": [
861
861
  "kind",
862
- "ms"
862
+ "duration"
863
863
  ],
864
864
  "additionalProperties": false
865
865
  },
@@ -876,6 +876,19 @@
876
876
  ],
877
877
  "additionalProperties": false
878
878
  },
879
+ {
880
+ "type": "object",
881
+ "properties": {
882
+ "kind": {
883
+ "type": "string",
884
+ "const": "never"
885
+ }
886
+ },
887
+ "required": [
888
+ "kind"
889
+ ],
890
+ "additionalProperties": false
891
+ },
879
892
  {
880
893
  "type": "object",
881
894
  "properties": {
@@ -1,23 +0,0 @@
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;
@@ -1,22 +0,0 @@
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,30 +0,0 @@
1
- /**
2
- * Deprecated aliases from the "memory layer" era of the framework.
3
- *
4
- * The layer system assembles the model's *context window* — recall, budget
5
- * allocation, history projection, the item-append pipeline — so it is named
6
- * after context, not memory. Every name below still resolves to its
7
- * replacement; nothing here changes behaviour.
8
- *
9
- * Most of these are plain pass-throughs: the alias and its replacement already
10
- * live in `@noetic-tools/types` / `@noetic-tools/context`, and re-exporting
11
- * carries each name's `@deprecated` pointer along with it. Only the renaming
12
- * aliases — where core exports a symbol under a *different* name than its
13
- * source package does — are declared here.
14
- *
15
- * The matching runtime aliases (the `memory:` config key on `provide`/`spawn`/
16
- * `tool`/`react`/`AgentHarness`, and the `ctx.memory` accessor) are handled at
17
- * their call sites — see `resolveContextOption`.
18
- *
19
- * Scheduled for removal in the next major of `@noetic-tools/core`.
20
- */
21
- export type { ObservationalMemoryConfig, PlanMemoryConfig, TemporalMemoryConfig, WorkingMemoryConfig, WorkingMemoryState, } from '@noetic-tools/context';
22
- export { observationalMemory, planMemory, temporalMemory, toolMemoryLayer, workingMemory, } from '@noetic-tools/context';
23
- export type { ContextMemory, InferMemory, InferMemoryShape, MemoryCallModelRequest, MemoryConfig, MemoryHooks, MemoryLayer, MemoryScope, MemoryTraceSpan, ToolMemory, ToolMemoryDeclaration, } from '@noetic-tools/types';
24
- export {
25
- /**
26
- * @public
27
- * @deprecated Renamed to `context`. Declared here rather than re-exported
28
- * because the builder itself lives in core under its new name.
29
- */
30
- context as memory, } from './builders/context-builder.js';