API Reference

AgentHarness Types

Type definitions for the AgentHarnessContract interface, AgentConfig, and related types in Noetic.

AgentHarnessContract

The core execution engine interface. The exported AgentHarness class implements this contract. Use the contract type when you want to be agnostic about the concrete implementation (e.g., for tests or custom harnesses).

declare interface HarnessApi<TParams extends Record<string, unknown> = Record<string, unknown>> {
  readonly config: AgentConfig<TParams>;
  readonly fs: FsAdapter;
  readonly shell: ShellAdapter;
  readonly rootCwdState: { cwd: string; previousCwd?: string };

  callModel(request: CallModelRequest): Promise<LLMResponse>;
  execute(input: ExecuteInput, options?: ExecuteOptions): Promise<void>;
  getAgentResponse(scope?: SessionScope): Promise<HarnessResponse>;
  getItemStream(scope?: SessionScope): AsyncIterable<StreamingItem>;
  getTextStream(scope?: SessionScope): AsyncIterable<string>;
  getReasoningStream(scope?: SessionScope): AsyncIterable<string>;
  getFullStream(scope?: SessionScope): AsyncIterable<StreamEvent>;
  abort(scope?: SessionScope & { reason?: string }): Promise<void>;
  getStatus(scope?: SessionScope): HarnessStatus;
  getQueueSize(scope?: SessionScope): number;
  seedSessionHistory(threadId: string, items: ReadonlyArray<Item>): void;
  setRootCwd(nextCwd: string): void;

  run<I, O>(step: Step<ContextMemory, I, O>, input: I, ctx: Context): Promise<O>;
  detachedSpawn<I, O>(
    step: Step<ContextMemory, I, O>,
    input: I,
    parentCtx: Context,
    overrides?: { threadId?: string; resourceId?: string; cwdInit?: string },
  ): DetachedHandle<O>;
  createContext(opts?: {
    parent?: Context;
    items?: Item[];
    state?: unknown;
    threadId?: string;
    resourceId?: string;
    memory?: MemoryLayer[];
    cwdInit?: string;
  }): Context;

  send<T>(channel: Channel<T>, value: T, ctx: Context): void;
  recv<T>(channel: Channel<T>, ctx: Context, opts?: { timeout?: number }): Promise<T>;
  tryRecv<T>(channel: Channel<T>, ctx: Context): T | null;
  getChannelHandle<T>(channel: ExternalChannel<T>, executionId: string): ChannelHandle<T>;

  initLayers(layers: MemoryLayer[], ctx: Context, storage: StorageAdapter): Promise<void>;
  recallLayers(layers: MemoryLayer[], input: string, ctx: Context): Promise<RecallLayerOutput[]>;
  previewRequestItems(scope?: SessionScope): Promise<ReadonlyArray<Item>>;
  storeLayers(layers: MemoryLayer[], response: LLMResponse, ctx: Context): Promise<void>;
  disposeLayers(layers: MemoryLayer[], ctx: Context): Promise<void>;
  getLayerState<T>(executionId: string, layerId: string): T | undefined;
  setLayerState<T>(executionId: string, layerId: string, state: T): void;

  beforeToolCall(
    layers: MemoryLayer[],
    toolName: string,
    toolArgs: unknown,
    ctx: Context,
  ): Promise<unknown>;
  afterModelCall(layers: MemoryLayer[], response: LLMResponse, ctx: Context): Promise<unknown>;

  checkpoint(ctx: Context): Promise<void>;
  restore(executionId: string): Promise<Context | null>;
  cancel(ctx: Context, reason?: string): Promise<void>;
  createSpan(name: string, parent: Span | null): Span;
}

AgentHarnessContract Methods

MethodDescription
configThe AgentConfig<TParams> the harness was constructed with.
fsThe FsAdapter the harness was constructed with (defaults to createLocalFsAdapter()). All filesystem operations — CLI tools, skill discovery, and memory layers — route through this adapter.
shellThe ShellAdapter (defaults to createLocalShellAdapter()). Tools that need a real shell go through this.
rootCwdStateLong-lived shared cwd state, seeded into every root context the harness creates so successive runs and the TUI observe each other's cds.
callModel(request)Issue a single LLM call, bypassing the session/queue runner. Used by plugins that need one-shot generation.
execute(input, options?)Enqueue a message on the session identified by options.threadId. Resolves once the message is accepted into the queue — not when the model responds.
getAgentResponse(scope?)Resolves with the accumulated response once the session drains.
getItemStream(scope?)Yields cumulative Item snapshots across every turn in the session.
getTextStream(scope?)Yields text deltas across every turn.
getReasoningStream(scope?)Yields reasoning-token deltas.
getFullStream(scope?)Yields all raw SDK + framework events.
abort(scope?)Cancel the in-flight turn. Queued messages are preserved.
getStatus(scope?)Session status snapshot.
getQueueSize(scope?)Messages currently queued on the session.
seedSessionHistory(threadId, items)Pre-populate a session's accumulated history with prior items. Used by resume flows.
setRootCwd(nextCwd)Update the harness root cwd (e.g., from a TUI ! cd).
run(step, input, ctx)Run a step with the given input and context.
detachedSpawn(step, input, parentCtx, overrides?)Launch a step concurrently, returning a DetachedHandle. Optional overrides.threadId / overrides.resourceId / overrides.cwdInit decouple the child's session-scoped state from the parent's.
createContext(opts?)Create a new execution context. Accepts optional memory to override harness-level defaults.
send(channel, value, ctx)Send a value to a channel.
recv(channel, ctx, opts?)Receive from a channel (blocking).
tryRecv(channel, ctx)Non-blocking receive.
getChannelHandle(channel, executionId)Get external channel handle.
initLayers(layers, ctx, storage)Initialize memory layers.
recallLayers(layers, input, ctx)Run recall on all layers.
previewRequestItems(scope?)Return the Item[] that would be sent on the next turn — accumulated history plus harness-level layer recall outputs. Read-mostly; no session is allocated for unknown thread ids.
storeLayers(layers, response, ctx)Run store on all layers.
disposeLayers(layers, ctx)Dispose all layers.
getLayerState(executionId, layerId)Read a layer's state for a given execution.
setLayerState(executionId, layerId, state)Overwrite a layer's state for a given execution.
beforeToolCall(layers, toolName, toolArgs, ctx)Invoke each layer's beforeToolCall steering hook and aggregate the decision.
afterModelCall(layers, response, ctx)Invoke each layer's afterModelCall steering hook.
checkpoint(ctx)Persist current execution state.
restore(executionId)Restore a previously checkpointed context.
cancel(ctx, reason?)Cancel an execution.
createSpan(name, parent)Create an observability span.

DeliveryMode

type DeliveryMode = 'next-turn' | 'between-rounds' | 'interrupt';
ModeBehaviour
next-turn (default)Queue and run after the current turn completes.
between-roundsInject as a user item before the next tool-round LLM call within the active turn.
interruptAbort the in-flight turn, place at head of queue, restart.

ExecuteOptions

interface ExecuteOptions {
  threadId?: string;
  resourceId?: string;
  state?: unknown;
  memory?: MemoryLayer[];
  deliveryMode?: DeliveryMode;
}

interface SessionScope {
  threadId?: string;
}

HarnessStatus

type HarnessStatus =
  | { readonly kind: 'idle' }
  | { readonly kind: 'generating'; readonly startedAt: number; readonly turnId: string }
  | { readonly kind: 'aborting'; readonly turnId: string };

HarnessResponse

interface HarnessResponse {
  readonly items: ReadonlyArray<Item>;
  readonly usage: { inputTokens: number; outputTokens: number; cachedTokens?: number };
  readonly cost?: number;
  readonly text: string;
  readonly lastLayerUsage?: LastLayerUsage;
}

StreamEvent

type StreamEvent = SdkStreamEvent | FrameworkStreamEvent;

interface SdkStreamEvent {
  readonly source: 'sdk';
  readonly type: string;
  readonly data: Record<string, unknown>;
  readonly outputIndex?: number;
  readonly contentIndex?: number;
}

interface FrameworkStreamEvent {
  readonly source: 'framework';
  readonly type: `${string}:${string}`;
  readonly data: Record<string, unknown>;
}

StreamingItem

type StreamingItem = Item & { readonly isComplete: boolean };

AgentConfig

Declarative configuration for an agent harness. Generic over TParams, an arbitrary key-value record accessible via ctx.harness.config.params. Filesystem and shell adapters are passed to the AgentHarness constructor and exposed as harness.fs / harness.shell; they are not part of AgentConfig itself.

declare interface AgentConfigShape<
  TParams extends Record<string, unknown> = Record<string, unknown>,
> {
  name: string;
  storage?: StorageAdapter;
  hooks?: AgentHooks;
  params: TParams;
  itemSchemas?: unknown;
  strictItemSchemas?: boolean;
}
FieldTypeRequiredDescription
namestringyesAgent name.
storageStorageAdapternoStorage backend for memory persistence. Defaults to an in-memory adapter.
hooksAgentHooksnoBefore/after step hooks.
paramsTParamsyesArbitrary key-value parameters available to every step and tool via ctx.harness.config.params.
itemSchemasItemSchemaExtensionsnoHarness-wide item-schema extensions used to validate emitted and returned items.
strictItemSchemasbooleannoWhether unknown extension item types must match a registered schema. Defaults to true.

AgentHooks

interface AgentHooks {
  beforeStep?: (step: Step, ctx: Context) => Promise<void>;
  afterStep?: (step: Step, result: unknown, ctx: Context) => Promise<void>;
}
HookParametersDescription
beforeStep(step, ctx)Called before each step executes
afterStep(step, result, ctx)Called after each step completes

DetachedHandle

A handle returned by harness.detachedSpawn() to track a concurrently running child step.

interface DetachedHandle<O> {
  readonly id: string;
  readonly status: DetachedStatus;
  readonly result: O | undefined;
  readonly error: string | undefined;
  await(timeout?: number): Promise<O>;
}
PropertyTypeDescription
idstringUnique handle identifier (child context ID)
statusDetachedStatusCurrent execution status
resultO | undefinedChild output (set when completed)
errorstring | undefinedError message (set when failed)
await(timeout?)Promise<O>Wait for completion, optionally with timeout in ms

DetachedStatus

const DetachedStatus = {
  Running: 'running',
  Completed: 'completed',
  Failed: 'failed',
} as const;
type DetachedStatus = (typeof DetachedStatus)[keyof typeof DetachedStatus];
ValueDescription
'running'Child step is still executing
'completed'Child step finished successfully
'failed'Child step threw an error

RecallLayerOutput

The output from a single memory layer's recall hook.

interface RecallLayerOutput {
  layerId: string;
  items: Item[];
  tokenCount: number;
}
FieldTypeDescription
layerIdstringWhich layer produced this output
itemsItem[]Items to inject into the prompt
tokenCountnumberToken cost of the items

LLMResponse

The response from an LLM call.

interface LLMResponse {
  items: Item[];
  usage: {
    inputTokens: number;
    outputTokens: number;
    cachedTokens?: number;
  };
  cost?: number;
}
FieldTypeDescription
itemsItem[]Response items (messages, function calls, etc.)
usage.inputTokensnumberInput tokens consumed
usage.outputTokensnumberOutput tokens generated
usage.cachedTokensnumberCached tokens used (optional)
costnumberCost in USD (optional)

On this page