Skip to main content
The RunState type represents the complete state of an agent execution. It’s returned from every run() call and can be passed back to continue conversations.

Type Definition

type RunState = {
  sessionState?: SessionState
  output: AgentOutput
}

Fields

sessionState
SessionState
Complete session state including message history, file context, and agent state. Pass this to previousRun to continue the conversation.
output
AgentOutput
required
The agent’s output from this run. This is a discriminated union based on the type field.

Session State

The session state contains all context needed to continue a conversation.
fileContext
ProjectFileContext
required
Project files, knowledge files, agent templates, and file tree information
mainAgentState
AgentState
required
State of the main agent including message history and execution context

Agent State

agentId
string
required
Unique identifier for the agent (deprecated, use runId instead)
runId
string
Current run identifier
agentType
string | null
required
Type of agent (e.g., base, base_max, file_picker)
messageHistory
Message[]
required
Array of all messages in the conversation
stepsRemaining
number
required
Number of steps the agent can still take (affected by maxAgentSteps)
creditsUsed
number
required
Total credits used in this session
directCreditsUsed
number
required
Credits used directly by this agent (excluding subagents)
contextTokenCount
number
required
Accurate token count from the LLM provider
agentContext
Record<string, Subgoal>
required
Agent’s internal context and subgoals
ancestorRunIds
string[]
required
Array of ancestor run IDs (for nested agents)
subagents
AgentState[]
required
State of any spawned subagents
childRunIds
string[]
required
IDs of child agent runs
output
Record<string, any>
Structured output from the agent
parentId
string
ID of the parent agent (for subagents)
systemPrompt
string
required
System prompt used by the agent
toolDefinitions
Record<string, { description?: string; inputSchema: {} }>
required
Available tool definitions

Agent Output Types

The output field is a discriminated union with four possible types:

Structured Output

Returned when the agent produces structured data.
type
'structuredOutput'
required
Output type identifier
value
Record<string, any> | null
required
Structured data returned by the agent
Example:
{
  type: 'structuredOutput',
  value: {
    filesCreated: ['index.ts', 'types.ts'],
    linesOfCode: 145
  }
}

Last Message

Returns the last turn of the conversation (assistant and tool messages).
type
'lastMessage'
required
Output type identifier
value
any[]
required
Array of messages from the last turn, including tool results
Example:
{
  type: 'lastMessage',
  value: [
    {
      role: 'assistant',
      content: [{ type: 'text', text: 'I will create the file' }]
    },
    {
      role: 'tool',
      toolName: 'write_file',
      output: [{ type: 'json', value: { success: true } }]
    }
  ]
}

All Messages

Returns the complete message history.
type
'allMessages'
required
Output type identifier
value
any[]
required
Complete array of all messages in the conversation
Example:
{
  type: 'allMessages',
  value: [
    { role: 'user', content: [{ type: 'text', text: 'Create a file' }] },
    { role: 'assistant', content: [{ type: 'text', text: 'Creating file...' }] }
  ]
}

Error

Returned when the agent encounters an error.
type
'error'
required
Output type identifier
message
string
required
Error message describing what went wrong
statusCode
number
HTTP status code if the error is related to an API call
Example:
{
  type: 'error',
  message: 'Failed to connect to API: Network timeout',
  statusCode: 503
}

Continuation Pattern

Use the RunState to continue conversations:
import { CodebuffClient } from '@codebuff/sdk'

const client = new CodebuffClient({ apiKey: 'cb_xxx' })

// First run
const firstRun = await client.run({
  agent: 'base',
  prompt: 'Create a TypeScript file'
})

// Continue the conversation
const secondRun = await client.run({
  agent: 'base',
  prompt: 'Now add tests for it',
  previousRun: firstRun // Pass the previous state
})

// Chain multiple runs
const thirdRun = await client.run({
  agent: 'base',
  prompt: 'Add documentation',
  previousRun: secondRun
})

Accessing Output

const result = await client.run({
  agent: 'base',
  prompt: 'Create hello world'
})

if (result.output.type === 'error') {
  console.error('Error:', result.output.message)
  if (result.output.statusCode) {
    console.error('Status code:', result.output.statusCode)
  }
} else if (result.output.type === 'structuredOutput') {
  console.log('Agent output:', result.output.value)
} else if (result.output.type === 'lastMessage') {
  console.log('Last turn:', result.output.value)
} else if (result.output.type === 'allMessages') {
  console.log('Full history:', result.output.value)
}

Inspecting State

const result = await client.run({
  agent: 'base',
  prompt: 'Analyze the codebase'
})

if (result.sessionState) {
  console.log('Messages:', result.sessionState.mainAgentState.messageHistory.length)
  console.log('Steps remaining:', result.sessionState.mainAgentState.stepsRemaining)
  console.log('Credits used:', result.sessionState.mainAgentState.creditsUsed)
  console.log('Token count:', result.sessionState.mainAgentState.contextTokenCount)
}

Persistence

You can serialize and persist RunState to continue sessions later:
import fs from 'fs'

// Save state
const result = await client.run({
  agent: 'base',
  prompt: 'Start a feature'
})
fs.writeFileSync('session.json', JSON.stringify(result))

// Load and continue
const savedState = JSON.parse(fs.readFileSync('session.json', 'utf8'))
const continuedRun = await client.run({
  agent: 'base',
  prompt: 'Continue the feature',
  previousRun: savedState
})

State Overrides

You can override certain fields when continuing:
const secondRun = await client.run({
  agent: 'base',
  prompt: 'Continue',
  previousRun: firstRun,
  maxAgentSteps: 50,        // Override step limit
  projectFiles: newFiles,   // Update project files
  knowledgeFiles: newKnowledge  // Update knowledge
})
These overrides are applied via applyOverridesToSessionState() which:
  • Deep clones the base session state
  • Updates specified fields
  • Recomputes derived data (file tree, token scores) when needed
  • Merges agent definitions and custom tools

Build docs developers (and LLMs) love