# turn and pending

Read one turn of the session log, or the turns that still need to run.

`runtime.turn(scope, request_id)` reads one turn, and `runtime.pending(scope)` reads every queued and running turn in log order. Both read through the SDK's `SessionLog` and work before `open`. Each turn comes back as a `TurnView` with the turn's report.

```ts title="host.ts"
import type { AgentRuntime } from 'nanocode-wasm'

declare const runtime: AgentRuntime

// 1. Read the status of one turn
const view = await runtime.turn('owner', 'turn-1')
console.log(view?.report.status)

// 2. Drive the oldest turn that still needs to run
const [next] = await runtime.pending('owner')
if (next) await runtime.drive(next.report.request_id)
```

## Signature

```ts
// One turn, or null if the scope has no turn with this ID
turn(scope: string, request_id: string): Promise<TurnView | null>

// Queued and running turns, oldest first
pending(scope: string): Promise<TurnView[]>
```

## Parameters

### scope

* **Type:** `string`

The session log scope, the same value as `config.scope`.

```ts
// Lists the scope's unfinished turns
const turns = await runtime.pending('owner')
```

### request_id

* **Type:** `string`

The ID that `submit` received. Only `turn` takes it.

```ts
// Reads one turn by ID
const view = await runtime.turn('owner', 'turn-1')
```

## Returns

```ts
type TurnView = {
  // The turn's status and result fields
  report: TurnReport
  // The seq of the turn's first event
  first_seq: number
  // The seq of the turn's last event, or null until it finishes
  last_seq: number | null
  // A cancel reached the turn while it ran
  cancel_requested: boolean
  // The metadata from submit
  metadata: unknown
}

type TurnReport = Record<string, unknown> & {
  request_id: string
  status: string
}
```

### report

* **Type:** `TurnReport`

The turn's result fields with `request_id` and `status`. `status` is `queued`, `running`, `completed`, `failed`, or `cancelled`. A note from `interrupted` appears as `error`. A turn that waits on its host after `retry` has `error`, `kind`, `attempts`, and `retry_at`.

```ts
import type { TurnView } from 'nanocode-wasm'

declare const view: TurnView

// Shows when the host retries the turn
if (typeof view.report.retry_at === 'number')
  console.log(new Date(view.report.retry_at))
```

### first_seq and last_seq

* **Type:** `number` and `number | null`

The log range of the turn. [`page`](/docs/api/wasm/page) with a `request_id` reads the events in this range.

```ts
import type { TurnView } from 'nanocode-wasm'

declare const view: TurnView

// A finished turn has a last event
const finished = view.last_seq !== null
```

### cancel_requested

* **Type:** `boolean`

`true` if [`cancel`](/docs/api/wasm/cancel) reached the turn while it was running.

```ts
import type { TurnView } from 'nanocode-wasm'

declare const view: TurnView

// Shows a pending cancellation
if (view.cancel_requested) console.log('cancelling')
```

### pending

* **Type:** `Promise<TurnView[]>`

The scope's turns with status `queued` or `running`, ordered by `first_seq`.

```ts
// The oldest unfinished turn
const [next] = await runtime.pending('owner')
```

## Errors

Both methods reject if the SQL host throws or the runtime is closed. `turn` resolves with `null` for an unknown request ID instead of rejecting.

```ts
import type { AgentRuntime } from 'nanocode-wasm'

declare const runtime: AgentRuntime

// null for an ID that was never submitted
const missing = await runtime.turn('owner', 'unknown')
```
