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

# Streaming and events

> Every event an agent run can send: text, tool calls, tool results, steps and the terminal events, with their fields and the rules for their order.

Every run of your agent is a sequence of events: the text it writes, each tool call it makes and the tool's result, the steps it passes through, and one event that ends it. Onecortex produces them from your framework, so callers see the same events whichever framework you use.

```mermaid theme={null}
sequenceDiagram
  participant App as Your app
  participant OC as Onecortex
  participant Agent as Your agent
  App->>OC: POST /invoke {"prompt": "...", "stream": true}
  OC->>Agent: the prompt
  Agent-->>App: step_start
  Agent-->>App: tool_call_start, tool_call_args, tool_call_end
  Agent-->>App: tool_result
  Agent-->>App: text, text, text
  Agent-->>App: step_end
  Agent-->>App: done (or error)
```

A streaming caller gets each event as it happens, as server sent events. A JSON caller gets the tool calls, results and steps in `events`, and the text whole in `result`. See [the invoke API](/call/invoke).

## The events

Every event is a JSON object with `v`, the event format version, which is `1`, and `type`.

### text

A piece of the reply.

```json theme={null}
{ "v": 1, "type": "text", "delta": "You said" }
```

Join the `delta` values in order for the whole reply. `done.result` also carries it whole.

### tool\_call\_start

A tool call begins.

```json theme={null}
{ "v": 1, "type": "tool_call_start", "id": "call_1", "name": "word_count" }
```

`id` is unique within the run, and ties the call's other events together.

### tool\_call\_args

A piece of the call's arguments, as JSON text.

```json theme={null}
{ "v": 1, "type": "tool_call_args", "id": "call_1", "delta": "{\"text\": \"hello\"}" }
```

Join the `delta` values for one `id` to get its arguments. A framework that does not stream arguments sends them whole in one event.

### tool\_call\_end

The call's arguments are complete.

```json theme={null}
{ "v": 1, "type": "tool_call_end", "id": "call_1" }
```

### tool\_result

The tool's output.

```json theme={null}
{ "v": 1, "type": "tool_result", "id": "call_1", "output": "1" }
```

`output` is a string: JSON text when the tool returned structured data. `isError` is `true` when the tool failed. Output longer than 64 KB is cut to 64 KB.

### step\_start and step\_end

A named stage of the run begins or ends: a LangGraph node, an OpenAI Agents SDK agent after a handoff, a CrewAI task.

```json theme={null}
{ "v": 1, "type": "step_start", "name": "classify" }
```

Steps can nest. Each [framework page](/frameworks/langgraph) says what its steps are.

### done

The run finished.

```json theme={null}
{ "v": 1, "type": "done", "result": "You said: hello", "sessionId": "01K...", "versionNumber": 1, "durationMs": 212 }
```

`result` is always present, and is the whole reply. On the stream, `done` also carries `sessionId`, `versionNumber` and `durationMs`.

### error

The run failed.

```json theme={null}
{ "v": 1, "type": "error", "code": "agent_error", "message": "ValueError: the agent was asked to raise" }
```

`code` is one of the [invoke error codes](/production/errors#invoke-errors), most often `agent_error`, when your code raised. Your traceback is in your [logs](/observe/logs), never in the event.

<Warning>
  A stream that has started has already sent `200 OK`, and cannot change it. If the run fails after that, the failure arrives in the stream as `event: error`. Handle it: a client that reads only `text` and `done` shows a failed run as an empty success.
</Warning>

## The rules

* **Exactly one terminal event, last.** Every run ends in `done` or `error`, and nothing follows it. A run that stops without one is reported as an `error` with `upstream_error`, `The agent stopped before finishing its reply.`
* **A tool call starts before anything else about it.** `tool_call_args`, `tool_call_end` and `tool_result` for an `id` always follow its `tool_call_start`.
* **A failed run may leave a call or a step open.** Do not wait for an `end` after an `error`.
* **Every framework sends at least `text` and `done`.** What more it sends depends on what the framework reports: see its page.

## On the wire

Each event is one server sent events frame, named by its type, with the event as single line JSON:

```text theme={null}
event: tool_call_start
data: {"v":1,"type":"tool_call_start","id":"call_1","name":"word_count"}

```

While your agent is silent, Onecortex sends `: ping` every 15 seconds. It is a comment, which server sent events clients ignore, and it keeps proxies from closing the connection.

## Send your own events

A plain function agent can report its own tool calls and steps by yielding event objects alongside its text. See [A Python function](/frameworks/python-function#report-tool-calls-and-steps) and [A TypeScript function](/frameworks/typescript-function#report-tool-calls).
