@noetic-tools/types 3.2.0 → 3.2.2

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.
@@ -1,11 +1,11 @@
1
1
  import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+ import type { AcpAgent, AcpClientCapabilityConfig, AcpContentBlock, AcpMcpServer, AcpPermissionHandler, AcpPermissionPolicy, AcpSessionPolicy } from './acp.js';
2
3
  import type { Channel } from './channel.js';
3
4
  import type { ModelParams, RetryPolicy, ServerToolSpec, StepMeta } from './common.js';
4
5
  import type { Context } from './context.js';
5
6
  import type { ContextConfig, ContextData, ContextLayer, ProjectionPolicy } from './context-layer.js';
6
7
  import type { NoeticError } from './error.js';
7
8
  import type { OutputCodec } from './output-codec.js';
8
- import type { SubHarness, SubHarnessKind, SubHarnessSessionPolicy, SubHarnessSettings } from './sub-harness.js';
9
9
  import type { SubprocessAdapter } from './subprocess-adapter.js';
10
10
  import type { Tool } from './tool.js';
11
11
  /**
@@ -52,13 +52,14 @@ export interface Verdict {
52
52
  export type Until = (snapshot: Snapshot) => Verdict | Promise<Verdict>;
53
53
  /**
54
54
  * Field type that accepts either an eager value or a `(ctx) => value` getter.
55
- * Used by `step.llm` for params that may vary per execution (model, instructions,
56
- * tool list). The getter runs at step execution time with the live context.
55
+ * Used by `step.callModel` for params that may vary per execution (model,
56
+ * instructions, tool list). The getter runs at step execution time with the
57
+ * live context.
57
58
  * @public
58
59
  */
59
60
  export type Lazy<T, TContext = ContextData> = T | ((ctx: Context<TContext>) => T | Promise<T>);
60
61
  /**
61
- * Outcome of a single path in a `settle`-mode fork (mirrors `Promise.allSettled`).
62
+ * Outcome of a single path in a `settle`-mode inParallel step (mirrors `Promise.allSettled`).
62
63
  * @public
63
64
  */
64
65
  export interface SettleResult<O> {
@@ -72,10 +73,10 @@ export interface SettleResult<O> {
72
73
  error?: NoeticError;
73
74
  }
74
75
  /** @public Discriminated union of all step kinds that can be composed into an execution tree. */
75
- export type Step<TContext = ContextData, I = unknown, O = unknown> = StepRun<TContext, I, O> | StepLLM<TContext, I, O> | StepSubHarness<TContext, I, O> | StepTool<TContext, I, O> | StepBranch<TContext, I, O> | StepFork<TContext, I, O> | StepSpawn<TContext, I, O> | StepProvide<TContext, I, O> | StepLoop<TContext, I, O> | StepEvery<TContext, I, O>;
76
+ export type Step<TContext = ContextData, I = unknown, O = unknown> = StepRunCode<TContext, I, O> | StepCallModel<TContext, I, O> | StepAcpAgent<TContext, I, O> | StepInvokeTool<TContext, I, O> | StepConditional<TContext, I, O> | StepInParallel<TContext, I, O> | StepSpawn<TContext, I, O> | StepWithContext<TContext, I, O> | StepLoop<TContext, I, O> | StepSchedule<TContext, I, O>;
76
77
  /** @public A step that executes arbitrary async logic via a user-supplied function. */
77
- export interface StepRun<TContext = ContextData, I = unknown, O = unknown> {
78
- kind: 'run';
78
+ export interface StepRunCode<TContext = ContextData, I = unknown, O = unknown> {
79
+ kind: 'runCode';
79
80
  id: string;
80
81
  execute: (input: I, ctx: Context<TContext>) => Promise<O>;
81
82
  retry?: RetryPolicy;
@@ -88,8 +89,8 @@ export interface StepRun<TContext = ContextData, I = unknown, O = unknown> {
88
89
  subprocess?: SubprocessAdapter;
89
90
  }
90
91
  /** @public A step that sends a prompt to a language model and returns its response. */
91
- export interface StepLLM<TContext = ContextData, _I = unknown, O = unknown> {
92
- kind: 'llm';
92
+ export interface StepCallModel<TContext = ContextData, _I = unknown, O = unknown> {
93
+ kind: 'callModel';
93
94
  id: string;
94
95
  /** Model id. Accepts either an eager string or a `(ctx) => string` getter. */
95
96
  model: Lazy<string, TContext>;
@@ -122,63 +123,77 @@ export interface StepLLM<TContext = ContextData, _I = unknown, O = unknown> {
122
123
  projection?: ProjectionPolicy;
123
124
  }
124
125
  /**
125
- * A step that delegates a turn to an external coding-agent harness
126
- * (Claude Code, Codex, opencode, pi). Each harness kind is a distinct
127
- * `Step.kind`, but every variant shares this shape and is executed by one
128
- * interpreter handler.
126
+ * A step that delegates a turn to an external coding agent over the Agent
127
+ * Client Protocol. One step kind serves every ACP-speaking agent — the agent
128
+ * itself is supplied as an adapter, so the set of supported agents is open.
129
129
  * @public
130
130
  */
131
- export interface StepSubHarness<TContext = ContextData, _I = unknown, O = unknown> {
132
- /** The harness kind, equal to the backing adapter's `harnessId`. */
133
- kind: SubHarnessKind;
131
+ export interface StepAcpAgent<TContext = ContextData, _I = unknown, O = unknown> {
132
+ kind: 'acp-agent';
134
133
  id: string;
135
134
  /**
136
- * The harness adapter that runs the turn. Eager or `(ctx) => SubHarness`.
135
+ * The ACP agent adapter that runs the turn. Eager or `(ctx) => AcpAgent`.
137
136
  * Programmatic builders take it inline; the JSON hydrator resolves it from
138
- * the workflow's harness registry and inlines it here.
137
+ * the workflow's agent registry and inlines it here.
139
138
  */
140
- harness: Lazy<SubHarness, TContext>;
141
- /** Turn prompt. Eager string or `(ctx) => string` getter. */
142
- prompt: Lazy<string, TContext>;
143
- /** Shared harness settings (model, permission mode, …). */
144
- settings?: SubHarnessSettings;
145
- /** System instructions applied on the first message of a fresh session. */
146
- instructions?: Lazy<string | undefined, TContext>;
139
+ agent: Lazy<AcpAgent, TContext>;
140
+ /** Turn prompt as plain text. Eager string or `(ctx) => string` getter. */
141
+ prompt?: Lazy<string, TContext>;
142
+ /**
143
+ * Full ACP prompt content — images, audio, resource links, embedded context.
144
+ * Appended after `prompt` when both are given. Validated against the agent's
145
+ * advertised `promptCapabilities` before the turn is sent.
146
+ */
147
+ content?: Lazy<ReadonlyArray<AcpContentBlock> | undefined, TContext>;
148
+ /** MCP servers to expose to the agent for this session. */
149
+ mcpServers?: Lazy<ReadonlyArray<AcpMcpServer> | undefined, TContext>;
150
+ /** Working directory for the session. Defaults to `ctx.cwdState.cwd`. */
151
+ cwd?: Lazy<string | undefined, TContext>;
152
+ /** Session mode to switch to before prompting (e.g. `'plan'`). */
153
+ mode?: Lazy<string | undefined, TContext>;
154
+ /** Model to select before prompting, for agents that expose model selection. */
155
+ model?: Lazy<string | undefined, TContext>;
156
+ /** Declarative answer to the agent's permission requests. */
157
+ permissions?: AcpPermissionPolicy;
158
+ /** Async resolver consulted when policy and steering both abstain. */
159
+ onPermissionRequest?: AcpPermissionHandler;
160
+ /** Which client capabilities to advertise to the agent. */
161
+ clientCapabilities?: AcpClientCapabilityConfig;
147
162
  /** When set, the assistant text is JSON-parsed and validated against this Standard Schema. */
148
163
  output?: StandardSchemaV1<unknown, O>;
149
164
  /** Session reuse + teardown policy across steps. */
150
- session?: SubHarnessSessionPolicy;
165
+ session?: AcpSessionPolicy;
151
166
  /** Controls framework event emission for this step. Defaults to `true`. */
152
167
  emit?: boolean | ((eventType: string, data: Record<string, unknown>) => boolean);
153
168
  }
154
- /** @public A step that invokes a single tool directly, bypassing the LLM. */
155
- export interface StepTool<_TContext = ContextData, I = unknown, O = unknown> {
156
- kind: 'tool';
169
+ /** @public A step that invokes a single tool directly, bypassing the model. */
170
+ export interface StepInvokeTool<_TContext = ContextData, I = unknown, O = unknown> {
171
+ kind: 'invokeTool';
157
172
  id: string;
158
173
  tool: Tool<StandardSchemaV1<unknown, I>, StandardSchemaV1<unknown, O>>;
159
174
  args?: Partial<I>;
160
175
  }
161
176
  /** @public A step that dynamically selects and executes one of several possible sub-steps. */
162
- export interface StepBranch<TContext = ContextData, I = unknown, O = unknown> {
163
- kind: 'branch';
177
+ export interface StepConditional<TContext = ContextData, I = unknown, O = unknown> {
178
+ kind: 'conditional';
164
179
  id: string;
165
180
  route: (input: I, ctx: Context<TContext>) => Step<TContext, I, O> | null | Promise<Step<TContext, I, O> | null>;
166
181
  _optimizable?: Step<TContext>[];
167
182
  }
168
- /** @public Union of fork step variants (`race`, `all`, `settle`) for concurrent path execution. */
169
- export type StepFork<TContext = ContextData, I = unknown, O = unknown> = StepForkRace<TContext, I, O> | StepForkAll<TContext, I, O> | StepForkSettle<TContext, I, O>;
170
- /** @public A fork step that returns the result of the first path to complete. */
171
- export interface StepForkRace<TContext = ContextData, I = unknown, O = unknown> {
172
- kind: 'fork';
183
+ /** @public Union of inParallel step variants (`race`, `all`, `settle`) for concurrent path execution. */
184
+ export type StepInParallel<TContext = ContextData, I = unknown, O = unknown> = StepInParallelRace<TContext, I, O> | StepInParallelAll<TContext, I, O> | StepInParallelSettle<TContext, I, O>;
185
+ /** @public An inParallel step that returns the result of the first path to complete. */
186
+ export interface StepInParallelRace<TContext = ContextData, I = unknown, O = unknown> {
187
+ kind: 'inParallel';
173
188
  id: string;
174
189
  mode: 'race';
175
190
  paths: (input: I, ctx: Context<TContext>) => Step<TContext, I, O>[];
176
191
  concurrency?: number;
177
192
  _optimizable?: Step<TContext>[];
178
193
  }
179
- /** @public A fork step that runs all paths and merges their results. */
180
- export interface StepForkAll<TContext = ContextData, I = unknown, O = unknown> {
181
- kind: 'fork';
194
+ /** @public An inParallel step that runs all paths and merges their results. */
195
+ export interface StepInParallelAll<TContext = ContextData, I = unknown, O = unknown> {
196
+ kind: 'inParallel';
182
197
  id: string;
183
198
  mode: 'all';
184
199
  paths: (input: I, ctx: Context<TContext>) => Step<TContext, I, O>[];
@@ -186,9 +201,9 @@ export interface StepForkAll<TContext = ContextData, I = unknown, O = unknown> {
186
201
  concurrency?: number;
187
202
  _optimizable?: Step<TContext>[];
188
203
  }
189
- /** @public A fork step that runs all paths and collects fulfilled/rejected outcomes. */
190
- export interface StepForkSettle<TContext = ContextData, I = unknown, O = unknown> {
191
- kind: 'fork';
204
+ /** @public An inParallel step that runs all paths and collects fulfilled/rejected outcomes. */
205
+ export interface StepInParallelSettle<TContext = ContextData, I = unknown, O = unknown> {
206
+ kind: 'inParallel';
192
207
  id: string;
193
208
  mode: 'settle';
194
209
  paths: (input: I, ctx: Context<TContext>) => Step<TContext, I, O>[];
@@ -202,8 +217,8 @@ export interface StepForkSettle<TContext = ContextData, I = unknown, O = unknown
202
217
  * Spawn and detachedSpawn break the inheritance chain.
203
218
  * @public
204
219
  */
205
- export interface StepProvide<TContext = ContextData, I = unknown, O = unknown> {
206
- kind: 'provide';
220
+ export interface StepWithContext<TContext = ContextData, I = unknown, O = unknown> {
221
+ kind: 'withContext';
207
222
  id: string;
208
223
  child: Step<TContext, I, O>;
209
224
  context: ContextConfig | ContextLayer[];
@@ -248,33 +263,33 @@ export interface StepLoop<TContext = ContextData, I = unknown, O = unknown> {
248
263
  onError?: (error: NoeticError, ctx: Context<TContext>) => 'retry' | 'skip' | 'abort';
249
264
  }
250
265
  /**
251
- * Error policy for the `every` operator when its body step throws.
266
+ * Error policy for the `schedule` operator when its body step throws.
252
267
  * - `'continue'` (default): emit a span event recording the error and continue parking.
253
268
  * - `'fail'`: re-throw, terminating the operator.
254
269
  * @public
255
270
  */
256
- export type EveryErrorPolicy = 'continue' | 'fail';
271
+ export type ScheduleErrorPolicy = 'continue' | 'fail';
257
272
  /**
258
273
  * A step that runs a body step on a fixed-interval schedule, optionally woken
259
- * sooner by a wake channel. Runs forever until the executing context is cancelled.
274
+ * sooner by an inbox channel. Runs forever until the executing context is cancelled.
260
275
  *
261
- * The operator output is `void` — `every` does not accumulate iteration outputs.
276
+ * The operator output is `void` — `schedule` does not accumulate iteration outputs.
262
277
  * The `O` type parameter exists only to anchor the body step's output type.
263
278
  *
264
279
  * @public
265
280
  */
266
- export interface StepEvery<TContext = ContextData, I = unknown, O = unknown> {
267
- kind: 'every';
281
+ export interface StepSchedule<TContext = ContextData, I = unknown, O = unknown> {
282
+ kind: 'schedule';
268
283
  /** Unique step identifier used in traces and error messages. */
269
284
  id: string;
270
285
  /** Body step executed on each iteration. */
271
286
  step: Step<TContext, I, O>;
272
287
  /** Park duration between iterations in milliseconds. Must be >= 0. */
273
- ms: number;
288
+ interval: number;
274
289
  /** Optional channel that wakes the parking interval when any value arrives. */
275
- wakeOn?: Channel<unknown>;
290
+ inbox?: Channel<unknown>;
276
291
  /** Behavior when `step` throws. Defaults to `'continue'`. */
277
- onError?: EveryErrorPolicy;
292
+ onError?: ScheduleErrorPolicy;
278
293
  /** Random jitter applied to the park duration in milliseconds. Must be >= 0. Default 0. */
279
294
  jitter?: number;
280
295
  }
@@ -25,13 +25,6 @@ export interface ToolExecutionContext {
25
25
  readonly shell: ShellAdapter;
26
26
  /** Per-layer state accessor for reading/writing tool-specific state. */
27
27
  readonly context: ToolContext;
28
- /**
29
- * @deprecated Renamed to `context`. Returns the same accessor.
30
- *
31
- * Required for the same reason as `Context.memory` — pre-rename code calls
32
- * `toolCtx.memory.get(...)` directly.
33
- */
34
- readonly memory: ToolContext;
35
28
  /** The fully assembled conversation view at the point of tool invocation. */
36
29
  readonly assembledView: ReadonlyArray<Item>;
37
30
  /** Metadata from the most recent step execution (token usage, tool calls, etc.). */
@@ -98,7 +98,14 @@ export function trackUsage(ctx, response) {
98
98
  ctx.tokens.input += response.usage.inputTokens;
99
99
  ctx.tokens.output += response.usage.outputTokens;
100
100
  ctx.tokens.total += response.usage.inputTokens + response.usage.outputTokens;
101
- ctx.tokens.cached = (ctx.tokens.cached ?? 0) + (response.usage.cachedTokens ?? 0);
101
+ // Only write `cached` when the response actually carried a figure. Defaulting
102
+ // a missing report to 0 would erase the `RoundUsage` invariant that
103
+ // `undefined` means "this provider says nothing about caching" — callers that
104
+ // steer on cache behaviour could no longer tell that from "nothing was
105
+ // cached". Mirrors the child→parent merge in execute-action.
106
+ if (response.usage.cachedTokens !== undefined) {
107
+ ctx.tokens.cached = (ctx.tokens.cached ?? 0) + response.usage.cachedTokens;
108
+ }
102
109
  if (response.cost) {
103
110
  ctx.cost = ctx.cost + response.cost;
104
111
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noetic-tools/types",
3
- "version": "3.2.0",
3
+ "version": "3.2.2",
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",
@@ -56,6 +56,7 @@
56
56
  "dependencies": {
57
57
  "@openrouter/agent": "^0.6.0",
58
58
  "@standard-schema/spec": "1.1.0",
59
+ "@zed-industries/agent-client-protocol": "^0.4.5",
59
60
  "zod": "^4.0.0"
60
61
  },
61
62
  "scripts": {
@@ -1,39 +0,0 @@
1
- /**
2
- * Deprecated aliases from the "memory layer" era of the framework.
3
- *
4
- * The layer system assembles the model's *context window* — recall, budget
5
- * allocation, history projection, the item-append pipeline — so it is named
6
- * after context, not memory. Every name below still resolves to its
7
- * replacement; nothing here changes behaviour.
8
- *
9
- * These are scheduled for removal in the next major of `@noetic-tools/types`.
10
- */
11
- import type { ContextConfig, ContextData, ContextLayer, ContextLayerHooks, InferContext, InferContextShape } from './types/context-layer.js';
12
- import type { ContextScope, LayerCallModelRequest } from './types/context-scope.js';
13
- import type { LayerTraceSpan } from './types/observability.js';
14
- import type { ToolContextDeclaration } from './types/tool.js';
15
- import type { ToolContext } from './types/tool-context.js';
16
- /** @public @deprecated Renamed to {@link ContextLayer}. */
17
- export type MemoryLayer<TState = unknown> = ContextLayer<TState>;
18
- /** @public @deprecated Renamed to {@link ContextLayerHooks}. */
19
- export type MemoryHooks<TState = unknown> = ContextLayerHooks<TState>;
20
- /** @public @deprecated Renamed to {@link ContextConfig}. */
21
- export type MemoryConfig<TLayers extends readonly ContextLayer[] = readonly ContextLayer[]> = ContextConfig<TLayers>;
22
- /** @public @deprecated Renamed to {@link ContextData}. */
23
- export type ContextMemory = ContextData;
24
- /** @public @deprecated Renamed to {@link InferContext}. */
25
- export type InferMemory<T extends {
26
- readonly _shape: unknown;
27
- }> = InferContext<T>;
28
- /** @public @deprecated Renamed to {@link InferContextShape}. */
29
- export type InferMemoryShape<T extends readonly ContextLayer[]> = InferContextShape<T>;
30
- /** @public @deprecated Renamed to {@link ContextScope}. */
31
- export type MemoryScope = ContextScope;
32
- /** @public @deprecated Renamed to {@link LayerCallModelRequest}. */
33
- export type MemoryCallModelRequest = LayerCallModelRequest;
34
- /** @public @deprecated Renamed to {@link LayerTraceSpan}. */
35
- export type MemoryTraceSpan = LayerTraceSpan;
36
- /** @public @deprecated Renamed to {@link ToolContext}. */
37
- export type ToolMemory = ToolContext;
38
- /** @public @deprecated Renamed to {@link ToolContextDeclaration}. */
39
- export type ToolMemoryDeclaration<TState = unknown> = ToolContextDeclaration<TState>;
@@ -1,273 +0,0 @@
1
- /**
2
- * Coding-agent harness contract.
3
- *
4
- * A "harness" here is a pluggable backend that drives an external agentic
5
- * coding tool — Claude Code, Codex, opencode, pi — as a Noetic step. It is the
6
- * direct analogue of the `ContextLayer` contract: defined in the dependency-free
7
- * `@noetic-tools/types` foundation so both `@noetic-tools/core` (which executes
8
- * harness steps) and the per-tool `@noetic-tools/sub-harness-*` packages (which
9
- * implement them) can depend on it without forming a cycle.
10
- *
11
- * Modelled on Vercel's `HarnessV1` spec: a tagged spec version, a small set of
12
- * descriptive fields, and a single `doStart` entry point that yields a session.
13
- * Optional capabilities are signalled by the presence of optional methods, not
14
- * a static capabilities object — an adapter that cannot satisfy a request
15
- * throws {@link SubHarnessCapabilityError} from the relevant method.
16
- */
17
- import { z } from 'zod';
18
- import type { TokenUsage } from './common.js';
19
- import type { FsAdapter } from './fs-adapter.js';
20
- import type { Item } from './items.js';
21
- import type { ShellAdapter } from './shell-adapter.js';
22
- import type { SubprocessAdapter } from './subprocess-adapter.js';
23
- /**
24
- * The set of harness step kinds. Each value is a distinct `Step.kind`, so a
25
- * `step.claudeCode(...)` and a `step.codex(...)` are separate, individually
26
- * typed step variants — while the interpreter routes all of them through a
27
- * single shared `executeSubHarness` handler.
28
- * @public
29
- */
30
- export declare const SubHarnessKind: {
31
- readonly ClaudeCode: 'claude-code';
32
- readonly Codex: 'codex';
33
- readonly Opencode: 'opencode';
34
- readonly Pi: 'pi';
35
- };
36
- /** @public Union of all harness step kinds. */
37
- export type SubHarnessKind = (typeof SubHarnessKind)[keyof typeof SubHarnessKind];
38
- /** @public Ordered list of every harness kind — the single source of truth consumed by the JSON schema and the interpreter. */
39
- export declare const SUB_HARNESS_KINDS: ReadonlyArray<SubHarnessKind>;
40
- /**
41
- * Settings shared by every harness step. Tool-specific knobs that don't map to
42
- * a shared concept go through `extra`, which each adapter interprets (and may
43
- * reject with {@link SubHarnessCapabilityError}).
44
- * @public
45
- */
46
- export interface SubHarnessSettings {
47
- /** Model identifier for the underlying agent (e.g. `claude-opus-4-8`). */
48
- model?: string;
49
- /** Permission posture for tool/file mutations the agent attempts. */
50
- permissionMode?: 'default' | 'plan' | 'acceptEdits' | 'bypassPermissions';
51
- /** Hard cap on internal agent turns before it must yield. */
52
- maxTurns?: number;
53
- /** Restrict the agent to this set of built-in tool names. */
54
- allowedTools?: ReadonlyArray<string>;
55
- /** Tool-specific passthrough options interpreted by the adapter. */
56
- extra?: Record<string, unknown>;
57
- }
58
- /**
59
- * Controls how a harness session is reused and torn down across steps.
60
- * @public
61
- */
62
- export interface SubHarnessSessionPolicy {
63
- /**
64
- * Reuse a live session keyed by this id across multiple harness steps. When
65
- * omitted, each step gets a fresh session that is stopped on completion.
66
- */
67
- reuse?: string;
68
- /**
69
- * Lifecycle action when the step completes. `'stop'` (default) persists state
70
- * and stops the runtime; `'detach'` parks it for later resume; `'destroy'`
71
- * discards it with no resume state.
72
- */
73
- onComplete?: 'stop' | 'detach' | 'destroy';
74
- }
75
- /** @public Why an agentic turn ended. */
76
- export type SubHarnessFinishReason = 'stop' | 'length' | 'aborted' | 'error' | 'tool-calls';
77
- /**
78
- * Runtime validation schema for {@link SubHarnessStreamPart}. Adapters that move
79
- * events across a process or transport boundary (e.g. a sandbox bridge)
80
- * validate with this before forwarding.
81
- * @public
82
- */
83
- export declare const SubHarnessStreamPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
84
- type: z.ZodLiteral<"stream-start">;
85
- }, z.core.$strip>, z.ZodObject<{
86
- type: z.ZodLiteral<"text-delta">;
87
- delta: z.ZodString;
88
- }, z.core.$strip>, z.ZodObject<{
89
- type: z.ZodLiteral<"reasoning-delta">;
90
- delta: z.ZodString;
91
- }, z.core.$strip>, z.ZodObject<{
92
- type: z.ZodLiteral<"tool-call">;
93
- toolCallId: z.ZodString;
94
- toolName: z.ZodString;
95
- input: z.ZodUnknown;
96
- providerExecuted: z.ZodOptional<z.ZodBoolean>;
97
- }, z.core.$strip>, z.ZodObject<{
98
- type: z.ZodLiteral<"tool-result">;
99
- toolCallId: z.ZodString;
100
- toolName: z.ZodString;
101
- output: z.ZodUnknown;
102
- isError: z.ZodOptional<z.ZodBoolean>;
103
- }, z.core.$strip>, z.ZodObject<{
104
- type: z.ZodLiteral<"file-change">;
105
- path: z.ZodOptional<z.ZodString>;
106
- summary: z.ZodOptional<z.ZodString>;
107
- }, z.core.$strip>, z.ZodObject<{
108
- type: z.ZodLiteral<"finish">;
109
- finishReason: z.ZodEnum<{
110
- aborted: "aborted";
111
- error: "error";
112
- length: "length";
113
- stop: "stop";
114
- "tool-calls": "tool-calls";
115
- }>;
116
- usage: z.ZodOptional<z.ZodObject<{
117
- input: z.ZodNumber;
118
- output: z.ZodNumber;
119
- total: z.ZodOptional<z.ZodNumber>;
120
- cached: z.ZodOptional<z.ZodNumber>;
121
- }, z.core.$strip>>;
122
- cost: z.ZodOptional<z.ZodNumber>;
123
- }, z.core.$strip>, z.ZodObject<{
124
- type: z.ZodLiteral<"error">;
125
- error: z.ZodString;
126
- }, z.core.$strip>, z.ZodObject<{
127
- type: z.ZodLiteral<"raw">;
128
- value: z.ZodUnknown;
129
- }, z.core.$strip>], "type">;
130
- /**
131
- * A single event emitted by a harness during a turn. Mirrors the model-stream
132
- * primitives so the interpreter can forward them as framework events with
133
- * minimal translation. Adapter-specific metadata rides on `raw`.
134
- * @public
135
- */
136
- export type SubHarnessStreamPart = z.infer<typeof SubHarnessStreamPartSchema>;
137
- /**
138
- * The workspace surface a harness session may touch during a turn. A focused
139
- * subset of {@link Context} so adapters don't depend on the full runtime type.
140
- * @public
141
- */
142
- export interface SubHarnessRunContext {
143
- /** Working directory the agent runs in (resolved from `ctx.cwdState.cwd`). */
144
- readonly cwd: string;
145
- readonly fs: FsAdapter;
146
- readonly shell: ShellAdapter;
147
- readonly subprocess: SubprocessAdapter;
148
- /** Conversation thread id, for adapters that persist per-thread session state. */
149
- readonly threadId: string;
150
- /** Abort signal for the surrounding execution. */
151
- readonly signal?: AbortSignal;
152
- }
153
- /** @public Opaque, adapter-defined state for resuming a stopped/detached session. */
154
- export interface SubHarnessResumeState {
155
- readonly harnessId: string;
156
- readonly sessionId: string;
157
- readonly state: unknown;
158
- }
159
- /** @public Opaque, adapter-defined state for continuing a turn frozen mid-flight. */
160
- export interface SubHarnessContinueState {
161
- readonly harnessId: string;
162
- readonly sessionId: string;
163
- readonly state: unknown;
164
- }
165
- /** @public Options handed to {@link SubHarness.doStart}. */
166
- export interface SubHarnessStartOptions<TSettings = SubHarnessSettings> {
167
- /** Per-step settings (model, permission mode, …). */
168
- settings?: TSettings;
169
- /**
170
- * System instructions applied once on the first message of a fresh session.
171
- * Never re-applied on resume.
172
- */
173
- instructions?: string;
174
- /**
175
- * Prior conversation history (from earlier LLM/sub-harness steps and turns)
176
- * used to seed a fresh session so the agent has full context of the
177
- * conversation so far. Empty for the very first step of a run.
178
- */
179
- history?: ReadonlyArray<Item>;
180
- /** The workspace surface for this run. */
181
- ctx: SubHarnessRunContext;
182
- /** Resume a previously stopped/detached session. */
183
- resumeFrom?: SubHarnessResumeState;
184
- /** Continue a turn previously frozen via {@link SubHarnessSession.doSuspendTurn}. */
185
- continueFrom?: SubHarnessContinueState;
186
- signal?: AbortSignal;
187
- }
188
- /** @public Options for a single agentic turn. */
189
- export interface SubHarnessPromptTurnOptions {
190
- /** Fresh turn input only — the session owns conversation history. */
191
- prompt: string;
192
- /** Sink for stream events produced during the turn. */
193
- emit: (part: SubHarnessStreamPart) => void;
194
- signal?: AbortSignal;
195
- }
196
- /** @public Options for continuing a turn frozen mid-flight. */
197
- export interface SubHarnessContinueTurnOptions {
198
- emit: (part: SubHarnessStreamPart) => void;
199
- signal?: AbortSignal;
200
- }
201
- /**
202
- * Result of a completed agentic turn. The interpreter appends `items` to the
203
- * item log, charges `usage`/`cost`, and returns `text` (or parses it through
204
- * the step's output schema).
205
- * @public
206
- */
207
- export interface SubHarnessTurnResult {
208
- /** Noetic Items produced this turn (assistant message, tool calls/results). */
209
- items: Item[];
210
- /** Final assistant text of the turn. */
211
- text: string;
212
- usage?: TokenUsage;
213
- cost?: number;
214
- finishReason?: SubHarnessFinishReason;
215
- /** Adapter-specific metadata (peer to provider metadata, not a subtype). */
216
- harnessMetadata?: Record<string, unknown>;
217
- }
218
- /**
219
- * Describes a tool the underlying agent executes natively, mapped to a shared
220
- * `commonName` so consumers can recognise "the same kind of tool" across
221
- * harnesses (Claude's `Bash`, Codex's `shell`, pi's `bash` → `shell`).
222
- * @public
223
- */
224
- export interface SubHarnessBuiltinTool {
225
- /** The agent's native tool name. */
226
- readonly nativeName: string;
227
- /** Shared cross-harness name, when one exists. */
228
- readonly commonName?: string;
229
- readonly description?: string;
230
- }
231
- /**
232
- * A live harness session: one workspace + one conversation history + one
233
- * running runtime, kept across turns by the interpreter.
234
- * @public
235
- */
236
- export interface SubHarnessSession {
237
- readonly sessionId: string;
238
- /** True when this session was resumed rather than freshly started. */
239
- readonly isResume: boolean;
240
- /** The model the session resolved to, when the runtime reports it. */
241
- readonly modelId?: string;
242
- /** Run one agentic turn to completion. */
243
- doPromptTurn(opts: SubHarnessPromptTurnOptions): Promise<SubHarnessTurnResult>;
244
- /** Continue a turn previously frozen via {@link doSuspendTurn}. */
245
- doContinueTurn?(opts: SubHarnessContinueTurnOptions): Promise<SubHarnessTurnResult>;
246
- /** Freeze the current turn at a precise event cursor; runtime stays alive. */
247
- doSuspendTurn?(): Promise<SubHarnessContinueState>;
248
- /** Manually compact conversation history. Throws {@link SubHarnessCapabilityError} if unsupported. */
249
- doCompact?(customInstructions?: string): Promise<void>;
250
- /** Park the session between turns; runtime stays alive. */
251
- doDetach?(): Promise<SubHarnessResumeState>;
252
- /** Persist state and stop the runtime. */
253
- doStop(): Promise<SubHarnessResumeState>;
254
- /** Stop the runtime with no resume state. */
255
- doDestroy?(): Promise<void>;
256
- }
257
- /**
258
- * A coding-agent harness. Each `@noetic-tools/sub-harness-*` package exports a
259
- * factory returning one of these (e.g. `claudeCode({ model })`).
260
- * @public
261
- */
262
- export interface SubHarness<TSettings = SubHarnessSettings> {
263
- /** Spec tag for forward-compatibility. */
264
- readonly specificationVersion: 'harness-v1';
265
- /** Stable identifier, equal to the step kind it backs (e.g. `claude-code`). */
266
- readonly harnessId: SubHarnessKind;
267
- /** Tools the underlying agent executes natively. */
268
- readonly builtinTools?: ReadonlyArray<SubHarnessBuiltinTool>;
269
- /** Validates `resumeFrom`/`continueFrom` payloads, when the adapter persists them. */
270
- readonly lifecycleStateSchema?: z.ZodType;
271
- /** Start (or resume/continue) a session. */
272
- doStart(opts: SubHarnessStartOptions<TSettings>): Promise<SubHarnessSession>;
273
- }