Cortex

Runs, Steps & Tool Calls

How Cortex tracks agent execution — runs, reasoning steps, and tool invocations.

Every agent execution is tracked as a Run containing Steps and ToolCalls. This hierarchical model provides full observability into how an agent reasons through a problem.

Run

A Run represents a single execution of an agent:

type Run struct {
    cortex.Entity
    ID           id.AgentRunID
    AgentID      id.AgentID
    TenantID     string
    State        RunState
    Input        string
    Output       string
    Error        string
    StepCount    int
    TokensUsed   int
    StartedAt    *time.Time
    CompletedAt  *time.Time
    PersonaRef   string
    Metadata     map[string]any
}

Run states

Runs follow a state machine with 6 states:

StateDescription
createdRun has been created but not started
runningRun is actively processing
completedRun finished successfully
failedRun terminated with an error
cancelledRun was cancelled by a user or system
pausedRun is paused at a checkpoint awaiting approval

State transitions

created → running → completed
                  → failed
                  → cancelled
                  → paused → running (after checkpoint resolution)

Step

A Step represents a single reasoning step within a run:

type Step struct {
    cortex.Entity
    ID          id.StepID
    RunID       id.AgentRunID
    Index       int
    Type        string
    Input       string
    Output      string
    TokensUsed  int
    StartedAt   *time.Time
    CompletedAt *time.Time
    Metadata    map[string]any
}

Steps are numbered sequentially (Index 0, 1, 2, ...) and track token usage per step.

ToolCall

A ToolCall represents a single tool invocation within a step:

type ToolCall struct {
    cortex.Entity
    ID          id.ToolCallID
    StepID      id.StepID
    RunID       id.AgentRunID
    ToolName    string
    Arguments   string
    Result      string
    Error       string
    StartedAt   *time.Time
    CompletedAt *time.Time
    Metadata    map[string]any
}

Hierarchical model

Run (arun_...)
  ├── Step 0 (astp_...)
  │     ├── ToolCall (tcall_...)
  │     └── ToolCall (tcall_...)
  ├── Step 1 (astp_...)
  │     └── ToolCall (tcall_...)
  └── Step 2 (astp_...)

Store interface

type Store interface {
    CreateRun(ctx context.Context, run *Run) error
    GetRun(ctx context.Context, runID id.AgentRunID) (*Run, error)
    UpdateRun(ctx context.Context, run *Run) error
    ListRuns(ctx context.Context, filter *ListFilter) ([]*Run, error)

    CreateStep(ctx context.Context, step *Step) error
    ListSteps(ctx context.Context, runID id.AgentRunID) ([]*Step, error)

    CreateToolCall(ctx context.Context, tc *ToolCall) error
    ListToolCalls(ctx context.Context, stepID id.StepID) ([]*ToolCall, error)
}

List filter

type ListFilter struct {
    AgentID  string
    TenantID string
    State    RunState
    Limit    int
    Offset   int
}

API routes

MethodPathDescription
GET/cortex/agents/{id}/runsList runs for an agent
GET/cortex/runs/{id}Get a specific run
POST/cortex/runs/{id}/cancelCancel a running run

On this page