> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentium.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Control a run

> Configure runtime grants and budgets, start execution, send input, cancel, and handle terminal results.

Construct one `HarnessRuntime` with host-approved configuration. Start runs with an authenticated caller's identity and a session ID. A run can use only the tools and model roles allowed by that runtime.

## Runtime configuration

| Option | Default and behavior |
| - | - |
| `grants` | Required. `toolIds` and `modelRoles` are explicit allowlists; `requiredToolIds` optionally requires tools to be present and remain active. |
| `driver` | Required unless the definition resolves one. Must support local controlled execution. |
| `definition` | Optional composition of abilities, Agent defaults, limits, and runtime bindings. |
| `projectRoot` | Absolute resolution of `process.cwd()` at construction. Anchors relative Agent paths. |
| `requirements` | Host-approved capability names required by abilities. No implicit grants. |
| `tools` | Empty array. Additional tools combined with bound ability tools. |
| `models` | Empty registry. Maps role names to `{ provider, options? }`; `options` allows controller/policy overrides by field name. |
| `budgets` | Optional caps for model calls, tool calls, tokens, and completion revisions. See below. |
| `executionPolicy` | Optional core execution policy governing intercepted effects. |
| `approvalManager` | Optional core approval manager used by controlled tool execution. |
| `controller` | Optional run/step selection; direct configuration overrides a definition binding. |
| `contextPolicy` | Optional request projection; direct configuration overrides a definition binding. |
| `completionPolicy` | Optional answer evaluation; direct configuration overrides a definition binding. |
| `allowRevisionEffects` | `false`. Explicitly opt in to new tool effects during completion revisions. |
| `sessionStore` | A new `InMemoryHarnessSessionStore`. |
| `resources` | A new `HarnessResourcePool`. |
| `eventCapacity` | `256` retained events; integer of at least `2`. |
| `telemetry` | Optional core `EventBus` for runtime and direct model/controller observations. |

The `main` role uses the provider supplied by an Agent or custom driver's model call unless `models.main` overrides it. Other roles need an explicit host model binding. Granting a role alone does not provide a model.

## Set shared budgets

| Budget | Meaning when set | When omitted |
| - | - | - |
| `maxModelCalls` | Total controlled task and policy model calls | No configured call cap |
| `maxToolCalls` | Controlled tool/effect call cap | No configured call cap |
| `maxTokens` | Shared token usage accounting and output reservations | No configured token cap |
| `maxRevisions` | Number of completion-policy revisions | `0` revisions |

Values must be nonnegative integers. `0` disables the corresponding operation. Follow-ups and completion revisions share the run's budgets; they do not receive fresh allowances. A policy model call also consumes the same model/token budgets.

Token caps constrain output reservations and account for reported usage. They are not an exact spending guarantee: provider-reported input or reasoning usage can exceed an estimate. Exhausted budgets stop further admitted work with `reason.code: "budget_exhausted"`.

## Start, await, or stream

`runtime.run(input, options)` returns the settled `HarnessResult`. `runtime.stream(input, options)` starts a new run and returns its event iterator. `runtime.start(input, options)` returns a `RunHandle` immediately, allowing you to consume events, send input, cancel, and await the result for the same run.

This function accepts an already configured runtime:

```typescript theme={null}
import type { HarnessIdentity, HarnessRuntime } from "@agentium/harness";

export async function runWithDeadline(runtime: HarnessRuntime, identity: HarnessIdentity) {
  const handle = runtime.start("Summarize the project.", {
    identity,
    sessionId: "project-review",
    deadline: Date.now() + 30_000,
    runMode: "execute",
  });
  for await (const event of handle.events()) {
    if (event.payload.type === "text.delta") process.stdout.write(event.payload.text);
  }
  const result = await handle.result();
  if (result.status !== "completed") {
    console.error(result.status, result.reason?.code, result.reason?.message);
  }
  return result;
}
```

| Start option | Behavior |
| - | - |
| `identity` | Required `{ tenantId, userId }`, both nonempty and verified by your host. |
| `sessionId` | Required nonempty identifier, scoped to both identity fields. |
| `signal` | Optional caller abort signal. |
| `deadline` | Optional absolute Unix time in milliseconds, such as `Date.now() + 30_000`. |
| `grants` | Optional narrower allowlists. Cannot add runtime-denied tools/roles or remove required tools. |
| `runMode` | `"execute"` by default; `"plan"` uses core planning/effect enforcement. |
| `parentRunId`, `rootRunId` | Optional lineage metadata. Root defaults to this run's ID. |

Planning mode is still an execution mode: do not assume it means no model calls or no reads. Use tool effect metadata and [execution policy](/agents/execution-policy) to control what operations are admitted.

## Send input and cancel

For an active handle, call `handle.send(input, { mode: "follow_up" })`. Built-in drivers support follow-ups: input is queued and processed after the current completed pass. The queue holds up to 32 inputs. Sending after cancellation or termination fails.

`steer` requires a custom driver that advertises and consumes it through `services.takeInput()`. It does not automatically interrupt a model call. `replace` appears in the shared type but is unsupported by the current runtime; constructing a driver that advertises it fails with `HarnessUnsupportedError`.

Call `handle.cancel(reason?)` or abort the caller signal to request cancellation. Wait for `handle.result()` to observe cleanup and final status. Closing an event iterator only disconnects that observer. Cancellation does not roll back external effects that already started.

## Handle results and errors

| Status | Meaning |
| - | - |
| `completed` | Driver completed and any completion policy accepted the output. |
| `stopped` | Explicit stop, budget exhaustion, or revision limit. Inspect `reason`. |
| `awaiting_input` | Completion policy requested more input; this run is terminal. Start a new run in the session. |
| `cancelled` | Caller cancellation or deadline was acknowledged. |
| `failed` | Execution or initialization failed. Inspect `reason.code` and `reason.message`. |

Invalid constructor/start arguments can throw synchronously. Errors after a run starts are normally represented in its terminal result. Cleanup errors appear in `cleanupDiagnostics` without hiding the primary outcome. Event iteration can separately throw a cursor/gap error; see [events](/harness/events).

Results include `text`, optional `structured`, `usage`, `runId`, `sessionId`, and `finalCursor`. Large output may be returned through scoped artifact references. See [full runtime declarations](/harness/api/runtime) and [events and results](/harness/api/events).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.