@noetic-tools/context 1.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 (49) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +28 -0
  3. package/dist/context/budget.d.ts +39 -0
  4. package/dist/context/budget.js +183 -0
  5. package/dist/context/exec-context-factory.d.ts +24 -0
  6. package/dist/context/exec-context-factory.js +30 -0
  7. package/dist/context/function-call-utils.d.ts +6 -0
  8. package/dist/context/function-call-utils.js +27 -0
  9. package/dist/context/layer-api.d.ts +11 -0
  10. package/dist/context/layer-api.js +91 -0
  11. package/dist/context/layer-lifecycle.d.ts +239 -0
  12. package/dist/context/layer-lifecycle.js +800 -0
  13. package/dist/context/layer-provides.d.ts +32 -0
  14. package/dist/context/layer-provides.js +33 -0
  15. package/dist/context/layer-usage.d.ts +13 -0
  16. package/dist/context/layer-usage.js +54 -0
  17. package/dist/context/layers/durable-task-state.d.ts +107 -0
  18. package/dist/context/layers/durable-task-state.js +250 -0
  19. package/dist/context/layers/file-reference.d.ts +55 -0
  20. package/dist/context/layers/file-reference.js +729 -0
  21. package/dist/context/layers/history-window.d.ts +31 -0
  22. package/dist/context/layers/history-window.js +150 -0
  23. package/dist/context/layers/observational-context.d.ts +56 -0
  24. package/dist/context/layers/observational-context.js +152 -0
  25. package/dist/context/layers/plan-context.d.ts +73 -0
  26. package/dist/context/layers/plan-context.js +749 -0
  27. package/dist/context/layers/static-content.d.ts +27 -0
  28. package/dist/context/layers/static-content.js +46 -0
  29. package/dist/context/layers/steering.d.ts +50 -0
  30. package/dist/context/layers/steering.js +291 -0
  31. package/dist/context/layers/temporal-context.d.ts +91 -0
  32. package/dist/context/layers/temporal-context.js +327 -0
  33. package/dist/context/layers/tool-context-layer.d.ts +15 -0
  34. package/dist/context/layers/tool-context-layer.js +43 -0
  35. package/dist/context/layers/working-memory-context.d.ts +46 -0
  36. package/dist/context/layers/working-memory-context.js +155 -0
  37. package/dist/context/projector.d.ts +19 -0
  38. package/dist/context/projector.js +89 -0
  39. package/dist/context/scope.d.ts +3 -0
  40. package/dist/context/scope.js +42 -0
  41. package/dist/context/storage-batch.d.ts +18 -0
  42. package/dist/context/storage-batch.js +35 -0
  43. package/dist/context/strip-unresolved.d.ts +13 -0
  44. package/dist/context/strip-unresolved.js +35 -0
  45. package/dist/deprecated.d.ts +43 -0
  46. package/dist/deprecated.js +28 -0
  47. package/dist/index.d.ts +29 -0
  48. package/dist/index.js +31 -0
  49. package/package.json +63 -0
@@ -0,0 +1,239 @@
1
+ import type { ContextLayer, ExecutionContext, Item, ItemLog, ItemSchemaRegistry, LLMResponse, ScopedStorage, SteeringDecision, StorageAdapter } from '@noetic-tools/types';
2
+ export interface LayerStateStore {
3
+ get<T>(executionId: string, layerId: string): T | undefined;
4
+ set<T>(executionId: string, layerId: string, state: T): void;
5
+ /**
6
+ * Whether ANY state entry exists for the (execution, layer) pair — including
7
+ * an explicit `undefined` written by a layer clearing its state. This is what
8
+ * lets the lifecycle distinguish "init never ran for this execution" (no
9
+ * entry → an init-bearing layer is skipped) from "layer legitimately cleared
10
+ * its state" (entry present → hooks keep running with `undefined` state).
11
+ * Optional so custom stores keep compiling; without it, the lifecycle falls
12
+ * back to the legacy sentinel (init-bearing layer with no state is skipped).
13
+ */
14
+ has?(executionId: string, layerId: string): boolean;
15
+ cleanup(executionId: string): void;
16
+ diagnostic: (layerId: string, hook: string, error: unknown) => void;
17
+ /**
18
+ * Register a durable write-through target for a layer's state under an
19
+ * execution. Once registered, EVERY `set()` for that (execution, layer) pair
20
+ * is asynchronously mirrored to `target` (key `'state'`); `set(…, undefined)`
21
+ * deletes the durable key. Writes are coalesced per key (latest wins) and
22
+ * mirror failures are reported via `diagnostic(layerId, 'persist', e)` —
23
+ * they never throw. Optional so custom stores keep compiling; without it,
24
+ * no durable mirroring occurs.
25
+ */
26
+ registerDurable?(executionId: string, layerId: string, target: ScopedStorage): void;
27
+ /** Await all in-flight durable mirror writes for an execution. */
28
+ flush?(executionId: string): Promise<void>;
29
+ /**
30
+ * Mark a layer disabled for an execution (its `init` failed with
31
+ * `onInitError: 'disable'`). Disabled layers are skipped by every later
32
+ * hook. Optional so custom stores keep compiling; without explicit
33
+ * tracking, the lifecycle falls back to the legacy sentinel (init-bearing
34
+ * layer with no state).
35
+ */
36
+ disable?(executionId: string, layerId: string): void;
37
+ /** Whether a layer was disabled for an execution. */
38
+ isDisabled?(executionId: string, layerId: string): boolean;
39
+ }
40
+ interface InitLayersParams {
41
+ layers: ContextLayer[];
42
+ ctx: ExecutionContext;
43
+ storage: StorageAdapter;
44
+ store: LayerStateStore;
45
+ }
46
+ interface RecallLayersParams {
47
+ layers: ContextLayer[];
48
+ query: string;
49
+ ctx: ExecutionContext;
50
+ log: ItemLog;
51
+ budgets: Map<string, number>;
52
+ store: LayerStateStore;
53
+ itemSchemas?: ItemSchemaRegistry;
54
+ }
55
+ interface StoreLayersParams {
56
+ layers: ContextLayer[];
57
+ response: LLMResponse;
58
+ ctx: ExecutionContext;
59
+ log: ItemLog;
60
+ store: LayerStateStore;
61
+ /**
62
+ * Unused by storeLayers itself — durable persistence is centralized in the
63
+ * state store's write-through (registered in `initLayers`). Accepted so
64
+ * existing call sites keep compiling.
65
+ */
66
+ storage?: StorageAdapter;
67
+ /** When provided, an eventual layer whose store produces new state is marked stale for the next recall. */
68
+ recallCache?: RecallCache;
69
+ }
70
+ interface SpawnLayersParams {
71
+ layers: ContextLayer[];
72
+ parentCtx: ExecutionContext;
73
+ childCtx: ExecutionContext;
74
+ store: LayerStateStore;
75
+ itemSchemas?: ItemSchemaRegistry;
76
+ /**
77
+ * When provided, durable write-through targets are registered for the child
78
+ * execution (non-execution scopes only), so state written during the child's
79
+ * run is mirrored durably just like the parent's.
80
+ */
81
+ storage?: StorageAdapter;
82
+ }
83
+ interface ReturnLayersParams<T = unknown> {
84
+ layers: ContextLayer[];
85
+ parentCtx: ExecutionContext;
86
+ childCtx: ExecutionContext;
87
+ childLog: ItemLog;
88
+ result: T;
89
+ store: LayerStateStore;
90
+ }
91
+ interface CompleteLayersParams {
92
+ layers: ContextLayer[];
93
+ ctx: ExecutionContext;
94
+ log: ItemLog;
95
+ outcome: 'success' | 'failure' | 'aborted';
96
+ store: LayerStateStore;
97
+ }
98
+ interface DisposeLayersParams {
99
+ layers: ContextLayer[];
100
+ ctx: ExecutionContext;
101
+ store: LayerStateStore;
102
+ }
103
+ interface BeforeToolCallLayersParams {
104
+ layers: ContextLayer[];
105
+ toolName: string;
106
+ toolArgs: unknown;
107
+ ctx: ExecutionContext;
108
+ store: LayerStateStore;
109
+ }
110
+ interface AfterModelCallLayersParams {
111
+ layers: ContextLayer[];
112
+ response: LLMResponse;
113
+ ctx: ExecutionContext;
114
+ store: LayerStateStore;
115
+ }
116
+ interface ProjectHistoryLayersParams {
117
+ layers: ContextLayer[];
118
+ items: ReadonlyArray<Item>;
119
+ ctx: ExecutionContext;
120
+ store: LayerStateStore;
121
+ }
122
+ /** @public A request to re-render the context window, collected from onItemAppend hooks. */
123
+ export interface RerenderRequest {
124
+ layerId: string;
125
+ slot: number;
126
+ timing: 'immediate' | 'batched';
127
+ scope: 'self' | 'slot-after' | 'all';
128
+ }
129
+ /** @public Result of running items through the onItemAppend pipeline. */
130
+ export interface AppendPipelineResult {
131
+ /** Final items to append after all transformations. */
132
+ items: Item[];
133
+ /** Re-render requests collected from layers. */
134
+ rerenderRequests: RerenderRequest[];
135
+ }
136
+ interface RunAppendPipelineParams {
137
+ layers: ContextLayer[];
138
+ items: Item[];
139
+ ctx: ExecutionContext;
140
+ log: ItemLog;
141
+ store: LayerStateStore;
142
+ }
143
+ interface ExecuteRerenderParams {
144
+ requests: RerenderRequest[];
145
+ layers: ContextLayer[];
146
+ ctx: ExecutionContext;
147
+ log: ItemLog;
148
+ budgets: Map<string, number>;
149
+ store: LayerStateStore;
150
+ itemSchemas?: ItemSchemaRegistry;
151
+ /** Query for context-aware recall (e.g., last user message) */
152
+ query?: string;
153
+ /** Current re-render depth (for loop protection) */
154
+ depth?: number;
155
+ }
156
+ export declare function createLayerStateStore(diagnostic?: (layerId: string, hook: string, error: unknown) => void): LayerStateStore;
157
+ interface RecallCacheEntry {
158
+ layerId: string;
159
+ items: Item[];
160
+ tokenCount: number;
161
+ }
162
+ /**
163
+ * Per-harness memoization for `recallMode: 'eventual'` layers. Eventual recall
164
+ * serves the cached entry when warm and re-runs only when `store()` produces new
165
+ * state (which marks the entry stale), so a slow layer's `recall()` does not run
166
+ * on every turn.
167
+ */
168
+ export interface RecallCache {
169
+ entries: Map<string, RecallCacheEntry>;
170
+ stale: Set<string>;
171
+ }
172
+ export declare function createRecallCache(): RecallCache;
173
+ export declare function mostRestrictive(decisions: SteeringDecision[]): SteeringDecision;
174
+ export declare function initLayers({ layers, ctx, storage, store }: InitLayersParams): Promise<void>;
175
+ export declare function recallLayers({ layers, query, ctx, log, budgets, store, itemSchemas, }: RecallLayersParams): Promise<{
176
+ layerId: string;
177
+ items: Item[];
178
+ tokenCount: number;
179
+ }[]>;
180
+ type RecallEntry = {
181
+ layerId: string;
182
+ items: Item[];
183
+ tokenCount: number;
184
+ };
185
+ interface RecallLayersModeParams extends RecallLayersParams {
186
+ /** When true, treat every layer as atomic regardless of its `recallMode`. */
187
+ forceAtomic?: boolean;
188
+ }
189
+ /**
190
+ * Recall the layers that must complete before the model call: those with
191
+ * `recallMode !== 'eventual'`, or every layer when `forceAtomic` is set.
192
+ */
193
+ export declare function recallLayersAtomic({ forceAtomic, ...params }: RecallLayersModeParams): Promise<RecallEntry[]>;
194
+ interface RecallLayersEventualParams extends RecallLayersModeParams {
195
+ cache: RecallCache;
196
+ }
197
+ /**
198
+ * Recall `recallMode: 'eventual'` layers, served from {@link RecallCache}.
199
+ * A cold or store-invalidated (stale) entry is recalled and cached; a warm
200
+ * entry is returned as-is, so an eventual layer's `recall()` runs only after
201
+ * its `store()` produces new state. Returns nothing when `forceAtomic` is set —
202
+ * those layers are then handled by {@link recallLayersAtomic} instead.
203
+ */
204
+ export declare function recallLayersEventual({ cache, forceAtomic, ...params }: RecallLayersEventualParams): Promise<RecallEntry[]>;
205
+ export declare function storeLayers({ layers, response, ctx, log, store, recallCache, }: StoreLayersParams): Promise<void>;
206
+ export declare function disposeLayers({ layers, ctx, store }: DisposeLayersParams): Promise<void>;
207
+ export declare function spawnLayers({ layers, parentCtx, childCtx, store, itemSchemas, storage, }: SpawnLayersParams): Promise<{
208
+ layerId: string;
209
+ childState: unknown;
210
+ items: Item[];
211
+ }[]>;
212
+ export declare function returnLayers<T>({ layers, parentCtx, childCtx, childLog, result, store, }: ReturnLayersParams<T>): Promise<T>;
213
+ export declare function completeLayers({ layers, ctx, log, outcome, store, }: CompleteLayersParams): Promise<void>;
214
+ export declare function beforeToolCallLayers({ layers, toolName, toolArgs, ctx, store, }: BeforeToolCallLayersParams): Promise<SteeringDecision>;
215
+ export declare function afterModelCallLayers({ layers, response, ctx, store, }: AfterModelCallLayersParams): Promise<SteeringDecision>;
216
+ /**
217
+ * Run history items through every layer's `projectHistory` hook in slot order.
218
+ * Each layer receives the previous layer's output. Storage (`itemLog`) is
219
+ * never mutated — this is a pure projection over the input array. Returns
220
+ * the projected items unchanged when no layer registers the hook.
221
+ */
222
+ export declare function projectHistoryLayers({ layers, items, ctx, store, }: ProjectHistoryLayersParams): Promise<ReadonlyArray<Item>>;
223
+ /**
224
+ * Run items through the onItemAppend pipeline.
225
+ * Each layer can filter, transform, or inject items.
226
+ * Returns final items to append and any re-render requests.
227
+ */
228
+ export declare function runAppendPipeline({ layers, items, ctx, log, store, }: RunAppendPipelineParams): Promise<AppendPipelineResult>;
229
+ /**
230
+ * Execute re-render based on collected requests.
231
+ * Determines which layers need re-recall based on scope and runs them.
232
+ * Returns new recall results to merge into view.
233
+ */
234
+ export declare function executeRerender({ requests, layers, ctx, log, budgets, store, itemSchemas, query, depth, }: ExecuteRerenderParams): Promise<{
235
+ layerId: string;
236
+ items: Item[];
237
+ tokenCount: number;
238
+ }[]>;
239
+ export {};