@noetic-tools/core 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { ItemSchemaRegistry } from '@noetic-tools/types';
2
2
  import type { DetachedSpawnOverrides } from './deps/interpreter.js';
3
3
  import type { LayerStateStore, RecallCache } from './deps/memory.js';
4
- import type { CheckpointStore, EventBroadcaster, StepLedgerStore } from './deps/runtime.js';
4
+ import type { CheckpointStore, EventBroadcaster, RestoreCheckpointOptions, StepLedgerStore } from './deps/runtime.js';
5
5
  import type { AgentConfig, AgentHarnessContract, AgentHooks, CallModelRequest, Channel, ChannelHandle, Context, ContextMemory, CwdState, DeliveryMode, DetachedHandle, ExecuteInput, ExecuteOptions, ExternalChannel, FsAdapter, HarnessResponse, HarnessStatus, Item, ItemSchemaExtensions, LLMResponse, LlmProviderConfig, MemoryLayer, ProjectionPolicy, RecallLayerOutput, SessionScope, ShellAdapter, Span, SteeringDecision, Step, StorageAdapter, StreamEvent, StreamingItem, SubHarnessSession, SubprocessAdapter, Tool, TraceExporter, ZodType } from './deps/types.js';
6
6
  export { createStreamIdleWatchdog } from './model-call.js';
7
7
  interface AgentHarnessOpts<TParams extends Record<string, unknown> = Record<string, unknown>> {
@@ -256,8 +256,20 @@ export declare class AgentHarness<TParams extends Record<string, unknown> = Reco
256
256
  * `NoeticConfigError(CHECKPOINT_SCHEMA_MISMATCH)` when the snapshot's
257
257
  * schema version is unrecognised — the caller is expected to discard the
258
258
  * checkpoint via `CheckpointStore.clear()` and start a fresh execution.
259
+ *
260
+ * `opts` is the `createContext`-shaped wiring the host attached to the
261
+ * original context (broadcaster, parent, state, memory overrides). A
262
+ * snapshot recovers data, not live objects — pass the same wiring here or
263
+ * the resumed run gets an undecorated context and whatever depended on that
264
+ * wiring (event streaming, mid-turn injection) stops working without
265
+ * failing. Fields the snapshot owns — items, threadId, resourceId, cwd —
266
+ * are not accepted; they always come from the persisted record.
267
+ *
268
+ * Decoration applied *after* construction (`Object.assign`ed fields, abort
269
+ * registration) stays the host's job: apply it to the context this returns,
270
+ * whose `id` is already the original `executionId`.
259
271
  */
260
- restore(executionId: string): Promise<Context | null>;
272
+ restore(executionId: string, opts?: RestoreCheckpointOptions): Promise<Context | null>;
261
273
  cancel(_ctx: Context, _reason?: string): Promise<void>;
262
274
  createSpan(name: string, parent: Span | null): Span;
263
275
  getLayerState<T>(executionId: string, layerId: string): T | undefined;
@@ -669,9 +669,21 @@ export class AgentHarness {
669
669
  * `NoeticConfigError(CHECKPOINT_SCHEMA_MISMATCH)` when the snapshot's
670
670
  * schema version is unrecognised — the caller is expected to discard the
671
671
  * checkpoint via `CheckpointStore.clear()` and start a fresh execution.
672
+ *
673
+ * `opts` is the `createContext`-shaped wiring the host attached to the
674
+ * original context (broadcaster, parent, state, memory overrides). A
675
+ * snapshot recovers data, not live objects — pass the same wiring here or
676
+ * the resumed run gets an undecorated context and whatever depended on that
677
+ * wiring (event streaming, mid-turn injection) stops working without
678
+ * failing. Fields the snapshot owns — items, threadId, resourceId, cwd —
679
+ * are not accepted; they always come from the persisted record.
680
+ *
681
+ * Decoration applied *after* construction (`Object.assign`ed fields, abort
682
+ * registration) stays the host's job: apply it to the context this returns,
683
+ * whose `id` is already the original `executionId`.
672
684
  */
673
- async restore(executionId) {
674
- return restoreFromCheckpoint(this, executionId);
685
+ async restore(executionId, opts) {
686
+ return restoreFromCheckpoint(this, executionId, opts);
675
687
  }
676
688
  //#endregion
677
689
  async cancel(_ctx, _reason) { }
@@ -2,6 +2,7 @@ export { ChannelStore } from '../../runtime/channel-store.js';
2
2
  export { ContextImpl } from '../../runtime/context-impl.js';
3
3
  export { snapshotCwdState } from '../../runtime/cwd-helpers.js';
4
4
  export type { CheckpointStore } from '../../runtime/durable/index.js';
5
+ export type { RestoreCheckpointOptions } from '../../runtime/durable/harness-checkpoints.js';
5
6
  export { captureCheckpoint, restoreFromCheckpoint, } from '../../runtime/durable/harness-checkpoints.js';
6
7
  export type { StepLedgerEntry, StepLedgerStore } from '../../runtime/durable/step-ledger.js';
7
8
  export { createStepLedgerStore, StepLedger } from '../../runtime/durable/step-ledger.js';
package/dist/index.d.ts CHANGED
@@ -121,7 +121,7 @@ export { isServerToolSpec } from '@noetic-tools/types';
121
121
  /** @public */
122
122
  /** @public */
123
123
  /** @public */
124
- export type { Context, ContextHarness, CwdState, ItemLog, LastLayerUsage, LayerUsageEntry, } from '@noetic-tools/types';
124
+ export type { Context, ContextHarness, CwdState, ItemLog, LastLayerUsage, LayerUsageEntry, RestoreContextOptions, } from '@noetic-tools/types';
125
125
  /** @public */
126
126
  export { getToolCwd, setToolCwd, snapshotCwdState } from './runtime/cwd-helpers.js';
127
127
  /** @public */
@@ -1,7 +1,20 @@
1
1
  import type { LayerStateStore, MemoryLayer } from '@noetic-tools/memory';
2
- import type { Context, Item, ItemSchemaRegistry } from '@noetic-tools/types';
2
+ import type { Context, Item, ItemSchemaRegistry, RestoreContextOptions } from '@noetic-tools/types';
3
+ import type { EventBroadcaster } from '../event-broadcaster.js';
3
4
  import type { CheckpointStore } from './checkpoint-store.js';
4
5
  import type { StepLedgerStore } from './step-ledger.js';
6
+ /**
7
+ * Host wiring forwarded into the context `restoreFromCheckpoint` builds.
8
+ * `RestoreContextOptions` covers the portable fields; core widens it with the
9
+ * internal `_broadcaster` seam so a resumed turn keeps streaming framework UI
10
+ * events.
11
+ *
12
+ * @internal
13
+ */
14
+ export type RestoreCheckpointOptions = RestoreContextOptions & {
15
+ /** @internal Event broadcaster the host attached to the original context. */
16
+ _broadcaster?: EventBroadcaster;
17
+ };
5
18
  /**
6
19
  * Minimum harness surface `captureCheckpoint` / `restoreFromCheckpoint`
7
20
  * require. `AgentHarness` already satisfies this shape via its
@@ -16,12 +29,11 @@ export interface CheckpointHarnessHandle {
16
29
  readonly layerStateStore: LayerStateStore;
17
30
  readonly itemSchemas: ItemSchemaRegistry;
18
31
  readonly _memory?: MemoryLayer[];
19
- createContext(opts?: {
32
+ createContext(opts?: RestoreCheckpointOptions & {
20
33
  items?: Item[];
21
34
  threadId?: string;
22
35
  resourceId?: string;
23
36
  cwdInit?: string;
24
- memory?: MemoryLayer[];
25
37
  }): Context;
26
38
  }
27
39
  /**
@@ -41,10 +53,18 @@ export declare function captureCheckpoint(h: CheckpointHarnessHandle, ctx: Conte
41
53
  * the restored context observes the pre-crash state through
42
54
  * `readLayerState` and the memory projectors.
43
55
  *
56
+ * `opts` carries the host's own context wiring (broadcaster, parent, state,
57
+ * layer overrides) into the rebuilt context. A snapshot cannot round-trip live
58
+ * objects, so a host that decorated the original context has to hand the same
59
+ * decoration back here — otherwise the resumed run gets a bare context and
60
+ * whatever depended on that wiring stops working silently. Snapshot-owned
61
+ * fields always win: identity, item log, and cwd come from the persisted
62
+ * record, never from `opts`.
63
+ *
44
64
  * Preserves the original executionId on the returned context via
45
65
  * `Object.defineProperty` — adapter correlation across crash/restart
46
66
  * requires a stable id.
47
67
  *
48
68
  * @internal
49
69
  */
50
- export declare function restoreFromCheckpoint(h: CheckpointHarnessHandle, executionId: string): Promise<Context | null>;
70
+ export declare function restoreFromCheckpoint(h: CheckpointHarnessHandle, executionId: string, opts?: RestoreCheckpointOptions): Promise<Context | null>;
@@ -65,13 +65,21 @@ export async function captureCheckpoint(h, ctx) {
65
65
  * the restored context observes the pre-crash state through
66
66
  * `readLayerState` and the memory projectors.
67
67
  *
68
+ * `opts` carries the host's own context wiring (broadcaster, parent, state,
69
+ * layer overrides) into the rebuilt context. A snapshot cannot round-trip live
70
+ * objects, so a host that decorated the original context has to hand the same
71
+ * decoration back here — otherwise the resumed run gets a bare context and
72
+ * whatever depended on that wiring stops working silently. Snapshot-owned
73
+ * fields always win: identity, item log, and cwd come from the persisted
74
+ * record, never from `opts`.
75
+ *
68
76
  * Preserves the original executionId on the returned context via
69
77
  * `Object.defineProperty` — adapter correlation across crash/restart
70
78
  * requires a stable id.
71
79
  *
72
80
  * @internal
73
81
  */
74
- export async function restoreFromCheckpoint(h, executionId) {
82
+ export async function restoreFromCheckpoint(h, executionId, opts) {
75
83
  const store = h.checkpointStore;
76
84
  if (!store) {
77
85
  return null;
@@ -85,12 +93,16 @@ export async function restoreFromCheckpoint(h, executionId) {
85
93
  }
86
94
  const items = h.itemSchemas.parseMany(snapshot.itemLog.items);
87
95
  const cwdInit = snapshot.cwd?.current ?? undefined;
96
+ /* Caller wiring first, snapshot second: a host may legitimately swap the memory
97
+ * layers or hang the restored execution under a new parent, but it must never be
98
+ * able to override the identity/history the snapshot is the record of. */
88
99
  const ctx = h.createContext({
100
+ ...opts,
89
101
  items,
90
102
  threadId: snapshot.threadId,
91
103
  resourceId: snapshot.resourceId,
92
104
  cwdInit,
93
- memory: h._memory,
105
+ memory: opts?.memory ?? h._memory,
94
106
  });
95
107
  if (ctx instanceof ContextImpl) {
96
108
  Object.defineProperty(ctx, 'id', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noetic-tools/core",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "type": "module",
5
5
  "description": "Step primitives, interpreter, runtime, and memory layer contract for Noetic agents.",
6
6
  "license": "Apache-2.0",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "dependencies": {
69
69
  "@noetic-tools/memory": "^2.0.0",
70
- "@noetic-tools/types": "^2.0.0",
70
+ "@noetic-tools/types": "^2.1.0",
71
71
  "@openrouter/agent": "^0.6.0",
72
72
  "zod": "^4.0.0"
73
73
  },