@noetic-tools/context 1.1.0 → 1.2.1
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.
- package/README.md +2 -3
- package/dist/context/cache-anchoring.d.ts +103 -0
- package/dist/context/cache-anchoring.js +273 -0
- package/dist/context/layer-lifecycle.d.ts +3 -5
- package/dist/context/layer-lifecycle.js +12 -2
- package/dist/context/layer-provides.d.ts +1 -1
- package/dist/context/layer-provides.js +1 -1
- package/dist/context/layer-usage.d.ts +18 -3
- package/dist/context/layer-usage.js +10 -1
- package/dist/context/layers/{file-reference.d.ts → filesystem.d.ts} +1 -1
- package/dist/context/layers/{file-reference.js → filesystem.js} +60 -3
- package/dist/context/layers/{history-window.d.ts → history.d.ts} +4 -4
- package/dist/context/layers/{history-window.js → history.js} +6 -6
- package/dist/context/layers/{static-content.d.ts → instructions.d.ts} +3 -2
- package/dist/context/layers/{static-content.js → instructions.js} +5 -2
- package/dist/context/layers/{observational-context.d.ts → observations.d.ts} +12 -12
- package/dist/context/layers/{observational-context.js → observations.js} +7 -7
- package/dist/context/layers/plan-prompts.d.ts +1 -1
- package/dist/context/layers/plan-prompts.js +16 -16
- package/dist/context/layers/plan-state.d.ts +31 -0
- package/dist/context/layers/plan-state.js +12 -0
- package/dist/context/layers/{plan-context.d.ts → plan.d.ts} +6 -28
- package/dist/context/layers/plan.js +697 -0
- package/dist/context/layers/{working-memory-context.d.ts → scratchpad.d.ts} +13 -13
- package/dist/context/layers/{working-memory-context.js → scratchpad.js} +8 -8
- package/dist/context/layers/steering.d.ts +1 -0
- package/dist/context/layers/steering.js +6 -1
- package/dist/context/layers/{durable-task-state.d.ts → task-state.d.ts} +20 -20
- package/dist/context/layers/{durable-task-state.js → task-state.js} +9 -9
- package/dist/context/layers/{temporal-context.d.ts → temporal.d.ts} +5 -5
- package/dist/context/layers/{temporal-context.js → temporal.js} +11 -5
- package/dist/context/layers/{tool-context-layer.d.ts → tool-calls.d.ts} +2 -2
- package/dist/context/layers/{tool-context-layer.js → tool-calls.js} +1 -1
- package/dist/context/projector.d.ts +27 -8
- package/dist/context/projector.js +42 -13
- package/dist/context/strip-unresolved.d.ts +1 -1
- package/dist/context/strip-unresolved.js +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +10 -10
- package/package.json +2 -2
- package/dist/context/layers/plan-context.js +0 -683
- package/dist/deprecated.d.ts +0 -43
- package/dist/deprecated.js +0 -28
|
@@ -32,8 +32,8 @@ const ANCHOR_SCAN_LIMIT = 4;
|
|
|
32
32
|
function validateMaxItems(value) {
|
|
33
33
|
if (!Number.isInteger(value) || value < MIN_MAX_ITEMS || value > MAX_MAX_ITEMS) {
|
|
34
34
|
throw new NoeticConfigError({
|
|
35
|
-
code: '
|
|
36
|
-
message: `
|
|
35
|
+
code: 'INVALID_HISTORY_MAX_ITEMS',
|
|
36
|
+
message: `history: maxItems must be an integer in [${MIN_MAX_ITEMS}, ${MAX_MAX_ITEMS}], got ${value}`,
|
|
37
37
|
hint: 'Pass a sensible cap such as { maxItems: 40 }, or omit the layer to keep history uncapped.',
|
|
38
38
|
});
|
|
39
39
|
}
|
|
@@ -94,19 +94,19 @@ function findHeadAnchor(items, windowStart) {
|
|
|
94
94
|
//#endregion
|
|
95
95
|
//#region Public API
|
|
96
96
|
/**
|
|
97
|
-
* Creates a history
|
|
97
|
+
* Creates a history context layer that caps the trailing items projected
|
|
98
98
|
* to the LLM. Storage stays unbounded; only the wire payload is narrowed.
|
|
99
99
|
*
|
|
100
100
|
* @public
|
|
101
101
|
* @param config - Optional `{ maxItems }`. Defaults to 40.
|
|
102
102
|
* @returns A `ContextLayer` that contributes only a `projectHistory` hook.
|
|
103
103
|
*/
|
|
104
|
-
export function
|
|
104
|
+
export function history(config) {
|
|
105
105
|
const maxItems = config?.maxItems ?? DEFAULT_MAX_ITEMS;
|
|
106
106
|
validateMaxItems(maxItems);
|
|
107
107
|
return {
|
|
108
|
-
id: 'history
|
|
109
|
-
name: 'History
|
|
108
|
+
id: 'history',
|
|
109
|
+
name: 'History',
|
|
110
110
|
slot: HISTORY_WINDOW_SLOT,
|
|
111
111
|
scope: 'execution',
|
|
112
112
|
hooks: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ContextScope } from '@noetic-tools/types';
|
|
2
|
-
interface
|
|
2
|
+
interface InstructionsOptions {
|
|
3
3
|
id?: string;
|
|
4
4
|
slot?: number;
|
|
5
5
|
scope?: ContextScope;
|
|
@@ -13,10 +13,11 @@ interface StaticContentOpts {
|
|
|
13
13
|
* @param opts - Configuration with a `load` function and optional id, slot, scope, and XML tag name.
|
|
14
14
|
* @returns A `ContextLayer` that provides static instructional content to the model.
|
|
15
15
|
*/
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function instructions(opts: InstructionsOptions): {
|
|
17
17
|
id: string;
|
|
18
18
|
slot: number;
|
|
19
19
|
scope: ContextScope;
|
|
20
|
+
placement: "anchor";
|
|
20
21
|
hooks: {
|
|
21
22
|
init(): Promise<{
|
|
22
23
|
state: string;
|
|
@@ -6,12 +6,15 @@ import { estimateTokens, Slot } from '@noetic-tools/types';
|
|
|
6
6
|
* @param opts - Configuration with a `load` function and optional id, slot, scope, and XML tag name.
|
|
7
7
|
* @returns A `ContextLayer` that provides static instructional content to the model.
|
|
8
8
|
*/
|
|
9
|
-
export function
|
|
9
|
+
export function instructions(opts) {
|
|
10
10
|
const tag = opts.tag ?? 'instructions';
|
|
11
11
|
return {
|
|
12
|
-
id: opts.id ?? '
|
|
12
|
+
id: opts.id ?? 'instructions',
|
|
13
13
|
slot: opts.slot ?? Slot.WORKING_MEMORY + 5,
|
|
14
14
|
scope: opts.scope ?? 'resource',
|
|
15
|
+
// Loaded once in `init` and never rewritten, so it can be pinned outright
|
|
16
|
+
// rather than waiting for churn telemetry to work that out.
|
|
17
|
+
placement: 'anchor',
|
|
15
18
|
hooks: {
|
|
16
19
|
async init() {
|
|
17
20
|
const raw = await opts.load();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export interface
|
|
1
|
+
export interface ObservationsState {
|
|
2
2
|
observations: string[];
|
|
3
3
|
buffer: string[];
|
|
4
4
|
bufferTokens: number;
|
|
5
5
|
version: number;
|
|
6
6
|
}
|
|
7
7
|
export type ObserverFn = (buffer: string[]) => Promise<string[]>;
|
|
8
|
-
export interface
|
|
8
|
+
export interface ObservationsConfig {
|
|
9
9
|
bufferThreshold?: number;
|
|
10
10
|
maxObservations?: number;
|
|
11
11
|
scope?: 'thread' | 'resource';
|
|
@@ -18,8 +18,8 @@ export interface ObservationalContextConfig {
|
|
|
18
18
|
* @param config - Optional configuration for buffer threshold, max observations, scope, and observer function.
|
|
19
19
|
* @returns A `ContextLayer` that accumulates and summarizes observations over time.
|
|
20
20
|
*/
|
|
21
|
-
export declare function
|
|
22
|
-
id: '
|
|
21
|
+
export declare function observations(config?: ObservationsConfig): {
|
|
22
|
+
id: 'observations';
|
|
23
23
|
name: string;
|
|
24
24
|
slot: 200;
|
|
25
25
|
scope: "resource" | "thread";
|
|
@@ -33,24 +33,24 @@ export declare function observationalContext(config?: ObservationalContextConfig
|
|
|
33
33
|
};
|
|
34
34
|
hooks: {
|
|
35
35
|
init({ storage }: import("@noetic-tools/types").InitParams): Promise<{
|
|
36
|
-
state:
|
|
36
|
+
state: ObservationsState;
|
|
37
37
|
}>;
|
|
38
|
-
recall({ state, budget }: import("@noetic-tools/types").RecallParams<
|
|
38
|
+
recall({ state, budget }: import("@noetic-tools/types").RecallParams<ObservationsState>): Promise<{
|
|
39
39
|
items: import("@noetic-tools/types").InputMessageItem[];
|
|
40
40
|
tokenCount: number;
|
|
41
41
|
} | null>;
|
|
42
|
-
store({ newItems, state }: import("@noetic-tools/types").StoreParams<
|
|
43
|
-
state:
|
|
42
|
+
store({ newItems, state }: import("@noetic-tools/types").StoreParams<ObservationsState>): Promise<{
|
|
43
|
+
state: ObservationsState;
|
|
44
44
|
}>;
|
|
45
|
-
onItemAppend({ items, state }: import("@noetic-tools/types").OnItemAppendParams<
|
|
45
|
+
onItemAppend({ items, state }: import("@noetic-tools/types").OnItemAppendParams<ObservationsState>): Promise<{
|
|
46
46
|
items: import("@noetic-tools/types").Item[];
|
|
47
47
|
state?: undefined;
|
|
48
48
|
} | {
|
|
49
49
|
items: import("@noetic-tools/types").Item[];
|
|
50
|
-
state:
|
|
50
|
+
state: ObservationsState;
|
|
51
51
|
}>;
|
|
52
|
-
onSpawn({ parentState }: import("@noetic-tools/types").SpawnParams<
|
|
53
|
-
childState:
|
|
52
|
+
onSpawn({ parentState }: import("@noetic-tools/types").SpawnParams<ObservationsState>): Promise<{
|
|
53
|
+
childState: ObservationsState;
|
|
54
54
|
}>;
|
|
55
55
|
};
|
|
56
56
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { collectInputText, collectOutputText, createMessage, estimateTokens, Slot, } from '@noetic-tools/types';
|
|
2
2
|
const DEFAULT_BUFFER_THRESHOLD_TOKENS = 2_000;
|
|
3
3
|
const DEFAULT_MAX_OBSERVATIONS = 50;
|
|
4
|
-
function
|
|
4
|
+
function emptyObservationsState() {
|
|
5
5
|
return {
|
|
6
6
|
observations: [],
|
|
7
7
|
buffer: [],
|
|
@@ -70,13 +70,13 @@ function renderObservationsWithinBudget(observations, budget) {
|
|
|
70
70
|
* @param config - Optional configuration for buffer threshold, max observations, scope, and observer function.
|
|
71
71
|
* @returns A `ContextLayer` that accumulates and summarizes observations over time.
|
|
72
72
|
*/
|
|
73
|
-
export function
|
|
73
|
+
export function observations(config) {
|
|
74
74
|
const maxObs = config?.maxObservations ?? DEFAULT_MAX_OBSERVATIONS;
|
|
75
75
|
const threshold = config?.bufferThreshold ?? DEFAULT_BUFFER_THRESHOLD_TOKENS;
|
|
76
76
|
const observer = config?.observer;
|
|
77
77
|
return {
|
|
78
|
-
id: '
|
|
79
|
-
name: '
|
|
78
|
+
id: 'observations',
|
|
79
|
+
name: 'Observations',
|
|
80
80
|
slot: Slot.OBSERVATIONS,
|
|
81
81
|
scope: config?.scope ?? 'resource',
|
|
82
82
|
budget: {
|
|
@@ -93,7 +93,7 @@ export function observationalContext(config) {
|
|
|
93
93
|
async init({ storage }) {
|
|
94
94
|
const saved = await storage.get('state');
|
|
95
95
|
return {
|
|
96
|
-
state: saved ??
|
|
96
|
+
state: saved ?? emptyObservationsState(),
|
|
97
97
|
};
|
|
98
98
|
},
|
|
99
99
|
async recall({ state, budget }) {
|
|
@@ -114,7 +114,7 @@ export function observationalContext(config) {
|
|
|
114
114
|
},
|
|
115
115
|
// Captures assistant output text.
|
|
116
116
|
async store({ newItems, state }) {
|
|
117
|
-
const s = state ??
|
|
117
|
+
const s = state ?? emptyObservationsState();
|
|
118
118
|
const texts = collectOutputText(newItems);
|
|
119
119
|
return {
|
|
120
120
|
state: await accumulate(s, texts, {
|
|
@@ -126,7 +126,7 @@ export function observationalContext(config) {
|
|
|
126
126
|
},
|
|
127
127
|
// Captures user input and tool output text (pass-through; no transform).
|
|
128
128
|
async onItemAppend({ items, state }) {
|
|
129
|
-
const s = state ??
|
|
129
|
+
const s = state ?? emptyObservationsState();
|
|
130
130
|
const texts = collectInputText(items);
|
|
131
131
|
if (texts.length === 0) {
|
|
132
132
|
return {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* one runs for a given phase.
|
|
14
14
|
*/
|
|
15
15
|
import type { WorkflowNode } from '@noetic-tools/types';
|
|
16
|
-
import type { PlanState } from './plan-
|
|
16
|
+
import type { PlanState } from './plan-state.js';
|
|
17
17
|
/** How the planning briefing shapes the turn. */
|
|
18
18
|
export declare const PlanStyle: {
|
|
19
19
|
/** Explore → design → review → write → exit. Best when the work's shape is known. */
|
|
@@ -203,19 +203,19 @@ Keep it scannable but executable. A reader should be able to skim the headers an
|
|
|
203
203
|
/** One line per node kind, split into the work itself and the shape it runs in. */
|
|
204
204
|
const KIND_ENTRIES = [
|
|
205
205
|
{
|
|
206
|
-
kind: '
|
|
206
|
+
kind: 'callModel',
|
|
207
207
|
group: 'leaf',
|
|
208
|
-
line: '`
|
|
208
|
+
line: '`callModel` — a model turn, driven by `instructions`; give it `tools` if it needs them',
|
|
209
209
|
},
|
|
210
210
|
{
|
|
211
|
-
kind: '
|
|
211
|
+
kind: 'invokeTool',
|
|
212
212
|
group: 'leaf',
|
|
213
|
-
line: '`
|
|
213
|
+
line: '`invokeTool` — one deterministic tool call: `toolName` plus `args`',
|
|
214
214
|
},
|
|
215
215
|
{
|
|
216
|
-
kind: '
|
|
216
|
+
kind: 'runCode',
|
|
217
217
|
group: 'leaf',
|
|
218
|
-
line: '`
|
|
218
|
+
line: '`runCode` — code in `execute`, run by a subprocess adapter the host must provide',
|
|
219
219
|
},
|
|
220
220
|
{
|
|
221
221
|
kind: 'claude-code',
|
|
@@ -228,14 +228,14 @@ const KIND_ENTRIES = [
|
|
|
228
228
|
line: '`sequence` — `steps` run in order, each fed the one before',
|
|
229
229
|
},
|
|
230
230
|
{
|
|
231
|
-
kind: '
|
|
231
|
+
kind: 'inParallel',
|
|
232
232
|
group: 'structure',
|
|
233
|
-
line: '`
|
|
233
|
+
line: '`inParallel` — `paths` run at once (or `each` over a runtime array); `mode` is `all`, `race` or `settle`, and `merge` says how the outputs of an `all` come back together',
|
|
234
234
|
},
|
|
235
235
|
{
|
|
236
|
-
kind: '
|
|
236
|
+
kind: 'conditional',
|
|
237
237
|
group: 'structure',
|
|
238
|
-
line: '`
|
|
238
|
+
line: '`conditional` — the FIRST route whose `match` appears in the input wins, case-insensitively, so order the routes narrowest first; `default` catches the rest',
|
|
239
239
|
},
|
|
240
240
|
{
|
|
241
241
|
kind: 'loop',
|
|
@@ -243,9 +243,9 @@ const KIND_ENTRIES = [
|
|
|
243
243
|
line: '`loop` — run `body`, then repeat while the `until` predicate does not hold; the body always runs at least once',
|
|
244
244
|
},
|
|
245
245
|
{
|
|
246
|
-
kind: '
|
|
246
|
+
kind: 'schedule',
|
|
247
247
|
group: 'structure',
|
|
248
|
-
line: '`
|
|
248
|
+
line: '`schedule` — run `step` on an `interval`, forever; nothing after it ever runs, so put it last',
|
|
249
249
|
},
|
|
250
250
|
{
|
|
251
251
|
kind: 'spawn',
|
|
@@ -253,9 +253,9 @@ const KIND_ENTRIES = [
|
|
|
253
253
|
line: '`spawn` — run `child` in an isolated context, so its work does not crowd this one',
|
|
254
254
|
},
|
|
255
255
|
{
|
|
256
|
-
kind: '
|
|
256
|
+
kind: 'withContext',
|
|
257
257
|
group: 'structure',
|
|
258
|
-
line: '`
|
|
258
|
+
line: '`withContext` — run `child` with a named set of context layers the host must have registered',
|
|
259
259
|
},
|
|
260
260
|
{
|
|
261
261
|
kind: 'subflow',
|
|
@@ -300,8 +300,8 @@ ${structure.join('\n')}
|
|
|
300
300
|
**Shaping it**
|
|
301
301
|
- Keep the tree the user reviews SMALL — about seven top-level nodes, readable at a glance. Push the mechanics down.
|
|
302
302
|
- Factor detail into named workflows: define each with \`plan/setWorkflow\` \`{ "name": "<slug>", "document": {...} }\` and point at it with \`{ "kind": "subflow", "id": "...", "ref": "<slug>" }\`. Named workflows may reference each other but must not form a cycle, and every ref must resolve or the exit is rejected.
|
|
303
|
-
-
|
|
304
|
-
- Prefer \`
|
|
303
|
+
- Fan out work that is genuinely independent; sequence work where one step needs the last one's output. Do not fan out for the look of it.
|
|
304
|
+
- Prefer \`invokeTool\` over \`callModel\` wherever the step is deterministic. A model turn that always does the same thing is a slow, expensive tool call.
|
|
305
305
|
- Always give a \`loop\` a \`maxIterations\`. Without one it stops at a hard ceiling of 1000 and fails the step.`;
|
|
306
306
|
}
|
|
307
307
|
const ACTIONS = `## Actions
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { WorkflowDocument } from '@noetic-tools/types';
|
|
2
|
+
/**
|
|
3
|
+
* Persisted state shared by the plan layer (`plan.ts`) and its prompt
|
|
4
|
+
* renderers (`plan-prompts.ts`). Lives in its own leaf module so the two can
|
|
5
|
+
* both depend on it without importing each other.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PlanPhase: {
|
|
8
|
+
readonly Idle: 'idle';
|
|
9
|
+
readonly Planning: 'planning';
|
|
10
|
+
readonly Executing: 'executing';
|
|
11
|
+
readonly Completed: 'completed';
|
|
12
|
+
readonly Failed: 'failed';
|
|
13
|
+
};
|
|
14
|
+
export type PlanPhase = (typeof PlanPhase)[keyof typeof PlanPhase];
|
|
15
|
+
export interface PlanExecutionEntry {
|
|
16
|
+
timestamp: number;
|
|
17
|
+
version: number;
|
|
18
|
+
outcome: 'success' | 'failure' | 'aborted';
|
|
19
|
+
}
|
|
20
|
+
export interface PlanState {
|
|
21
|
+
phase: PlanPhase;
|
|
22
|
+
prd: string | null;
|
|
23
|
+
/** The reviewed plan: a complete JSON workflow document. */
|
|
24
|
+
planTree: WorkflowDocument | null;
|
|
25
|
+
/** Named workflows referenced from the tree via `{ kind: 'subflow', ref }` nodes. */
|
|
26
|
+
workflows: Record<string, WorkflowDocument>;
|
|
27
|
+
executionLog: PlanExecutionEntry[];
|
|
28
|
+
version: number;
|
|
29
|
+
/** Identifier of the on-disk plan session (set by `onEnterSession` host callback). */
|
|
30
|
+
planSlug?: string | null;
|
|
31
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted state shared by the plan layer (`plan.ts`) and its prompt
|
|
3
|
+
* renderers (`plan-prompts.ts`). Lives in its own leaf module so the two can
|
|
4
|
+
* both depend on it without importing each other.
|
|
5
|
+
*/
|
|
6
|
+
export const PlanPhase = {
|
|
7
|
+
Idle: 'idle',
|
|
8
|
+
Planning: 'planning',
|
|
9
|
+
Executing: 'executing',
|
|
10
|
+
Completed: 'completed',
|
|
11
|
+
Failed: 'failed',
|
|
12
|
+
};
|
|
@@ -1,31 +1,9 @@
|
|
|
1
|
-
import type { ContextLayer, ContextScope,
|
|
1
|
+
import type { ContextLayer, ContextScope, WorkflowNode } from '@noetic-tools/types';
|
|
2
2
|
import { PlanStyle } from './plan-prompts.js';
|
|
3
|
+
import type { PlanState } from './plan-state.js';
|
|
3
4
|
export { PlanStyle } from './plan-prompts.js';
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
readonly Planning: 'planning';
|
|
7
|
-
readonly Executing: 'executing';
|
|
8
|
-
readonly Completed: 'completed';
|
|
9
|
-
readonly Failed: 'failed';
|
|
10
|
-
};
|
|
11
|
-
export type PlanPhase = (typeof PlanPhase)[keyof typeof PlanPhase];
|
|
12
|
-
export interface PlanExecutionEntry {
|
|
13
|
-
timestamp: number;
|
|
14
|
-
version: number;
|
|
15
|
-
outcome: 'success' | 'failure' | 'aborted';
|
|
16
|
-
}
|
|
17
|
-
export interface PlanState {
|
|
18
|
-
phase: PlanPhase;
|
|
19
|
-
prd: string | null;
|
|
20
|
-
/** The reviewed plan: a complete JSON workflow document. */
|
|
21
|
-
planTree: WorkflowDocument | null;
|
|
22
|
-
/** Named workflows referenced from the tree via `{ kind: 'subflow', ref }` nodes. */
|
|
23
|
-
workflows: Record<string, WorkflowDocument>;
|
|
24
|
-
executionLog: PlanExecutionEntry[];
|
|
25
|
-
version: number;
|
|
26
|
-
/** Identifier of the on-disk plan session (set by `onEnterSession` host callback). */
|
|
27
|
-
planSlug?: string | null;
|
|
28
|
-
}
|
|
5
|
+
export type { PlanExecutionEntry, PlanState } from './plan-state.js';
|
|
6
|
+
export { PlanPhase } from './plan-state.js';
|
|
29
7
|
/** Host-supplied callback invoked when entering plan mode. Returns a session identifier the host owns (e.g. on-disk dir slug). */
|
|
30
8
|
export type PlanEnterSessionCallback = () => Promise<{
|
|
31
9
|
slug: string;
|
|
@@ -37,7 +15,7 @@ export type PlanEnterSessionCallback = () => Promise<{
|
|
|
37
15
|
export type PlanExitCallback = (state: PlanState) => Promise<{
|
|
38
16
|
approved: boolean;
|
|
39
17
|
}>;
|
|
40
|
-
export interface
|
|
18
|
+
export interface PlanConfig {
|
|
41
19
|
scope?: ContextScope;
|
|
42
20
|
additionalAllowedTools?: string[];
|
|
43
21
|
maxPrdLength?: number;
|
|
@@ -86,4 +64,4 @@ export interface PlanContextConfig {
|
|
|
86
64
|
* @param config - Optional configuration for scope, allowed tools, and limits.
|
|
87
65
|
* @returns A `ContextLayer` providing plan mode, PRD storage, and execution tracking.
|
|
88
66
|
*/
|
|
89
|
-
export declare function
|
|
67
|
+
export declare function plan(config?: PlanConfig): ContextLayer<PlanState>;
|