Documentation Index
Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
OpenClaw integreert met pi-coding-agent en de bijbehorende siblingpakketten (pi-ai, pi-agent-core, pi-tui) om de mogelijkheden van zijn AI-agent aan te drijven.
Overzicht
OpenClaw gebruikt de pi SDK om een AI-codeeragent in zijn messaging-Gateway-architectuur in te bedden. In plaats van pi als subprocess te starten of RPC-modus te gebruiken, importeert en instantieert OpenClaw pi’s AgentSession direct via createAgentSession(). Deze ingebedde aanpak biedt:
- Volledige controle over sessielevenscyclus en eventafhandeling
- Injectie van aangepaste tools (messaging, sandbox, kanaalspecifieke acties)
- Aanpassing van systeemprompt per kanaal/context
- Sessiepersistentie met ondersteuning voor vertakking/Compaction
- Rotatie van auth-profielen voor meerdere accounts met failover
- Provider-agnostisch wisselen van model
Pakketafhankelijkheden
{
"@earendil-works/pi-agent-core": "0.74.0",
"@earendil-works/pi-ai": "0.74.0",
"@earendil-works/pi-coding-agent": "0.74.0",
"@earendil-works/pi-tui": "0.74.0"
}
| Pakket | Doel |
|---|
pi-ai | Kernabstracties voor LLM’s: Model, streamSimple, berichttypen, provider-API’s |
pi-agent-core | Agentlus, tooluitvoering, typen voor AgentMessage |
pi-coding-agent | Hoog-niveau-SDK: createAgentSession, SessionManager, AuthStorage, ModelRegistry, ingebouwde tools |
pi-tui | Terminal-UI-componenten (gebruikt in OpenClaw’s lokale TUI-modus) |
Bestandsstructuur
src/agents/
├── pi-embedded-runner.ts # Re-exports from pi-embedded-runner/
├── pi-embedded-runner/
│ ├── run.ts # Main entry: runEmbeddedPiAgent()
│ ├── run/
│ │ ├── attempt.ts # Single attempt logic with session setup
│ │ ├── params.ts # RunEmbeddedPiAgentParams type
│ │ ├── payloads.ts # Build response payloads from run results
│ │ ├── images.ts # Vision model image injection
│ │ └── types.ts # EmbeddedRunAttemptResult
│ ├── abort.ts # Abort error detection
│ ├── cache-ttl.ts # Cache TTL tracking for context pruning
│ ├── compact.ts # Manual/auto compaction logic
│ ├── extensions.ts # Load pi extensions for embedded runs
│ ├── extra-params.ts # Provider-specific stream params
│ ├── google.ts # Google/Gemini turn ordering fixes
│ ├── history.ts # History limiting (DM vs group)
│ ├── lanes.ts # Session/global command lanes
│ ├── logger.ts # Subsystem logger
│ ├── model.ts # Model resolution via ModelRegistry
│ ├── runs.ts # Active run tracking, abort, queue
│ ├── sandbox-info.ts # Sandbox info for system prompt
│ ├── session-manager-cache.ts # SessionManager instance caching
│ ├── session-manager-init.ts # Session file initialization
│ ├── system-prompt.ts # System prompt builder
│ ├── tool-split.ts # Split tools into builtIn vs custom
│ ├── types.ts # EmbeddedPiAgentMeta, EmbeddedPiRunResult
│ └── utils.ts # ThinkLevel mapping, error description
├── pi-embedded-subscribe.ts # Session event subscription/dispatch
├── pi-embedded-subscribe.types.ts # SubscribeEmbeddedPiSessionParams
├── pi-embedded-subscribe.handlers.ts # Event handler factory
├── pi-embedded-subscribe.handlers.lifecycle.ts
├── pi-embedded-subscribe.handlers.types.ts
├── pi-embedded-block-chunker.ts # Streaming block reply chunking
├── pi-embedded-messaging.ts # Messaging tool sent tracking
├── pi-embedded-helpers.ts # Error classification, turn validation
├── pi-embedded-helpers/ # Helper modules
├── pi-embedded-utils.ts # Formatting utilities
├── pi-tools.ts # createOpenClawCodingTools()
├── pi-tools.abort.ts # AbortSignal wrapping for tools
├── pi-tools.policy.ts # Tool allowlist/denylist policy
├── pi-tools.read.ts # Read tool customizations
├── pi-tools.schema.ts # Tool schema normalization
├── pi-tools.types.ts # AnyAgentTool type alias
├── pi-tool-definition-adapter.ts # AgentTool -> ToolDefinition adapter
├── pi-settings.ts # Settings overrides
├── pi-hooks/ # Custom pi hooks
│ ├── compaction-safeguard.ts # Safeguard extension
│ ├── compaction-safeguard-runtime.ts
│ ├── context-pruning.ts # Cache-TTL context pruning extension
│ └── context-pruning/
├── model-auth.ts # Auth profile resolution
├── auth-profiles.ts # Profile store, cooldown, failover
├── model-selection.ts # Default model resolution
├── models-config.ts # models.json generation
├── model-catalog.ts # Model catalog cache
├── context-window-guard.ts # Context window validation
├── failover-error.ts # FailoverError class
├── defaults.ts # DEFAULT_PROVIDER, DEFAULT_MODEL
├── system-prompt.ts # buildAgentSystemPrompt()
├── system-prompt-params.ts # System prompt parameter resolution
├── system-prompt-report.ts # Debug report generation
├── tool-summaries.ts # Tool description summaries
├── tool-policy.ts # Tool policy resolution
├── transcript-policy.ts # Transcript validation policy
├── skills.ts # Skill snapshot/prompt building
├── skills/ # Skill subsystem
├── sandbox.ts # Sandbox context resolution
├── sandbox/ # Sandbox subsystem
├── channel-tools.ts # Channel-specific tool injection
├── openclaw-tools.ts # OpenClaw-specific tools
├── bash-tools.ts # exec/process tools
├── apply-patch.ts # apply_patch tool (OpenAI)
├── tools/ # Individual tool implementations
│ ├── browser-tool.ts
│ ├── canvas-tool.ts
│ ├── cron-tool.ts
│ ├── gateway-tool.ts
│ ├── image-tool.ts
│ ├── message-tool.ts
│ ├── nodes-tool.ts
│ ├── session*.ts
│ ├── web-*.ts
│ └── ...
└── ...
Kanaalspecifieke runtimes voor berichtacties staan nu in de extensionmappen die eigendom zijn van de Plugin,
in plaats van onder src/agents/tools, bijvoorbeeld:
- de runtimebestanden voor acties van de Discord-Plugin
- het runtimebestand voor acties van de Slack-Plugin
- het runtimebestand voor acties van de Telegram-Plugin
- het runtimebestand voor acties van de WhatsApp-Plugin
Kernintegratiestroom
1. Een ingebedde agent uitvoeren
Het hoofdingangspunt is runEmbeddedPiAgent() in pi-embedded-runner/run.ts:
import { runEmbeddedPiAgent } from "./agents/pi-embedded-runner.js";
const result = await runEmbeddedPiAgent({
sessionId: "user-123",
sessionKey: "main:whatsapp:+1234567890",
sessionFile: "/path/to/session.jsonl",
workspaceDir: "/path/to/workspace",
config: openclawConfig,
prompt: "Hello, how are you?",
provider: "anthropic",
model: "claude-sonnet-4-6",
timeoutMs: 120_000,
runId: "run-abc",
onBlockReply: async (payload) => {
await sendToChannel(payload.text, payload.mediaUrls);
},
});
2. Sessie aanmaken
Binnen runEmbeddedAttempt() (aangeroepen door runEmbeddedPiAgent()) wordt de pi SDK gebruikt:
import {
createAgentSession,
DefaultResourceLoader,
SessionManager,
SettingsManager,
} from "@earendil-works/pi-coding-agent";
const resourceLoader = new DefaultResourceLoader({
cwd: resolvedWorkspace,
agentDir,
settingsManager,
additionalExtensionPaths,
});
await resourceLoader.reload();
const { session } = await createAgentSession({
cwd: resolvedWorkspace,
agentDir,
authStorage: params.authStorage,
modelRegistry: params.modelRegistry,
model: params.model,
thinkingLevel: mapThinkingLevel(params.thinkLevel),
tools: builtInTools,
customTools: allCustomTools,
sessionManager,
settingsManager,
resourceLoader,
});
applySystemPromptOverrideToSession(session, systemPromptOverride);
3. Eventabonnement
subscribeEmbeddedPiSession() abonneert zich op events van pi’s AgentSession:
const subscription = subscribeEmbeddedPiSession({
session: activeSession,
runId: params.runId,
verboseLevel: params.verboseLevel,
reasoningMode: params.reasoningLevel,
toolResultFormat: params.toolResultFormat,
onToolResult: params.onToolResult,
onReasoningStream: params.onReasoningStream,
onBlockReply: params.onBlockReply,
onPartialReply: params.onPartialReply,
onAgentEvent: params.onAgentEvent,
});
Afgehandelde events zijn onder andere:
message_start / message_end / message_update (streaming tekst/denken)
tool_execution_start / tool_execution_update / tool_execution_end
turn_start / turn_end
agent_start / agent_end
compaction_start / compaction_end
4. Prompting
Na de configuratie krijgt de sessie een prompt:
await session.prompt(effectivePrompt, { images: imageResult.images });
De SDK handelt de volledige agentlus af: verzenden naar LLM, toolaanroepen uitvoeren, responses streamen.
Afbeeldingsinjectie is prompt-lokaal: OpenClaw laadt afbeeldingsreferenties uit de huidige prompt en
geeft ze alleen voor die beurt door via images. Oudere history turns worden niet opnieuw gescand
om afbeeldingspayloads opnieuw te injecteren.
- Basistools: pi’s
codingTools (read, bash, edit, write)
- Aangepaste vervangingen: OpenClaw vervangt bash door
exec/process, past read/edit/write aan voor sandbox
- OpenClaw-tools: messaging, browser, canvas, sessies, Cron, Gateway, enz.
- Kanaaltools: Discord-/Telegram-/Slack-/WhatsApp-specifieke actietools
- Beleidsfiltering: Tools gefilterd op profiel, provider, agent, groep, sandboxbeleid
- Schemanormalisatie: Schema’s opgeschoond voor eigenaardigheden van Gemini/OpenAI
- AbortSignal-wrapping: Tools gewrapt om abortsignalen te respecteren
pi-agent-core’s AgentTool heeft een andere execute-signatuur dan pi-coding-agent’s ToolDefinition. De adapter in pi-tool-definition-adapter.ts overbrugt dit:
export function toToolDefinitions(tools: AnyAgentTool[]): ToolDefinition[] {
return tools.map((tool) => ({
name: tool.name,
label: tool.label ?? name,
description: tool.description ?? "",
parameters: tool.parameters,
execute: async (toolCallId, params, onUpdate, _ctx, signal) => {
// pi-coding-agent signature differs from pi-agent-core
return await tool.execute(toolCallId, params, signal, onUpdate);
},
}));
}
splitSdkTools() geeft alle tools door via customTools:
export function splitSdkTools(options: { tools: AnyAgentTool[]; sandboxEnabled: boolean }) {
return {
builtInTools: [], // Empty. We override everything
customTools: toToolDefinitions(options.tools),
};
}
Dit zorgt ervoor dat OpenClaw’s beleidsfiltering, sandboxintegratie en uitgebreide toolset consistent blijven tussen providers.
Constructie van de systeemprompt
De systeemprompt wordt opgebouwd in buildAgentSystemPrompt() (system-prompt.ts). Deze stelt een volledige prompt samen met secties zoals Tooling, Tool Call Style, Safety guardrails, OpenClaw Control, Skills, Docs, Workspace, Sandbox, Messaging, Assistant Output Directives, Voice, Silent Replies, Heartbeats, Runtime-metadata, plus Memory en Reactions wanneer ingeschakeld, en optionele contextbestanden en extra systeempromptinhoud. Secties worden ingekort voor de minimale promptmodus die door subagents wordt gebruikt.
De prompt wordt na het maken van de sessie toegepast via applySystemPromptOverrideToSession():
const systemPromptOverride = createSystemPromptOverride(appendPrompt);
applySystemPromptOverrideToSession(session, systemPromptOverride);
Sessiebeheer
Sessiebestanden
Sessies zijn JSONL-bestanden met een boomstructuur (koppeling via id/parentId). Pi’s SessionManager verwerkt persistentie:
const sessionManager = SessionManager.open(params.sessionFile);
OpenClaw omwikkelt dit met guardSessionManager() voor veiligheid van toolresultaten.
Sessiecaching
session-manager-cache.ts cachet SessionManager-instanties om herhaald parseren van bestanden te vermijden:
await prewarmSessionFile(params.sessionFile);
sessionManager = SessionManager.open(params.sessionFile);
trackSessionManagerAccess(params.sessionFile);
Geschiedenis beperken
limitHistoryTurns() beperkt de gespreksgeschiedenis op basis van kanaaltype (DM versus groep).
Compaction
Automatische Compaction wordt geactiveerd bij contextoverflow. Veelvoorkomende overflow-signaturen
zijn request_too_large, context length exceeded, input exceeds the maximum number of tokens, input token count exceeds the maximum number of input tokens, input is too long for the model en ollama error: context length exceeded. compactEmbeddedPiSessionDirect() verwerkt handmatige
Compaction:
const compactResult = await compactEmbeddedPiSessionDirect({
sessionId, sessionFile, provider, model, ...
});
Authenticatie en modelresolutie
Authenticatieprofielen
OpenClaw onderhoudt een opslag voor authenticatieprofielen met meerdere API-sleutels per provider:
const authStore = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false });
const profileOrder = resolveAuthProfileOrder({ cfg, store: authStore, provider, preferredProfile });
Profielen roteren bij fouten met cooldown-tracking:
await markAuthProfileFailure({ store, profileId, reason, cfg, agentDir });
const rotated = await advanceAuthProfile();
Modelresolutie
import { resolveModel } from "./pi-embedded-runner/model.js";
const { model, error, authStorage, modelRegistry } = resolveModel(
provider,
modelId,
agentDir,
config,
);
// Uses pi's ModelRegistry and AuthStorage
authStorage.setRuntimeApiKey(model.provider, apiKeyInfo.apiKey);
Failover
FailoverError activeert modelterugval wanneer dit is geconfigureerd:
if (fallbackConfigured && isFailoverErrorMessage(errorText)) {
throw new FailoverError(errorText, {
reason: promptFailoverReason ?? "unknown",
provider,
model: modelId,
profileId,
status: resolveFailoverStatus(promptFailoverReason),
});
}
Pi-extensies
OpenClaw laadt aangepaste Pi-extensies voor gespecialiseerd gedrag:
Compaction-beveiliging
src/agents/pi-hooks/compaction-safeguard.ts voegt guardrails toe aan Compaction, inclusief adaptieve tokenbudgettering plus samenvattingen van toolfouten en bestandsbewerkingen:
if (resolveCompactionMode(params.cfg) === "safeguard") {
setCompactionSafeguardRuntime(params.sessionManager, { maxHistoryShare });
paths.push(resolvePiExtensionPath("compaction-safeguard"));
}
Contextsnoei
src/agents/pi-hooks/context-pruning.ts implementeert contextsnoei op basis van cache-TTL:
if (cfg?.agents?.defaults?.contextPruning?.mode === "cache-ttl") {
setContextPruningRuntime(params.sessionManager, {
settings,
contextWindowTokens,
isToolPrunable,
lastCacheTouchAt,
});
paths.push(resolvePiExtensionPath("context-pruning"));
}
Streaming en blokantwoorden
Blokken opdelen
EmbeddedBlockChunker beheert het streamen van tekst naar afzonderlijke antwoordblokken:
const blockChunker = blockChunking ? new EmbeddedBlockChunker(blockChunking) : null;
Denken-/final-tagverwijdering
Streaminguitvoer wordt verwerkt om <think>-/<thinking>-blokken te verwijderen en <final>-inhoud te extraheren:
const stripBlockTags = (text: string, state: { thinking: boolean; final: boolean }) => {
// Strip <think>...</think> content
// If enforceFinalTag, only return <final>...</final> content
};
Antwoordinstructies
Antwoordinstructies zoals [[media:url]], [[voice]] en [[reply:id]] worden geparset en geëxtraheerd:
const { text: cleanedText, mediaUrls, audioAsVoice, replyToId } = consumeReplyDirectives(chunk);
Foutafhandeling
Foutclassificatie
pi-embedded-helpers.ts classificeert fouten voor passende afhandeling:
isContextOverflowError(errorText) // Context too large
isCompactionFailureError(errorText) // Compaction failed
isAuthAssistantError(lastAssistant) // Auth failure
isRateLimitAssistantError(...) // Rate limited
isFailoverAssistantError(...) // Should failover
classifyFailoverReason(errorText) // "auth" | "rate_limit" | "quota" | "timeout" | ...
Terugval voor denkniveau
Als een denkniveau niet wordt ondersteund, valt het terug:
const fallbackThinking = pickFallbackThinkingLevel({
message: errorText,
attempted: attemptedThinking,
});
if (fallbackThinking) {
thinkLevel = fallbackThinking;
continue;
}
Sandboxintegratie
Wanneer sandboxmodus is ingeschakeld, worden tools en paden beperkt:
const sandbox = await resolveSandboxContext({
config: params.config,
sessionKey: sandboxSessionKey,
workspaceDir: resolvedWorkspace,
});
if (sandboxRoot) {
// Use sandboxed read/edit/write tools
// Exec runs in container
// Browser uses bridge URL
}
Providerspecifieke afhandeling
Anthropic
- Opschonen van magic string voor weigeringen
- Beurtvalidatie voor opeenvolgende rollen
- Strikte upstream Pi-validatie van toolparameters
Google/Gemini
- Sanering van door de Plugin beheerde toolschema’s
OpenAI
apply_patch-tool voor Codex-modellen
- Afhandeling van downgrade van denkniveau
TUI-integratie
OpenClaw heeft ook een lokale TUI-modus die pi-tui-componenten direct gebruikt:
// src/tui/tui.ts
import { ... } from "@earendil-works/pi-tui";
Dit biedt de interactieve terminalervaring die vergelijkbaar is met Pi’s native modus.
Belangrijkste verschillen met Pi CLI
| Aspect | Pi CLI | OpenClaw Embedded |
|---|
| Aanroep | pi-opdracht / RPC | SDK via createAgentSession() |
| Tools | Standaard codingtools | Aangepaste OpenClaw-toolsuite |
| Systeemprompt | AGENTS.md + prompts | Dynamisch per kanaal/context |
| Sessieopslag | ~/.pi/agent/sessions/ | ~/.openclaw/agents/<agentId>/sessions/ (of $OPENCLAW_STATE_DIR/agents/<agentId>/sessions/) |
| Authenticatie | Eén credential | Meerdere profielen met rotatie |
| Extensies | Geladen vanaf schijf | Programmatisch + schijfpaden |
| Eventafhandeling | TUI-rendering | Callback-gebaseerd (onBlockReply, enz.) |
Toekomstige overwegingen
Gebieden voor mogelijke herziening:
- Afstemming van toolsignatures: Past momenteel aan tussen pi-agent-core- en pi-coding-agent-signatures
- Omwikkeling van sessiebeheerder:
guardSessionManager voegt veiligheid toe, maar verhoogt de complexiteit
- Laden van extensies: Zou Pi’s
ResourceLoader directer kunnen gebruiken
- Complexiteit van streaminghandler:
subscribeEmbeddedPiSession is groot geworden
- Provider-eigenaardigheden: Veel providerspecifieke codepaden die Pi mogelijk zou kunnen afhandelen
Tests
Pi-integratiedekking omvat deze suites:
src/agents/pi-*.test.ts
src/agents/pi-auth-json.test.ts
src/agents/pi-embedded-*.test.ts
src/agents/pi-embedded-helpers*.test.ts
src/agents/pi-embedded-runner*.test.ts
src/agents/pi-embedded-runner/**/*.test.ts
src/agents/pi-embedded-subscribe*.test.ts
src/agents/pi-tools*.test.ts
src/agents/pi-tool-definition-adapter*.test.ts
src/agents/pi-settings.test.ts
src/agents/pi-hooks/**/*.test.ts
Live/opt-in:
src/agents/pi-embedded-runner-extraparams.live.test.ts (schakel OPENCLAW_LIVE_TEST=1 in)
Zie Pi-ontwikkelworkflow voor huidige uitvoeropdrachten.
Gerelateerd