@noetic-tools/context 1.2.1 → 1.3.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.
|
@@ -104,6 +104,7 @@ interface BeforeToolCallLayersParams {
|
|
|
104
104
|
layers: ContextLayer[];
|
|
105
105
|
toolName: string;
|
|
106
106
|
toolArgs: unknown;
|
|
107
|
+
callId?: string;
|
|
107
108
|
ctx: ExecutionContext;
|
|
108
109
|
store: LayerStateStore;
|
|
109
110
|
}
|
|
@@ -209,7 +210,7 @@ export declare function spawnLayers({ layers, parentCtx, childCtx, store, itemSc
|
|
|
209
210
|
}[]>;
|
|
210
211
|
export declare function returnLayers<T>({ layers, parentCtx, childCtx, childLog, result, store, }: ReturnLayersParams<T>): Promise<T>;
|
|
211
212
|
export declare function completeLayers({ layers, ctx, log, outcome, store, }: CompleteLayersParams): Promise<void>;
|
|
212
|
-
export declare function beforeToolCallLayers({ layers, toolName, toolArgs, ctx, store, }: BeforeToolCallLayersParams): Promise<SteeringDecision>;
|
|
213
|
+
export declare function beforeToolCallLayers({ layers, toolName, toolArgs, callId, ctx, store, }: BeforeToolCallLayersParams): Promise<SteeringDecision>;
|
|
213
214
|
export declare function afterModelCallLayers({ layers, response, ctx, store, }: AfterModelCallLayersParams): Promise<SteeringDecision>;
|
|
214
215
|
/**
|
|
215
216
|
* Run history items through every layer's `projectHistory` hook in slot order.
|
|
@@ -566,7 +566,7 @@ export async function completeLayers({ layers, ctx, log, outcome, store, }) {
|
|
|
566
566
|
}
|
|
567
567
|
await store.flush?.(ctx.executionId);
|
|
568
568
|
}
|
|
569
|
-
export async function beforeToolCallLayers({ layers, toolName, toolArgs, ctx, store, }) {
|
|
569
|
+
export async function beforeToolCallLayers({ layers, toolName, toolArgs, callId, ctx, store, }) {
|
|
570
570
|
const sorted = [
|
|
571
571
|
...layers,
|
|
572
572
|
].sort((a, b) => a.slot - b.slot);
|
|
@@ -589,6 +589,7 @@ export async function beforeToolCallLayers({ layers, toolName, toolArgs, ctx, st
|
|
|
589
589
|
const result = await withTimeout(layer.hooks.beforeToolCall({
|
|
590
590
|
toolName,
|
|
591
591
|
toolArgs,
|
|
592
|
+
callId,
|
|
592
593
|
ctx,
|
|
593
594
|
state,
|
|
594
595
|
}), timeout);
|
|
@@ -605,6 +606,15 @@ export async function beforeToolCallLayers({ layers, toolName, toolArgs, ctx, st
|
|
|
605
606
|
throw e;
|
|
606
607
|
}
|
|
607
608
|
store.diagnostic(layer.id, 'beforeToolCall', e);
|
|
609
|
+
// A permission GATE must fail closed: a hook that threw or timed out is
|
|
610
|
+
// a check that did not run, and for a gating layer that means deny, not
|
|
611
|
+
// the silent approval an abstention would collapse into.
|
|
612
|
+
if (layer.onBeforeToolCallError === 'deny') {
|
|
613
|
+
return {
|
|
614
|
+
action: SteeringAction.Deny,
|
|
615
|
+
guidance: `tool call denied: gating layer '${layer.id}' failed (${e instanceof Error ? e.message : String(e)})`,
|
|
616
|
+
};
|
|
617
|
+
}
|
|
608
618
|
}
|
|
609
619
|
}
|
|
610
620
|
return mostRestrictive(decisions);
|
|
@@ -218,9 +218,9 @@ const KIND_ENTRIES = [
|
|
|
218
218
|
line: '`runCode` — code in `execute`, run by a subprocess adapter the host must provide',
|
|
219
219
|
},
|
|
220
220
|
{
|
|
221
|
-
kind: '
|
|
221
|
+
kind: 'acp-agent',
|
|
222
222
|
group: 'leaf',
|
|
223
|
-
line: '`
|
|
223
|
+
line: '`acp-agent` — hand a `prompt` to an external coding agent named by `agent` (e.g. `claude-code`, `codex`, `gemini`)',
|
|
224
224
|
},
|
|
225
225
|
{
|
|
226
226
|
kind: 'sequence',
|
|
@@ -263,21 +263,12 @@ const KIND_ENTRIES = [
|
|
|
263
263
|
line: '`subflow` — run a named workflow by `ref`',
|
|
264
264
|
},
|
|
265
265
|
];
|
|
266
|
-
/** The harness kinds share one line, so they are folded into the `claude-code` entry. */
|
|
267
|
-
const HARNESS_KINDS = [
|
|
268
|
-
'claude-code',
|
|
269
|
-
'codex',
|
|
270
|
-
'opencode',
|
|
271
|
-
'pi',
|
|
272
|
-
];
|
|
273
266
|
function kindEntries(allowed) {
|
|
274
267
|
if (!allowed) {
|
|
275
268
|
return KIND_ENTRIES;
|
|
276
269
|
}
|
|
277
270
|
const permitted = new Set(allowed);
|
|
278
|
-
return KIND_ENTRIES.filter((entry) => entry.kind
|
|
279
|
-
? HARNESS_KINDS.some((kind) => permitted.has(kind))
|
|
280
|
-
: permitted.has(entry.kind));
|
|
271
|
+
return KIND_ENTRIES.filter((entry) => permitted.has(entry.kind));
|
|
281
272
|
}
|
|
282
273
|
function treeGuide(schemaUrl, allowed) {
|
|
283
274
|
const entries = kindEntries(allowed);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noetic-tools/context",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Context layer system for Noetic agents: the ContextLayer contract, lifecycle, budget/projection machinery, and built-in layer implementations.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"zod": "^4.0.0"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@noetic-tools/types": "^3.
|
|
47
|
+
"@noetic-tools/types": "^3.3.0",
|
|
48
48
|
"zod": "^4.0.0"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|