@noetic-tools/types 3.7.0 → 3.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.
@@ -9,6 +9,7 @@
9
9
  * document back into live `Step` objects via the existing builders.
10
10
  */
11
11
  import { z } from 'zod';
12
+ import type { ToolChoice } from '../types/common.js';
12
13
  import type { DecideQuestion } from '../types/decide.js';
13
14
  import type { DecideView } from '../types/step.js';
14
15
  interface UntilAnyPredicate {
@@ -226,6 +227,12 @@ export interface CallModelWorkflowNode extends WorkflowNodeBase {
226
227
  * decided by the `type` value.
227
228
  */
228
229
  tools?: z.infer<typeof CallModelToolEntrySchema>[];
230
+ /**
231
+ * How the model may use its tools: `"auto"` (default), `"required"`,
232
+ * `"none"`, or `{ "tool": "<registered-tool-name>" }` to force one client
233
+ * tool from `tools`.
234
+ */
235
+ toolChoice?: ToolChoice;
229
236
  params?: z.infer<typeof ModelParamsSchema>;
230
237
  /** Streaming output-codec reference, resolved from `HydrationContext.uiLibraries`. */
231
238
  output?: OutputCodecRef;
@@ -9,7 +9,7 @@
9
9
  * document back into live `Step` objects via the existing builders.
10
10
  */
11
11
  import { z } from 'zod';
12
- import { ServiceTier } from '../types/common.js';
12
+ import { ServiceTier, ToolChoiceMode } from '../types/common.js';
13
13
  import { DecideQuestionsSchema, routeOutcomes } from '../types/decide.js';
14
14
  //#endregion
15
15
  //#region Until Predicate Schemas
@@ -93,6 +93,12 @@ const ModelParamsSchema = z.object({
93
93
  stopSequences: z.array(z.string()).optional(),
94
94
  serviceTier: z.enum(ServiceTier).optional(),
95
95
  });
96
+ const ToolChoiceSchema = z.union([
97
+ z.enum(ToolChoiceMode),
98
+ z.object({
99
+ tool: z.string().min(1),
100
+ }),
101
+ ]);
96
102
  //#endregion
97
103
  //#region Tool Entries
98
104
  /**
@@ -230,6 +236,7 @@ const CallModelNodeSchema = z.object({
230
236
  model: z.string().optional(),
231
237
  instructions: z.string(),
232
238
  tools: z.array(CallModelToolEntrySchema).optional(),
239
+ toolChoice: ToolChoiceSchema.optional(),
233
240
  params: ModelParamsSchema.optional(),
234
241
  output: OutputCodecRefSchema.optional(),
235
242
  });
@@ -52,6 +52,25 @@ export declare const ServiceTier: {
52
52
  };
53
53
  /** @public Union of OpenRouter service tiers. */
54
54
  export type ServiceTier = (typeof ServiceTier)[keyof typeof ServiceTier];
55
+ /**
56
+ * @public How a model call may use its tools. `auto` lets the model decide,
57
+ * `required` makes it call at least one tool, `none` forbids tool calls.
58
+ */
59
+ export declare const ToolChoiceMode: {
60
+ readonly Auto: "auto";
61
+ readonly Required: "required";
62
+ readonly None: "none";
63
+ };
64
+ /** @public Union of {@link ToolChoiceMode} values. */
65
+ export type ToolChoiceMode = (typeof ToolChoiceMode)[keyof typeof ToolChoiceMode];
66
+ /**
67
+ * @public Tool choice for a model call: a {@link ToolChoiceMode}, or
68
+ * `{ tool: name }` to force a call to one client tool. It combines with the
69
+ * step's `tools` restriction (spec 02, Unified Tool Set).
70
+ */
71
+ export type ToolChoice = ToolChoiceMode | {
72
+ tool: string;
73
+ };
55
74
  /**
56
75
  * Optional parameters forwarded to the model provider during an LLM step.
57
76
  * @public
@@ -63,7 +82,12 @@ export interface ModelParams {
63
82
  topP?: number;
64
83
  /** Maximum number of tokens the model may generate. */
65
84
  maxTokens?: number;
66
- /** Sequences that cause the model to stop generating. */
85
+ /**
86
+ * Sequences that would cause the model to stop generating.
87
+ * @deprecated Not sent to the model: the OpenRouter Responses API that
88
+ * `callModel` uses has no stop parameter. Accepted so existing steps and
89
+ * workflow documents still parse; it will be removed in the next major.
90
+ */
67
91
  stopSequences?: string[];
68
92
  /** OpenRouter service tier to request. Omit to use the provider default. */
69
93
  serviceTier?: ServiceTier;
@@ -31,3 +31,12 @@ export const ServiceTier = {
31
31
  Scale: 'scale',
32
32
  Ultrafast: 'ultrafast',
33
33
  };
34
+ /**
35
+ * @public How a model call may use its tools. `auto` lets the model decide,
36
+ * `required` makes it call at least one tool, `none` forbids tool calls.
37
+ */
38
+ export const ToolChoiceMode = {
39
+ Auto: 'auto',
40
+ Required: 'required',
41
+ None: 'none',
42
+ };
@@ -1,6 +1,6 @@
1
1
  import type { StandardSchemaV1 } from '@standard-schema/spec';
2
2
  import type { Channel, ChannelHandle, ExternalChannel } from './channel.js';
3
- import type { LLMResponse, ModelParams } from './common.js';
3
+ import type { LLMResponse, ModelParams, ToolChoice } from './common.js';
4
4
  import type { Context, CwdState, RestoreContextOptions } from './context.js';
5
5
  import type { ContextCacheConfig, ContextCacheStore } from './context-cache.js';
6
6
  import type { ContextData, ContextLayer, ProjectionPolicy, RecallOptions, StorageAdapter } from './context-layer.js';
@@ -29,6 +29,7 @@ interface ContextCallModelRequestBase {
29
29
  items: ReadonlyArray<Item>;
30
30
  instructions?: string;
31
31
  params?: ModelParams;
32
+ toolChoice?: ToolChoice;
32
33
  outputSchema?: StandardSchemaV1;
33
34
  /** Explicit non-Zod override/fallback after StandardJSONSchemaV1 conversion. */
34
35
  outputJsonSchema?: Record<string, unknown>;
@@ -17,6 +17,7 @@ export interface LayerTimeouts {
17
17
  store?: number;
18
18
  onSpawn?: number;
19
19
  onReturn?: number;
20
+ onParentUpdate?: number;
20
21
  onComplete?: number;
21
22
  dispose?: number;
22
23
  beforeToolCall?: number;
@@ -246,6 +247,21 @@ export interface ReturnResult<TState> {
246
247
  parentState: TState;
247
248
  result?: unknown;
248
249
  }
250
+ /** @public Parameters passed to a context layer's `onParentUpdate` hook when the parent writes the layer's state while a child runs. */
251
+ export interface ParentUpdateParams<TState> {
252
+ /** The state the parent just wrote. */
253
+ parentState: TState;
254
+ /** The child's state for the layer when the hook starts. */
255
+ childState: TState;
256
+ childCtx: ExecutionContext;
257
+ }
258
+ /** @public Value returned by a context layer's `onParentUpdate` hook. */
259
+ export interface ParentUpdateResult<TState> {
260
+ /** New child state. Detected with `'childState' in result`, so `undefined` clears it. */
261
+ childState?: TState;
262
+ /** Items appended to the child's ItemLog. */
263
+ items?: Item[];
264
+ }
249
265
  /** @public Parameters passed to a context layer's `onComplete` hook at execution end. */
250
266
  export interface CompleteParams<TState> {
251
267
  log: ItemLog;
@@ -325,6 +341,12 @@ export interface ContextLayerHooks<TState = unknown> {
325
341
  store?(params: StoreParams<TState>): Promise<StoreResult<TState> | undefined>;
326
342
  onSpawn?(params: SpawnParams<TState>): Promise<SpawnResult<TState> | null>;
327
343
  onReturn?(params: ReturnParams<TState>): Promise<ReturnResult<TState> | undefined>;
344
+ /**
345
+ * Called in a live child when its parent writes this layer's state. Runs in
346
+ * the background: the parent's write never waits for it or fails because of
347
+ * it. Return nothing to ignore the update.
348
+ */
349
+ onParentUpdate?(params: ParentUpdateParams<TState>): Promise<ParentUpdateResult<TState> | undefined>;
328
350
  onComplete?(params: CompleteParams<TState>): Promise<undefined | {
329
351
  state: TState;
330
352
  }>;
@@ -12,6 +12,15 @@ export interface LayerCallModelRequest {
12
12
  items: ReadonlyArray<Item>;
13
13
  instructions?: string;
14
14
  }
15
+ /**
16
+ * @public Span opened from an `ExecutionContext`. `end()` closes the span and
17
+ * hands it to the harness's trace exporter; await it so the export finishes.
18
+ */
19
+ export interface ExecutionSpan {
20
+ setAttribute(key: string, value: string | number | boolean): void;
21
+ addEvent(name: string, attributes?: Record<string, string | number | boolean>): void;
22
+ end(): Promise<void>;
23
+ }
15
24
  /** @public Runtime metadata available to context layer hooks during each lifecycle phase. */
16
25
  export interface ExecutionContext {
17
26
  executionId: string;
@@ -33,6 +42,11 @@ export interface ExecutionContext {
33
42
  trace: {
34
43
  setAttribute(key: string, value: string | number | boolean): void;
35
44
  addEvent(name: string, attributes?: Record<string, string | number | boolean>): void;
45
+ /**
46
+ * Opens a span under the context's span. Optional: a context with no span
47
+ * tree to grow omits it, and callers fall back to `addEvent`.
48
+ */
49
+ createSpan?(name: string): ExecutionSpan;
36
50
  };
37
51
  /** Snapshot a sibling context layer's state by its `layer.id`. */
38
52
  readLayerState<T>(layerId: string): T | undefined;
@@ -14,7 +14,7 @@ export interface TraceExporter {
14
14
  /** @public Diagnostic span recording a single context layer hook invocation and its outcome. */
15
15
  export interface LayerTraceSpan {
16
16
  layerId: string;
17
- hook: 'init' | 'recall' | 'store' | 'onSpawn' | 'onReturn' | 'onComplete' | 'dispose';
17
+ hook: 'init' | 'recall' | 'store' | 'onSpawn' | 'onReturn' | 'onParentUpdate' | 'onComplete' | 'dispose' | 'onDecision' | 'beforeToolCall' | 'afterModelCall' | 'projectHistory' | 'onItemAppend';
18
18
  /** Duration in milliseconds. */
19
19
  duration: number;
20
20
  status: 'ok' | 'error' | 'timeout' | 'skipped';
@@ -1,6 +1,6 @@
1
1
  import type { StandardSchemaV1 } from '@standard-schema/spec';
2
2
  import type { Channel, ChannelHandle, ExternalChannel } from './channel.js';
3
- import type { LLMResponse, ModelParams, ServerToolSpec } from './common.js';
3
+ import type { LLMResponse, ModelParams, ServerToolSpec, ToolChoice } from './common.js';
4
4
  import type { Context, CwdState, RestoreContextOptions } from './context.js';
5
5
  import type { ContextCacheConfig, ContextCacheStore } from './context-cache.js';
6
6
  import type { ContextData, ContextLayer, ProjectionPolicy, RecallOptions, StorageAdapter } from './context-layer.js';
@@ -11,6 +11,7 @@ import type { HarnessResponse, StreamEvent, StreamingItem } from './harness-resu
11
11
  import type { ExecuteInput, Item, ItemSchemaExtensions } from './items.js';
12
12
  import type { Span, TraceExporter } from './observability.js';
13
13
  import type { ShellAdapter } from './shell-adapter.js';
14
+ import type { ToolApprover } from './steering.js';
14
15
  import type { Step } from './step.js';
15
16
  import type { SubprocessAdapter } from './subprocess-adapter.js';
16
17
  import type { Tool } from './tool.js';
@@ -42,6 +43,8 @@ export interface AgentConfig<TParams extends Record<string, unknown> = Record<st
42
43
  contextCache?: ContextCacheConfig;
43
44
  /** Default model for `decide` steps. */
44
45
  decisionModel?: string;
46
+ /** Approves or refuses calls to tools that declare `needsApproval`. Without one, those calls run unapproved. */
47
+ approveToolCall?: ToolApprover;
45
48
  }
46
49
  /** @public How a message submitted during an active turn is delivered to the model.
47
50
  *
@@ -60,6 +63,12 @@ interface CallModelRequestBase {
60
63
  items: ReadonlyArray<Item>;
61
64
  instructions?: string;
62
65
  params?: ModelParams;
66
+ /**
67
+ * How the model may use its tools. Defaults to `'auto'`. Combines with
68
+ * `allowedToolNames` (spec 02, Unified Tool Set). A `{ tool }` naming a tool
69
+ * the call cannot run throws `NoeticConfigError` `UNKNOWN_TOOL_CHOICE`.
70
+ */
71
+ toolChoice?: ToolChoice;
63
72
  /** When provided, the harness sends a JSON Schema constraint to the model so it returns structured JSON. */
64
73
  outputSchema?: StandardSchemaV1;
65
74
  /**
@@ -94,6 +103,12 @@ interface CallModelRequestBase {
94
103
  * each span back to its node in the declared DAG.
95
104
  */
96
105
  nodeId?: string;
106
+ /**
107
+ * @internal Attributes for the first `llm.call` span this request opens. Set
108
+ * by `callModel` steps to record how the view was banded (the
109
+ * `noetic.context.*` anchoring attributes).
110
+ */
111
+ spanAttributes?: Record<string, string | number | boolean>;
97
112
  }
98
113
  /** @public Request shape when tools are provided — ctx is required for tool execution callbacks. */
99
114
  interface CallModelRequestWithTools extends CallModelRequestBase {
@@ -1,4 +1,5 @@
1
1
  import type { LLMResponse } from './common.js';
2
+ import type { Context } from './context.js';
2
3
  import type { ContextScope, ExecutionContext } from './context-scope.js';
3
4
  /** @public Enumeration of actions a steering rule can take on a tool call or model response. */
4
5
  export declare const SteeringAction: {
@@ -59,6 +60,30 @@ export interface BeforeToolCallResult<TState = unknown> {
59
60
  decision: SteeringDecision;
60
61
  state?: TState;
61
62
  }
63
+ /**
64
+ * @public Parameters passed to the harness approver for a call to a tool that
65
+ * declares `needsApproval`.
66
+ */
67
+ export interface ApproveToolCallParams {
68
+ toolName: string;
69
+ /** The validated arguments — exactly what `execute` receives if the call is approved. */
70
+ toolArgs: unknown;
71
+ /** Correlation id of the pending call; see `BeforeToolCallParams.callId`. */
72
+ callId?: string;
73
+ /**
74
+ * The calling step's context. An approver that waits on a human passes it
75
+ * to `ctx.harness.send` / `ctx.harness.recv` to park on a channel.
76
+ */
77
+ ctx: Context;
78
+ }
79
+ /**
80
+ * @public Decides whether a call to a tool that declares `needsApproval` may
81
+ * run. Configured once per harness (`AgentHarness({ approveToolCall })`) and
82
+ * consulted after every `beforeToolCall` layer has allowed the call. `allow`
83
+ * runs the call; any other action refuses it, with `guidance` as the reason.
84
+ * May be async and may wait — e.g. on a channel a human answers.
85
+ */
86
+ export type ToolApprover = (params: ApproveToolCallParams) => SteeringDecision | Promise<SteeringDecision>;
62
87
  /** @public Parameters passed to a steering rule's `afterModelCall` evaluation. */
63
88
  export interface AfterModelCallParams<TState = unknown> {
64
89
  response: LLMResponse;
@@ -1,7 +1,7 @@
1
1
  import type { StandardSchemaV1 } from '@standard-schema/spec';
2
2
  import type { AcpAgent, AcpClientCapabilityConfig, AcpContentBlock, AcpMcpServer, AcpPermissionHandler, AcpPermissionPolicy, AcpSessionPolicy } from './acp.js';
3
3
  import type { Channel } from './channel.js';
4
- import type { ModelParams, RetryPolicy, ServerToolSpec, StepMeta } from './common.js';
4
+ import type { ModelParams, RetryPolicy, ServerToolSpec, StepMeta, ToolChoice } from './common.js';
5
5
  import type { Context } from './context.js';
6
6
  import type { ContextConfig, ContextData, ContextLayer, ProjectionPolicy } from './context-layer.js';
7
7
  import type { DecideAnswers, DecideQuestions } from './decide.js';
@@ -138,6 +138,12 @@ export interface StepCallModel<TContext = ContextData, I = unknown, O = unknown>
138
138
  * they are resolved per execution.
139
139
  */
140
140
  tools?: Lazy<(Tool | ServerToolSpec)[] | undefined, TContext>;
141
+ /**
142
+ * How the model may use its tools: `'auto'` (default), `'required'`,
143
+ * `'none'`, or `{ tool: name }` to force one client tool. Applies within the
144
+ * `tools` restriction; see spec 02, Unified Tool Set.
145
+ */
146
+ toolChoice?: ToolChoice;
141
147
  /**
142
148
  * Structured output: a Standard Schema (assistant text is JSON-parsed and
143
149
  * validated) or a streaming `OutputCodec` (fed each text delta, produces
@@ -66,6 +66,13 @@ export interface StepSubprocessRequest extends SubprocessRequestBase {
66
66
  serializedInput: unknown;
67
67
  /** Stable id for the execution — used for handle lookup and durable checkpointing. */
68
68
  executionId: string;
69
+ /**
70
+ * Id of the context that created this child (`spawn`, `detachedSpawn`).
71
+ * Durable adapters persist it so a host can `harness.restore()` the parent
72
+ * after a restart. Absent for a `runCode`, which runs on the dispatching
73
+ * context itself.
74
+ */
75
+ parentExecutionId?: string;
69
76
  /** Child-context overrides (thread, resource, cwd). */
70
77
  overrides: StepSubprocessOverrides;
71
78
  /**
@@ -92,6 +99,8 @@ export interface SubprocessHandleMetadata extends Record<string, unknown> {
92
99
  error?: SerializedError;
93
100
  /** Execution id echoed from the originating `StepSubprocessRequest`. */
94
101
  executionId?: string;
102
+ /** Parent execution id echoed from the originating `StepSubprocessRequest`. */
103
+ parentExecutionId?: string;
95
104
  }
96
105
  /** @public Handle returned by `SubprocessAdapter.spawn()` — a durable reference to a child. */
97
106
  export interface SubprocessHandle {
@@ -127,7 +127,12 @@ export interface Tool<I extends StandardSchemaV1 = StandardSchemaV1, O extends S
127
127
  * the call site to get a typed handle.
128
128
  */
129
129
  execute(args: InferSchemaOutput<I>, toolCtx: unknown): ToolExecutionResult<O>;
130
- /** When true, execution pauses for human approval before running. */
130
+ /**
131
+ * Every call needs approval before it runs. The harness asks its
132
+ * `approveToolCall` approver after the `beforeToolCall` layers allow the
133
+ * call. With no approver configured the call runs unapproved and the
134
+ * harness warns once per tool name.
135
+ */
131
136
  needsApproval?: boolean;
132
137
  /** Optional context declaration — the runtime generates a ContextLayer from this. */
133
138
  context?: ToolContextDeclaration;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noetic-tools/types",
3
- "version": "3.7.0",
3
+ "version": "3.9.0",
4
4
  "type": "module",
5
5
  "description": "Foundational type contracts and primitives shared across the Noetic framework (items, LLM config, adapters, steering, errors).",
6
6
  "license": "Apache-2.0",