Plugin SDK reference
Plugin-Laufzeit-Hilfsfunktionen
Referenz für das api.runtime-Objekt, das jedem Plugin während der Registrierung injiziert wird. Verwenden Sie diese Hilfsfunktionen, statt Host-Interna direkt zu importieren.
Schritt-für-Schritt-Anleitung, die diese Hilfsfunktionen im Kontext für Channel-Plugins verwendet.
Schritt-für-Schritt-Anleitung, die diese Hilfsfunktionen im Kontext für Provider-Plugins verwendet.
register(api) { const runtime = api.runtime;}Laden und Schreiben der Konfiguration
Bevorzugen Sie Konfiguration, die bereits an den aktiven Aufrufpfad übergeben wurde, zum Beispiel api.config während der Registrierung oder ein cfg-Argument in Channel-/Provider-Callbacks. So fließt ein Prozess-Snapshot durch die Arbeit, statt die Konfiguration auf Hot Paths erneut zu parsen.
Verwenden Sie api.runtime.config.current() nur, wenn ein langlebiger Handler den aktuellen Prozess-Snapshot benötigt und keine Konfiguration an diese Funktion übergeben wurde. Der zurückgegebene Wert ist schreibgeschützt; klonen Sie ihn oder verwenden Sie vor Änderungen eine Mutationshilfsfunktion.
Tool-Factories erhalten ctx.runtimeConfig plus ctx.getRuntimeConfig(). Verwenden Sie den Getter innerhalb des execute-Callbacks eines langlebigen Tools, wenn sich die Konfiguration ändern kann, nachdem die Tool-Definition erstellt wurde.
Persistieren Sie Änderungen mit api.runtime.config.mutateConfigFile(...) oder api.runtime.config.replaceConfigFile(...). Jeder Schreibvorgang muss eine explizite afterWrite-Policy auswählen:
afterWrite: { mode: "auto" }lässt die Gateway-Neuladeplanung entscheiden.afterWrite: { mode: "restart", reason: "..." }erzwingt einen sauberen Neustart, wenn der Schreiber weiß, dass Hot Reload unsicher ist.afterWrite: { mode: "none", reason: "..." }unterdrückt automatisches Neuladen/Neustarten nur, wenn der Aufrufer den Follow-up besitzt.
Die Mutationshilfsfunktionen geben afterWrite plus eine typisierte followUp-Zusammenfassung zurück, damit Aufrufer protokollieren oder testen können, ob sie einen Neustart angefordert haben. Das Gateway besitzt weiterhin die Entscheidung, wann dieser Neustart tatsächlich erfolgt.
api.runtime.config.loadConfig() und api.runtime.config.writeConfigFile(...) sind veraltete Kompatibilitätshilfsfunktionen unter runtime-config-load-write. Sie warnen zur Laufzeit einmal und bleiben während des Migrationsfensters für alte externe Plugins verfügbar. Gebündelte Plugins dürfen sie nicht verwenden; die Konfigurationsgrenzwächter schlagen fehl, wenn Plugin-Code sie aufruft oder diese Hilfsfunktionen aus Plugin-SDK-Unterpfaden importiert.
Verwenden Sie für direkte SDK-Importe die fokussierten Konfigurationsunterpfade statt des breiten Kompatibilitäts-Barrels openclaw/plugin-sdk/config-runtime: config-contracts für Typen, plugin-config-runtime für Assertions zu bereits geladener Konfiguration und Plugin-Eintrags-Lookup, runtime-config-snapshot für aktuelle Prozess-Snapshots und config-mutation für Schreibvorgänge. Tests für gebündelte Plugins sollten diese fokussierten Unterpfade direkt mocken, statt das breite Kompatibilitäts-Barrel zu mocken.
Interner OpenClaw-Runtime-Code folgt derselben Richtung: Konfiguration einmal an der CLI-, Gateway- oder Prozessgrenze laden und diesen Wert dann weiterreichen. Erfolgreiche Mutationsschreibvorgänge aktualisieren den Prozess-Runtime-Snapshot und erhöhen seine interne Revision; langlebige Caches sollten den runtime-eigenen Cache-Key verwenden, statt Konfiguration lokal zu serialisieren. Langlebige Runtime-Module haben einen Null-Toleranz-Scanner für umgebende loadConfig()-Aufrufe; verwenden Sie ein übergebenes cfg, ein Anfrage-context.getRuntimeConfig() oder getRuntimeConfig() an einer expliziten Prozessgrenze.
Provider- und Channel-Ausführungspfade müssen den aktiven Runtime-Konfigurations-Snapshot verwenden, nicht einen Datei-Snapshot, der zum Zurücklesen oder Bearbeiten der Konfiguration zurückgegeben wurde. Datei-Snapshots bewahren Quellwerte wie SecretRef-Marker für UI und Schreibvorgänge; Provider-Callbacks benötigen die aufgelöste Runtime-Sicht. Wenn eine Hilfsfunktion entweder mit dem aktiven Quell-Snapshot oder dem aktiven Runtime-Snapshot aufgerufen werden kann, führen Sie vor dem Lesen von Zugangsdaten über selectApplicableRuntimeConfig().
Wiederverwendbare Runtime-Dienstprogramme
Verwenden Sie eingehende botLoopProtection-Fakten für von Bots verfasste eingehende Nachrichten. Core wendet den gemeinsam genutzten In-Memory-Sliding-Window-Schutz vor Sitzungsdatensatz und Dispatch an, ohne die Policy an einen Channel zu binden. Der Schutz verfolgt (scopeId, conversationId, participant pair)-Schlüssel, zählt beide Richtungen eines Paars zusammen, wendet eine Abkühlzeit an, sobald das Fensterbudget überschritten ist, und entfernt inaktive Einträge opportunistisch.
Channel-Plugins, die dieses Verhalten Betreibern zugänglich machen, sollten die gemeinsam genutzte channels.defaults.botLoopProtection-Form für Basisbudgets bevorzugen und dann channel-/provider-spezifische Overrides darüberlegen. Die gemeinsame Konfiguration verwendet Sekunden, weil sie benutzerseitig ist:
type ChannelBotLoopProtectionConfig = { enabled?: boolean; maxEventsPerWindow?: number; windowSeconds?: number; cooldownSeconds?: number;};Übergeben Sie normalisierte Bot-Paar-Fakten mit dem aufgelösten Turn. Core löst Defaults, Einheitenumrechnung und enabled-Semantik auf:
return { channel: "example", routeSessionKey, storePath, ctxPayload, recordInboundSession, runDispatch, botLoopProtection: { scopeId: "account-1", conversationId: "channel-1", senderId: "bot-a", receiverId: "bot-b", config: channelConfig.botLoopProtection, defaultsConfig: runtimeConfig.channels?.defaults?.botLoopProtection, defaultEnabled: allowBotsMode !== "off", },};Verwenden Sie openclaw/plugin-sdk/pair-loop-guard-runtime nur direkt für benutzerdefinierte Zwei-Parteien-Event-Loops, die nicht über den gemeinsam genutzten Runner für eingehende Antworten laufen.
Runtime-Namespaces
api.runtime.agent
Agent-Identität, Verzeichnisse und Sitzungsverwaltung.
// Resolve the agent's working directoryconst agentDir = api.runtime.agent.resolveAgentDir(cfg); // Resolve agent workspaceconst workspaceDir = api.runtime.agent.resolveAgentWorkspaceDir(cfg); // Get agent identityconst identity = api.runtime.agent.resolveAgentIdentity(cfg); // Get default thinking levelconst thinking = api.runtime.agent.resolveThinkingDefault({ cfg, provider, model,}); // Validate a user-provided thinking level against the active provider profileconst policy = api.runtime.agent.resolveThinkingPolicy({ provider, model });const level = api.runtime.agent.normalizeThinkingLevel("extra high");if (level && policy.levels.some((entry) => entry.id === level)) { // pass level to an embedded run} // Get agent timeoutconst timeoutMs = api.runtime.agent.resolveAgentTimeoutMs(cfg); // Ensure workspace existsawait api.runtime.agent.ensureAgentWorkspace(cfg); // Run an embedded agent turnconst result = await api.runtime.agent.runEmbeddedAgent({ sessionId: "my-plugin:task-1", runId: crypto.randomUUID(), workspaceDir: api.runtime.agent.resolveAgentWorkspaceDir(cfg), prompt: "Summarize the latest changes", timeoutMs: api.runtime.agent.resolveAgentTimeoutMs(cfg),});runEmbeddedAgent(...) ist die neutrale Hilfsfunktion zum Starten eines normalen OpenClaw-Agent-Turns aus Plugin-Code. Sie verwendet dieselbe Provider-/Modellauflösung und Agent-Harness-Auswahl wie durch Channels ausgelöste Antworten.
runEmbeddedPiAgent(...) bleibt als veralteter Kompatibilitätsalias für bestehende Plugins erhalten. Neuer Code sollte runEmbeddedAgent(...) verwenden.
resolveThinkingPolicy(...) gibt die unterstützten Denkstufen des Providers/Modells und optional den Default zurück. Provider-Plugins besitzen das modellspezifische Profil über ihre Thinking-Hooks, daher sollten Tool-Plugins diese Runtime-Hilfsfunktion aufrufen, statt Provider-Listen zu importieren oder zu duplizieren.
normalizeThinkingLevel(...) konvertiert Benutzertext wie on, x-high oder extra high in die kanonisch gespeicherte Stufe, bevor sie gegen die aufgelöste Policy geprüft wird.
Hilfsfunktionen für den Sitzungsspeicher liegen unter api.runtime.agent.session:
const entry = api.runtime.agent.session.getSessionEntry({ agentId, sessionKey });for (const { sessionKey, entry } of api.runtime.agent.session.listSessionEntries({ agentId })) { // Iterate session rows without depending on the legacy sessions.json shape.}await api.runtime.agent.session.patchSessionEntry({ agentId, sessionKey, update: (entry) => ({ thinkingLevel: "high" }),});Bevorzugen Sie getSessionEntry(...), listSessionEntries(...), patchSessionEntry(...) oder upsertSessionEntry(...) für Sitzungsworkflows. Diese Hilfsfunktionen adressieren Sitzungen über Agent-/Sitzungsidentität, sodass Plugins nicht von der alten sessions.json-Speicherform abhängen. Verwenden Sie preserveActivity: true für reine Metadaten-Patches, die Sitzungsaktivität nicht aktualisieren sollen, und replaceEntry: true nur, wenn der Callback einen vollständigen Eintrag zurückgibt und gelöschte Felder gelöscht bleiben müssen.
Importieren Sie für Transcript-Lese- und Schreibvorgänge openclaw/plugin-sdk/session-transcript-runtime und verwenden Sie resolveSessionTranscriptIdentity(...), resolveSessionTranscriptTarget(...), readSessionTranscriptEvents(...), appendSessionTranscriptMessageByIdentity(...), publishSessionTranscriptUpdateByIdentity(...) oder withSessionTranscriptWriteLock(...) mit { agentId, sessionKey, sessionId }. Diese APIs ermöglichen Plugins, ein Transcript zu identifizieren, seine Events zu lesen, Nachrichten anzuhängen, Updates zu veröffentlichen und zugehörige Operationen unter derselben Transcript-Schreibsperre auszuführen. Das Übergeben von sessionFile, die Verwendung von resolveSessionTranscriptLegacyFileTarget(...) oder der Import der Low-Level-Funktionen appendSessionTranscriptMessage(...) / emitSessionTranscriptUpdate(...) aus openclaw/plugin-sdk/agent-harness-runtime ist veraltet; diese Pfade existieren nur für Legacy-Code, der bereits ein aktives Transcript-Artefakt erhält.
loadSessionStore(...), saveSessionStore(...), updateSessionStore(...), resolveSessionFilePath(...) und resolveAndPersistSessionFile(...) sind veraltete Kompatibilitätshilfsfunktionen für Plugins, die weiterhin absichtlich von der alten Whole-Store- oder Transcript-Dateiform abhängen. Neuer Plugin-Code darf diese Hilfsfunktionen nicht verwenden, und bestehende Aufrufer sollten auf Eintragshilfsfunktionen und Transcript-Identitätshilfsfunktionen migrieren.
api.runtime.agent.defaults
Default-Modell- und Provider-Konstanten:
const model = api.runtime.agent.defaults.model; // e.g. "anthropic/claude-sonnet-4-6"const provider = api.runtime.agent.defaults.provider; // e.g. "anthropic"api.runtime.llm
Führen Sie eine host-eigene Textvervollständigung aus, ohne Provider-Interna zu importieren oder die OpenClaw-Vorbereitung für Modell/Auth/Basis-URL zu duplizieren.
const result = await api.runtime.llm.complete({ messages: [{ role: "user", content: "Summarize this transcript." }], purpose: "my-plugin.summary", maxTokens: 512, temperature: 0.2,});Die Hilfsfunktion verwendet denselben Vorbereitungspfad für einfache Vervollständigungen wie die integrierte Runtime von OpenClaw und den host-eigenen Runtime-Konfigurations-Snapshot. Kontext-Engines erhalten eine sitzungsgebundene llm.complete-Capability, sodass Modellaufrufe den Agent der aktiven Sitzung verwenden und nicht stillschweigend auf den Default-Agent zurückfallen. Das Ergebnis enthält Provider-/Modell-/Agent-Zuordnung sowie normalisierte Token-, Cache- und geschätzte Kostennutzung, sofern verfügbar.
api.runtime.subagent
Starten und verwalten Sie Subagent-Läufe im Hintergrund.
// Start a subagent runconst { runId } = await api.runtime.subagent.run({ sessionKey: "agent:main:subagent:search-helper", message: "Expand this query into focused follow-up searches.", provider: "openai", // optional override model: "gpt-4.1-mini", // optional override deliver: false,}); // Wait for completionconst result = await api.runtime.subagent.waitForRun({ runId, timeoutMs: 30000 }); // Read session messagesconst { messages } = await api.runtime.subagent.getSessionMessages({ sessionKey: "agent:main:subagent:search-helper", limit: 10,}); // Delete a sessionawait api.runtime.subagent.deleteSession({ sessionKey: "agent:main:subagent:search-helper",});deleteSession(...) kann Sessions löschen, die dasselbe Plugin über api.runtime.subagent.run(...) erstellt hat. Das Löschen beliebiger Benutzer- oder Operator-Sessions erfordert weiterhin eine Gateway-Anfrage mit Admin-Scope.
api.runtime.nodes
Listet verbundene Nodes auf und ruft einen Node-Host-Befehl aus vom Gateway geladenem Plugin-Code oder aus Plugin-CLI-Befehlen auf. Verwenden Sie dies, wenn ein Plugin lokale Arbeit auf einem gekoppelten Gerät besitzt, zum Beispiel eine Browser- oder Audio-Bridge auf einem anderen Mac.
const { nodes } = await api.runtime.nodes.list({ connected: true }); const result = await api.runtime.nodes.invoke({ nodeId: "mac-studio", command: "my-plugin.command", params: { action: "start" }, timeoutMs: 30000,});Innerhalb des Gateway läuft diese Runtime im Prozess. In Plugin-CLI-Befehlen ruft sie das konfigurierte Gateway über RPC auf, sodass Befehle wie openclaw googlemeet recover-tab gekoppelte Nodes vom Terminal aus prüfen können. Node-Befehle durchlaufen weiterhin das normale Gateway-Node-Pairing, Befehls-Allowlists, Plugin-Node-Invoke-Richtlinien und die lokale Befehlsverarbeitung des Nodes.
Plugins, die gefährliche Node-Host-Befehle bereitstellen, sollten mit api.registerNodeInvokePolicy(...) eine Node-Invoke-Richtlinie registrieren. Die Richtlinie läuft im Gateway nach den Befehls-Allowlist-Prüfungen und bevor der Befehl an den Node weitergeleitet wird, sodass direkte node.invoke-Aufrufe und höherstufige Plugin-Tools denselben Durchsetzungspfad teilen.
api.runtime.tasks.managedFlows
Binden Sie eine Task-Flow-Runtime an einen vorhandenen OpenClaw-Session-Schlüssel oder vertrauenswürdigen Tool-Kontext und erstellen und verwalten Sie dann Task Flows, ohne bei jedem Aufruf einen Owner zu übergeben.
Task Flow verfolgt dauerhaften mehrstufigen Workflow-Zustand. Es ist kein Scheduler:
Verwenden Sie Cron oder api.session.workflow.scheduleSessionTurn(...) für zukünftige
Wakeups und anschließend managedFlows aus dem geplanten Turn, wenn diese Arbeit
Flow-Zustand, Child-Tasks, Wartezeiten oder Abbruch benötigt.
const taskFlow = api.runtime.tasks.managedFlows.fromToolContext(ctx); const created = taskFlow.createManaged({ controllerId: "my-plugin/review-batch", goal: "Review new pull requests",}); const child = taskFlow.runTask({ flowId: created.flowId, runtime: "acp", childSessionKey: "agent:main:subagent:reviewer", task: "Review PR #123", status: "running", startedAt: Date.now(),}); const waiting = taskFlow.setWaiting({ flowId: created.flowId, expectedRevision: created.revision, currentStep: "await-human-reply", waitJson: { kind: "reply", channel: "telegram" },});Verwenden Sie bindSession({ sessionKey, requesterOrigin }), wenn Sie bereits einen vertrauenswürdigen OpenClaw-Session-Schlüssel aus Ihrer eigenen Binding-Schicht haben. Binden Sie nicht aus rohen Benutzereingaben.
api.runtime.tts
Text-zu-Sprache-Synthese.
// Standard TTSconst clip = await api.runtime.tts.textToSpeech({ text: "Hello from OpenClaw", cfg: api.config,}); // Telephony-optimized TTSconst telephonyClip = await api.runtime.tts.textToSpeechTelephony({ text: "Hello from OpenClaw", cfg: api.config,}); // List available voicesconst voices = await api.runtime.tts.listVoices({ provider: "elevenlabs", cfg: api.config,});Verwendet die zentrale messages.tts-Konfiguration und Provider-Auswahl. Gibt PCM-Audiopuffer und Abtastrate zurück.
api.runtime.mediaUnderstanding
Bild-, Audio- und Videoanalyse.
// Describe an imageconst image = await api.runtime.mediaUnderstanding.describeImageFile({ filePath: "/tmp/inbound-photo.jpg", cfg: api.config, agentDir: "/tmp/agent",}); // Transcribe audioconst { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ filePath: "/tmp/inbound-audio.ogg", cfg: api.config, mime: "audio/ogg", // optional, for when MIME cannot be inferred}); // Describe a videoconst video = await api.runtime.mediaUnderstanding.describeVideoFile({ filePath: "/tmp/inbound-video.mp4", cfg: api.config,}); // Generic file analysisconst result = await api.runtime.mediaUnderstanding.runFile({ filePath: "/tmp/inbound-file.pdf", cfg: api.config,}); // Structured image extraction through a specific provider/model.// Include at least one image; text inputs are supplemental context.const evidence = await api.runtime.mediaUnderstanding.extractStructuredWithModel({ provider: "codex", model: "gpt-5.5", input: [ { type: "image", buffer: receiptImageBuffer, fileName: "receipt.png", mime: "image/png", }, { type: "text", text: "Prefer the printed total over handwritten notes." }, ], instructions: "Extract vendor, total, and searchable tags.", schemaName: "receipt.evidence", jsonSchema: { type: "object", properties: { vendor: { type: "string" }, total: { type: "number" }, tags: { type: "array", items: { type: "string" } }, }, required: ["vendor", "total"], }, cfg: api.config,});Gibt { text: undefined } zurück, wenn keine Ausgabe erzeugt wird (z. B. übersprungene Eingabe).
api.runtime.imageGeneration
Bildgenerierung.
const result = await api.runtime.imageGeneration.generate({ prompt: "A robot painting a sunset", cfg: api.config,}); const providers = api.runtime.imageGeneration.listProviders({ cfg: api.config });api.runtime.webSearch
Websuche.
const providers = api.runtime.webSearch.listProviders({ config: api.config }); const result = await api.runtime.webSearch.search({ config: api.config, args: { query: "OpenClaw plugin SDK", count: 5 },});api.runtime.media
Low-Level-Medienwerkzeuge.
const webMedia = await api.runtime.media.loadWebMedia(url);const mime = await api.runtime.media.detectMime(buffer);const kind = api.runtime.media.mediaKindFromMime("image/jpeg"); // "image"const isVoice = api.runtime.media.isVoiceCompatibleAudio(filePath);const metadata = await api.runtime.media.getImageMetadata(filePath);const resized = await api.runtime.media.resizeToJpeg(buffer, { maxWidth: 800 });const terminalQr = await api.runtime.media.renderQrTerminal("https://openclaw.ai");const pngQr = await api.runtime.media.renderQrPngBase64("https://openclaw.ai", { scale: 6, // 1-12 marginModules: 4, // 0-16});const pngQrDataUrl = await api.runtime.media.renderQrPngDataUrl("https://openclaw.ai");const tmpRoot = resolvePreferredOpenClawTmpDir();const pngQrFile = await api.runtime.media.writeQrPngTempFile("https://openclaw.ai", { tmpRoot, dirPrefix: "my-plugin-qr-", fileName: "qr.png",});api.runtime.config
Aktueller Runtime-Konfigurations-Snapshot und transaktionale Konfigurationsschreibvorgänge. Bevorzugen Sie
Konfiguration, die bereits an den aktiven Aufrufpfad übergeben wurde; verwenden Sie
current() nur, wenn der Handler den Prozess-Snapshot direkt benötigt.
const cfg = api.runtime.config.current();await api.runtime.config.mutateConfigFile({ afterWrite: { mode: "auto" }, mutate(draft) { draft.plugins ??= {}; },});mutateConfigFile(...) und replaceConfigFile(...) geben einen followUp-
Wert zurück, zum Beispiel { mode: "restart", requiresRestart: true, reason },
der die Absicht des Writers erfasst, ohne dem
Gateway die Neustartkontrolle zu entziehen.
api.runtime.system
Systemweite Werkzeuge.
await api.runtime.system.enqueueSystemEvent(event);api.runtime.system.requestHeartbeat({ source: "other", intent: "event", reason: "plugin-event",});api.runtime.system.requestHeartbeatNow({ reason: "plugin-event" }); // Deprecated compatibility alias.const output = await api.runtime.system.runCommandWithTimeout(cmd, args, opts);const hint = api.runtime.system.formatNativeDependencyHint(pkg);runCommandWithTimeout(...) gibt erfasstes stdout und stderr, optionale
Kürzungszähler, code, signal, killed, termination und
noOutputTimedOut zurück. Timeout- und No-Output-Timeout-Ergebnisse melden code: 124,
wenn der Kindprozess keinen von null verschiedenen Exit-Code bereitstellt. Nicht durch Timeout bedingte
Signal-Exits können weiterhin code: null zurückgeben; verwenden Sie daher termination und
noOutputTimedOut, um Timeout-Gründe zu unterscheiden.
api.runtime.events
Event-Abonnements.
api.runtime.events.onAgentEvent((event) => { /* ... */});api.runtime.events.onSessionTranscriptUpdate((update) => { /* ... */});api.runtime.logging
Logging.
const verbose = api.runtime.logging.shouldLogVerbose();const childLogger = api.runtime.logging.getChildLogger({ plugin: "my-plugin" }, { level: "debug" });api.runtime.modelAuth
Modell- und Provider-Auth-Auflösung.
const auth = await api.runtime.modelAuth.getApiKeyForModel({ model, cfg });const providerAuth = await api.runtime.modelAuth.resolveApiKeyForProvider({ provider: "openai", cfg,});api.runtime.state
Zustandsverzeichnis-Auflösung und SQLite-gestützter Keyed Storage.
const stateDir = api.runtime.state.resolveStateDir(process.env);const store = api.runtime.state.openKeyedStore<MyRecord>({ namespace: "my-feature", maxEntries: 200, defaultTtlMs: 15 * 60_000,}); await store.register("key-1", { value: "hello" });const claimed = await store.registerIfAbsent("dedupe-key", { value: "first" });const value = await store.lookup("key-1");await store.consume("key-1");await store.clear();Keyed Stores überstehen Neustarts und sind durch die runtime-gebundene Plugin-ID isoliert. Verwenden Sie registerIfAbsent(...) für atomare Dedupe-Claims: Es gibt true zurück, wenn der Schlüssel fehlte oder abgelaufen war und registriert wurde, oder false, wenn bereits ein aktiver Wert existiert, ohne dessen Wert, Erstellungszeit oder TTL zu überschreiben. Grenzen: maxEntries pro Namespace, 6.000 aktive Zeilen pro Plugin, JSON-Werte unter 64 KB und optionaler TTL-Ablauf. Wenn ein Schreibvorgang die Zeilenobergrenze des Plugins überschreiten würde, kann die Runtime die ältesten aktiven Zeilen aus dem Namespace entfernen, in den geschrieben wird; benachbarte Namespaces werden für diesen Schreibvorgang nicht entfernt, und der Schreibvorgang schlägt weiterhin fehl, wenn der Namespace nicht genügend Zeilen freigeben kann.
api.runtime.tools
Factories für Memory-Tools und CLI.
const getTool = api.runtime.tools.createMemoryGetTool(/* ... */);const searchTool = api.runtime.tools.createMemorySearchTool(/* ... */);api.runtime.tools.registerMemoryCli(/* ... */);api.runtime.channel
Kanalspezifische Runtime-Helfer (verfügbar, wenn ein Kanal-Plugin geladen ist).
api.runtime.channel.media ist die bevorzugte Oberfläche für Downloads und Speicherung von Kanalmedien:
const saved = await api.runtime.channel.media.saveRemoteMedia({ url, subdir: "inbound", maxBytes, filePathHint: fileName,});Verwenden Sie saveRemoteMedia(...), wenn eine Remote-URL zu OpenClaw-Medien werden soll. Verwenden Sie saveResponseMedia(...), wenn das Plugin bereits eine Response mit Plugin-eigener Authentifizierung, Weiterleitungs- oder Allowlist-Behandlung abgerufen hat. Verwenden Sie readRemoteMediaBuffer(...) nur, wenn das Plugin Rohbytes zur Prüfung, Transformation, Entschlüsselung oder zum erneuten Hochladen benötigt. fetchRemoteMedia(...) bleibt ein veralteter Kompatibilitätsalias für readRemoteMediaBuffer(...).
api.runtime.channel.mentions ist die gemeinsame Oberfläche für eingehende Erwähnungsrichtlinien für gebündelte Kanal-Plugins, die Runtime-Injection verwenden:
const mentionMatch = api.runtime.channel.mentions.matchesMentionWithExplicit(text, { mentionRegexes, mentionPatterns,}); const decision = api.runtime.channel.mentions.resolveInboundMentionDecision({ facts: { canDetectMention: true, wasMentioned: mentionMatch.matched, implicitMentionKinds: api.runtime.channel.mentions.implicitMentionKindWhen( "reply_to_bot", isReplyToBot, ), }, policy: { isGroup, requireMention, allowTextCommands, hasControlCommand, commandAuthorized, },});Verfügbare Erwähnungshelfer:
buildMentionRegexesmatchesMentionPatternsmatchesMentionWithExplicitimplicitMentionKindWhenresolveInboundMentionDecision
api.runtime.channel.mentions stellt die älteren resolveMentionGating*-Kompatibilitätshelfer absichtlich nicht bereit. Bevorzugen Sie den normalisierten { facts, policy }-Pfad.
Runtime-Referenzen speichern
Verwenden Sie createPluginRuntimeStore, um die Runtime-Referenz für die Nutzung außerhalb des register-Callbacks zu speichern:
Create the store
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";import type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store"; const store = createPluginRuntimeStore<PluginRuntime>({ pluginId: "my-plugin", errorMessage: "my-plugin runtime not initialized",});Wire into the entry point
export default defineChannelPluginEntry({ id: "my-plugin", name: "My Plugin", description: "Example", plugin: myPlugin, setRuntime: store.setRuntime,});Access from other files
export function getRuntime() { return store.getRuntime(); // throws if not initialized} export function tryGetRuntime() { return store.tryGetRuntime(); // returns null if not initialized}Weitere Felder der obersten Ebene von api
Über api.runtime hinaus stellt das API-Objekt außerdem Folgendes bereit:
api.idstringPlugin-ID.
api.namestringAnzeigename des Plugins.
api.configOpenClawConfigAktueller Config-Snapshot (aktiver speicherinterner Runtime-Snapshot, wenn verfügbar).
OPENCLAW_DOCS_MARKER:paramOpen:IHBhdGg9ImFwaS5wbHVnaW5Db25maWciIHR5cGU9IlJlY29yZDxzdHJpbmcsIHVua25vd24
">
Plugin-spezifische Konfiguration aus plugins.entries.<id>.config.
api.loggerPluginLoggerBereichsgebundener Logger (debug, info, warn, error).
api.registrationModePluginRegistrationModeAktueller Lademodus; "setup-runtime" ist das leichtgewichtige Start-/Setup-Fenster vor dem vollständigen Entry.
api.resolvePath(input)"(string)Verwandt
- Plugin-Interna — Capability-Modell und Registry
- SDK-Einstiegspunkte — Optionen für
definePluginEntry - SDK-Übersicht — Subpfad-Referenz