@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,8 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
import { isAssistantMessage } from '../interpreter/typeguards';
|
|
2
|
+
import { NoeticConfigError } from '../errors/noetic-config-error';
|
|
4
3
|
import { buildToolExecutionContext } from '../runtime/tool-memory';
|
|
5
4
|
import { SteeringAction } from '../types/steering';
|
|
5
|
+
import { frameworkCast } from '../util/framework-cast';
|
|
6
|
+
import { isAssistantMessage } from '../util/message-helpers';
|
|
6
7
|
const EmbeddingsResponseSchema = z.object({
|
|
7
8
|
data: z.array(z.object({
|
|
8
9
|
embedding: z.array(z.number()),
|
|
@@ -20,6 +21,44 @@ function contentPartsToText(parts) {
|
|
|
20
21
|
.map((p) => p.text)
|
|
21
22
|
.join('');
|
|
22
23
|
}
|
|
24
|
+
function inputTextPartToProvider(part) {
|
|
25
|
+
return {
|
|
26
|
+
type: 'input_text',
|
|
27
|
+
text: part.text,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function inputImagePartToProvider(part) {
|
|
31
|
+
return {
|
|
32
|
+
type: 'input_image',
|
|
33
|
+
imageUrl: part.imageUrl,
|
|
34
|
+
detail: part.detail ?? 'auto',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function inputFilePartToProvider(part) {
|
|
38
|
+
return {
|
|
39
|
+
type: 'input_file',
|
|
40
|
+
filename: part.filename,
|
|
41
|
+
fileData: part.fileData,
|
|
42
|
+
fileUrl: part.fileUrl,
|
|
43
|
+
fileId: part.fileId,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function inputContentPartToProvider(part) {
|
|
47
|
+
if (part.type === 'input_text') {
|
|
48
|
+
return inputTextPartToProvider(part);
|
|
49
|
+
}
|
|
50
|
+
if (part.type === 'input_image') {
|
|
51
|
+
return inputImagePartToProvider(part);
|
|
52
|
+
}
|
|
53
|
+
return inputFilePartToProvider(part);
|
|
54
|
+
}
|
|
55
|
+
function contentPartsToProviderContent(parts) {
|
|
56
|
+
const hasStructuredInput = parts.some((part) => part.type === 'input_image' || part.type === 'input_file');
|
|
57
|
+
if (!hasStructuredInput) {
|
|
58
|
+
return contentPartsToText(parts);
|
|
59
|
+
}
|
|
60
|
+
return frameworkCast(parts).map(inputContentPartToProvider);
|
|
61
|
+
}
|
|
23
62
|
//#endregion
|
|
24
63
|
//#region Item → OpenRouter Input Conversion
|
|
25
64
|
/** @internal Extracts system messages from items and returns them as a single instructions string. */
|
|
@@ -51,7 +90,7 @@ function itemToInputItem(item) {
|
|
|
51
90
|
// because the SDK's input union does not accept ResponsesOutputMessage directly.
|
|
52
91
|
return {
|
|
53
92
|
role: item.role,
|
|
54
|
-
content:
|
|
93
|
+
content: contentPartsToProviderContent(item.content),
|
|
55
94
|
};
|
|
56
95
|
}
|
|
57
96
|
if (item.type === 'function_call') {
|
|
@@ -141,12 +180,22 @@ export function extractUsage(usage) {
|
|
|
141
180
|
// This prevents the SDK from handling tool calls internally, which would
|
|
142
181
|
// make tool interactions invisible to Noetic's itemLog, token tracking,
|
|
143
182
|
// and observability. Instead, the AgentHarness manages the tool loop.
|
|
183
|
+
/**
|
|
184
|
+
* Provider APIs (Anthropic via OpenRouter) enforce tool names match
|
|
185
|
+
* `^[a-zA-Z0-9_-]{1,64}$`. Noetic's internal layer-tool names use `layerId/fn`
|
|
186
|
+
* which contains a forbidden `/`. We translate to a wire-safe form only at
|
|
187
|
+
* the SDK boundary; internal tool-name identity (and every codebase reference
|
|
188
|
+
* to names like `plan/updatePrd`) is preserved.
|
|
189
|
+
*/
|
|
190
|
+
export function sanitizeToolNameForWire(name) {
|
|
191
|
+
return name.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
192
|
+
}
|
|
144
193
|
/** @internal */
|
|
145
194
|
export function convertTools({ tools }) {
|
|
146
195
|
return tools.map((t) => frameworkCast({
|
|
147
196
|
type: 'function',
|
|
148
197
|
function: {
|
|
149
|
-
name: t.name,
|
|
198
|
+
name: sanitizeToolNameForWire(t.name),
|
|
150
199
|
description: t.description,
|
|
151
200
|
inputSchema: t.input,
|
|
152
201
|
},
|
|
@@ -171,7 +220,12 @@ async function consumeGenerator(generator) {
|
|
|
171
220
|
}
|
|
172
221
|
/** @internal Execute a single tool call with steering checks. */
|
|
173
222
|
export async function executeToolCall(params) {
|
|
174
|
-
|
|
223
|
+
// Model sees sanitised tool names (see `sanitizeToolNameForWire`). Match
|
|
224
|
+
// against both the original and sanitised name so internal identity (e.g.
|
|
225
|
+
// `plan/updatePrd` used by steering whitelists, skill docs, and the
|
|
226
|
+
// `planMemory.beforeToolCall` hook) stays intact while the wire name is
|
|
227
|
+
// provider-compliant.
|
|
228
|
+
const matchedTool = params.tools.find((t) => t.name === params.toolName || sanitizeToolNameForWire(t.name) === params.toolName);
|
|
175
229
|
if (!matchedTool) {
|
|
176
230
|
return {
|
|
177
231
|
output: `Error: unknown tool '${params.toolName}'`,
|
|
@@ -223,6 +277,13 @@ export async function executeToolCall(params) {
|
|
|
223
277
|
* @returns An `EmbedFn` that produces embedding vectors for the given texts.
|
|
224
278
|
*/
|
|
225
279
|
export function createOpenRouterEmbed(apiKey, embeddingModel) {
|
|
280
|
+
if (!apiKey) {
|
|
281
|
+
throw new NoeticConfigError({
|
|
282
|
+
code: 'MISSING_API_KEY',
|
|
283
|
+
message: 'createOpenRouterEmbed() requires an OpenRouter API key.',
|
|
284
|
+
hint: 'Pass the key explicitly, e.g. createOpenRouterEmbed(process.env.OPENROUTER_API_KEY).',
|
|
285
|
+
});
|
|
286
|
+
}
|
|
226
287
|
const model = embeddingModel ?? 'openai/text-embedding-3-small';
|
|
227
288
|
return async (texts) => {
|
|
228
289
|
const response = await fetch('https://openrouter.ai/api/v1/embeddings', {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NoeticConfigError } from '../errors/noetic-config-error';
|
|
2
|
-
import {
|
|
2
|
+
import { getDefaultRegistrar } from '../types/step-registrar';
|
|
3
|
+
import { frameworkCast } from '../util/framework-cast';
|
|
3
4
|
export function fork(opts) {
|
|
4
5
|
if (!opts.id || opts.id.trim() === '') {
|
|
5
6
|
throw new NoeticConfigError({
|
|
@@ -15,10 +16,12 @@ export function fork(opts) {
|
|
|
15
16
|
hint: 'Provide a merge function that combines path results into a single output.',
|
|
16
17
|
});
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
+
const built = frameworkCast({
|
|
19
20
|
kind: 'fork',
|
|
20
21
|
...opts,
|
|
21
22
|
});
|
|
23
|
+
getDefaultRegistrar().register(built);
|
|
24
|
+
return built;
|
|
22
25
|
}
|
|
23
26
|
/**
|
|
24
27
|
* Creates a conditional routing step that selects the next step at runtime.
|
|
@@ -46,8 +49,10 @@ export function branch(opts) {
|
|
|
46
49
|
hint: 'Provide a route function that selects the next step at runtime.',
|
|
47
50
|
});
|
|
48
51
|
}
|
|
49
|
-
|
|
52
|
+
const built = {
|
|
50
53
|
kind: 'branch',
|
|
51
54
|
...opts,
|
|
52
55
|
};
|
|
56
|
+
getDefaultRegistrar().register(built);
|
|
57
|
+
return built;
|
|
53
58
|
}
|
package/dist/builders/every.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NoeticConfigError } from '../errors/noetic-config-error';
|
|
2
|
+
import { getDefaultRegistrar } from '../types/step-registrar';
|
|
2
3
|
/**
|
|
3
4
|
* Creates an `every` step that runs a body step on a fixed-interval schedule.
|
|
4
5
|
*
|
|
@@ -48,7 +49,7 @@ export function every(opts) {
|
|
|
48
49
|
hint: 'Pass a non-negative number of milliseconds for jitter, or omit it.',
|
|
49
50
|
});
|
|
50
51
|
}
|
|
51
|
-
|
|
52
|
+
const built = {
|
|
52
53
|
kind: 'every',
|
|
53
54
|
id: opts.id,
|
|
54
55
|
step: opts.step,
|
|
@@ -57,4 +58,6 @@ export function every(opts) {
|
|
|
57
58
|
onError: opts.onError ?? 'continue',
|
|
58
59
|
jitter: opts.jitter ?? 0,
|
|
59
60
|
};
|
|
61
|
+
getDefaultRegistrar().register(built);
|
|
62
|
+
return built;
|
|
60
63
|
}
|
|
@@ -1,32 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import type { ExecutionContext, LayerDataDecl, LayerFunctionDecl } from '../types/memory';
|
|
3
|
-
/**
|
|
4
|
-
* Creates a read-only data declaration for a memory layer's `provides` map.
|
|
5
|
-
*
|
|
6
|
-
* @public
|
|
7
|
-
* @param opts.read - Function that projects a value from the layer's current state.
|
|
8
|
-
* @returns A `LayerDataDecl` to include in a layer's `provides`.
|
|
9
|
-
*/
|
|
10
|
-
export declare function layerData<T, TState>(opts: {
|
|
11
|
-
read: (state: TState) => T;
|
|
12
|
-
}): LayerDataDecl<T, TState>;
|
|
13
|
-
/**
|
|
14
|
-
* Creates a callable function declaration for a memory layer's `provides` map.
|
|
15
|
-
* Functions are accessible via `ctx.memory['layerId'].fn()` and automatically exposed as LLM tools.
|
|
16
|
-
*
|
|
17
|
-
* @public
|
|
18
|
-
* @param opts.description - Human-readable description (used as tool description for LLM).
|
|
19
|
-
* @param opts.input - Zod schema validating input arguments.
|
|
20
|
-
* @param opts.output - Zod schema validating the return value.
|
|
21
|
-
* @param opts.execute - Async function receiving args, current state, and execution context.
|
|
22
|
-
* @returns A `LayerFunctionDecl` to include in a layer's `provides`.
|
|
23
|
-
*/
|
|
24
|
-
export declare function layerFn<TInput, TOutput, TState>(opts: {
|
|
25
|
-
description: string;
|
|
26
|
-
input: ZodType<TInput>;
|
|
27
|
-
output: ZodType<TOutput>;
|
|
28
|
-
execute: (args: TInput, state: TState, ctx: ExecutionContext) => Promise<{
|
|
29
|
-
result: TOutput;
|
|
30
|
-
state?: TState;
|
|
31
|
-
}>;
|
|
32
|
-
}): LayerFunctionDecl<TInput, TOutput, TState>;
|
|
1
|
+
export { layerData, layerFn } from '../memory/layer-provides';
|
|
@@ -1,33 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Creates a read-only data declaration for a memory layer's `provides` map.
|
|
3
|
-
*
|
|
4
|
-
* @public
|
|
5
|
-
* @param opts.read - Function that projects a value from the layer's current state.
|
|
6
|
-
* @returns A `LayerDataDecl` to include in a layer's `provides`.
|
|
7
|
-
*/
|
|
8
|
-
export function layerData(opts) {
|
|
9
|
-
return {
|
|
10
|
-
kind: 'data',
|
|
11
|
-
read: opts.read,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Creates a callable function declaration for a memory layer's `provides` map.
|
|
16
|
-
* Functions are accessible via `ctx.memory['layerId'].fn()` and automatically exposed as LLM tools.
|
|
17
|
-
*
|
|
18
|
-
* @public
|
|
19
|
-
* @param opts.description - Human-readable description (used as tool description for LLM).
|
|
20
|
-
* @param opts.input - Zod schema validating input arguments.
|
|
21
|
-
* @param opts.output - Zod schema validating the return value.
|
|
22
|
-
* @param opts.execute - Async function receiving args, current state, and execution context.
|
|
23
|
-
* @returns A `LayerFunctionDecl` to include in a layer's `provides`.
|
|
24
|
-
*/
|
|
25
|
-
export function layerFn(opts) {
|
|
26
|
-
return {
|
|
27
|
-
kind: 'function',
|
|
28
|
-
description: opts.description,
|
|
29
|
-
input: opts.input,
|
|
30
|
-
output: opts.output,
|
|
31
|
-
execute: opts.execute,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
1
|
+
export { layerData, layerFn } from '../memory/layer-provides';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NoeticConfigError } from '../errors/noetic-config-error';
|
|
2
|
+
import { getDefaultRegistrar } from '../types/step-registrar';
|
|
2
3
|
/**
|
|
3
4
|
* Creates a loop step that iterates a body step until a termination predicate is satisfied.
|
|
4
5
|
*
|
|
@@ -39,8 +40,10 @@ export function loop(opts) {
|
|
|
39
40
|
hint: 'Provide an until predicate, e.g. until.maxSteps(10).',
|
|
40
41
|
});
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
+
const built = {
|
|
43
44
|
kind: 'loop',
|
|
44
45
|
...opts,
|
|
45
46
|
};
|
|
47
|
+
getDefaultRegistrar().register(built);
|
|
48
|
+
return built;
|
|
46
49
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { frameworkCast } from '../
|
|
1
|
+
import { frameworkCast } from '../util/framework-cast';
|
|
2
2
|
/**
|
|
3
3
|
* Creates a type-safe memory configuration from a tuple of memory layers.
|
|
4
4
|
* The returned config preserves literal layer types for compile-time inference
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NoeticConfigError } from '../errors/noetic-config-error';
|
|
2
|
+
import { getDefaultRegistrar } from '../types/step-registrar';
|
|
2
3
|
/**
|
|
3
4
|
* Creates a provide step that attaches memory layers to its child without creating an isolated context.
|
|
4
5
|
* Like React's Context.Provider — layers are available to all descendant steps.
|
|
@@ -27,8 +28,10 @@ export function provide(opts) {
|
|
|
27
28
|
hint: 'Provide a child step to execute with the provided memory layers.',
|
|
28
29
|
});
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
+
const built = {
|
|
31
32
|
kind: 'provide',
|
|
32
33
|
...opts,
|
|
33
34
|
};
|
|
35
|
+
getDefaultRegistrar().register(built);
|
|
36
|
+
return built;
|
|
34
37
|
}
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { ContextMemory, MemoryConfig, MemoryLayer } from '../types/memory';
|
|
2
2
|
import type { Step, StepSpawn } from '../types/step';
|
|
3
|
+
import type { SubprocessAdapter } from '../types/subprocess-adapter';
|
|
4
|
+
interface SpawnOpts<TMemory, I, O> {
|
|
5
|
+
id: string;
|
|
6
|
+
child: Step<TMemory, I, O>;
|
|
7
|
+
memory?: MemoryConfig | MemoryLayer[];
|
|
8
|
+
timeout?: number;
|
|
9
|
+
/**
|
|
10
|
+
* Optional per-step subprocess adapter override. The interpreter routes
|
|
11
|
+
* this spawn through the given adapter instead of the harness default.
|
|
12
|
+
* See spec 04 for the `overrides ?? step ?? harness` precedence rule.
|
|
13
|
+
*/
|
|
14
|
+
subprocess?: SubprocessAdapter;
|
|
15
|
+
}
|
|
3
16
|
/**
|
|
4
17
|
* Creates a spawn step that executes a child step in an isolated context boundary.
|
|
5
18
|
*
|
|
@@ -8,13 +21,13 @@ import type { Step, StepSpawn } from '../types/step';
|
|
|
8
21
|
* @param opts.child - Step to execute in the isolated child context.
|
|
9
22
|
* @param opts.memory - Optional memory config or layers for the child context (replaces parent layers entirely).
|
|
10
23
|
* @param opts.timeout - Optional execution timeout in ms; the child is aborted if it exceeds this.
|
|
11
|
-
* @
|
|
24
|
+
* @param opts.subprocess - Optional per-step subprocess adapter override.
|
|
25
|
+
* @returns A `StepSpawn` step. The spawn step and its `child` step are both
|
|
26
|
+
* auto-registered in the shared step registry so the subprocess adapter
|
|
27
|
+
* can dispatch either by id.
|
|
12
28
|
* @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
|
|
13
29
|
* @throws `NoeticConfigError` with code `MISSING_CHILD_STEP` if `child` is not provided.
|
|
30
|
+
* @throws `NoeticConfigError` with code `DUPLICATE_STEP_ID` if another step with the same id is already registered.
|
|
14
31
|
*/
|
|
15
|
-
export declare function spawn<TMemory = ContextMemory, I = unknown, O = unknown>(opts:
|
|
16
|
-
|
|
17
|
-
child: Step<TMemory, I, O>;
|
|
18
|
-
memory?: MemoryConfig | MemoryLayer[];
|
|
19
|
-
timeout?: number;
|
|
20
|
-
}): StepSpawn<TMemory, I, O>;
|
|
32
|
+
export declare function spawn<TMemory = ContextMemory, I = unknown, O = unknown>(opts: SpawnOpts<TMemory, I, O>): StepSpawn<TMemory, I, O>;
|
|
33
|
+
export {};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { NoeticConfigError } from '../errors/noetic-config-error';
|
|
2
|
+
import { getDefaultRegistrar } from '../types/step-registrar';
|
|
3
|
+
//#endregion
|
|
4
|
+
//#region Public API
|
|
2
5
|
/**
|
|
3
6
|
* Creates a spawn step that executes a child step in an isolated context boundary.
|
|
4
7
|
*
|
|
@@ -7,9 +10,13 @@ import { NoeticConfigError } from '../errors/noetic-config-error';
|
|
|
7
10
|
* @param opts.child - Step to execute in the isolated child context.
|
|
8
11
|
* @param opts.memory - Optional memory config or layers for the child context (replaces parent layers entirely).
|
|
9
12
|
* @param opts.timeout - Optional execution timeout in ms; the child is aborted if it exceeds this.
|
|
10
|
-
* @
|
|
13
|
+
* @param opts.subprocess - Optional per-step subprocess adapter override.
|
|
14
|
+
* @returns A `StepSpawn` step. The spawn step and its `child` step are both
|
|
15
|
+
* auto-registered in the shared step registry so the subprocess adapter
|
|
16
|
+
* can dispatch either by id.
|
|
11
17
|
* @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
|
|
12
18
|
* @throws `NoeticConfigError` with code `MISSING_CHILD_STEP` if `child` is not provided.
|
|
19
|
+
* @throws `NoeticConfigError` with code `DUPLICATE_STEP_ID` if another step with the same id is already registered.
|
|
13
20
|
*/
|
|
14
21
|
export function spawn(opts) {
|
|
15
22
|
if (!opts.id?.trim()) {
|
|
@@ -26,8 +33,15 @@ export function spawn(opts) {
|
|
|
26
33
|
hint: 'Provide a child step to execute in the isolated child context.',
|
|
27
34
|
});
|
|
28
35
|
}
|
|
29
|
-
|
|
36
|
+
const built = {
|
|
30
37
|
kind: 'spawn',
|
|
31
38
|
...opts,
|
|
32
39
|
};
|
|
40
|
+
getDefaultRegistrar().register(built);
|
|
41
|
+
// Ensure the child is addressable by id — builders for `run`/`llm`/`tool`
|
|
42
|
+
// self-register, but a caller can construct a step literal and pass it as
|
|
43
|
+
// `child` without going through a builder.
|
|
44
|
+
getDefaultRegistrar().register(opts.child);
|
|
45
|
+
return built;
|
|
33
46
|
}
|
|
47
|
+
//#endregion
|
|
@@ -1,8 +1,38 @@
|
|
|
1
1
|
import type { ZodType } from 'zod';
|
|
2
|
-
import type { ModelParams, RetryPolicy
|
|
2
|
+
import type { ModelParams, RetryPolicy } from '../types/common';
|
|
3
3
|
import type { Context } from '../types/context';
|
|
4
4
|
import type { ContextMemory } from '../types/memory';
|
|
5
|
-
import type { StepLLM, StepRun, StepTool } from '../types/step';
|
|
5
|
+
import type { Lazy, StepLLM, StepRun, StepTool } from '../types/step';
|
|
6
|
+
import type { SubprocessAdapter } from '../types/subprocess-adapter';
|
|
7
|
+
import type { Tool } from '../types/tool';
|
|
8
|
+
interface StepRunOpts<TMemory, I, O> {
|
|
9
|
+
id: string;
|
|
10
|
+
execute: (input: I, ctx: Context<TMemory>) => Promise<O>;
|
|
11
|
+
retry?: RetryPolicy;
|
|
12
|
+
/**
|
|
13
|
+
* Optional subprocess adapter override. When set, `execute()` is routed
|
|
14
|
+
* through this adapter instead of the harness default. See spec 04 for
|
|
15
|
+
* precedence rules.
|
|
16
|
+
*/
|
|
17
|
+
subprocess?: SubprocessAdapter;
|
|
18
|
+
}
|
|
19
|
+
interface StepLLMOpts<TMemory, O> {
|
|
20
|
+
id: string;
|
|
21
|
+
/** Model id. Eager string or `(ctx) => string` getter (resolved at step execution). */
|
|
22
|
+
model: Lazy<string, TMemory>;
|
|
23
|
+
/** Optional instructions; eager string or `(ctx) => string | undefined` getter. */
|
|
24
|
+
instructions?: Lazy<string | undefined, TMemory>;
|
|
25
|
+
/** Optional tools; eager array or `(ctx) => Tool[] | undefined` getter. */
|
|
26
|
+
tools?: Lazy<Tool[] | undefined, TMemory>;
|
|
27
|
+
output?: ZodType<O>;
|
|
28
|
+
params?: ModelParams;
|
|
29
|
+
emit?: boolean | ((eventType: string, data: Record<string, unknown>) => boolean);
|
|
30
|
+
}
|
|
31
|
+
interface StepToolOpts<I, O> {
|
|
32
|
+
id: string;
|
|
33
|
+
tool: Tool<ZodType<I>, ZodType<O>>;
|
|
34
|
+
args?: Partial<I>;
|
|
35
|
+
}
|
|
6
36
|
export declare const step: {
|
|
7
37
|
/**
|
|
8
38
|
* Creates a pure async computation step.
|
|
@@ -11,38 +41,31 @@ export declare const step: {
|
|
|
11
41
|
* @param opts.id - Unique step identifier used in traces and error messages.
|
|
12
42
|
* @param opts.execute - Async function `(input, ctx) => output` that performs the work.
|
|
13
43
|
* @param opts.retry - Optional retry policy controlling attempts, backoff, and delay.
|
|
14
|
-
* @
|
|
44
|
+
* @param opts.subprocess - Optional per-step subprocess adapter override.
|
|
45
|
+
* @returns A `StepRun` that can be composed into larger pipelines. The step
|
|
46
|
+
* is auto-registered in the shared step registry so the subprocess
|
|
47
|
+
* adapter can dispatch it by id.
|
|
15
48
|
* @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
|
|
16
49
|
* @throws `NoeticConfigError` with code `MISSING_EXECUTE_FUNCTION` if `execute` is not provided.
|
|
50
|
+
* @throws `NoeticConfigError` with code `DUPLICATE_STEP_ID` if another step with the same id is already registered with a different body.
|
|
17
51
|
*/
|
|
18
|
-
run<TMemory = Readonly<Record<string, Record<string, unknown>>>, I = unknown, O = unknown>(opts:
|
|
19
|
-
id: string;
|
|
20
|
-
execute: (input: I, ctx: Context<TMemory>) => Promise<O>;
|
|
21
|
-
retry?: RetryPolicy;
|
|
22
|
-
}): StepRun<TMemory, I, O>;
|
|
52
|
+
run<TMemory = Readonly<Record<string, Record<string, unknown>>>, I = unknown, O = unknown>(opts: StepRunOpts<TMemory, I, O>): StepRun<TMemory, I, O>;
|
|
23
53
|
/**
|
|
24
54
|
* Creates an LLM model call step with optional tools and structured output.
|
|
25
55
|
*
|
|
26
56
|
* @public
|
|
27
57
|
* @param opts.id - Unique step identifier used in traces and error messages.
|
|
28
|
-
* @param opts.model - Model identifier string (
|
|
29
|
-
* @param opts.instructions - Optional system prompt
|
|
30
|
-
* @param opts.tools - Optional tools
|
|
58
|
+
* @param opts.model - Model identifier, eager string or `(ctx) => string` getter (resolved at step execution time).
|
|
59
|
+
* @param opts.instructions - Optional system prompt; eager string or `(ctx) => string | undefined` getter.
|
|
60
|
+
* @param opts.tools - Optional tools; eager array or `(ctx) => Tool[] | undefined` getter.
|
|
31
61
|
* @param opts.output - Optional Zod schema enabling structured output parsing.
|
|
32
62
|
* @param opts.params - Optional model parameters (temperature, topP, maxTokens, stopSequences).
|
|
33
|
-
* @returns A `StepLLM` that can be composed into larger pipelines.
|
|
63
|
+
* @returns A `StepLLM` that can be composed into larger pipelines. The step
|
|
64
|
+
* is auto-registered in the shared step registry.
|
|
34
65
|
* @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
|
|
35
|
-
* @throws `NoeticConfigError` with code `MISSING_MODEL` if `model` is empty.
|
|
66
|
+
* @throws `NoeticConfigError` with code `MISSING_MODEL` if an eager `model` string is empty. Function-form models are validated at step execution.
|
|
36
67
|
*/
|
|
37
|
-
llm<TMemory = Readonly<Record<string, Record<string, unknown>>>, I = unknown, O = unknown>(opts:
|
|
38
|
-
id: string;
|
|
39
|
-
model: string;
|
|
40
|
-
instructions?: string;
|
|
41
|
-
tools?: Tool[];
|
|
42
|
-
output?: ZodType<O>;
|
|
43
|
-
params?: ModelParams;
|
|
44
|
-
emit?: boolean | ((eventType: string, data: Record<string, unknown>) => boolean);
|
|
45
|
-
}): StepLLM<TMemory, I, O>;
|
|
68
|
+
llm<TMemory = Readonly<Record<string, Record<string, unknown>>>, I = unknown, O = unknown>(opts: StepLLMOpts<TMemory, O>): StepLLM<TMemory, I, O>;
|
|
46
69
|
/**
|
|
47
70
|
* Creates a tool execution step that invokes a typed tool definition.
|
|
48
71
|
*
|
|
@@ -50,13 +73,11 @@ export declare const step: {
|
|
|
50
73
|
* @param opts.id - Unique step identifier used in traces and error messages.
|
|
51
74
|
* @param opts.tool - The tool definition with typed input/output schemas.
|
|
52
75
|
* @param opts.args - Optional partial args that override or supplement LLM-provided arguments.
|
|
53
|
-
* @returns A `StepTool` that can be composed into larger pipelines.
|
|
76
|
+
* @returns A `StepTool` that can be composed into larger pipelines. The step
|
|
77
|
+
* is auto-registered in the shared step registry.
|
|
54
78
|
* @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
|
|
55
79
|
* @throws `NoeticConfigError` with code `MISSING_TOOL` if `tool` is not provided.
|
|
56
80
|
*/
|
|
57
|
-
tool<TMemory = Readonly<Record<string, Record<string, unknown>>>, I = unknown, O = unknown>(opts:
|
|
58
|
-
id: string;
|
|
59
|
-
tool: Tool<ZodType<I>, ZodType<O>>;
|
|
60
|
-
args?: Partial<I>;
|
|
61
|
-
}): StepTool<TMemory, I, O>;
|
|
81
|
+
tool<TMemory = Readonly<Record<string, Record<string, unknown>>>, I = unknown, O = unknown>(opts: StepToolOpts<I, O>): StepTool<TMemory, I, O>;
|
|
62
82
|
};
|
|
83
|
+
export {};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { NoeticConfigError } from '../errors/noetic-config-error';
|
|
2
|
+
import { getDefaultRegistrar } from '../types/step-registrar';
|
|
3
|
+
//#endregion
|
|
4
|
+
//#region Builders
|
|
2
5
|
export const step = {
|
|
3
6
|
/**
|
|
4
7
|
* Creates a pure async computation step.
|
|
@@ -7,9 +10,13 @@ export const step = {
|
|
|
7
10
|
* @param opts.id - Unique step identifier used in traces and error messages.
|
|
8
11
|
* @param opts.execute - Async function `(input, ctx) => output` that performs the work.
|
|
9
12
|
* @param opts.retry - Optional retry policy controlling attempts, backoff, and delay.
|
|
10
|
-
* @
|
|
13
|
+
* @param opts.subprocess - Optional per-step subprocess adapter override.
|
|
14
|
+
* @returns A `StepRun` that can be composed into larger pipelines. The step
|
|
15
|
+
* is auto-registered in the shared step registry so the subprocess
|
|
16
|
+
* adapter can dispatch it by id.
|
|
11
17
|
* @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
|
|
12
18
|
* @throws `NoeticConfigError` with code `MISSING_EXECUTE_FUNCTION` if `execute` is not provided.
|
|
19
|
+
* @throws `NoeticConfigError` with code `DUPLICATE_STEP_ID` if another step with the same id is already registered with a different body.
|
|
13
20
|
*/
|
|
14
21
|
run(opts) {
|
|
15
22
|
if (!opts.id || opts.id.trim() === '') {
|
|
@@ -26,24 +33,27 @@ export const step = {
|
|
|
26
33
|
hint: 'Provide an async execute function, e.g. execute: async (input, ctx) => result.',
|
|
27
34
|
});
|
|
28
35
|
}
|
|
29
|
-
|
|
36
|
+
const built = {
|
|
30
37
|
kind: 'run',
|
|
31
38
|
...opts,
|
|
32
39
|
};
|
|
40
|
+
getDefaultRegistrar().register(built);
|
|
41
|
+
return built;
|
|
33
42
|
},
|
|
34
43
|
/**
|
|
35
44
|
* Creates an LLM model call step with optional tools and structured output.
|
|
36
45
|
*
|
|
37
46
|
* @public
|
|
38
47
|
* @param opts.id - Unique step identifier used in traces and error messages.
|
|
39
|
-
* @param opts.model - Model identifier string (
|
|
40
|
-
* @param opts.instructions - Optional system prompt
|
|
41
|
-
* @param opts.tools - Optional tools
|
|
48
|
+
* @param opts.model - Model identifier, eager string or `(ctx) => string` getter (resolved at step execution time).
|
|
49
|
+
* @param opts.instructions - Optional system prompt; eager string or `(ctx) => string | undefined` getter.
|
|
50
|
+
* @param opts.tools - Optional tools; eager array or `(ctx) => Tool[] | undefined` getter.
|
|
42
51
|
* @param opts.output - Optional Zod schema enabling structured output parsing.
|
|
43
52
|
* @param opts.params - Optional model parameters (temperature, topP, maxTokens, stopSequences).
|
|
44
|
-
* @returns A `StepLLM` that can be composed into larger pipelines.
|
|
53
|
+
* @returns A `StepLLM` that can be composed into larger pipelines. The step
|
|
54
|
+
* is auto-registered in the shared step registry.
|
|
45
55
|
* @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
|
|
46
|
-
* @throws `NoeticConfigError` with code `MISSING_MODEL` if `model` is empty.
|
|
56
|
+
* @throws `NoeticConfigError` with code `MISSING_MODEL` if an eager `model` string is empty. Function-form models are validated at step execution.
|
|
47
57
|
*/
|
|
48
58
|
llm(opts) {
|
|
49
59
|
if (!opts.id || opts.id.trim() === '') {
|
|
@@ -53,17 +63,22 @@ export const step = {
|
|
|
53
63
|
hint: 'Pass a unique string as the id field, e.g. step.llm({ id: "my-llm", ... }).',
|
|
54
64
|
});
|
|
55
65
|
}
|
|
56
|
-
|
|
66
|
+
// Only validate eager models here. Function-form models are validated
|
|
67
|
+
// post-resolution in executeLLM so the same MISSING_MODEL error surfaces
|
|
68
|
+
// whether the caller passes a string or a getter.
|
|
69
|
+
if (typeof opts.model === 'string' && opts.model.trim() === '') {
|
|
57
70
|
throw new NoeticConfigError({
|
|
58
71
|
code: 'MISSING_MODEL',
|
|
59
72
|
message: 'step.llm() requires a non-empty model.',
|
|
60
73
|
hint: "Pass a model identifier, e.g. model: 'anthropic/claude-sonnet-4-20250514'.",
|
|
61
74
|
});
|
|
62
75
|
}
|
|
63
|
-
|
|
76
|
+
const built = {
|
|
64
77
|
kind: 'llm',
|
|
65
78
|
...opts,
|
|
66
79
|
};
|
|
80
|
+
getDefaultRegistrar().register(built);
|
|
81
|
+
return built;
|
|
67
82
|
},
|
|
68
83
|
/**
|
|
69
84
|
* Creates a tool execution step that invokes a typed tool definition.
|
|
@@ -72,7 +87,8 @@ export const step = {
|
|
|
72
87
|
* @param opts.id - Unique step identifier used in traces and error messages.
|
|
73
88
|
* @param opts.tool - The tool definition with typed input/output schemas.
|
|
74
89
|
* @param opts.args - Optional partial args that override or supplement LLM-provided arguments.
|
|
75
|
-
* @returns A `StepTool` that can be composed into larger pipelines.
|
|
90
|
+
* @returns A `StepTool` that can be composed into larger pipelines. The step
|
|
91
|
+
* is auto-registered in the shared step registry.
|
|
76
92
|
* @throws `NoeticConfigError` with code `EMPTY_STEP_ID` if `id` is empty.
|
|
77
93
|
* @throws `NoeticConfigError` with code `MISSING_TOOL` if `tool` is not provided.
|
|
78
94
|
*/
|
|
@@ -91,9 +107,12 @@ export const step = {
|
|
|
91
107
|
hint: 'Provide a tool definition created with the tool() builder.',
|
|
92
108
|
});
|
|
93
109
|
}
|
|
94
|
-
|
|
110
|
+
const built = {
|
|
95
111
|
kind: 'tool',
|
|
96
112
|
...opts,
|
|
97
113
|
};
|
|
114
|
+
getDefaultRegistrar().register(built);
|
|
115
|
+
return built;
|
|
98
116
|
},
|
|
99
117
|
};
|
|
118
|
+
//#endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ZodTypeAny, z } from 'zod';
|
|
2
|
-
import type { Tool } from '../types/common';
|
|
3
2
|
import type { FunctionCallItem, FunctionCallOutputItem, Item, ItemSchemaExtensions, ToolResultExtensionItem } from '../types/items';
|
|
3
|
+
import type { Tool, ToolMemoryDeclaration } from '../types/tool';
|
|
4
4
|
import type { ToolExecutionContext } from '../types/tool-context';
|
|
5
5
|
interface ToolConfig<I extends ZodTypeAny, O extends ZodTypeAny> {
|
|
6
6
|
name: string;
|
|
@@ -18,6 +18,8 @@ interface ToolConfig<I extends ZodTypeAny, O extends ZodTypeAny> {
|
|
|
18
18
|
}) => Item | ToolResultExtensionItem;
|
|
19
19
|
execute: (args: z.infer<I>, toolCtx: ToolExecutionContext) => Promise<z.infer<O>>;
|
|
20
20
|
needsApproval?: boolean;
|
|
21
|
+
/** Optional memory declaration — the runtime generates a MemoryLayer from this via toolMemoryLayer(). */
|
|
22
|
+
memory?: ToolMemoryDeclaration;
|
|
21
23
|
}
|
|
22
24
|
interface GeneratorToolConfig<I extends ZodTypeAny, E extends ZodTypeAny, O extends ZodTypeAny> {
|
|
23
25
|
name: string;
|
|
@@ -36,6 +38,8 @@ interface GeneratorToolConfig<I extends ZodTypeAny, E extends ZodTypeAny, O exte
|
|
|
36
38
|
}) => Item | ToolResultExtensionItem;
|
|
37
39
|
execute: (args: z.infer<I>, toolCtx: ToolExecutionContext) => AsyncGenerator<z.infer<E>, z.infer<O>>;
|
|
38
40
|
needsApproval?: boolean;
|
|
41
|
+
/** Optional memory declaration — the runtime generates a MemoryLayer from this via toolMemoryLayer(). */
|
|
42
|
+
memory?: ToolMemoryDeclaration;
|
|
39
43
|
}
|
|
40
44
|
/**
|
|
41
45
|
* Creates a typed Tool with Zod schema inference for input and output.
|
|
@@ -35,6 +35,7 @@ export function tool(config) {
|
|
|
35
35
|
decorateResultItem: config.decorateResultItem,
|
|
36
36
|
execute: config.execute,
|
|
37
37
|
needsApproval: config.needsApproval,
|
|
38
|
+
memory: config.memory,
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
@@ -54,6 +55,7 @@ export function toolWithGenerator(config) {
|
|
|
54
55
|
decorateResultItem: config.decorateResultItem,
|
|
55
56
|
execute: config.execute,
|
|
56
57
|
needsApproval: config.needsApproval,
|
|
58
|
+
memory: config.memory,
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
61
|
//#endregion
|