@noetic-tools/core 0.0.1 → 0.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.
- package/dist/adapters/in-memory-fs-adapter.js +1 -1
- package/dist/adapters/in-memory-subprocess/manifest-persistence.d.ts +8 -0
- package/dist/adapters/in-memory-subprocess/manifest-persistence.js +56 -0
- package/dist/adapters/in-memory-subprocess/metadata.d.ts +12 -0
- package/dist/adapters/in-memory-subprocess/metadata.js +58 -0
- package/dist/adapters/in-memory-subprocess/step-completion.d.ts +3 -0
- package/dist/adapters/in-memory-subprocess/step-completion.js +86 -0
- package/dist/adapters/in-memory-subprocess/types.d.ts +88 -0
- package/dist/adapters/in-memory-subprocess/types.js +2 -0
- package/dist/adapters/in-memory-subprocess-adapter.d.ts +12 -4
- package/dist/adapters/in-memory-subprocess-adapter.js +164 -55
- package/dist/adapters/openrouter.d.ts +11 -2
- package/dist/adapters/openrouter.js +66 -5
- package/dist/builders/control-flow-builders.js +8 -3
- package/dist/builders/every.js +4 -1
- package/dist/builders/layer-provides-builders.d.ts +1 -32
- package/dist/builders/layer-provides-builders.js +1 -33
- package/dist/builders/loop-builder.js +4 -1
- package/dist/builders/memory-builder.js +1 -1
- package/dist/builders/provide-builder.js +4 -1
- package/dist/builders/spawn-builder.d.ts +20 -7
- package/dist/builders/spawn-builder.js +16 -2
- package/dist/builders/step-builders.d.ts +49 -28
- package/dist/builders/step-builders.js +30 -11
- package/dist/builders/tool-builder.d.ts +5 -1
- package/dist/builders/tool-builder.js +2 -0
- package/dist/builders/workflow-hydrator.d.ts +38 -0
- package/dist/builders/workflow-hydrator.js +336 -0
- package/dist/conditions/conditions.js +1 -1
- package/dist/errors/noetic-error.js +2 -0
- package/dist/{runtime → harness}/agent-harness.d.ts +65 -45
- package/dist/harness/agent-harness.js +576 -0
- package/dist/harness/deps/adapters.d.ts +4 -0
- package/dist/harness/deps/adapters.js +4 -0
- package/dist/harness/deps/interpreter.d.ts +5 -0
- package/dist/harness/deps/interpreter.js +4 -0
- package/dist/harness/deps/memory.d.ts +5 -0
- package/dist/harness/deps/memory.js +4 -0
- package/dist/harness/deps/runtime.d.ts +10 -0
- package/dist/harness/deps/runtime.js +7 -0
- package/dist/harness/deps/types.d.ts +17 -0
- package/dist/harness/deps/types.js +1 -0
- package/dist/harness/model-call.d.ts +50 -0
- package/dist/harness/model-call.js +694 -0
- package/dist/harness/model-schema.d.ts +19 -0
- package/dist/harness/model-schema.js +46 -0
- package/dist/harness/step-bootstrap.d.ts +25 -0
- package/dist/harness/step-bootstrap.js +170 -0
- package/dist/index.d.ts +48 -12
- package/dist/index.js +29 -7
- package/dist/interpreter/action-deps.d.ts +12 -0
- package/dist/interpreter/action-deps.js +10 -0
- package/dist/interpreter/action-types.d.ts +8 -0
- package/dist/interpreter/action-types.js +1 -0
- package/dist/interpreter/collect-tools.d.ts +1 -1
- package/dist/interpreter/collect-tools.js +6 -2
- package/dist/interpreter/execute-action.d.ts +22 -0
- package/dist/interpreter/execute-action.js +527 -0
- package/dist/interpreter/{execute-every.d.ts → execute-control.d.ts} +7 -1
- package/dist/interpreter/execute-control.js +530 -0
- package/dist/interpreter/execute.d.ts +13 -0
- package/dist/interpreter/execute.js +151 -48
- package/dist/interpreter/message-helpers.d.ts +1 -9
- package/dist/interpreter/message-helpers.js +1 -42
- package/dist/interpreter/step-dispatcher.d.ts +61 -0
- package/dist/interpreter/step-dispatcher.js +67 -0
- package/dist/interpreter/typeguards.d.ts +3 -10
- package/dist/interpreter/typeguards.js +3 -20
- package/dist/{runtime → memory}/exec-context-factory.js +1 -1
- package/dist/memory/flow-schema.d.ts +52 -0
- package/dist/memory/flow-schema.js +102 -0
- package/dist/memory/function-call-utils.js +4 -2
- package/dist/memory/layer-api.d.ts +1 -1
- package/dist/memory/layer-api.js +2 -2
- package/dist/memory/layer-lifecycle.d.ts +1 -1
- package/dist/memory/layer-lifecycle.js +2 -2
- package/dist/memory/layer-provides.d.ts +32 -0
- package/dist/memory/layer-provides.js +33 -0
- package/dist/memory/layer-usage.d.ts +3 -2
- package/dist/memory/layer-usage.js +9 -3
- package/dist/memory/layers/durable-task-state.js +1 -1
- package/dist/memory/layers/file-reference.js +302 -246
- package/dist/memory/layers/history-window.js +1 -1
- package/dist/memory/layers/observational-memory.js +1 -2
- package/dist/memory/layers/plan.d.ts +1 -1
- package/dist/memory/layers/plan.js +13 -8
- package/dist/memory/layers/steering.js +1 -1
- package/dist/memory/layers/tool-memory-layer.d.ts +1 -1
- package/dist/memory/layers/working-memory.js +2 -2
- package/dist/patterns/dynamic-workflow.d.ts +55 -0
- package/dist/patterns/dynamic-workflow.js +194 -0
- package/dist/patterns/flow.d.ts +2 -52
- package/dist/patterns/flow.js +1 -103
- package/dist/patterns/interview.js +1 -1
- package/dist/patterns/plans.d.ts +3 -3
- package/dist/patterns/plans.js +3 -3
- package/dist/patterns/ralph-wiggum.d.ts +1 -1
- package/dist/patterns/react.d.ts +1 -1
- package/dist/portable/adapters.d.ts +6 -0
- package/dist/portable/adapters.js +6 -0
- package/dist/portable/ask-user.d.ts +4 -0
- package/dist/portable/ask-user.js +2 -0
- package/dist/portable/builders.d.ts +12 -0
- package/dist/portable/builders.js +12 -0
- package/dist/portable/memory-layers.d.ts +12 -0
- package/dist/portable/memory-layers.js +12 -0
- package/dist/portable/runtime.d.ts +4 -0
- package/dist/portable/runtime.js +4 -0
- package/dist/portable/until.d.ts +4 -0
- package/dist/portable/until.js +4 -0
- package/dist/portable.d.ts +8 -26
- package/dist/portable.js +8 -34
- package/dist/runtime/broadcaster-utils.d.ts +5 -1
- package/dist/runtime/broadcaster-utils.js +11 -6
- package/dist/runtime/channel-store.js +1 -1
- package/dist/runtime/context-deps.d.ts +4 -0
- package/dist/runtime/context-deps.js +2 -0
- package/dist/runtime/context-impl.d.ts +42 -12
- package/dist/runtime/context-impl.js +51 -4
- package/dist/runtime/context-type-deps.d.ts +14 -0
- package/dist/runtime/context-type-deps.js +1 -0
- package/dist/runtime/detached-handle.d.ts +50 -2
- package/dist/runtime/detached-handle.js +216 -12
- package/dist/runtime/durable/checkpoint-store.d.ts +38 -0
- package/dist/runtime/durable/checkpoint-store.js +101 -0
- package/dist/runtime/durable/detached-signal.d.ts +37 -0
- package/dist/runtime/durable/detached-signal.js +52 -0
- package/dist/runtime/durable/harness-checkpoints.d.ts +51 -0
- package/dist/runtime/durable/harness-checkpoints.js +104 -0
- package/dist/runtime/durable/index.d.ts +10 -0
- package/dist/runtime/durable/index.js +5 -0
- package/dist/runtime/durable/runnable-loop.d.ts +100 -0
- package/dist/runtime/durable/runnable-loop.js +90 -0
- package/dist/runtime/durable/session-seed.d.ts +28 -0
- package/dist/runtime/durable/session-seed.js +27 -0
- package/dist/runtime/durable/stall-nudge.d.ts +82 -0
- package/dist/runtime/durable/stall-nudge.js +87 -0
- package/dist/runtime/in-memory-storage.js +1 -1
- package/dist/runtime/item-log-impl.d.ts +1 -1
- package/dist/runtime/step-registry.d.ts +42 -0
- package/dist/runtime/step-registry.js +77 -0
- package/dist/schemas/workflow.d.ts +139 -0
- package/dist/schemas/workflow.js +232 -0
- package/dist/types/ask-user-types.d.ts +57 -0
- package/dist/types/ask-user-types.js +74 -0
- package/dist/types/checkpoint.d.ts +98 -0
- package/dist/types/checkpoint.js +81 -0
- package/dist/types/common.d.ts +1 -50
- package/dist/types/context-parts/item-log.d.ts +6 -0
- package/dist/types/context-parts/item-log.js +1 -0
- package/dist/types/context-parts/layer-usage.d.ts +18 -0
- package/dist/types/context-parts/layer-usage.js +1 -0
- package/dist/types/context.d.ts +135 -26
- package/dist/types/error.d.ts +15 -0
- package/dist/types/harness-result.d.ts +1 -1
- package/dist/types/items.d.ts +18 -2
- package/dist/types/memory-context.d.ts +39 -0
- package/dist/types/memory-context.js +1 -0
- package/dist/types/memory.d.ts +35 -65
- package/dist/types/runtime.d.ts +2 -1
- package/dist/types/steering.d.ts +1 -1
- package/dist/types/step-registrar.d.ts +46 -0
- package/dist/types/step-registrar.js +56 -0
- package/dist/types/step.d.ts +30 -5
- package/dist/types/subprocess-adapter.d.ts +119 -3
- package/dist/types/subprocess-adapter.js +2 -0
- package/dist/types/tool.d.ts +64 -0
- package/dist/types/tool.js +1 -0
- package/dist/unstable.d.ts +2 -2
- package/dist/unstable.js +2 -2
- package/dist/until/predicates.d.ts +9 -0
- package/dist/until/predicates.js +14 -0
- package/dist/util/message-helpers.d.ts +17 -0
- package/dist/util/message-helpers.js +64 -0
- package/package.json +1 -1
- package/dist/adapters/local-fs-adapter.d.ts +0 -3
- package/dist/adapters/local-fs-adapter.js +0 -43
- package/dist/adapters/local-shell-adapter.d.ts +0 -51
- package/dist/adapters/local-shell-adapter.js +0 -167
- package/dist/adapters/local-subprocess-adapter.d.ts +0 -16
- package/dist/adapters/local-subprocess-adapter.js +0 -187
- package/dist/interpreter/execute-branch.d.ts +0 -3
- package/dist/interpreter/execute-branch.js +0 -10
- package/dist/interpreter/execute-every.js +0 -143
- package/dist/interpreter/execute-fork.d.ts +0 -3
- package/dist/interpreter/execute-fork.js +0 -215
- package/dist/interpreter/execute-llm.d.ts +0 -4
- package/dist/interpreter/execute-llm.js +0 -217
- package/dist/interpreter/execute-loop.d.ts +0 -3
- package/dist/interpreter/execute-loop.js +0 -171
- package/dist/interpreter/execute-provide.d.ts +0 -10
- package/dist/interpreter/execute-provide.js +0 -64
- package/dist/interpreter/execute-run.d.ts +0 -3
- package/dist/interpreter/execute-run.js +0 -39
- package/dist/interpreter/execute-spawn.d.ts +0 -11
- package/dist/interpreter/execute-spawn.js +0 -113
- package/dist/interpreter/execute-tool.d.ts +0 -5
- package/dist/interpreter/execute-tool.js +0 -81
- package/dist/runtime/agent-harness.js +0 -1170
- /package/dist/{runtime → memory}/exec-context-factory.d.ts +0 -0
- /package/dist/{interpreter → util}/framework-cast.d.ts +0 -0
- /package/dist/{interpreter → util}/framework-cast.js +0 -0
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { isNoeticError, NoeticErrorImpl } from '../errors/noetic-error';
|
|
2
|
-
import { frameworkCast } from './framework-cast';
|
|
3
|
-
import { createMessage } from './message-helpers';
|
|
4
|
-
import { isMutableContext } from './typeguards';
|
|
5
|
-
//#endregion
|
|
6
|
-
//#region Helper Functions
|
|
7
|
-
function hasTextField(value) {
|
|
8
|
-
return typeof value === 'object' && value !== null && 'text' in value;
|
|
9
|
-
}
|
|
10
|
-
async function recvInboxWithTimeout(ctx, step) {
|
|
11
|
-
if (!step.inbox) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
if ((step.parkTimeout ?? 0) <= 0) {
|
|
15
|
-
return ctx.tryRecv(step.inbox);
|
|
16
|
-
}
|
|
17
|
-
try {
|
|
18
|
-
return await ctx.recv(step.inbox, {
|
|
19
|
-
timeout: step.parkTimeout,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
// Expected: channel_timeout error when parkTimeout expires with no message.
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
function prepareNextInput(step, lastOutput, verdict, ctx) {
|
|
28
|
-
if (step.prepareNext) {
|
|
29
|
-
return step.prepareNext(lastOutput, verdict, ctx);
|
|
30
|
-
}
|
|
31
|
-
// Requires I === O when prepareNext is omitted — the loop feeds output
|
|
32
|
-
// back as input. Callers must ensure I and O are compatible types.
|
|
33
|
-
return frameworkCast(lastOutput);
|
|
34
|
-
}
|
|
35
|
-
//#endregion
|
|
36
|
-
//#region Public API
|
|
37
|
-
export async function executeLoop(step, input, ctx, executeStep) {
|
|
38
|
-
const baseCtx = frameworkCast(ctx);
|
|
39
|
-
let currentInput = input;
|
|
40
|
-
let lastOutput;
|
|
41
|
-
let lastText = '';
|
|
42
|
-
const history = [];
|
|
43
|
-
const startTime = Date.now();
|
|
44
|
-
let stepCount = 0;
|
|
45
|
-
const maxIterations = step.maxIterations ?? 1e3;
|
|
46
|
-
const maxHistory = step.maxHistorySize ?? 100;
|
|
47
|
-
let totalIterations = 0;
|
|
48
|
-
// Validate maxIterations
|
|
49
|
-
if (!Number.isFinite(maxIterations) || maxIterations < 1) {
|
|
50
|
-
throw new NoeticErrorImpl({
|
|
51
|
-
kind: 'step_failed',
|
|
52
|
-
stepId: step.id,
|
|
53
|
-
cause: new Error(`Invalid maxIterations: ${step.maxIterations}`),
|
|
54
|
-
retriesExhausted: false,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
while (true) {
|
|
58
|
-
// Abort check at top of each iteration
|
|
59
|
-
if (ctx.aborted) {
|
|
60
|
-
throw new NoeticErrorImpl({
|
|
61
|
-
kind: 'cancelled',
|
|
62
|
-
reason: ctx.abortReason ?? 'context aborted',
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
// Enforce hard iteration ceiling (includes retries)
|
|
66
|
-
totalIterations++;
|
|
67
|
-
if (totalIterations > maxIterations) {
|
|
68
|
-
throw new NoeticErrorImpl({
|
|
69
|
-
kind: 'step_failed',
|
|
70
|
-
stepId: step.id,
|
|
71
|
-
cause: new Error(`Loop exceeded maximum iterations (${maxIterations})`),
|
|
72
|
-
retriesExhausted: false,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
// Execute body steps sequentially
|
|
76
|
-
let output;
|
|
77
|
-
try {
|
|
78
|
-
let stepOutput = currentInput;
|
|
79
|
-
for (const bodyStep of step.steps) {
|
|
80
|
-
stepOutput = await executeStep(bodyStep, frameworkCast(stepOutput), ctx);
|
|
81
|
-
}
|
|
82
|
-
output = frameworkCast(stepOutput);
|
|
83
|
-
stepCount++;
|
|
84
|
-
}
|
|
85
|
-
catch (e) {
|
|
86
|
-
if (!step.onError || !isNoeticError(e)) {
|
|
87
|
-
throw e;
|
|
88
|
-
}
|
|
89
|
-
const action = step.onError(e.noeticError, ctx);
|
|
90
|
-
if (action === 'retry') {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
if (action !== 'skip') {
|
|
94
|
-
throw e;
|
|
95
|
-
}
|
|
96
|
-
// Skip does not increment stepCount — it is not a successful execution.
|
|
97
|
-
if (lastOutput === undefined) {
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
output = lastOutput;
|
|
101
|
-
}
|
|
102
|
-
lastOutput = output;
|
|
103
|
-
history.push(output);
|
|
104
|
-
// Trim history if it exceeds maxHistorySize
|
|
105
|
-
if (history.length > maxHistory) {
|
|
106
|
-
history.splice(0, history.length - maxHistory);
|
|
107
|
-
}
|
|
108
|
-
// Extract text from output for snapshot
|
|
109
|
-
if (typeof output === 'string') {
|
|
110
|
-
lastText = output;
|
|
111
|
-
}
|
|
112
|
-
else if (hasTextField(output)) {
|
|
113
|
-
lastText = String(output.text);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
lastText = output === undefined ? '' : JSON.stringify(output);
|
|
117
|
-
}
|
|
118
|
-
// Build snapshot
|
|
119
|
-
const snapshot = {
|
|
120
|
-
stepCount,
|
|
121
|
-
tokens: {
|
|
122
|
-
...ctx.tokens,
|
|
123
|
-
},
|
|
124
|
-
elapsed: Date.now() - startTime,
|
|
125
|
-
cost: ctx.cost,
|
|
126
|
-
lastOutput: output,
|
|
127
|
-
lastText,
|
|
128
|
-
history: [
|
|
129
|
-
...history,
|
|
130
|
-
],
|
|
131
|
-
depth: ctx.depth,
|
|
132
|
-
lastStepMeta: isMutableContext(baseCtx) ? baseCtx.lastStepMeta : null,
|
|
133
|
-
};
|
|
134
|
-
// Evaluate until predicate
|
|
135
|
-
let verdict;
|
|
136
|
-
try {
|
|
137
|
-
verdict = await step.until(snapshot);
|
|
138
|
-
}
|
|
139
|
-
catch (predicateError) {
|
|
140
|
-
// Per spec: if until predicate throws, treat as stop
|
|
141
|
-
verdict = {
|
|
142
|
-
stop: true,
|
|
143
|
-
reason: `Predicate error: ${predicateError instanceof Error ? predicateError.message : String(predicateError)}`,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
if (verdict.stop) {
|
|
147
|
-
if (lastOutput === undefined) {
|
|
148
|
-
throw new NoeticErrorImpl({
|
|
149
|
-
kind: 'step_failed',
|
|
150
|
-
stepId: step.id,
|
|
151
|
-
cause: new Error('Loop completed with no successful output'),
|
|
152
|
-
retriesExhausted: false,
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
// Check inbox before truly stopping
|
|
156
|
-
if (step.inbox) {
|
|
157
|
-
const inboxMessage = await recvInboxWithTimeout(baseCtx, step);
|
|
158
|
-
if (inboxMessage !== null) {
|
|
159
|
-
baseCtx.itemLog.append(createMessage(inboxMessage, 'developer'));
|
|
160
|
-
// Continue the loop — don't stop
|
|
161
|
-
currentInput = prepareNextInput(step, lastOutput, verdict, ctx);
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return lastOutput;
|
|
166
|
-
}
|
|
167
|
-
// Prepare input for next iteration
|
|
168
|
-
currentInput = prepareNextInput(step, output, verdict, ctx);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
//#endregion
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { Context } from '../types/context';
|
|
2
|
-
import type { ExecuteStepFn, StepProvide } from '../types/step';
|
|
3
|
-
/**
|
|
4
|
-
* Executes a provide step by attaching memory layers to the current context
|
|
5
|
-
* without creating an isolated child context.
|
|
6
|
-
*
|
|
7
|
-
* Unlike spawn, provide does not create a new itemLog or clone state.
|
|
8
|
-
* Events flow through to the parent in real-time.
|
|
9
|
-
*/
|
|
10
|
-
export declare function executeProvide<TMemory, I, O>(step: StepProvide<TMemory, I, O>, input: I, ctx: Context<TMemory>, executeStep: ExecuteStepFn): Promise<O>;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { resolveLayerTools } from '../memory/layer-api';
|
|
2
|
-
import { deduplicateTools } from './collect-tools';
|
|
3
|
-
import { frameworkCast } from './framework-cast';
|
|
4
|
-
//#region Helper Functions
|
|
5
|
-
function isMemoryConfig(value) {
|
|
6
|
-
return typeof value === 'object' && value !== null && 'layers' in value;
|
|
7
|
-
}
|
|
8
|
-
function resolveLayers(step) {
|
|
9
|
-
if (isMemoryConfig(step.memory)) {
|
|
10
|
-
return [
|
|
11
|
-
...step.memory.layers,
|
|
12
|
-
];
|
|
13
|
-
}
|
|
14
|
-
return step.memory;
|
|
15
|
-
}
|
|
16
|
-
function mergeLayers(existing, provided) {
|
|
17
|
-
if (!existing || existing.length === 0) {
|
|
18
|
-
return provided;
|
|
19
|
-
}
|
|
20
|
-
// Provided layers override existing layers with the same id (like nested React context)
|
|
21
|
-
const providedIds = new Set(provided.map((l) => l.id));
|
|
22
|
-
const kept = existing.filter((l) => !providedIds.has(l.id));
|
|
23
|
-
return [
|
|
24
|
-
...kept,
|
|
25
|
-
...provided,
|
|
26
|
-
];
|
|
27
|
-
}
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region Public API
|
|
30
|
-
/**
|
|
31
|
-
* Executes a provide step by attaching memory layers to the current context
|
|
32
|
-
* without creating an isolated child context.
|
|
33
|
-
*
|
|
34
|
-
* Unlike spawn, provide does not create a new itemLog or clone state.
|
|
35
|
-
* Events flow through to the parent in real-time.
|
|
36
|
-
*/
|
|
37
|
-
export async function executeProvide(step, input, ctx, executeStep) {
|
|
38
|
-
const baseCtx = frameworkCast(ctx);
|
|
39
|
-
const previousLayers = baseCtx.layers;
|
|
40
|
-
const previousUnifiedTools = baseCtx.unifiedTools;
|
|
41
|
-
const newLayers = resolveLayers(step);
|
|
42
|
-
const mergedLayers = mergeLayers(previousLayers, newLayers);
|
|
43
|
-
// Attach layers to the current context (no isolation)
|
|
44
|
-
baseCtx.layers = mergedLayers;
|
|
45
|
-
// Merge new layer-provided tools into the unified tool set
|
|
46
|
-
if (baseCtx.unifiedTools && newLayers.length > 0) {
|
|
47
|
-
const layerTools = resolveLayerTools(newLayers, baseCtx.harness, baseCtx);
|
|
48
|
-
if (layerTools.length > 0) {
|
|
49
|
-
baseCtx.unifiedTools = deduplicateTools([
|
|
50
|
-
...baseCtx.unifiedTools,
|
|
51
|
-
...layerTools,
|
|
52
|
-
]);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
return await executeStep(step.child, input, ctx);
|
|
57
|
-
}
|
|
58
|
-
finally {
|
|
59
|
-
// Restore previous layers and unified tools so siblings are not affected
|
|
60
|
-
baseCtx.layers = previousLayers;
|
|
61
|
-
baseCtx.unifiedTools = previousUnifiedTools;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
//#endregion
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { NoeticErrorImpl } from '../errors/noetic-error';
|
|
2
|
-
export async function executeRun(step, input, ctx) {
|
|
3
|
-
const retry = step.retry;
|
|
4
|
-
const maxAttempts = retry?.maxAttempts ?? 1;
|
|
5
|
-
let lastError = new Error('No attempts executed');
|
|
6
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
7
|
-
try {
|
|
8
|
-
return await step.execute(input, ctx);
|
|
9
|
-
}
|
|
10
|
-
catch (e) {
|
|
11
|
-
lastError = e instanceof Error ? e : new Error(String(e));
|
|
12
|
-
if (attempt < maxAttempts - 1 && retry) {
|
|
13
|
-
const delay = computeDelay(retry, attempt);
|
|
14
|
-
await new Promise((r) => setTimeout(r, delay));
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
throw new NoeticErrorImpl({
|
|
19
|
-
kind: 'step_failed',
|
|
20
|
-
stepId: step.id,
|
|
21
|
-
cause: lastError,
|
|
22
|
-
retriesExhausted: maxAttempts > 1,
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
function computeDelay(retry, attempt) {
|
|
26
|
-
let delay;
|
|
27
|
-
switch (retry.backoff) {
|
|
28
|
-
case 'fixed':
|
|
29
|
-
delay = retry.initialDelay;
|
|
30
|
-
break;
|
|
31
|
-
case 'linear':
|
|
32
|
-
delay = retry.initialDelay * (attempt + 1);
|
|
33
|
-
break;
|
|
34
|
-
case 'exponential':
|
|
35
|
-
delay = retry.initialDelay * 2 ** attempt;
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
return Math.min(delay, retry.maxDelay ?? 30_000);
|
|
39
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { LayerStateStore } from '../memory/layer-lifecycle';
|
|
2
|
-
import type { ItemSchemaRegistry } from '../schemas/item';
|
|
3
|
-
import type { Context } from '../types/context';
|
|
4
|
-
import type { MemoryLayer } from '../types/memory';
|
|
5
|
-
import type { ExecuteStepFn, StepSpawn } from '../types/step';
|
|
6
|
-
export interface ExecuteSpawnOpts {
|
|
7
|
-
layerStore?: LayerStateStore;
|
|
8
|
-
parentLayers?: MemoryLayer[];
|
|
9
|
-
itemSchemas?: ItemSchemaRegistry;
|
|
10
|
-
}
|
|
11
|
-
export declare function executeSpawn<TMemory, I, O>(step: StepSpawn<TMemory, I, O>, input: I, ctx: Context<TMemory>, executeStep: ExecuteStepFn, opts?: ExecuteSpawnOpts): Promise<O>;
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { resolveLayerTools } from '../memory/layer-api';
|
|
2
|
-
import { returnLayers, spawnLayers } from '../memory/layer-lifecycle';
|
|
3
|
-
import { ContextImpl } from '../runtime/context-impl';
|
|
4
|
-
import { snapshotCwdState } from '../runtime/cwd-helpers';
|
|
5
|
-
import { contextToExecCtx } from '../runtime/exec-context-factory';
|
|
6
|
-
import { defaultItemSchemaRegistry } from '../schemas/item';
|
|
7
|
-
import { cloneWithGuard } from './clone-guard';
|
|
8
|
-
import { collectAllTools, deduplicateTools } from './collect-tools';
|
|
9
|
-
import { frameworkCast } from './framework-cast';
|
|
10
|
-
import { getContextChannelStore } from './typeguards';
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region Helper Functions
|
|
13
|
-
function isMemoryConfig(value) {
|
|
14
|
-
return typeof value === 'object' && value !== null && 'layers' in value;
|
|
15
|
-
}
|
|
16
|
-
function resolveLayersForSpawn(step, parentLayers) {
|
|
17
|
-
if (!step.memory) {
|
|
18
|
-
return parentLayers ?? [];
|
|
19
|
-
}
|
|
20
|
-
if (isMemoryConfig(step.memory)) {
|
|
21
|
-
return [
|
|
22
|
-
...step.memory.layers,
|
|
23
|
-
];
|
|
24
|
-
}
|
|
25
|
-
return step.memory;
|
|
26
|
-
}
|
|
27
|
-
async function collectSpawnItems({ layers, parentExecutionCtx, childExecutionCtx, layerStore, itemSchemas = defaultItemSchemaRegistry, }) {
|
|
28
|
-
const spawnResults = await spawnLayers({
|
|
29
|
-
layers,
|
|
30
|
-
parentCtx: parentExecutionCtx,
|
|
31
|
-
childCtx: childExecutionCtx,
|
|
32
|
-
store: layerStore,
|
|
33
|
-
itemSchemas,
|
|
34
|
-
});
|
|
35
|
-
return spawnResults.flatMap((r) => r.items);
|
|
36
|
-
}
|
|
37
|
-
//#endregion
|
|
38
|
-
//#region Public API
|
|
39
|
-
export async function executeSpawn(step, input, ctx, executeStep, opts) {
|
|
40
|
-
const baseCtx = frameworkCast(ctx);
|
|
41
|
-
const layers = resolveLayersForSpawn(step, opts?.parentLayers);
|
|
42
|
-
const childId = crypto.randomUUID();
|
|
43
|
-
const childExecutionCtx = contextToExecCtx(baseCtx, {
|
|
44
|
-
executionId: childId,
|
|
45
|
-
depth: baseCtx.depth + 1,
|
|
46
|
-
stepNumber: 0,
|
|
47
|
-
tokenUsage: {
|
|
48
|
-
input: 0,
|
|
49
|
-
output: 0,
|
|
50
|
-
},
|
|
51
|
-
cost: 0,
|
|
52
|
-
readLayerStateId: childId,
|
|
53
|
-
});
|
|
54
|
-
const layerStore = opts?.layerStore;
|
|
55
|
-
const hasLayers = layers.length > 0 && layerStore !== undefined;
|
|
56
|
-
// Collect items from memory layers via onSpawn hooks
|
|
57
|
-
let childItems = [];
|
|
58
|
-
let parentExecutionCtx;
|
|
59
|
-
if (hasLayers) {
|
|
60
|
-
parentExecutionCtx = contextToExecCtx(baseCtx);
|
|
61
|
-
childItems = await collectSpawnItems({
|
|
62
|
-
layers,
|
|
63
|
-
parentExecutionCtx,
|
|
64
|
-
childExecutionCtx,
|
|
65
|
-
layerStore,
|
|
66
|
-
itemSchemas: opts?.itemSchemas,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
// Build unified tool set for child from its step tree + layers
|
|
70
|
-
const childStepTools = collectAllTools(step.child);
|
|
71
|
-
const childLayerTools = layers.length > 0 ? resolveLayerTools(layers, baseCtx.harness, baseCtx) : [];
|
|
72
|
-
const childUnifiedTools = deduplicateTools([
|
|
73
|
-
...childStepTools,
|
|
74
|
-
...childLayerTools,
|
|
75
|
-
]);
|
|
76
|
-
// Create child context — empty by default, layers provide items via onSpawn.
|
|
77
|
-
const childCtx = new ContextImpl({
|
|
78
|
-
harness: baseCtx.harness,
|
|
79
|
-
parent: baseCtx,
|
|
80
|
-
items: childItems,
|
|
81
|
-
state: cloneWithGuard(baseCtx.state, `Spawn '${step.id}'`),
|
|
82
|
-
threadId: baseCtx.threadId,
|
|
83
|
-
resourceId: baseCtx.resourceId,
|
|
84
|
-
channelStore: getContextChannelStore(baseCtx),
|
|
85
|
-
layers: layers.length > 0 ? layers : undefined,
|
|
86
|
-
unifiedTools: childUnifiedTools.length > 0 ? childUnifiedTools : undefined,
|
|
87
|
-
cwdState: snapshotCwdState(baseCtx),
|
|
88
|
-
});
|
|
89
|
-
try {
|
|
90
|
-
// Execute the child step
|
|
91
|
-
const childOutput = await executeStep(step.child, input, frameworkCast(childCtx));
|
|
92
|
-
// Pipeline result through layer onReturn hooks
|
|
93
|
-
if (!hasLayers || !parentExecutionCtx) {
|
|
94
|
-
return childOutput;
|
|
95
|
-
}
|
|
96
|
-
const pipelinedResult = await returnLayers({
|
|
97
|
-
layers,
|
|
98
|
-
parentCtx: parentExecutionCtx,
|
|
99
|
-
childCtx: childExecutionCtx,
|
|
100
|
-
childLog: childCtx.itemLog,
|
|
101
|
-
result: childOutput,
|
|
102
|
-
store: layerStore,
|
|
103
|
-
});
|
|
104
|
-
return pipelinedResult;
|
|
105
|
-
}
|
|
106
|
-
finally {
|
|
107
|
-
// Clean up child execution state to prevent memory leaks — runs on success and error
|
|
108
|
-
if (hasLayers) {
|
|
109
|
-
layerStore.cleanup(childExecutionCtx.executionId);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
//#endregion
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { Context } from '../types/context';
|
|
2
|
-
import type { MemoryLayer } from '../types/memory';
|
|
3
|
-
import type { AgentHarnessContract } from '../types/runtime';
|
|
4
|
-
import type { StepTool } from '../types/step';
|
|
5
|
-
export declare function executeTool<TMemory, I, O>(step: StepTool<TMemory, I, O>, input: I, ctx: Context<TMemory>, harness: AgentHarnessContract, layers?: MemoryLayer[]): Promise<O>;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { NoeticErrorImpl } from '../errors/noetic-error';
|
|
2
|
-
import { emitFrameworkEvent, getBroadcaster } from '../runtime/broadcaster-utils';
|
|
3
|
-
import { buildToolExecutionContext } from '../runtime/tool-memory';
|
|
4
|
-
import { SteeringAction } from '../types/steering';
|
|
5
|
-
import { frameworkCast } from './framework-cast';
|
|
6
|
-
//#region Helpers
|
|
7
|
-
function isAsyncGenerator(value) {
|
|
8
|
-
if (typeof value !== 'object' || value === null) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
return Symbol.asyncIterator in value;
|
|
12
|
-
}
|
|
13
|
-
async function consumeToolGenerator(params) {
|
|
14
|
-
const broadcaster = getBroadcaster(params.ctx);
|
|
15
|
-
const agentName = params.ctx.harness.config.name;
|
|
16
|
-
while (true) {
|
|
17
|
-
const next = await params.generator.next();
|
|
18
|
-
if (next.done) {
|
|
19
|
-
return next.value;
|
|
20
|
-
}
|
|
21
|
-
emitFrameworkEvent({
|
|
22
|
-
broadcaster,
|
|
23
|
-
agentName,
|
|
24
|
-
eventType: 'tool_progress',
|
|
25
|
-
data: {
|
|
26
|
-
stepId: params.stepId,
|
|
27
|
-
toolName: params.toolName,
|
|
28
|
-
event: next.value,
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
//#endregion
|
|
34
|
-
//#region Public API
|
|
35
|
-
export async function executeTool(step, input, ctx, harness, layers) {
|
|
36
|
-
const baseCtx = frameworkCast(ctx);
|
|
37
|
-
const args = step.args ? Object.assign({}, input, step.args) : input;
|
|
38
|
-
const parseResult = step.tool.input.safeParse(args);
|
|
39
|
-
if (!parseResult.success) {
|
|
40
|
-
throw new NoeticErrorImpl({
|
|
41
|
-
kind: 'step_failed',
|
|
42
|
-
stepId: step.id,
|
|
43
|
-
cause: new Error(`Tool input validation failed: ${parseResult.error.message}`),
|
|
44
|
-
retriesExhausted: false,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
if (layers && layers.length > 0) {
|
|
48
|
-
const decision = await harness.beforeToolCall(layers, step.tool.name, parseResult.data, baseCtx);
|
|
49
|
-
if (decision.action !== SteeringAction.Allow) {
|
|
50
|
-
throw new NoeticErrorImpl({
|
|
51
|
-
kind: 'steering_denied',
|
|
52
|
-
guidance: decision.guidance,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
try {
|
|
57
|
-
const toolCtx = buildToolExecutionContext(baseCtx, harness);
|
|
58
|
-
const result = step.tool.execute(parseResult.data, toolCtx);
|
|
59
|
-
if (isAsyncGenerator(result)) {
|
|
60
|
-
return frameworkCast(await consumeToolGenerator({
|
|
61
|
-
generator: result,
|
|
62
|
-
stepId: step.id,
|
|
63
|
-
toolName: step.tool.name,
|
|
64
|
-
ctx: baseCtx,
|
|
65
|
-
}));
|
|
66
|
-
}
|
|
67
|
-
return frameworkCast(await result);
|
|
68
|
-
}
|
|
69
|
-
catch (e) {
|
|
70
|
-
if (e instanceof NoeticErrorImpl) {
|
|
71
|
-
throw e;
|
|
72
|
-
}
|
|
73
|
-
throw new NoeticErrorImpl({
|
|
74
|
-
kind: 'step_failed',
|
|
75
|
-
stepId: step.id,
|
|
76
|
-
cause: e instanceof Error ? e : new Error(String(e)),
|
|
77
|
-
retriesExhausted: false,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
//#endregion
|