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

# createHarnessStepContext()

> **createHarnessStepContext**(`ports`, `options`): [`HarnessStepContext`](/docs/agent-sdk/harness-sdk/persistence/step-context#harnessstepcontext)

**Parameters**

| Parameter | Type |
| - | - |
| `ports` | [`AgentHarnessPorts`](/docs/agent-sdk/harness-sdk/ports) |
| `options` | [`HarnessStepContextOptions`](/docs/agent-sdk/harness-sdk/persistence/step-context#harnessstepcontextoptions) |

**Returns**
[`HarnessStepContext`](/docs/agent-sdk/harness-sdk/persistence/step-context#harnessstepcontext)

## On the Agent Runtime

The step memo is a table in the SQL port, written in transactions around the step's function.

```ts theme={null}
// steps.ts
ports.sql.transactionSync(() => {
  const next = first(ports.sql.exec("SELECT COALESCE(MAX(journal_seq), 0) + 1 AS next FROM __telnyx_agent_harness_steps WHERE run_id = ?", options.runId).toArray()).next;
  ports.sql.exec("INSERT INTO __telnyx_agent_harness_steps(run_id,name,identity,input_fingerprint,version,status,output,journal_seq) VALUES (?,?,?,?,?,'prepared',NULL,?)", options.runId, name, identity, inputFingerprint, version, next);
});
// …
const output = await fn();
// …
const serialized = serializeStepOutput(output, stepOptions.external === true);
ports.sql.transactionSync(() => {
  ports.sql.exec("UPDATE __telnyx_agent_harness_steps SET status = 'completed', output = ?, output_failure = ? WHERE run_id = ? AND name = ?", serialized.output, serialized.failure, options.runId, name);
});
```

* `ports.sql.exec()` runs on the instance's own SQLite database, [`this.ctx.storage.sql`](/docs/agent-sdk/interface/ctx). The memo's table sits beside the run ledger's.
* `ports.sql.transactionSync()` is `this.ctx.storage.transactionSync()`. A transaction that throws is rolled back whole.

## HarnessStepContext

**Properties**
**isContinuation**

> `readonly` **isContinuation**: `boolean`

True only when this persistent run is replaying after interruption or approval.

**runId**

> `readonly` **runId**: `string`

Private persistent run identity for harness-owned continuation state.

**Methods**
**associateToolCallJournal()**

> **associateToolCallJournal**(`calls`): `ReadonlyMap`\<`string`, `string`>

Associates this provider step's correlation IDs with its already-reserved persistent positions.

**Parameters**

| Parameter | Type |
| - | - |
| `calls` | readonly `Readonly`\<\{ `toolCallId`: `string`; `toolName`: `string`; }>\[] |

**Returns**
`ReadonlyMap`\<`string`, `string`>

**isCompleted()**

> **isCompleted**(`name`, `options?`): `boolean`

True only when this exact persistent step has committed its memoized output.

**Parameters**

| Parameter | Type |
| - | - |
| `name` | `string` |
| `options?` | `Pick`\<[`HarnessStepOptions`](/docs/agent-sdk/harness-sdk/persistence/step-context#harnessstepoptions), `"input"` \| `"version"`> |

**Returns**
`boolean`

**nextToolCallOrdinal()**

> **nextToolCallOrdinal**(`toolName`, `toolCallId`): `number`

Allocates a run-scoped logical tool position independent of provider call IDs.

**Parameters**

| Parameter | Type |
| - | - |
| `toolName` | `string` |
| `toolCallId` | `string` \| `undefined` |

**Returns**
`number`

**reconcileToolCallJournal()**

> **reconcileToolCallJournal**(`journalMarkers`): `void`

Reconciles harness-owned journal markers with persistent message history.

**Parameters**

| Parameter | Type |
| - | - |
| `journalMarkers` | `ReadonlySet`\<`string`> |

**Returns**
`void`

**step()**

> **step**\<`T`>(`name`, `fn`, `options?`): `Promise`\<`T`>

Executes a named effect once per stable run/input/version identity, then
persistently returns its JSON-safe output on replay. External effects are
at-least-once: an interruption after the effect starts is outcome-unknown,
never silently retried.

**Type Parameters**

| Type Parameter |
| - |
|  `T` |

**Parameters**

| Parameter | Type |
| - | - |
| `name` | `string` |
| `fn` | () => `Promise`\<`T`> |
| `options?` | [`HarnessStepOptions`](/docs/agent-sdk/harness-sdk/persistence/step-context#harnessstepoptions) |

**Returns**
`Promise`\<`T`>

## HarnessStepContextOptions

**Properties**
**checkpoints?**

> `readonly` `optional` **checkpoints?**: [`HarnessCheckpoint`](/docs/agent-sdk/harness-sdk/persistence/run-ledger#harnesscheckpoint)

Deterministic test seam. Production callers must not use this to infer external-effect success.

**input**

> `readonly` **input**: `unknown`

**isContinuation?**

> `readonly` `optional` **isContinuation?**: `boolean`

True only when this persistent run is replaying after interruption or approval.

**runId**

> `readonly` **runId**: `string`

**version**

> `readonly` **version**: `string`

## HarnessStepOptions

**Properties**
**beforeEffect?**

> `readonly` `optional` **beforeEffect?**: () => `void`

Private synchronous hook committed with the external effect-start fence.

**Returns**
`void`

**external?**

> `readonly` `optional` **external?**: `boolean`

Marks a call that can mutate an external system and therefore needs reconciliation after an interrupted effect.

**input?**

> `readonly` `optional` **input?**: `unknown`

JSON-safe effect input used for this step's persistent memo fingerprint.

**version?**

> `readonly` `optional` **version?**: `string`

Explicit effect contract version used for this step's persistent memo identity.

## HarnessStepOutputSerializationError

Private persistent marker that never shares the tool-output value channel.

**Constructors**
**Constructor**

> **new HarnessStepOutputSerializationError**(): `HarnessStepOutputSerializationError`

**Returns**
`HarnessStepOutputSerializationError`

**Properties**
**cause?**

> `optional` **cause?**: `unknown`

**message**

> **message**: `string`

**name**

> **name**: `string`

**stack?**

> `optional` **stack?**: `string`

**stackTraceLimit**

> `static` **stackTraceLimit**: `number`

The `Error.stackTraceLimit` property specifies the number of stack frames
collected by a stack trace (whether generated by `new Error().stack` or
`Error.captureStackTrace(obj)`).

The default value is `10` but may be set to any valid JavaScript number. Changes
will affect any stack trace captured *after* the value has been changed.

If set to a non-number value, or set to a negative number, stack traces will
not capture any frames.

**Methods**
**captureStackTrace()**

> `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void`

Creates a `.stack` property on `targetObject`, which when accessed returns
a string representing the location in the code at which
`Error.captureStackTrace()` was called.

```js theme={null}
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack;  // Similar to `new Error().stack`
```

The first line of the trace will be prefixed with
`${myObject.name}: ${myObject.message}`.

The optional `constructorOpt` argument accepts a function. If given, all frames
above `constructorOpt`, including `constructorOpt`, will be omitted from the
generated stack trace.

The `constructorOpt` argument is useful for hiding implementation
details of error generation from the user. For instance:

```js theme={null}
function a() {
  b();
}

function b() {
  c();
}

function c() {
  // Create an error without stack trace to avoid calculating the stack trace twice.
  const { stackTraceLimit } = Error;
  Error.stackTraceLimit = 0;
  const error = new Error();
  Error.stackTraceLimit = stackTraceLimit;

  // Capture the stack trace above function b
  Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
  throw error;
}

a();
```

**Parameters**

| Parameter | Type |
| - | - |
| `targetObject` | `object` |
| `constructorOpt?` | `Function` |

**Returns**
`void`

**prepareStackTrace()**

> `static` **prepareStackTrace**(`err`, `stackTraces`): `any`

**Parameters**

| Parameter | Type |
| - | - |
| `err` | `Error` |
| `stackTraces` | `CallSite`\[] |

**Returns**
`any`

**See**
[https://v8.dev/docs/stack-trace-api#customizing-stack-traces](https://v8.dev/docs/stack-trace-api#customizing-stack-traces)

## isToolOutputSerializationFailure()

> **isToolOutputSerializationFailure**(`value`): `boolean`

**Parameters**

| Parameter | Type |
| - | - |
| `value` | `unknown` |

**Returns**
`boolean`
