Plugin SDK reference
ตัวช่วยรันไทม์ของ Plugin
ข้อมูลอ้างอิงสำหรับอ็อบเจกต์ api.runtime ที่ถูกฉีดเข้าไปในทุก Plugin ระหว่างการลงทะเบียน ใช้ตัวช่วยเหล่านี้แทนการนำเข้าภายในของโฮสต์โดยตรง
คู่มือทีละขั้นตอนที่ใช้ตัวช่วยเหล่านี้ในบริบทสำหรับ Plugin ช่องทาง
คู่มือทีละขั้นตอนที่ใช้ตัวช่วยเหล่านี้ในบริบทสำหรับ Plugin ผู้ให้บริการ
register(api) { const runtime = api.runtime;}การโหลดและเขียน Config
ให้ใช้ Config ที่ถูกส่งเข้ามาในเส้นทางการเรียกที่ใช้งานอยู่แล้วเป็นหลัก เช่น api.config ระหว่างการลงทะเบียน หรืออาร์กิวเมนต์ cfg ใน callback ของช่องทาง/ผู้ให้บริการ วิธีนี้ทำให้สแนปช็อตของกระบวนการเดียวไหลผ่านงาน แทนการแยกวิเคราะห์ Config ซ้ำใน hot path
ใช้ api.runtime.config.current() เฉพาะเมื่อ handler ที่มีอายุยาวต้องใช้สแนปช็อตของกระบวนการปัจจุบันและไม่มี Config ถูกส่งให้ฟังก์ชันนั้น ค่าที่ส่งกลับเป็นแบบอ่านอย่างเดียว ให้ clone หรือใช้ตัวช่วย mutation ก่อนแก้ไข
Tool factory จะได้รับ ctx.runtimeConfig พร้อมกับ ctx.getRuntimeConfig() ใช้ getter ภายใน callback execute ของ tool ที่มีอายุยาวเมื่อ Config อาจเปลี่ยนหลังจากสร้างคำนิยาม tool แล้ว
บันทึกการเปลี่ยนแปลงด้วย api.runtime.config.mutateConfigFile(...) หรือ api.runtime.config.replaceConfigFile(...) การเขียนแต่ละครั้งต้องเลือกนโยบาย afterWrite อย่างชัดเจน:
afterWrite: { mode: "auto" }ให้ตัวตัดสินการ reload ของ Gateway เป็นผู้ตัดสินใจafterWrite: { mode: "restart", reason: "..." }บังคับ restart อย่างสะอาดเมื่อผู้เขียนรู้ว่า hot reload ไม่ปลอดภัยafterWrite: { mode: "none", reason: "..." }ระงับการ reload/restart อัตโนมัติเฉพาะเมื่อผู้เรียกเป็นเจ้าของการดำเนินการต่อ
ตัวช่วย mutation จะส่งคืน afterWrite พร้อมสรุป followUp ที่มี type เพื่อให้ผู้เรียก log หรือ test ได้ว่ามีการร้องขอ restart หรือไม่ Gateway ยังคงเป็นเจ้าของว่า restart นั้นจะเกิดขึ้นจริงเมื่อใด
api.runtime.config.loadConfig() และ api.runtime.config.writeConfigFile(...) เป็นตัวช่วยความเข้ากันได้ที่เลิกใช้แล้วภายใต้ runtime-config-load-write ตัวช่วยเหล่านี้เตือนหนึ่งครั้งใน runtime และยังคงพร้อมใช้งานสำหรับ Plugin ภายนอกเก่าระหว่างช่วง migration Plugin ที่ bundled ต้องไม่ใช้ตัวช่วยเหล่านี้; ตัว guard ขอบเขต Config จะล้มเหลวถ้าโค้ด Plugin เรียกใช้ตัวช่วยเหล่านี้หรือนำเข้าตัวช่วยจาก subpath ของ Plugin SDK
สำหรับการนำเข้า SDK โดยตรง ให้ใช้ subpath Config แบบเจาะจงแทน compatibility barrel กว้าง
openclaw/plugin-sdk/config-runtime: ใช้ config-contracts สำหรับ
type, plugin-config-runtime สำหรับ assertion ของ Config ที่โหลดแล้วและการค้นหารายการ Plugin,
runtime-config-snapshot สำหรับสแนปช็อตกระบวนการปัจจุบัน และ
config-mutation สำหรับการเขียน test ของ Plugin ที่ bundled ควร mock subpath แบบเจาะจงเหล่านี้โดยตรง แทนการ mock compatibility barrel กว้าง
โค้ด runtime ภายในของ OpenClaw มีทิศทางเดียวกัน: โหลด Config หนึ่งครั้งที่ขอบเขต CLI, Gateway หรือกระบวนการ แล้วส่งค่านั้นต่อไป การเขียน mutation ที่สำเร็จจะ refresh สแนปช็อต runtime ของกระบวนการและเพิ่ม revision ภายใน cache ที่มีอายุยาวควร key จาก cache key ที่ runtime เป็นเจ้าของ แทนการ serialize Config เองในเครื่อง โมดูล runtime ที่มีอายุยาวมี scanner แบบไม่ยอมรับการเรียก loadConfig() แวดล้อมโดยเด็ดขาด; ใช้ cfg ที่ถูกส่งมา, context.getRuntimeConfig() ของคำขอ หรือ getRuntimeConfig() ที่ขอบเขตกระบวนการอย่างชัดเจน
เส้นทางการทำงานของผู้ให้บริการและช่องทางต้องใช้สแนปช็อต Config ของ runtime ที่ใช้งานอยู่ ไม่ใช่สแนปช็อตไฟล์ที่ส่งคืนมาเพื่ออ่านกลับหรือแก้ไข Config สแนปช็อตไฟล์จะคงค่าต้นทาง เช่น marker SecretRef สำหรับ UI และการเขียน; callback ของผู้ให้บริการต้องใช้มุมมอง runtime ที่ resolve แล้ว เมื่อตัวช่วยอาจถูกเรียกด้วยสแนปช็อตต้นทางที่ใช้งานอยู่หรือสแนปช็อต runtime ที่ใช้งานอยู่ ให้ route ผ่าน selectApplicableRuntimeConfig() ก่อนอ่าน credential
Namespace ของ runtime
api.runtime.agent
ตัวตนของ agent, ไดเรกทอรี และการจัดการ session
// 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 agentDir = api.runtime.agent.resolveAgentDir(cfg);const result = await api.runtime.agent.runEmbeddedAgent({ sessionId: "my-plugin:task-1", runId: crypto.randomUUID(), sessionFile: path.join(agentDir, "sessions", "my-plugin-task-1.jsonl"), workspaceDir: api.runtime.agent.resolveAgentWorkspaceDir(cfg), prompt: "Summarize the latest changes", timeoutMs: api.runtime.agent.resolveAgentTimeoutMs(cfg),});runEmbeddedAgent(...) เป็นตัวช่วยกลางสำหรับเริ่มรอบ agent ปกติของ OpenClaw จากโค้ด Plugin โดยใช้การ resolve ผู้ให้บริการ/โมเดลและการเลือก agent harness เดียวกับการตอบกลับที่ถูกกระตุ้นจากช่องทาง
runEmbeddedPiAgent(...) ยังคงอยู่ในฐานะ alias เพื่อความเข้ากันได้
resolveThinkingPolicy(...) ส่งคืนระดับ thinking ที่ผู้ให้บริการ/โมเดลรองรับและค่า default แบบ optional ผู้ให้บริการ Plugin เป็นเจ้าของ profile เฉพาะโมเดลผ่าน hook thinking ของตน ดังนั้น tool Plugin ควรเรียกตัวช่วย runtime นี้แทนการนำเข้าหรือทำซ้ำรายการผู้ให้บริการ
normalizeThinkingLevel(...) แปลงข้อความผู้ใช้ เช่น on, x-high หรือ extra high เป็นระดับที่จัดเก็บตาม canonical ก่อนตรวจสอบกับ policy ที่ resolve แล้ว
ตัวช่วย session store อยู่ภายใต้ api.runtime.agent.session:
const storePath = api.runtime.agent.session.resolveStorePath(cfg);const store = api.runtime.agent.session.loadSessionStore(storePath);await api.runtime.agent.session.updateSessionStore(storePath, (nextStore) => { // Patch one entry without replacing the whole file from stale state. nextStore[sessionKey] = { ...nextStore[sessionKey], thinkingLevel: "high" };});const filePath = api.runtime.agent.session.resolveSessionFilePath(cfg, sessionId);ให้ใช้ updateSessionStore(...) หรือ updateSessionStoreEntry(...) เป็นหลักสำหรับการเขียน runtime ตัวช่วยเหล่านี้ route ผ่านตัวเขียน session-store ที่ Gateway เป็นเจ้าของ, รักษาการอัปเดตพร้อมกัน และใช้ hot cache ซ้ำ saveSessionStore(...) ยังคงพร้อมใช้งานเพื่อความเข้ากันได้และการเขียนซ้ำแบบบำรุงรักษา offline
api.runtime.agent.defaults
ค่าคงที่โมเดลและผู้ให้บริการ default:
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
เรียกใช้ text completion ที่โฮสต์เป็นเจ้าของโดยไม่ต้องนำเข้าภายในของผู้ให้บริการหรือ ทำซ้ำการเตรียมโมเดล/auth/base 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,});ตัวช่วยนี้ใช้เส้นทางการเตรียม simple-completion เดียวกับ runtime built-in ของ OpenClaw
และสแนปช็อต Config runtime ที่โฮสต์เป็นเจ้าของ context engine
จะได้รับ capability llm.complete ที่ผูกกับ session ดังนั้นการเรียกโมเดลจะใช้
agent ของ session ที่ใช้งานอยู่ และไม่ fallback ไปยัง agent default อย่างเงียบ ๆ
ผลลัพธ์มี attribution ของผู้ให้บริการ/โมเดล/agent รวมถึงการใช้งาน token,
cache และค่าใช้จ่ายโดยประมาณที่ถูก normalize เมื่อมีข้อมูล
api.runtime.subagent
เปิดและจัดการการรัน subagent เบื้องหลัง
// 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(...) สามารถลบ session ที่สร้างโดย Plugin เดียวกันผ่าน api.runtime.subagent.run(...) การลบ session ของผู้ใช้หรือ operator ใด ๆ ยังคงต้องใช้คำขอ Gateway ที่มี scope admin
api.runtime.nodes
แสดงรายการ Node ที่เชื่อมต่อและเรียกคำสั่งที่โฮสต์บน Node จากโค้ด Plugin ที่โหลดโดย Gateway หรือจากคำสั่ง CLI ของ Plugin ใช้สิ่งนี้เมื่อ Plugin เป็นเจ้าของงาน local บนอุปกรณ์ที่จับคู่ไว้ เช่น browser หรือ audio bridge บน 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,});ภายใน Gateway runtime นี้เป็นแบบ in-process ในคำสั่ง CLI ของ Plugin จะเรียก Gateway ที่กำหนดค่าไว้ผ่าน RPC ดังนั้นคำสั่งเช่น openclaw googlemeet recover-tab สามารถตรวจสอบ Node ที่จับคู่ไว้จาก terminal ได้ คำสั่ง Node ยังคงผ่านการจับคู่ Node ของ Gateway ตามปกติ, allowlist คำสั่ง, policy node-invoke ของ Plugin และการจัดการคำสั่งแบบ node-local
Plugin ที่เปิดเผยคำสั่ง node-host ที่อันตรายควรลงทะเบียน policy node-invoke ด้วย api.registerNodeInvokePolicy(...) policy จะรันใน Gateway หลังการตรวจสอบ allowlist คำสั่งและก่อนส่งต่อคำสั่งไปยัง Node ดังนั้นการเรียก node.invoke โดยตรงและ tool ระดับสูงของ Plugin จะใช้เส้นทาง enforcement เดียวกัน
api.runtime.tasks.managedFlows
ผูก runtime ของ Task Flow เข้ากับ session key ของ OpenClaw ที่มีอยู่หรือ context ของ tool ที่เชื่อถือได้ จากนั้นสร้างและจัดการ Task Flow โดยไม่ต้องส่ง owner ในทุกการเรียก
Task Flow ติดตามสถานะ workflow หลายขั้นตอนแบบ durable ไม่ใช่ scheduler:
ใช้ Cron หรือ api.session.workflow.scheduleSessionTurn(...) สำหรับการปลุกในอนาคต
จากนั้นใช้ managedFlows จากรอบที่ถูก schedule เมื่อการทำงานนั้น
ต้องการสถานะ flow, งานลูก, การรอ หรือการยกเลิก
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" },});ใช้ bindSession({ sessionKey, requesterOrigin }) เมื่อคุณมีคีย์เซสชัน OpenClaw ที่เชื่อถือได้จากเลเยอร์การผูกของคุณเองอยู่แล้ว อย่าผูกจากข้อมูลดิบที่ผู้ใช้ป้อน
api.runtime.tts
การสังเคราะห์ข้อความเป็นเสียงพูด
// 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,});ใช้การกำหนดค่า messages.tts ของแกนหลักและการเลือก provider คืนค่าบัฟเฟอร์เสียง PCM + อัตราตัวอย่าง
api.runtime.mediaUnderstanding
การวิเคราะห์รูปภาพ เสียง และวิดีโอ
// 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,});คืนค่า { text: undefined } เมื่อไม่มีเอาต์พุตถูกสร้างขึ้น (เช่น ข้อมูลอินพุตถูกข้าม)
api.runtime.imageGeneration
การสร้างรูปภาพ
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
การค้นหาเว็บ
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
ยูทิลิตีสื่อระดับต่ำ
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
สแนปช็อตการกำหนดค่า runtime ปัจจุบันและการเขียนการกำหนดค่าแบบทรานแซกชัน ควรใช้
การกำหนดค่าที่ถูกส่งเข้าสู่เส้นทางการเรียกที่กำลังใช้งานอยู่แล้ว ใช้
current() เฉพาะเมื่อ handler ต้องการสแนปช็อตของ process โดยตรง
const cfg = api.runtime.config.current();await api.runtime.config.mutateConfigFile({ afterWrite: { mode: "auto" }, mutate(draft) { draft.plugins ??= {}; },});mutateConfigFile(...) และ replaceConfigFile(...) คืนค่า followUp
เช่น { mode: "restart", requiresRestart: true, reason }
ซึ่งบันทึกเจตนาของตัวเขียนโดยไม่ดึงการควบคุมการรีสตาร์ตออกจาก
Gateway
api.runtime.system
ยูทิลิตีระดับระบบ
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);api.runtime.events
การสมัครรับเหตุการณ์
api.runtime.events.onAgentEvent((event) => { /* ... */});api.runtime.events.onSessionTranscriptUpdate((update) => { /* ... */});api.runtime.logging
การบันทึกล็อก
const verbose = api.runtime.logging.shouldLogVerbose();const childLogger = api.runtime.logging.getChildLogger({ plugin: "my-plugin" }, { level: "debug" });api.runtime.modelAuth
การแก้ไข auth ของโมเดลและ provider
const auth = await api.runtime.modelAuth.getApiKeyForModel({ model, cfg });const providerAuth = await api.runtime.modelAuth.resolveApiKeyForProvider({ provider: "openai", cfg,});api.runtime.state
การแก้ไขไดเรกทอรีสถานะและที่เก็บแบบ keyed ที่สำรองด้วย 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();ที่เก็บแบบ keyed อยู่รอดหลังรีสตาร์ตและถูกแยกตาม id ของ Plugin ที่ผูกกับ runtime ใช้ registerIfAbsent(...) สำหรับการอ้างสิทธิ์ dedupe แบบอะตอมิก: คืนค่า true เมื่อคีย์หายไปหรือหมดอายุและถูกลงทะเบียนแล้ว หรือ false เมื่อมีค่าสดอยู่แล้วโดยไม่เขียนทับค่า เวลาในการสร้าง หรือ TTL ข้อจำกัด: maxEntries ต่อ namespace, แถวสด 1,000 แถวต่อ Plugin, ค่า JSON ต่ำกว่า 64KB และการหมดอายุ TTL แบบไม่บังคับ
api.runtime.tools
factory ของเครื่องมือหน่วยความจำและ CLI
const getTool = api.runtime.tools.createMemoryGetTool(/* ... */);const searchTool = api.runtime.tools.createMemorySearchTool(/* ... */);api.runtime.tools.registerMemoryCli(/* ... */);api.runtime.channel
helper ของ runtime เฉพาะ channel (พร้อมใช้งานเมื่อโหลด channel Plugin แล้ว)
api.runtime.channel.mentions คือพื้นผิวนโยบายการ mention ขาเข้าที่ใช้ร่วมกันสำหรับ channel Plugin ที่บันเดิลมาและใช้การฉีด 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, },});helper สำหรับ mention ที่พร้อมใช้งาน:
buildMentionRegexesmatchesMentionPatternsmatchesMentionWithExplicitimplicitMentionKindWhenresolveInboundMentionDecision
api.runtime.channel.mentions ตั้งใจไม่เปิดเผย helper ความเข้ากันได้ resolveMentionGating* รุ่นเก่า ควรใช้เส้นทาง { facts, policy } ที่ normalize แล้ว
การจัดเก็บข้อมูลอ้างอิง runtime
ใช้ createPluginRuntimeStore เพื่อจัดเก็บข้อมูลอ้างอิง runtime สำหรับใช้นอก callback 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}ฟิลด์ api ระดับบนสุดอื่น ๆ
นอกเหนือจาก api.runtime แล้ว อ็อบเจกต์ API ยังมี:
api.idstringid ของ Plugin
api.namestringชื่อที่แสดงของ Plugin
api.configOpenClawConfigสแนปช็อต config ปัจจุบัน (สแนปช็อต runtime ในหน่วยความจำที่ใช้งานอยู่เมื่อมี)
OPENCLAW_DOCS_MARKER:paramOpen:IHBhdGg9ImFwaS5wbHVnaW5Db25maWciIHR5cGU9IlJlY29yZDxzdHJpbmcsIHVua25vd24
">
config เฉพาะ Plugin จาก plugins.entries.<id>.config
api.loggerPluginLoggerlogger แบบกำหนดขอบเขต (debug, info, warn, error)
api.registrationModePluginRegistrationModeโหมดการโหลดปัจจุบัน; "setup-runtime" คือช่วงเริ่มต้น/ตั้งค่าขนาดเบาก่อนเข้า entry แบบเต็ม
api.resolvePath(input)"(string)ที่เกี่ยวข้อง
- ภายในของ Plugin — โมเดล capability และ registry
- จุดเข้าใช้งาน SDK — ตัวเลือก
definePluginEntry - ภาพรวม SDK — ข้อมูลอ้างอิง subpath