Skip to main content

Overview

The @mariozechner/pi-agent-core package provides type-safe interfaces for building AI agents. This page documents the core types used throughout the package.

State Types

AgentState

Complete agent state containing configuration and conversation data.
string
System prompt sent to the LLM at the start of each request.
Model<any>
LLM model from @mariozechner/pi-ai (e.g., getModel('openai', 'gpt-4o')).
ThinkingLevel
Reasoning level for models that support it: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'.Note: 'xhigh' is only supported by OpenAI gpt-5.1-codex-max, gpt-5.2, gpt-5.2-codex, gpt-5.3, and gpt-5.3-codex models.
AgentTool<any>[]
Tools available for the agent to execute.
AgentMessage[]
Full conversation history including user, assistant, toolResult, and custom message types.
boolean
True when the agent is actively streaming a response.
AgentMessage | null
Partial message being streamed (null when not streaming).
Set<string>
Set of tool call IDs currently being executed.
string | undefined
Error message from the last failed operation.

ThinkingLevel

Controls how much reasoning the model does before responding. Higher levels use more tokens but may produce better results for complex tasks.
  • 'off': No explicit reasoning (fastest)
  • 'minimal': Very brief reasoning
  • 'low': Light reasoning for simple tasks
  • 'medium': Balanced reasoning (recommended default)
  • 'high': Deep reasoning for complex tasks
  • 'xhigh': Maximum reasoning (OpenAI gpt-5.x models only)

Message Types

AgentMessage

Union of standard LLM messages (from @mariozechner/pi-ai) and custom application messages. Applications can extend this via declaration merging:

CustomAgentMessages

Extensible interface for custom message types. Use declaration merging to add app-specific messages:

Event Types

AgentEvent

Events emitted by the agent during execution. Subscribe via agent.subscribe().

Agent Lifecycle

{ type: 'agent_start' }
Emitted when the agent starts processing.
{ type: 'agent_end'; messages: AgentMessage[] }
Emitted when the agent completes processing. Contains all new messages added during this run.

Turn Lifecycle

{ type: 'turn_start' }
Emitted at the start of each turn (one assistant response + any tool calls/results).
{ type: 'turn_end'; message: AgentMessage; toolResults: ToolResultMessage[] }
Emitted when a turn completes. Contains the assistant message and any tool results from this turn.

Message Lifecycle

{ type: 'message_start'; message: AgentMessage }
Emitted when a new message starts (user, assistant, or tool result).
{ type: 'message_update'; message: AgentMessage; assistantMessageEvent: AssistantMessageEvent }
Emitted during streaming of assistant messages. Only emitted for assistant messages.
{ type: 'message_end'; message: AgentMessage }
Emitted when a message is complete and added to the conversation history.

Tool Execution

{ type: 'tool_execution_start'; toolCallId: string; toolName: string; args: any }
Emitted when a tool starts executing.
{ type: 'tool_execution_update'; toolCallId: string; toolName: string; args: any; partialResult: any }
Emitted when a tool sends a partial result via the onUpdate callback.
{ type: 'tool_execution_end'; toolCallId: string; toolName: string; result: any; isError: boolean }
Emitted when a tool completes. isError indicates whether the tool threw an error.

Configuration Types

AgentContext

Context passed to the agent loop. Similar to Context from @mariozechner/pi-ai but uses AgentTool instead of Tool.

AgentLoopConfig

Configuration for the agent loop. Extends SimpleStreamOptions from @mariozechner/pi-ai.
Model<any>
required
LLM model to use for generation.
(messages: AgentMessage[]) => Message[] | Promise<Message[]>
required
Converts AgentMessage[] to LLM-compatible Message[] before each LLM call.Each AgentMessage must be converted to a UserMessage, AssistantMessage, or ToolResultMessage. Messages that cannot be converted (e.g., UI-only notifications) should be filtered out.
(messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>
Optional transform applied to the context before convertToLlm.Use for:
  • Context window management (pruning old messages)
  • Injecting context from external sources
(provider: string) => Promise<string | undefined> | string | undefined
Resolves an API key dynamically for each LLM call.Useful for short-lived OAuth tokens (e.g., GitHub Copilot) that may expire during long-running tool execution.
() => Promise<AgentMessage[]>
Returns steering messages to inject into the conversation mid-run.Called after each tool execution to check for user interruptions. If messages are returned, remaining tool calls are skipped and these messages are added to the context before the next LLM call.Use for “steering” the agent while it’s working.
() => Promise<AgentMessage[]>
Returns follow-up messages to process after the agent would otherwise stop.Called when the agent has no more tool calls and no steering messages. If messages are returned, they’re added to the context and the agent continues with another turn.Use for follow-up messages that should wait until the agent finishes.

StreamFn

Custom stream function type. Can be sync or async to support dynamic configuration lookup.

Transport Types

Transport

Preferred transport mechanism for LLM providers:
  • 'sse': Server-Sent Events (default, better for streaming)
  • 'responses': HTTP responses (better for compatibility)

Proxy Types

streamProxy

Stream function that proxies through a backend server instead of calling LLM providers directly.

ProxyStreamOptions

string
required
Auth token for the proxy server.
string
required
Proxy server URL (e.g., https://genai.example.com).

ProxyAssistantMessageEvent

Events sent by the proxy server. The partial field is stripped to reduce bandwidth - the client reconstructs it.

Loop Functions

agentLoop

Start an agent loop with new prompt messages. The prompts are added to the context and events are emitted.

agentLoopContinue

Continue an agent loop from the current context without adding a new message. Used for retries. Important: The last message in context must convert to a user or toolResult message via convertToLlm.

Example: Custom Message Type