Implementation:Openclaw Openclaw RunEmbeddedPiAgent
| Knowledge Sources | |
|---|---|
| Domains | Agent_Runtime, LLM_Integration |
| Last Updated | 2026-02-06 12:00 GMT |
Overview
Concrete wrapper for multi-turn LLM inference with streaming, tool execution, and resilience provided by the OpenClaw agent runtime. Wraps the @mariozechner/pi-coding-agent library.
Description
runEmbeddedPiAgent is the primary inference entry point. It accepts fully assembled run parameters (prompt, session file, model, tools, callbacks) and orchestrates the complete LLM interaction lifecycle:
- Model resolution and context window guard: Resolves the model from the registry, checks context window limits, and blocks models with insufficient context.
- Auth profile management: Resolves API keys from the auth profile store, rotates through profiles on failure, and tracks cooldown state for rate-limited profiles.
- Inference loop: Delegates to
runEmbeddedAttemptfor each prompt-response cycle. The attempt handles streaming, tool calls, and turn management via the underlying@mariozechner/pi-coding-agentlibrary. - Error recovery: Handles context overflow (auto-compaction + retry), role ordering errors, image size errors, auth failures (profile rotation), thinking level fallback, rate limits, billing errors, and timeouts.
- Payload construction: After the inference loop completes, calls
buildEmbeddedRunPayloadsto construct the final reply payloads from accumulated assistant texts, tool metadata, and error information. - Concurrency control: Enqueues the entire run in both a per-session lane and a global lane to ensure sequential turn processing within a session and global rate compliance.
The function returns an EmbeddedPiRunResult containing the reply payloads, execution metadata (duration, provider, model, usage statistics), and flags indicating whether messaging tools were used during the run.
Usage
runEmbeddedPiAgent is called by runPreparedReply (the final stage of context assembly). It is not typically called directly by channel handlers. Use it when building custom agent runners that bypass the standard getReplyFromConfig pipeline.
Code Reference
Source Location
- Repository: openclaw
- File:
src/agents/pi-embedded-runner/run.ts - Lines: 73-710
Signature
export async function runEmbeddedPiAgent(
params: RunEmbeddedPiAgentParams,
): Promise<EmbeddedPiRunResult>
Import
import { runEmbeddedPiAgent } from "../agents/pi-embedded-runner/run.js";
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
sessionId |
string |
Yes | Unique session identifier for this conversation. |
sessionKey |
string |
No | Session key for persistence and concurrency lane derivation. |
sessionFile |
string |
Yes | Path to the session JSONL file for conversation persistence. |
workspaceDir |
string |
Yes | Agent workspace directory path. |
prompt |
string |
Yes | The assembled prompt text to send to the LLM. |
provider |
string |
No | LLM provider identifier (e.g., "anthropic", "openai"). Defaults to DEFAULT_PROVIDER.
|
model |
string |
No | Model identifier (e.g., "claude-sonnet-4-20250514"). Defaults to DEFAULT_MODEL.
|
config |
OpenClawConfig |
No | Runtime configuration for tool policies, auth profiles, and agent settings. |
thinkLevel |
ThinkLevel |
No | Thinking/extended reasoning level ("off", "low", "medium", "high").
|
timeoutMs |
number |
Yes | Maximum time in milliseconds for the entire inference run. |
runId |
string |
Yes | Unique run identifier for event correlation. |
images |
ImageContent[] |
No | Image attachments to include in the prompt. |
disableTools |
boolean |
No | If true, run in LLM-only mode without tools.
|
abortSignal |
AbortSignal |
No | Signal to abort the inference run. |
onPartialReply |
(payload) => void |
No | Callback for streaming partial text replies. |
onBlockReply |
(payload) => void |
No | Callback for block-level reply chunks. |
onToolResult |
(payload) => void |
No | Callback for tool execution results. |
onReasoningStream |
(payload) => void |
No | Callback for reasoning/thinking token streams. |
onAgentEvent |
(evt) => void |
No | Callback for structured agent events. |
Outputs
| Name | Type | Description |
|---|---|---|
payloads |
Array<{ text?: string; mediaUrl?: string; mediaUrls?: string[]; replyToId?: string; isError?: boolean }> |
The constructed reply payloads for delivery to the originating channel. |
meta |
EmbeddedPiRunMeta |
Execution metadata including duration, provider/model info, usage statistics, stop reason, error details, and system prompt report. |
didSendViaMessagingTool |
boolean |
Whether a messaging tool (e.g., Telegram send, WhatsApp send) successfully sent a message during the run. |
messagingToolSentTexts |
string[] |
Texts successfully delivered via messaging tools. |
messagingToolSentTargets |
MessagingToolSend[] |
Messaging tool send targets that succeeded. |
Usage Examples
Basic Usage
import { runEmbeddedPiAgent } from "../agents/pi-embedded-runner/run.js";
import { v4 as uuidv4 } from "uuid";
const result = await runEmbeddedPiAgent({
sessionId: "session-abc123",
sessionKey: "agent:default:telegram:dm:12345",
sessionFile: "/home/user/.openclaw/sessions/session-abc123.jsonl",
workspaceDir: "/home/user/.openclaw/workspace",
prompt: "What files are in the current directory?",
provider: "anthropic",
model: "claude-sonnet-4-20250514",
thinkLevel: "off",
timeoutMs: 120_000,
runId: uuidv4(),
onPartialReply: ({ text }) => {
if (text) process.stdout.write(text);
},
onToolResult: ({ text }) => {
if (text) console.log("[tool]", text);
},
});
// Process the final payloads
for (const payload of result.payloads ?? []) {
console.log(payload.text);
}
console.log(`Duration: ${result.meta.durationMs}ms`);