Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

หน้านี้คือการออกแบบอ้างอิง API แบบละเอียดสำหรับ OpenClaw App SDK สาธารณะ โดยจงใจแยกออกจาก Plugin SDK
@openclaw/sdk คือแพ็กเกจแอป/ไคลเอนต์ภายนอกสำหรับสื่อสารกับ Gateway ส่วน openclaw/plugin-sdk/* คือสัญญาการเขียน Plugin แบบ in-process ห้ามนำเข้า subpath ของ Plugin SDK จากแอปที่ต้องการเพียงแค่รันเอเจนต์
SDK ของแอปสาธารณะควรสร้างขึ้นเป็นสองชั้น:
  1. ไคลเอนต์ Gateway ระดับต่ำที่สร้างจากโค้ด
  2. แรปเปอร์ระดับสูงที่ใช้งานสะดวกพร้อมออบเจ็กต์ OpenClaw, Agent, Session, Run, Task, Artifact, Approval และ Environment

การออกแบบเนมสเปซ

เนมสเปซระดับต่ำควรตามทรัพยากรของ Gateway อย่างใกล้ชิด:
oc.agents.list();
oc.agents.get("main");
oc.agents.create(...);
oc.agents.update(...);

oc.sessions.list();
oc.sessions.create(...);
oc.sessions.resolve(...);
oc.sessions.send(...);
oc.sessions.messages(...);
oc.sessions.fork(...);
oc.sessions.compact(...);
oc.sessions.abort(...);

oc.runs.create(...);
oc.runs.get(runId);
oc.runs.events(runId, { after });
oc.runs.wait(runId);
oc.runs.cancel(runId);

oc.tasks.list({ status: "running" });
oc.tasks.get(taskId);
oc.tasks.cancel(taskId, { reason });
oc.tasks.events(taskId, { after }); // future API

oc.models.list();
oc.models.status(); // Gateway models.authStatus

oc.tools.list();
oc.tools.invoke("tool-name", { sessionKey, idempotencyKey });

oc.artifacts.list({ runId });
oc.artifacts.get(artifactId, { runId });
oc.artifacts.download(artifactId, { runId });

oc.approvals.list();
oc.approvals.respond(approvalId, ...);

oc.environments.list();
oc.environments.create(...); // future API: current SDK throws unsupported
oc.environments.status(environmentId);
oc.environments.delete(environmentId); // future API: current SDK throws unsupported
แรปเปอร์ระดับสูงควรคืนค่าเป็นออบเจ็กต์ที่ทำให้โฟลว์ทั่วไปใช้งานได้ราบรื่น:
const run = await agent.run(inputOrParams);
await run.cancel();
await run.wait();

for await (const event of run.events()) {
  // normalized event stream
}

const artifacts = await run.artifacts.list();
const session = await run.session();

สัญญาเหตุการณ์

SDK สาธารณะควรเปิดเผยเหตุการณ์ที่มีเวอร์ชัน เล่นซ้ำได้ และทำให้เป็นมาตรฐานแล้ว
type OpenClawEvent = {
  version: 1;
  id: string;
  ts: number;
  type: OpenClawEventType;
  runId?: string;
  sessionId?: string;
  sessionKey?: string;
  taskId?: string;
  agentId?: string;
  data: unknown;
  raw?: unknown;
};
id คือเคอร์เซอร์สำหรับเล่นซ้ำ ผู้บริโภคควรสามารถเชื่อมต่อใหม่ด้วย events({ after: id }) และรับเหตุการณ์ที่พลาดไปเมื่อการเก็บรักษาอนุญาต กลุ่มเหตุการณ์มาตรฐานที่แนะนำ:
เหตุการณ์ความหมาย
run.createdรับ Run แล้ว
run.queuedRun กำลังรอเลนเซสชัน รันไทม์ หรือสภาพแวดล้อม
run.startedรันไทม์เริ่มดำเนินการแล้ว
run.completedRun เสร็จสิ้นสำเร็จ
run.failedRun จบลงด้วยข้อผิดพลาด
run.cancelledRun ถูกยกเลิก
run.timed_outRun เกินเวลาที่กำหนด
assistant.deltaเดลตาข้อความของผู้ช่วย
assistant.messageข้อความผู้ช่วยที่สมบูรณ์หรือข้อความแทนที่
thinking.deltaเดลตาการให้เหตุผลหรือแผน เมื่อ policy อนุญาตให้เปิดเผย
tool.call.startedเริ่มเรียกใช้เครื่องมือแล้ว
tool.call.deltaการเรียกใช้เครื่องมือสตรีมความคืบหน้าหรือเอาต์พุตบางส่วน
tool.call.completedการเรียกใช้เครื่องมือคืนค่าสำเร็จ
tool.call.failedการเรียกใช้เครื่องมือล้มเหลว
approval.requestedRun หรือเครื่องมือต้องการการอนุมัติ
approval.resolvedการอนุมัติได้รับอนุญาต ถูกปฏิเสธ หมดอายุ หรือถูกยกเลิก
question.requestedรันไทม์ขอข้อมูลจากผู้ใช้หรือแอปโฮสต์
question.answeredแอปโฮสต์ให้คำตอบแล้ว
artifact.createdมี artifact ใหม่พร้อมใช้งาน
artifact.updatedartifact ที่มีอยู่เปลี่ยนแปลง
session.createdสร้างเซสชันแล้ว
session.updatedเมตาดาต้าเซสชันเปลี่ยนแปลง
session.compactedเกิด Compaction ของเซสชัน
task.updatedสถานะงานเบื้องหลังเปลี่ยนแปลง
git.branchรันไทม์ตรวจพบหรือเปลี่ยนสถานะ branch
git.diffรันไทม์สร้างหรือเปลี่ยน diff
git.prรันไทม์เปิด อัปเดต หรือลิงก์ pull request
เพย์โหลดดั้งเดิมของรันไทม์ควรพร้อมใช้งานผ่าน raw แต่แอปไม่ควร ต้องแยกวิเคราะห์ raw สำหรับ UI ปกติ

สัญญาผลลัพธ์

Run.wait() ควรคืน envelope ผลลัพธ์ที่เสถียร:
type RunResult = {
  runId: string;
  status: "accepted" | "completed" | "failed" | "cancelled" | "timed_out";
  sessionId?: string;
  sessionKey?: string;
  taskId?: string;
  startedAt?: string | number;
  endedAt?: string | number;
  output?: {
    text?: string;
    messages?: SDKMessage[];
  };
  usage?: {
    inputTokens?: number;
    outputTokens?: number;
    totalTokens?: number;
    costUsd?: number;
  };
  artifacts?: ArtifactSummary[];
  error?: SDKError;
};
ผลลัพธ์ควรเรียบง่ายและเสถียร ค่าประทับเวลาจะคงรูปแบบของ Gateway ดังนั้น Run ปัจจุบันที่อิง lifecycle มักรายงานเป็นตัวเลข epoch millisecond ขณะที่ adapter อาจยังแสดงสตริง ISO ได้ UI ที่มีรายละเอียด ร่องรอยเครื่องมือ และ รายละเอียดดั้งเดิมของรันไทม์ควรอยู่ในเหตุการณ์และ artifact accepted คือผลลัพธ์การรอที่ยังไม่สิ้นสุด: หมายความว่าเส้นตายการรอของ Gateway หมดอายุก่อนที่ Run จะสร้างจุดสิ้นสุด/error ของ lifecycle ห้ามถือว่าเป็น timed_out; timed_out สงวนไว้สำหรับ Run ที่เกิน timeout ของรันไทม์ตัวเอง

การอนุมัติและคำถาม

การอนุมัติต้องเป็นแนวคิดหลัก เพราะเอเจนต์เขียนโค้ดมักข้ามขอบเขตความปลอดภัยอยู่เสมอ
run.onApproval(async (request) => {
  if (request.kind === "tool" && request.toolName === "exec") {
    return request.approveOnce({ reason: "CI command allowed by policy" });
  }

  return request.askUser();
});
เหตุการณ์การอนุมัติควรมี:
  • id การอนุมัติ
  • id ของ Run และ id ของเซสชัน
  • ชนิดคำขอ
  • สรุปการกระทำที่ขอ
  • ชื่อเครื่องมือหรือการกระทำของสภาพแวดล้อม
  • ระดับความเสี่ยง
  • การตัดสินใจที่ใช้ได้
  • เวลาหมดอายุ
  • ระบุว่าการตัดสินใจนั้นนำกลับมาใช้ซ้ำได้หรือไม่
คำถามแยกจากการอนุมัติ คำถามคือการขอข้อมูลจากผู้ใช้หรือแอปโฮสต์ ส่วนการอนุมัติคือการขออนุญาตดำเนินการบางอย่าง

โมเดล ToolSpace

แอปต้องเข้าใจพื้นผิวเครื่องมือโดยไม่ต้องนำเข้าภายในของ Plugin
const tools = await run.toolSpace();

for (const tool of tools.list()) {
  console.log(tool.name, tool.source, tool.requiresApproval);
}
SDK ควรเปิดเผย:
  • เมตาดาต้าเครื่องมือที่ทำให้เป็นมาตรฐานแล้ว
  • แหล่งที่มา: OpenClaw, MCP, Plugin, channel, runtime หรือ app
  • สรุป schema
  • policy การอนุมัติ
  • ความเข้ากันได้ของรันไทม์
  • ระบุว่าเครื่องมือถูกซ่อน เป็น readonly เขียนได้ หรือโฮสต์ได้หรือไม่
การเรียกใช้เครื่องมือผ่าน SDK ควรชัดเจนและมีขอบเขต แอปส่วนใหญ่ควร รันเอเจนต์ ไม่ใช่เรียกใช้เครื่องมือใดก็ได้โดยตรง

โมเดล Artifact

Artifact ควรครอบคลุมมากกว่าไฟล์
type ArtifactSummary = {
  id: string;
  runId?: string;
  sessionId?: string;
  type:
    | "file"
    | "patch"
    | "diff"
    | "log"
    | "media"
    | "screenshot"
    | "trajectory"
    | "pull_request"
    | "workspace";
  title?: string;
  mimeType?: string;
  sizeBytes?: number;
  createdAt: string;
  expiresAt?: string;
};
ตัวอย่างทั่วไป:
  • การแก้ไขไฟล์และไฟล์ที่สร้างขึ้น
  • ชุด patch
  • diff ของ VCS
  • screenshot และเอาต์พุตสื่อ
  • log และชุด trace
  • ลิงก์ pull request
  • trajectory ของรันไทม์
  • snapshot workspace ของสภาพแวดล้อมที่จัดการ
การเข้าถึง artifact ควรรองรับการปกปิดข้อมูล การเก็บรักษา และ URL ดาวน์โหลด โดยไม่ สมมติว่า artifact ทุกชิ้นเป็นไฟล์โลคัลปกติ

โมเดลความปลอดภัย

SDK ของแอปต้องชัดเจนเรื่องอำนาจ scope ของ token ที่แนะนำ:
Scopeอนุญาตให้
agent.readแสดงรายการและตรวจสอบเอเจนต์
agent.runเริ่ม Run
session.readอ่านเมตาดาต้าและข้อความของเซสชัน
session.writeสร้าง ส่งไปยัง fork compact และ abort เซสชัน
task.readอ่านสถานะงานเบื้องหลัง
task.writeยกเลิกหรือแก้ไข policy การแจ้งเตือนของงาน
approval.respondอนุมัติหรือปฏิเสธคำขอ
tools.invokeเรียกใช้เครื่องมือที่เปิดเผยโดยตรง
artifacts.readแสดงรายการและดาวน์โหลด artifact
environment.writeสร้างหรือทำลายสภาพแวดล้อมที่จัดการ
adminการดำเนินการด้านผู้ดูแลระบบ
ค่าเริ่มต้น:
  • ไม่ส่งต่อ secret โดยค่าเริ่มต้น
  • ไม่มีการส่งผ่านตัวแปรสภาพแวดล้อมแบบไม่จำกัด
  • ใช้การอ้างอิง secret แทนค่า secret
  • policy ของ sandbox และเครือข่ายที่ชัดเจน
  • การเก็บรักษาสภาพแวดล้อมระยะไกลที่ชัดเจน
  • ต้องมีการอนุมัติสำหรับการดำเนินการบนโฮสต์ เว้นแต่ policy จะพิสูจน์เป็นอย่างอื่น
  • เหตุการณ์รันไทม์ดิบถูกปกปิดข้อมูลก่อนออกจาก Gateway เว้นแต่ผู้เรียกจะมี scope การวินิจฉัยที่เข้มกว่า

ผู้ให้บริการสภาพแวดล้อมที่จัดการ

เอเจนต์ที่จัดการควรถูกนำไปใช้เป็นผู้ให้บริการสภาพแวดล้อม
type EnvironmentProvider = {
  id: string;
  capabilities: {
    checkout?: boolean;
    sandbox?: boolean;
    networkPolicy?: boolean;
    secrets?: boolean;
    artifacts?: boolean;
    logs?: boolean;
    pullRequests?: boolean;
    longRunning?: boolean;
  };
};
การใช้งานครั้งแรกไม่จำเป็นต้องเป็น SaaS ที่โฮสต์ไว้ อาจกำหนดเป้าหมายไปที่ โฮสต์ Node ที่มีอยู่, workspace ชั่วคราว, runner แบบ CI หรือสภาพแวดล้อม แบบ Testbox ก็ได้ สัญญาที่สำคัญคือ:
  1. เตรียม workspace
  2. ผูกสภาพแวดล้อมและ secret ที่ปลอดภัย
  3. เริ่ม Run
  4. สตรีมเหตุการณ์
  5. รวบรวม artifact
  6. ล้างข้อมูลหรือเก็บรักษาตาม policy
เมื่อสิ่งนี้เสถียรแล้ว บริการคลาวด์ที่โฮสต์ไว้ก็สามารถนำสัญญาผู้ให้บริการเดียวกันไปใช้ได้

โครงสร้างแพ็กเกจ

แพ็กเกจที่แนะนำ:
แพ็กเกจวัตถุประสงค์
@openclaw/sdkSDK ระดับสูงสาธารณะและไคลเอนต์ Gateway ระดับต่ำที่สร้างจากโค้ด
@openclaw/sdk-reactReact hooks ทางเลือกสำหรับแดชบอร์ดและผู้สร้างแอป
@openclaw/sdk-testingตัวช่วยทดสอบและเซิร์ฟเวอร์ Gateway ปลอมสำหรับการผสานรวมแอป
รีโปมี openclaw/plugin-sdk/* สำหรับ Plugin อยู่แล้ว ให้แยกเนมสเปซนั้นไว้ เพื่อหลีกเลี่ยงความสับสนระหว่างผู้เขียน Plugin กับนักพัฒนาแอป

กลยุทธ์ไคลเอนต์ที่สร้างจากโค้ด

ไคลเอนต์ระดับต่ำควรสร้างจาก schema โปรโตคอล Gateway ที่มีเวอร์ชัน แล้วห่อด้วยคลาสที่เขียนเองเพื่อให้ใช้งานสะดวก การแบ่งชั้น:
  1. แหล่งความจริงของสคีมา Gateway
  2. ไคลเอนต์ TypeScript ระดับต่ำที่สร้างขึ้น
  3. ตัวตรวจสอบความถูกต้องขณะรันไทม์สำหรับอินพุตภายนอกและเพย์โหลดเหตุการณ์
  4. ตัวห่อหุ้มระดับสูง OpenClaw, Agent, Session, Run, Task และ Artifact
  5. ตัวอย่าง cookbook และการทดสอบการเชื่อมต่อ
ประโยชน์:
  • เห็นการคลาดเคลื่อนของโปรโตคอลได้ชัดเจน
  • การทดสอบสามารถเปรียบเทียบเมธอดที่สร้างขึ้นกับเอ็กซ์พอร์ตของ Gateway ได้
  • App SDK ยังคงเป็นอิสระจากส่วนภายในของ Plugin SDK
  • ผู้ใช้งานระดับต่ำยังคงเข้าถึงโปรโตคอลได้เต็มรูปแบบ
  • ผู้ใช้งานระดับสูงได้รับ API ของผลิตภัณฑ์ขนาดเล็ก

ที่เกี่ยวข้อง