@noetic-tools/context 1.8.0 → 1.9.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.
|
@@ -290,7 +290,7 @@ ${structure.join('\n')}
|
|
|
290
290
|
|
|
291
291
|
**Shaping it**
|
|
292
292
|
- Keep the tree the user reviews SMALL — about seven top-level nodes, readable at a glance. Push the mechanics down.
|
|
293
|
-
- 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
|
|
293
|
+
- 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, and may recurse (a workflow may call itself) as long as a branch eventually stops the recursion; every ref must resolve or the exit is rejected.
|
|
294
294
|
- 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.
|
|
295
295
|
- Prefer \`invokeTool\` over \`callModel\` wherever the step is deterministic. A model turn that always does the same thing is a slow, expensive tool call.
|
|
296
296
|
- Always give a \`loop\` a \`maxIterations\`. Without one it stops at a hard ceiling of 1000 and fails the step.`;
|
|
@@ -161,49 +161,6 @@ function findDanglingRefs(state) {
|
|
|
161
161
|
}
|
|
162
162
|
return dangling;
|
|
163
163
|
}
|
|
164
|
-
/**
|
|
165
|
-
* Detects a reference cycle among named workflows (self-reference included).
|
|
166
|
-
* Returns the cycle path for the rejection message, or null when acyclic.
|
|
167
|
-
*/
|
|
168
|
-
function findWorkflowCycle(workflows) {
|
|
169
|
-
const edges = new Map();
|
|
170
|
-
for (const [name, doc] of Object.entries(workflows)) {
|
|
171
|
-
edges.set(name, collectSubflowRefs(doc).filter((ref) => ref in workflows));
|
|
172
|
-
}
|
|
173
|
-
const visiting = new Set();
|
|
174
|
-
const done = new Set();
|
|
175
|
-
const path = [];
|
|
176
|
-
const visit = (name) => {
|
|
177
|
-
if (done.has(name)) {
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
if (visiting.has(name)) {
|
|
181
|
-
return [
|
|
182
|
-
...path.slice(path.indexOf(name)),
|
|
183
|
-
name,
|
|
184
|
-
];
|
|
185
|
-
}
|
|
186
|
-
visiting.add(name);
|
|
187
|
-
path.push(name);
|
|
188
|
-
for (const next of edges.get(name) ?? []) {
|
|
189
|
-
const cycle = visit(next);
|
|
190
|
-
if (cycle) {
|
|
191
|
-
return cycle;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
path.pop();
|
|
195
|
-
visiting.delete(name);
|
|
196
|
-
done.add(name);
|
|
197
|
-
return null;
|
|
198
|
-
};
|
|
199
|
-
for (const name of edges.keys()) {
|
|
200
|
-
const cycle = visit(name);
|
|
201
|
-
if (cycle) {
|
|
202
|
-
return cycle;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
164
|
function buildAllowedTools(config) {
|
|
208
165
|
if (!config?.additionalAllowedTools?.length) {
|
|
209
166
|
return ALLOWED_TOOLS_IN_PLAN_MODE;
|
|
@@ -462,13 +419,6 @@ async function executeExitPlanMode(args, state, options) {
|
|
|
462
419
|
state,
|
|
463
420
|
};
|
|
464
421
|
}
|
|
465
|
-
const cycle = findWorkflowCycle(state.workflows);
|
|
466
|
-
if (cycle) {
|
|
467
|
-
return {
|
|
468
|
-
result: `Cannot execute: workflows reference each other in a cycle: ${cycle.join(' -> ')}. Break the cycle before exiting.`,
|
|
469
|
-
state,
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
422
|
if (options.onExit) {
|
|
473
423
|
const { approved } = await options.onExit(state);
|
|
474
424
|
if (!approved) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noetic-tools/context",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.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.10.0",
|
|
48
48
|
"zod": "^4.0.0"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|