Plugin SDK reference
Pomocnicze funkcje środowiska uruchomieniowego Plugin
Dokumentacja referencyjna obiektu api.runtime wstrzykiwanego do każdego pluginu podczas rejestracji. Używaj tych helperów zamiast bezpośrednio importować wewnętrzne elementy hosta.
Przewodnik krok po kroku pokazujący użycie tych helperów w kontekście pluginów kanałów.
Przewodnik krok po kroku pokazujący użycie tych helperów w kontekście pluginów dostawców.
register(api) { const runtime = api.runtime;}Wczytywanie i zapisywanie konfiguracji
Preferuj konfigurację, która została już przekazana do aktywnej ścieżki wywołania, na przykład api.config podczas rejestracji albo argument cfg w callbackach kanału/dostawcy. Dzięki temu przez pracę przepływa jedna migawka procesu zamiast ponownego parsowania konfiguracji na gorących ścieżkach.
Używaj api.runtime.config.current() tylko wtedy, gdy długotrwały handler potrzebuje bieżącej migawki procesu i do tej funkcji nie przekazano żadnej konfiguracji. Zwrócona wartość jest tylko do odczytu; przed edycją sklonuj ją albo użyj helpera mutacji.
Fabryki narzędzi otrzymują ctx.runtimeConfig oraz ctx.getRuntimeConfig(). Użyj gettera wewnątrz callbacka execute długotrwałego narzędzia, gdy konfiguracja może zmienić się po utworzeniu definicji narzędzia.
Utrwalaj zmiany za pomocą api.runtime.config.mutateConfigFile(...) albo api.runtime.config.replaceConfigFile(...). Każdy zapis musi wybrać jawne zasady afterWrite:
afterWrite: { mode: "auto" }pozwala planerowi przeładowania Gateway podjąć decyzję.afterWrite: { mode: "restart", reason: "..." }wymusza czysty restart, gdy autor zapisu wie, że gorące przeładowanie jest niebezpieczne.afterWrite: { mode: "none", reason: "..." }wyłącza automatyczne przeładowanie/restart tylko wtedy, gdy wywołujący odpowiada za dalsze działania.
Helpery mutacji zwracają afterWrite oraz typowane podsumowanie followUp, aby wywołujący mogli logować lub testować, czy zażądali restartu. Gateway nadal decyduje, kiedy ten restart faktycznie nastąpi.
api.runtime.config.loadConfig() i api.runtime.config.writeConfigFile(...) to przestarzałe helpery kompatybilności pod runtime-config-load-write. Ostrzegają raz w czasie działania i pozostają dostępne dla starych zewnętrznych pluginów w okresie migracji. Dołączone pluginy nie mogą ich używać; strażnicy granicy konfiguracji zawodzą, jeśli kod pluginu je wywołuje albo importuje te helpery z podścieżek SDK pluginów.
W przypadku bezpośrednich importów SDK używaj wyspecjalizowanych podścieżek konfiguracji zamiast szerokiego barrela kompatybilności
openclaw/plugin-sdk/config-runtime: config-contracts dla
typów, plugin-config-runtime dla asercji już wczytanej konfiguracji i wyszukiwania
wejścia pluginu, runtime-config-snapshot dla bieżących migawek procesu oraz
config-mutation dla zapisów. Testy dołączonych pluginów powinny bezpośrednio mockować te wyspecjalizowane
podścieżki zamiast mockować szeroki barrel kompatybilności.
Wewnętrzny kod środowiska wykonawczego OpenClaw podąża w tym samym kierunku: wczytaj konfigurację raz na granicy CLI, Gateway lub procesu, a następnie przekazuj tę wartość dalej. Udane zapisy mutacji odświeżają migawkę środowiska wykonawczego procesu i zwiększają jej wewnętrzną rewizję; długotrwałe cache powinny opierać klucze na kluczu cache należącym do środowiska wykonawczego zamiast lokalnie serializować konfigurację. Długotrwałe moduły środowiska wykonawczego mają skaner bez tolerancji dla otaczających wywołań loadConfig(); użyj przekazanego cfg, żądania context.getRuntimeConfig() albo getRuntimeConfig() na jawnej granicy procesu.
Ścieżki wykonywania dostawców i kanałów muszą używać aktywnej migawki konfiguracji środowiska wykonawczego, a nie migawki pliku zwróconej do odczytu lub edycji konfiguracji. Migawki plików zachowują wartości źródłowe, takie jak znaczniki SecretRef dla UI i zapisów; callbacki dostawcy potrzebują rozwiązanego widoku środowiska wykonawczego. Gdy helper może zostać wywołany z aktywną migawką źródłową albo aktywną migawką środowiska wykonawczego, przed odczytem poświadczeń przeprowadź ścieżkę przez selectApplicableRuntimeConfig().
Wielokrotnego użytku narzędzia środowiska wykonawczego
Używaj przychodzących faktów botLoopProtection dla przychodzących wiadomości autorstwa botów. Core stosuje współdzielony, pamięciowy strażnik z przesuwanym oknem przed zapisem sesji i dispatch, bez wiązania zasad z jednym kanałem. Strażnik śledzi klucze (scopeId, conversationId, participant pair), zlicza oba kierunki pary razem, stosuje okres wyciszenia po przekroczeniu budżetu okna i oportunistycznie usuwa nieaktywne wpisy.
Pluginy kanałów, które udostępniają to zachowanie operatorom, powinny preferować współdzielony kształt channels.defaults.botLoopProtection dla bazowych budżetów, a następnie nakładać na niego nadpisania specyficzne dla kanału/dostawcy. Współdzielona konfiguracja używa sekund, ponieważ jest widoczna dla użytkownika:
type ChannelBotLoopProtectionConfig = { enabled?: boolean; maxEventsPerWindow?: number; windowSeconds?: number; cooldownSeconds?: number;};Przekaż znormalizowane fakty par botów wraz z rozwiązanym turn. Core rozwiązuje wartości domyślne, konwersję jednostek i semantykę enabled:
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", },};Używaj openclaw/plugin-sdk/pair-loop-guard-runtime bezpośrednio tylko dla niestandardowych
dwustronnych pętli zdarzeń, które nie przechodzą przez współdzielony runner odpowiedzi przychodzących.
Przestrzenie nazw środowiska wykonawczego
api.runtime.agent
Tożsamość agenta, katalogi i zarządzanie sesjami.
// 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(...) to neutralny helper do uruchamiania normalnego turn agenta OpenClaw z kodu pluginu. Używa tego samego rozwiązywania dostawcy/modelu i wyboru uprzęży agenta co odpowiedzi wyzwalane przez kanał.
runEmbeddedPiAgent(...) pozostaje przestarzałym aliasem kompatybilności dla istniejących pluginów. Nowy kod powinien używać runEmbeddedAgent(...).
resolveThinkingPolicy(...) zwraca obsługiwane poziomy rozumowania dostawcy/modelu oraz opcjonalną wartość domyślną. Pluginy dostawców są właścicielami profilu specyficznego dla modelu poprzez swoje hooki rozumowania, więc pluginy narzędziowe powinny wywoływać ten helper środowiska wykonawczego zamiast importować lub duplikować listy dostawców.
normalizeThinkingLevel(...) konwertuje tekst użytkownika, taki jak on, x-high albo extra high, do kanonicznego zapisanego poziomu przed sprawdzeniem go względem rozwiązanych zasad.
Helpery magazynu sesji znajdują się pod 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" }),});Preferuj getSessionEntry(...), listSessionEntries(...), patchSessionEntry(...) albo upsertSessionEntry(...) dla przepływów pracy sesji. Te helpery adresują sesje według tożsamości agenta/sesji, dzięki czemu pluginy nie zależą od starszego kształtu magazynu sessions.json. Użyj preserveActivity: true dla poprawek obejmujących tylko metadane, które nie powinny odświeżać aktywności sesji, oraz replaceEntry: true tylko wtedy, gdy callback zwraca kompletny wpis, a usunięte pola muszą pozostać usunięte.
Do odczytów i zapisów transkryptu importuj openclaw/plugin-sdk/session-transcript-runtime i używaj resolveSessionTranscriptIdentity(...), resolveSessionTranscriptTarget(...), readSessionTranscriptEvents(...), appendSessionTranscriptMessageByIdentity(...), publishSessionTranscriptUpdateByIdentity(...) albo withSessionTranscriptWriteLock(...) z { agentId, sessionKey, sessionId }. Te API pozwalają pluginom zidentyfikować transkrypt, odczytać jego zdarzenia, dołączać wiadomości, publikować aktualizacje i uruchamiać powiązane operacje pod tą samą blokadą zapisu transkryptu. Przekazywanie sessionFile, używanie resolveSessionTranscriptLegacyFileTarget(...) albo importowanie niskopoziomowych appendSessionTranscriptMessage(...) / emitSessionTranscriptUpdate(...) z openclaw/plugin-sdk/agent-harness-runtime jest przestarzałe; te ścieżki istnieją tylko dla starszego kodu, który już otrzymuje aktywny artefakt transkryptu.
loadSessionStore(...), saveSessionStore(...), updateSessionStore(...), resolveSessionFilePath(...) i resolveAndPersistSessionFile(...) to przestarzałe helpery kompatybilności dla pluginów, które nadal celowo zależą od starszego kształtu całego magazynu albo pliku transkryptu. Nowy kod pluginu nie może używać tych helperów, a istniejący wywołujący powinni migrować do helperów wpisów i helperów tożsamości transkryptów.
api.runtime.agent.defaults
Domyślne stałe modelu i dostawcy:
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
Uruchom uzupełnianie tekstu należące do hosta bez importowania wewnętrznych elementów dostawcy ani duplikowania przygotowania modelu, uwierzytelniania i bazowego URL OpenClaw.
const result = await api.runtime.llm.complete({ messages: [{ role: "user", content: "Summarize this transcript." }], purpose: "my-plugin.summary", maxTokens: 512, temperature: 0.2,});Helper używa tej samej ścieżki przygotowania prostego uzupełniania co wbudowane
środowisko wykonawcze OpenClaw oraz należącej do hosta migawki konfiguracji środowiska wykonawczego. Silniki kontekstu
otrzymują powiązaną z sesją zdolność llm.complete, więc wywołania modelu używają
agenta aktywnej sesji i nie przechodzą po cichu na domyślnego agenta. Wynik
zawiera atrybucję dostawcy/modelu/agenta oraz znormalizowane użycie tokenów,
cache i szacowanego kosztu, gdy są dostępne.
api.runtime.subagent
Uruchamiaj i zarządzaj działaniami subagentów w tle.
// 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(...) może usuwać sesje utworzone przez ten sam Plugin za pomocą api.runtime.subagent.run(...). Usuwanie dowolnych sesji użytkownika lub operatora nadal wymaga żądania Gateway w zakresie administratora.
api.runtime.nodes
Wyświetla połączone węzły i wywołuje polecenie hosta węzła z kodu Pluginu załadowanego przez Gateway albo z poleceń CLI Pluginu. Użyj tego, gdy Plugin odpowiada za lokalną pracę na sparowanym urządzeniu, na przykład most przeglądarki lub audio na innym Macu.
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,});Wewnątrz Gateway to środowisko wykonawcze działa w procesie. W poleceniach CLI Pluginu wywołuje skonfigurowany Gateway przez RPC, więc polecenia takie jak openclaw googlemeet recover-tab mogą sprawdzać sparowane węzły z terminala. Polecenia węzłów nadal przechodzą przez standardowe parowanie węzłów Gateway, listy dozwolonych poleceń, zasady wywoływania węzłów Pluginów oraz lokalną obsługę poleceń węzła.
Pluginy, które udostępniają niebezpieczne polecenia hosta węzła, powinny zarejestrować zasadę wywoływania węzła za pomocą api.registerNodeInvokePolicy(...). Zasada działa w Gateway po sprawdzeniu listy dozwolonych poleceń i przed przekazaniem polecenia do węzła, więc bezpośrednie wywołania node.invoke i narzędzia Pluginów wyższego poziomu współdzielą tę samą ścieżkę egzekwowania.
api.runtime.tasks.managedFlows
Powiąż środowisko wykonawcze przepływu zadań z istniejącym kluczem sesji OpenClaw lub zaufanym kontekstem narzędzia, a następnie twórz przepływy zadań i zarządzaj nimi bez przekazywania właściciela przy każdym wywołaniu.
Przepływ zadań śledzi trwały stan wieloetapowego przepływu pracy. Nie jest harmonogramem:
użyj Cron lub api.session.workflow.scheduleSessionTurn(...) do przyszłych
wybudzeń, a następnie użyj managedFlows z zaplanowanej tury, gdy ta praca
wymaga stanu przepływu, zadań podrzędnych, oczekiwań lub anulowania.
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" },});Użyj bindSession({ sessionKey, requesterOrigin }), gdy masz już zaufany klucz sesji OpenClaw z własnej warstwy wiązania. Nie wiąż z surowych danych wejściowych użytkownika.
api.runtime.tts
Synteza mowy z tekstu.
// 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,});Używa podstawowej konfiguracji messages.tts i wyboru dostawcy. Zwraca bufor audio PCM oraz częstotliwość próbkowania.
api.runtime.mediaUnderstanding
Analiza obrazów, audio i wideo.
// 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,});Zwraca { text: undefined }, gdy nie zostanie wygenerowane żadne wyjście (np. pominięte dane wejściowe).
api.runtime.imageGeneration
Generowanie obrazów.
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
Wyszukiwanie w sieci.
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
Niskopoziomowe narzędzia multimedialne.
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
Bieżąca migawka konfiguracji środowiska wykonawczego i transakcyjne zapisy konfiguracji. Preferuj
konfigurację, która została już przekazana do aktywnej ścieżki wywołania; używaj
current() tylko wtedy, gdy handler potrzebuje bezpośrednio migawki procesu.
const cfg = api.runtime.config.current();await api.runtime.config.mutateConfigFile({ afterWrite: { mode: "auto" }, mutate(draft) { draft.plugins ??= {}; },});mutateConfigFile(...) i replaceConfigFile(...) zwracają wartość followUp,
na przykład { mode: "restart", requiresRestart: true, reason },
która zapisuje intencję zapisującego bez odbierania kontroli nad restartem
Gateway.
api.runtime.system
Narzędzia na poziomie systemu.
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(...) zwraca przechwycone stdout i stderr, opcjonalne
liczby obcięć, code, signal, killed, termination oraz
noOutputTimedOut. Wyniki limitu czasu i limitu czasu bez wyjścia zgłaszają code: 124,
gdy proces potomny nie podaje niezerowego kodu zakończenia. Zakończenia sygnałem
niezwiązane z limitem czasu mogą nadal zwracać code: null, więc użyj termination i
noOutputTimedOut, aby odróżnić powody limitu czasu.
api.runtime.events
Subskrypcje zdarzeń.
api.runtime.events.onAgentEvent((event) => { /* ... */});api.runtime.events.onSessionTranscriptUpdate((update) => { /* ... */});api.runtime.logging
Logowanie.
const verbose = api.runtime.logging.shouldLogVerbose();const childLogger = api.runtime.logging.getChildLogger({ plugin: "my-plugin" }, { level: "debug" });api.runtime.modelAuth
Rozwiązywanie uwierzytelniania modelu i dostawcy.
const auth = await api.runtime.modelAuth.getApiKeyForModel({ model, cfg });const providerAuth = await api.runtime.modelAuth.resolveApiKeyForProvider({ provider: "openai", cfg,});api.runtime.state
Rozwiązywanie katalogu stanu i magazyn klucz-wartość oparty na SQLite.
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();Magazyny kluczowane przetrwają ponowne uruchomienia i są izolowane przez powiązany ze środowiskiem runtime identyfikator pluginu. Użyj registerIfAbsent(...) do atomowych żądań deduplikacji: zwraca true, gdy klucza brakowało albo wygasł i został zarejestrowany, albo false, gdy aktywna wartość już istnieje, bez nadpisywania jej wartości, czasu utworzenia ani TTL. Limity: maxEntries na przestrzeń nazw, 6000 aktywnych wierszy na plugin, wartości JSON poniżej 64 KB i opcjonalne wygasanie TTL. Gdy zapis przekroczyłby limit wierszy pluginu, runtime może usunąć najstarsze aktywne wiersze z zapisywanej przestrzeni nazw; sąsiednie przestrzenie nazw nie są usuwane dla tego zapisu, a zapis nadal kończy się niepowodzeniem, jeśli przestrzeń nazw nie może zwolnić wystarczającej liczby wierszy.
api.runtime.tools
Fabryki narzędzi pamięci i CLI.
const getTool = api.runtime.tools.createMemoryGetTool(/* ... */);const searchTool = api.runtime.tools.createMemorySearchTool(/* ... */);api.runtime.tools.registerMemoryCli(/* ... */);api.runtime.channel
Pomocnicze funkcje runtime specyficzne dla kanału (dostępne, gdy plugin kanału jest załadowany).
api.runtime.channel.media to preferowana powierzchnia do pobierania i przechowywania multimediów kanału:
const saved = await api.runtime.channel.media.saveRemoteMedia({ url, subdir: "inbound", maxBytes, filePathHint: fileName,});Użyj saveRemoteMedia(...), gdy zdalny URL ma stać się multimedium OpenClaw. Użyj saveResponseMedia(...), gdy plugin już pobrał Response z obsługą uwierzytelniania, przekierowań lub listy dozwolonych adresów należącą do pluginu. Używaj readRemoteMediaBuffer(...) tylko wtedy, gdy plugin potrzebuje surowych bajtów do inspekcji, transformacji, odszyfrowania lub ponownego przesłania. fetchRemoteMedia(...) pozostaje przestarzałym aliasem zgodności dla readRemoteMediaBuffer(...).
api.runtime.channel.mentions to współdzielona powierzchnia zasad wzmianek przychodzących dla wbudowanych pluginów kanałów, które używają wstrzykiwania runtime:
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, },});Dostępne pomocnicze funkcje wzmianek:
buildMentionRegexesmatchesMentionPatternsmatchesMentionWithExplicitimplicitMentionKindWhenresolveInboundMentionDecision
api.runtime.channel.mentions celowo nie udostępnia starszych pomocniczych funkcji zgodności resolveMentionGating*. Preferuj znormalizowaną ścieżkę { facts, policy }.
Przechowywanie referencji runtime
Użyj createPluginRuntimeStore, aby przechować referencję runtime do użycia poza wywołaniem zwrotnym register:
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}Inne pola api najwyższego poziomu
Poza api.runtime obiekt API udostępnia także:
api.idstringIdentyfikator pluginu.
api.namestringWyświetlana nazwa pluginu.
api.configOpenClawConfigBieżąca migawka konfiguracji (aktywna migawka runtime w pamięci, gdy jest dostępna).
OPENCLAW_DOCS_MARKER:paramOpen:IHBhdGg9ImFwaS5wbHVnaW5Db25maWciIHR5cGU9IlJlY29yZDxzdHJpbmcsIHVua25vd24
">
Konfiguracja specyficzna dla pluginu z plugins.entries.<id>.config.
api.loggerPluginLoggerLogger o ograniczonym zakresie (debug, info, warn, error).
api.registrationModePluginRegistrationModeBieżący tryb ładowania; "setup-runtime" to lekkie okno uruchamiania/konfiguracji przed pełnym punktem wejścia.
api.resolvePath(input)(string) =,�������Q�<Powiązane
- Wewnętrzne mechanizmy pluginów — model możliwości i rejestr
- Punkty wejścia SDK — opcje
definePluginEntry - Omówienie SDK — referencja podścieżek