From cb8b09b2f9e48106c03c8643a1297528ab8fed3e Mon Sep 17 00:00:00 2001 From: "openclaw-docs-sync[bot]" Date: Wed, 29 Apr 2026 23:54:15 +0000 Subject: [PATCH] chore(sync): mirror docs from openclaw/openclaw@b7c3e19ed65ebe01938de2cbba26f16da000ea3e --- .openclaw-sync/source.json | 4 +- docs/concepts/openclaw-sdk.md | 367 +++++++++++++++++++++ docs/docs.json | 32 ++ docs/fa/tools/skills.md | 1 + docs/gateway/protocol.md | 2 +- docs/nl/tools/skills.md | 1 + docs/reference/openclaw-sdk-api-design.md | 383 ++++++++++++++++++++++ docs/vi/tools/skills.md | 1 + 8 files changed, 788 insertions(+), 3 deletions(-) create mode 100644 docs/concepts/openclaw-sdk.md create mode 100644 docs/reference/openclaw-sdk-api-design.md diff --git a/.openclaw-sync/source.json b/.openclaw-sync/source.json index f8a94895f..9a17a4c2d 100644 --- a/.openclaw-sync/source.json +++ b/.openclaw-sync/source.json @@ -1,5 +1,5 @@ { "repository": "openclaw/openclaw", - "sha": "845dd2a7d5bf90ecff3610d696d2ca2579e98ab7", - "syncedAt": "2026-04-29T23:16:47.543Z" + "sha": "b7c3e19ed65ebe01938de2cbba26f16da000ea3e", + "syncedAt": "2026-04-29T23:52:37.868Z" } diff --git a/docs/concepts/openclaw-sdk.md b/docs/concepts/openclaw-sdk.md new file mode 100644 index 000000000..165998780 --- /dev/null +++ b/docs/concepts/openclaw-sdk.md @@ -0,0 +1,367 @@ +--- +summary: "Design proposal for a public OpenClaw app SDK for agent runs, sessions, tasks, artifacts, and managed environments" +title: "OpenClaw SDK design" +read_when: + - You are designing or implementing a public OpenClaw app SDK + - You are comparing OpenClaw agent APIs with Cursor, Claude Agent SDK, OpenAI Agents, Google ADK, OpenCode, Codex, or ACP + - You need to decide whether a feature belongs in the public app SDK, plugin SDK, Gateway protocol, ACP backend, or managed environment layer +--- + +This page is a design proposal for a future public **OpenClaw app SDK**. It is +separate from the existing [plugin SDK](/plugins/sdk-overview). + +The plugin SDK is for code that runs inside OpenClaw and extends providers, +channels, tools, hooks, and trusted runtimes. The app SDK should be for +external applications, scripts, dashboards, CI jobs, IDE extensions, and +automation systems that want to run and observe OpenClaw agents through a stable +public API. + +## Status + +Draft architecture. + +This document captures the design direction from a comparative review of these +agent SDK and runtime surfaces: + +| Project | Useful lesson | +| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cursor SDK cookbook | Best high-level product API: `Agent`, `Run`, local and cloud runtimes, streaming, cancellation, model discovery, repositories, artifacts, and cloud pull request flows. | +| Claude Agent SDK | Strong bidirectional session client, interrupt and steer support, permission modes, hooks, custom tools, session stores, and resumable transcripts. | +| OpenAI Agents SDK | Strong workflow concepts: handoffs, guardrails, human approvals, tracing, run state, streaming result objects, and resume after interruptions. | +| Google ADK | Strong internal architecture: runner, session service, memory service, artifact service, credential service, plugins, event actions, and long running tool confirmations. | +| OpenCode | Strong client/server shape: generated API client, REST plus SSE, sessions, workspaces, worktrees, permissions, questions, files, VCS, PTY, tools, agents, skills, and MCP. | +| Codex | Strong local runtime boundary: approvals, sandboxing, network policy, local and remote exec servers, structured protocol events, and thread aware app-server sessions. | +| ACP and acpx | Strong interoperability layer for external coding harnesses with named sessions, prompt queues, cooperative cancellation, and runtime adapters. | + +The recommendation is to build a Cursor-simple public facade on top of an +OpenCode-style generated Gateway client, while keeping Claude, OpenAI Agents, +ADK, Codex, and ACP concepts as internal design references where they fit. + +## Goals + +- Give app developers a tiny high-level API for running OpenClaw agents. +- Keep local-first OpenClaw as the default runtime. +- Make cloud or managed environments an additive environment provider, not a + different agent API. +- Preserve existing OpenClaw boundaries: Gateway owns public protocol, plugin + SDK owns in-process extensions, ACP owns external harness interop. +- Support `stream`, `wait`, `cancel`, `resume`, `fork`, artifacts, approvals, + and background tasks as first-class operations. +- Expose stable normalized events while preserving runtime-native raw events for + advanced consumers. +- Make SDK permissions, secret forwarding, approvals, sandboxing, and remote + environments explicit. +- Keep the public contract small enough to document, test, version, and + generate. + +## Non goals + +- Do not expose `openclaw/plugin-sdk/*` as the app SDK. +- Do not make ACP the only runtime model. +- Do not require a cloud service before the SDK is useful. +- Do not clone Cursor, Claude, OpenAI, ADK, OpenCode, Codex, or ACP APIs + exactly. +- Do not expose unbounded `any` event payloads as the only public contract. +- Do not promise sandbox or network isolation for an external harness unless + the selected environment can actually enforce it. +- Do not make plugin authors depend on app SDK objects inside plugin runtime + code. + +## Current OpenClaw fit + +OpenClaw already has most of the substrate: + +| Existing surface | What it contributes | +| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| [Agent loop](/concepts/agent-loop) | `agent` and `agent.wait` run lifecycle, streaming, timeout, and session serialization. | +| [Agent runtimes](/concepts/agent-runtimes) | Provider, model, runtime, and channel separation. | +| [ACP agents](/tools/acp-agents) | External harness sessions for Claude Code, Cursor, Gemini CLI, OpenCode, explicit Codex ACP, and similar tools. | +| [Background tasks](/automation/tasks) | Detached activity ledger for ACP, subagents, cron, CLI operations, and async media jobs. | +| [Sub-agents](/tools/subagents) | Isolated background agent runs, optional forked context, delivery back to requester sessions. | +| [Agent harness plugins](/plugins/sdk-agent-harness) | Trusted native runtime registration for embedded harnesses such as Codex. | +| Gateway protocol schemas | Current typed method and event definitions for agent params, sessions, subscriptions, aborts, compaction, and checkpoints. | + +The gap is not agent execution. The gap is a stable, friendly public facade over +these pieces. + +## Core model + +The app SDK should use a small set of durable nouns. + +| Noun | Meaning | +| ------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `OpenClaw` | Client entry point. Owns Gateway discovery, auth, low-level client access, and namespace factories. | +| `Agent` | Configured actor. Carries agent id, default model, default runtime, default tool policy, and app-facing helpers. | +| `Session` | Durable transcript, routing, workspace, context, and runtime binding. | +| `Run` | One submitted turn or task. Streams events, waits for result, cancels, and exposes artifacts. | +| `Task` | Detached or background activity ledger entry. Covers subagents, ACP spawns, cron jobs, CLI runs, and async jobs. | +| `Artifact` | Files, patches, diffs, media, logs, trajectories, pull requests, screenshots, and generated bundles. | +| `Environment` | Where the run executes: local Gateway, local workspace, node host, ACP harness, managed runner, or future cloud workspace. | +| `ToolSpace` | The effective tool surface: OpenClaw tools, MCP servers, channel tools, app tools, approval rules, and tool metadata. | +| `Approval` | Human or policy decision requested by a run, tool, environment, or harness. | + +These nouns map cleanly to existing OpenClaw concepts but avoid leaking +implementation-specific names such as PI runner internals, plugin harness +registration, or ACP adapter details. + +## Product shape + +The high-level SDK should feel like this: + +```typescript +import { OpenClaw } from "@openclaw/sdk"; + +const oc = new OpenClaw({ gateway: "auto" }); +const agent = await oc.agents.get("main"); + +const run = await agent.run({ + input: "Review this pull request and suggest the smallest safe fix.", + model: "openai/gpt-5.5", +}); + +for await (const event of run.events()) { + if (event.type === "assistant.delta") { + process.stdout.write(event.text); + } +} + +const result = await run.wait(); +console.log(result.status); +``` + +The same app should be able to use a durable session: + +```typescript +const session = await oc.sessions.create({ + agentId: "main", + label: "release-review", +}); + +const run = await session.send("Prepare release notes from the current diff."); +await run.wait(); +``` + +Current implementation note: `@openclaw/sdk` starts with the Gateway-backed +surface that exists today. Provider-qualified model refs such as +`openai/gpt-5.5` are split into Gateway `provider` and `model` overrides. +Per-run `workspace`, `runtime`, `environment`, and `approvals` selections are +still design targets; the client throws when callers set them so requests do not +silently execute with defaults. Task, artifact, environment, and generic tool +invocation helpers are also scaffolded as future API shape and throw explicit +unsupported errors until Gateway RPCs exist for them. + +And the same API should be able to use an external ACP harness: + +```typescript +const run = await oc.runs.create({ + input: "Deep review this repository and return only high-risk findings.", + workspace: { cwd: process.cwd() }, + runtime: { type: "acp", harness: "claude" }, + mode: "task", +}); +``` + +Managed environments should not change the top-level API: + +```typescript +const run = await agent.run({ + input: "Run the full changed gate and summarize failures.", + workspace: { repo: "openclaw/openclaw", ref: "main" }, + runtime: { + type: "managed", + provider: "testbox", + timeoutMinutes: 90, + }, +}); +``` + +## Runtime selection + +The app SDK should expose runtime selection as a normalized union: + +```typescript +type RuntimeSelection = + | "auto" + | { type: "embedded"; id: "pi" | "codex" | string } + | { type: "cli"; id: "claude-cli" | string } + | { type: "acp"; harness: "claude" | "cursor" | "gemini" | "opencode" | string } + | { type: "managed"; provider: "local" | "node" | "testbox" | "cloud" | string }; +``` + +Rules: + +- `auto` follows OpenClaw runtime selection rules. +- `embedded` targets trusted in-process harnesses registered through the plugin + SDK, such as `pi` or `codex`. +- `cli` targets OpenClaw-owned CLI backend execution where available. +- `acp` targets external harnesses through ACP/acpx. +- `managed` targets an environment provider and may still run an embedded, + CLI, or ACP runtime inside that environment. + +The runtime selection object should be descriptive. It should not be the place +where secret handling, sandbox policy, or workspace provisioning hides. + +## Environment model + +The environment is the execution substrate. It should be explicit because local +CLI runs, external harnesses, node hosts, and cloud workspaces have different +safety and lifecycle properties. + +```typescript +type EnvironmentSelection = + | { type: "local"; cwd?: string } + | { type: "gateway"; url?: string; cwd?: string } + | { type: "node"; nodeId: string; cwd?: string } + | { type: "managed"; provider: string; repo?: string; ref?: string } + | { type: "ephemeral"; provider: string; repo?: string; ref?: string }; +``` + +The environment owns: + +- checkout or workspace preparation +- process and file access +- sandbox and network enforcement +- environment variables and secret references +- logs, traces, and artifacts +- cleanup and retention +- runtime availability + +This separation makes managed agents a natural extension of the SDK. A managed +agent is a normal run in a managed environment, not a special product fork. + +The detailed namespace, event, result, approval, artifact, security, package, +and environment provider contracts live in +[OpenClaw SDK API design](/reference/openclaw-sdk-api-design). + +## Cookbook plan + +The SDK should ship with a cookbook, not just reference docs. + +Recommended examples: + +| Example | Shows | +| ---------------------------- | -------------------------------------------------------------------------------------------- | +| Quickstart | Create client, run an agent, stream output, wait for result. | +| Coding agent CLI | Local workspace, model picker, cancellation, approvals, JSON output. | +| Agent dashboard | Sessions, runs, background tasks, artifacts, event replay, status filters. | +| App builder | Agent edits a workspace while a preview server runs beside it. | +| Pull request reviewer | Run against a repository ref, collect diff comments and artifacts. | +| Approval console | Subscribe to approvals and answer them from a UI. | +| ACP harness runner | Run Claude Code, Cursor, Gemini CLI, or OpenCode through ACP using the same `Run` API. | +| Managed environment provider | Minimal provider that prepares a workspace, streams events, saves artifacts, and cleans up. | +| Slack or Discord bridge | External app receives events and posts progress summaries without becoming a channel plugin. | +| Multi-agent research | Spawn parallel runs, collect artifacts, and synthesize a final report. | + +Cookbook examples should use the high-level API first. Low-level generated +client examples belong in an advanced section. + +## Phased implementation + +### Phase 0: RFC and vocabulary + +- Agree on public nouns and names. +- Decide package names. +- Define the first event taxonomy. +- Mark the current plugin SDK as intentionally separate in docs. + +### Phase 1: Low-level generated client + +- Generate a TypeScript client from Gateway protocol schemas. +- Cover `agent`, `agent.wait`, sessions, subscriptions, aborts, and tasks first. +- Add smoke tests that generated methods match Gateway method names and schema + shapes. +- Publish as experimental or internal package. + +### Phase 2: High-level run API + +- Add `OpenClaw`, `Agent`, `Session`, and `Run`. +- Support `run.events()`, `run.wait()`, and `run.cancel()`. +- Support local Gateway discovery and explicit Gateway URLs. +- Support durable sessions and session send. + +### Phase 3: Normalized event projection + +- Add Gateway-side normalized event projection beside existing raw events. +- Preserve raw runtime events where policy allows. +- Add replay cursors and reconnect behavior. +- Map PI, Codex, ACP, and task events into the stable taxonomy. + +### Phase 4: Artifacts and approvals + +- Add artifact listing and download. +- Add approval subscription and response helpers. +- Add question subscription and response helpers. +- Add cookbook approval console. + +### Phase 5: Environment providers + +- Introduce local, node, and managed environment provider contracts. +- Start with an environment that already exists operationally. +- Add workspace preparation, logs, artifacts, timeout, cleanup, and retention. + +### Phase 6: Cloud style workflows + +- Add repository and branch oriented runs. +- Add pull request artifacts. +- Add run boards grouped by repo, branch, status, and assignee. +- Add long-running managed sessions and retention policy. + +## Design choices to copy + +Copy these ideas: + +- From Cursor: `Agent` plus `Run`, local and cloud symmetry, model discovery, + artifacts, and cookbook-driven onboarding. +- From Claude Agent SDK: bidirectional clients, interrupt, permissions, hooks, + custom tools, session stores, and resume semantics. +- From OpenAI Agents: handoffs, guardrails, human approval resume, tracing, and + structured streamed result objects. +- From Google ADK: services behind runner, event actions, memory, artifacts, + credential services, and plugin interception around run lifecycle. +- From OpenCode: generated protocol client, REST plus SSE, sessions, + workspaces, questions, permissions, files, VCS, PTY, MCP, agents, and skills. +- From Codex: explicit sandbox, approval, network, local and remote exec, and + app-server thread boundaries. +- From ACP and acpx: adapter based external harness interoperability and named + prompt queues. + +## Design choices to avoid + +Avoid these traps: + +- A public SDK that is just a thin dump of Gateway internals. +- A public SDK that imports plugin SDK subpaths. +- A public SDK where events are only `stream` plus `data`. +- A cloud-first API that makes local OpenClaw feel like a legacy mode. +- Runtime selection hidden in model id prefixes. +- Secret forwarding hidden in environment maps. +- ACP specific options at the top level of every run. +- Sandbox flags that cannot be enforced by the chosen runtime. +- One SDK object that tries to be provider plugin, channel plugin, app client, + and managed runner at once. + +## Open questions + +- Should the initial package live in this repo or a separate SDK repo? +- Should the generated low-level client be published publicly before the + high-level wrapper stabilizes? +- What is the first supported app auth mechanism: local token, admin token, + OAuth device flow, or signed app registration? +- How much session message history should the SDK expose by default? +- Should managed environments be configured only in Gateway config, or can SDK + callers request them directly with scoped tokens? +- What retention rules apply to artifacts generated by local runs? +- Which event payloads require redaction before app delivery? +- Should `Run` cover normal chat turns and detached tasks, or should detached + background work always return a `Task` wrapper with a nested `Run`? + +## Related docs + +- [Agent loop](/concepts/agent-loop) +- [Agent runtimes](/concepts/agent-runtimes) +- [Session](/concepts/session) +- [Sub-agents](/tools/subagents) +- [Background tasks](/automation/tasks) +- [ACP agents](/tools/acp-agents) +- [Agent harness plugins](/plugins/sdk-agent-harness) +- [Plugin SDK overview](/plugins/sdk-overview) diff --git a/docs/docs.json b/docs/docs.json index e3b660c13..3edd4ad3a 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -1127,6 +1127,7 @@ "concepts/agent", "concepts/agent-loop", "concepts/agent-runtimes", + "concepts/openclaw-sdk", "concepts/system-prompt", "concepts/context", "concepts/context-engine", @@ -1699,6 +1700,7 @@ "group": "RPC and API", "pages": [ "reference/rpc", + "reference/openclaw-sdk-api-design", "reference/device-models" ] }, @@ -2598,6 +2600,7 @@ "zh-TW/concepts/agent", "zh-TW/concepts/agent-loop", "zh-TW/concepts/agent-runtimes", + "zh-TW/concepts/openclaw-sdk", "zh-TW/concepts/system-prompt", "zh-TW/concepts/context", "zh-TW/concepts/context-engine", @@ -3170,6 +3173,7 @@ "group": "RPC and API", "pages": [ "zh-TW/reference/rpc", + "zh-TW/reference/openclaw-sdk-api-design", "zh-TW/reference/device-models" ] }, @@ -3454,6 +3458,7 @@ "ja-JP/concepts/agent", "ja-JP/concepts/agent-loop", "ja-JP/concepts/agent-runtimes", + "ja-JP/concepts/openclaw-sdk", "ja-JP/concepts/system-prompt", "ja-JP/concepts/context", "ja-JP/concepts/context-engine", @@ -4026,6 +4031,7 @@ "group": "RPC and API", "pages": [ "ja-JP/reference/rpc", + "ja-JP/reference/openclaw-sdk-api-design", "ja-JP/reference/device-models" ] }, @@ -4310,6 +4316,7 @@ "es/concepts/agent", "es/concepts/agent-loop", "es/concepts/agent-runtimes", + "es/concepts/openclaw-sdk", "es/concepts/system-prompt", "es/concepts/context", "es/concepts/context-engine", @@ -4882,6 +4889,7 @@ "group": "RPC and API", "pages": [ "es/reference/rpc", + "es/reference/openclaw-sdk-api-design", "es/reference/device-models" ] }, @@ -5166,6 +5174,7 @@ "pt-BR/concepts/agent", "pt-BR/concepts/agent-loop", "pt-BR/concepts/agent-runtimes", + "pt-BR/concepts/openclaw-sdk", "pt-BR/concepts/system-prompt", "pt-BR/concepts/context", "pt-BR/concepts/context-engine", @@ -5738,6 +5747,7 @@ "group": "RPC and API", "pages": [ "pt-BR/reference/rpc", + "pt-BR/reference/openclaw-sdk-api-design", "pt-BR/reference/device-models" ] }, @@ -6022,6 +6032,7 @@ "ko/concepts/agent", "ko/concepts/agent-loop", "ko/concepts/agent-runtimes", + "ko/concepts/openclaw-sdk", "ko/concepts/system-prompt", "ko/concepts/context", "ko/concepts/context-engine", @@ -6594,6 +6605,7 @@ "group": "RPC and API", "pages": [ "ko/reference/rpc", + "ko/reference/openclaw-sdk-api-design", "ko/reference/device-models" ] }, @@ -6878,6 +6890,7 @@ "de/concepts/agent", "de/concepts/agent-loop", "de/concepts/agent-runtimes", + "de/concepts/openclaw-sdk", "de/concepts/system-prompt", "de/concepts/context", "de/concepts/context-engine", @@ -7450,6 +7463,7 @@ "group": "RPC and API", "pages": [ "de/reference/rpc", + "de/reference/openclaw-sdk-api-design", "de/reference/device-models" ] }, @@ -7734,6 +7748,7 @@ "fr/concepts/agent", "fr/concepts/agent-loop", "fr/concepts/agent-runtimes", + "fr/concepts/openclaw-sdk", "fr/concepts/system-prompt", "fr/concepts/context", "fr/concepts/context-engine", @@ -8306,6 +8321,7 @@ "group": "RPC and API", "pages": [ "fr/reference/rpc", + "fr/reference/openclaw-sdk-api-design", "fr/reference/device-models" ] }, @@ -8590,6 +8606,7 @@ "ar/concepts/agent", "ar/concepts/agent-loop", "ar/concepts/agent-runtimes", + "ar/concepts/openclaw-sdk", "ar/concepts/system-prompt", "ar/concepts/context", "ar/concepts/context-engine", @@ -9162,6 +9179,7 @@ "group": "RPC and API", "pages": [ "ar/reference/rpc", + "ar/reference/openclaw-sdk-api-design", "ar/reference/device-models" ] }, @@ -9446,6 +9464,7 @@ "it/concepts/agent", "it/concepts/agent-loop", "it/concepts/agent-runtimes", + "it/concepts/openclaw-sdk", "it/concepts/system-prompt", "it/concepts/context", "it/concepts/context-engine", @@ -10018,6 +10037,7 @@ "group": "RPC and API", "pages": [ "it/reference/rpc", + "it/reference/openclaw-sdk-api-design", "it/reference/device-models" ] }, @@ -10302,6 +10322,7 @@ "vi/concepts/agent", "vi/concepts/agent-loop", "vi/concepts/agent-runtimes", + "vi/concepts/openclaw-sdk", "vi/concepts/system-prompt", "vi/concepts/context", "vi/concepts/context-engine", @@ -10874,6 +10895,7 @@ "group": "RPC and API", "pages": [ "vi/reference/rpc", + "vi/reference/openclaw-sdk-api-design", "vi/reference/device-models" ] }, @@ -11158,6 +11180,7 @@ "nl/concepts/agent", "nl/concepts/agent-loop", "nl/concepts/agent-runtimes", + "nl/concepts/openclaw-sdk", "nl/concepts/system-prompt", "nl/concepts/context", "nl/concepts/context-engine", @@ -11730,6 +11753,7 @@ "group": "RPC and API", "pages": [ "nl/reference/rpc", + "nl/reference/openclaw-sdk-api-design", "nl/reference/device-models" ] }, @@ -12014,6 +12038,7 @@ "tr/concepts/agent", "tr/concepts/agent-loop", "tr/concepts/agent-runtimes", + "tr/concepts/openclaw-sdk", "tr/concepts/system-prompt", "tr/concepts/context", "tr/concepts/context-engine", @@ -12586,6 +12611,7 @@ "group": "RPC and API", "pages": [ "tr/reference/rpc", + "tr/reference/openclaw-sdk-api-design", "tr/reference/device-models" ] }, @@ -12870,6 +12896,7 @@ "uk/concepts/agent", "uk/concepts/agent-loop", "uk/concepts/agent-runtimes", + "uk/concepts/openclaw-sdk", "uk/concepts/system-prompt", "uk/concepts/context", "uk/concepts/context-engine", @@ -13442,6 +13469,7 @@ "group": "RPC and API", "pages": [ "uk/reference/rpc", + "uk/reference/openclaw-sdk-api-design", "uk/reference/device-models" ] }, @@ -13726,6 +13754,7 @@ "id/concepts/agent", "id/concepts/agent-loop", "id/concepts/agent-runtimes", + "id/concepts/openclaw-sdk", "id/concepts/system-prompt", "id/concepts/context", "id/concepts/context-engine", @@ -14298,6 +14327,7 @@ "group": "RPC and API", "pages": [ "id/reference/rpc", + "id/reference/openclaw-sdk-api-design", "id/reference/device-models" ] }, @@ -14582,6 +14612,7 @@ "pl/concepts/agent", "pl/concepts/agent-loop", "pl/concepts/agent-runtimes", + "pl/concepts/openclaw-sdk", "pl/concepts/system-prompt", "pl/concepts/context", "pl/concepts/context-engine", @@ -15154,6 +15185,7 @@ "group": "RPC and API", "pages": [ "pl/reference/rpc", + "pl/reference/openclaw-sdk-api-design", "pl/reference/device-models" ] }, diff --git a/docs/fa/tools/skills.md b/docs/fa/tools/skills.md index 8ce130352..968cb4ac5 100644 --- a/docs/fa/tools/skills.md +++ b/docs/fa/tools/skills.md @@ -76,6 +76,7 @@ OpenClaw مهارت‌ها را از این منابع بارگذاری می‌ - برای نداشتن هیچ مهارتی، `agents.list[].skills: []` را تنظیم کنید. - یک فهرست غیرخالی `agents.list[].skills` مجموعه **نهایی** آن عامل است — با پیش‌فرض‌ها ادغام نمی‌شود. - فهرست مجاز مؤثر روی ساخت اعلان، کشف دستورهای اسلش مهارت، همگام‌سازی sandbox، و snapshotهای مهارت اعمال می‌شود. + diff --git a/docs/gateway/protocol.md b/docs/gateway/protocol.md index 17287c592..9a0fa2870 100644 --- a/docs/gateway/protocol.md +++ b/docs/gateway/protocol.md @@ -402,7 +402,7 @@ enumeration of `src/gateway/server-methods/*.ts`. - `sessions.create` creates a new session entry. - `sessions.send` sends a message into an existing session. - `sessions.steer` is the interrupt-and-steer variant for an active session. - - `sessions.abort` aborts active work for a session. + - `sessions.abort` aborts active work for a session. A caller may pass `key` plus optional `runId`, or pass `runId` alone for active runs the Gateway can resolve to a session. - `sessions.patch` updates session metadata/overrides and reports the resolved canonical model plus effective `agentRuntime`. - `sessions.reset`, `sessions.delete`, and `sessions.compact` perform session maintenance. - `sessions.get` returns the full stored session row. diff --git a/docs/nl/tools/skills.md b/docs/nl/tools/skills.md index ad1c7bb49..0c360adb0 100644 --- a/docs/nl/tools/skills.md +++ b/docs/nl/tools/skills.md @@ -77,6 +77,7 @@ bepalen welke Skills een agent daadwerkelijk kan gebruiken. - Een niet-lege `agents.list[].skills`-lijst is de **definitieve** set voor die agent — deze wordt niet samengevoegd met standaardwaarden. - De effectieve allowlist wordt toegepast op promptopbouw, ontdekking van Skill-slashcommando's, sandbox-synchronisatie en Skill-snapshots. + diff --git a/docs/reference/openclaw-sdk-api-design.md b/docs/reference/openclaw-sdk-api-design.md new file mode 100644 index 000000000..da94270de --- /dev/null +++ b/docs/reference/openclaw-sdk-api-design.md @@ -0,0 +1,383 @@ +--- +summary: "Reference design for the proposed public OpenClaw app SDK API, event taxonomy, artifacts, approvals, and package structure" +title: "OpenClaw SDK API design" +read_when: + - You are implementing the proposed public OpenClaw app SDK + - You need the draft namespace, event, result, artifact, approval, or security contract for the app SDK + - You are comparing Gateway protocol resources with the high-level OpenClaw SDK wrapper +--- + +This page is the detailed API reference design for the proposed public +[OpenClaw SDK](/concepts/openclaw-sdk). It is intentionally separate from the +[plugin SDK](/plugins/sdk-overview). + +The public app SDK should be built in two layers: + +1. A low-level generated Gateway client. +2. A high-level ergonomic wrapper with `OpenClaw`, `Agent`, `Session`, `Run`, + `Task`, `Artifact`, `Approval`, and `Environment` objects. + +## Namespace design + +The low-level namespaces should closely follow Gateway resources: + +```typescript +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(); // future API: current SDK throws unsupported +oc.tasks.get(taskId); // future API: current SDK throws unsupported +oc.tasks.cancel(taskId); // future API: current SDK throws unsupported +oc.tasks.events(taskId, { after }); // future API + +oc.models.list(); +oc.models.status(); // Gateway models.authStatus + +oc.tools.list(); +oc.tools.invoke(...); // future API: current SDK throws unsupported + +oc.artifacts.list({ runId }); // future API: current SDK throws unsupported +oc.artifacts.get(artifactId); // future API: current SDK throws unsupported +oc.artifacts.download(artifactId); // future API: current SDK throws unsupported + +oc.approvals.list(); +oc.approvals.respond(approvalId, ...); + +oc.environments.list(); // future API: current SDK throws unsupported +oc.environments.create(...); // future API: current SDK throws unsupported +oc.environments.status(environmentId); // future API: current SDK throws unsupported +oc.environments.delete(environmentId); // future API: current SDK throws unsupported +``` + +High-level wrappers should return objects that make common flows pleasant: + +```typescript +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(); +``` + +## Event contract + +The public SDK should expose versioned, replayable, normalized events. + +```typescript +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` is a replay cursor. Consumers should be able to reconnect with +`events({ after: id })` and receive missed events when retention allows. + +Recommended normalized event families: + +| Event | Meaning | +| --------------------- | ----------------------------------------------------------- | +| `run.created` | Run accepted. | +| `run.queued` | Run is waiting for a session lane, runtime, or environment. | +| `run.started` | Runtime started execution. | +| `run.completed` | Run finished successfully. | +| `run.failed` | Run ended with an error. | +| `run.cancelled` | Run was cancelled. | +| `run.timed_out` | Run exceeded its timeout. | +| `assistant.delta` | Assistant text delta. | +| `assistant.message` | Complete assistant message or replacement. | +| `thinking.delta` | Reasoning or plan delta, when policy allows exposure. | +| `tool.call.started` | Tool call began. | +| `tool.call.delta` | Tool call streamed progress or partial output. | +| `tool.call.completed` | Tool call returned successfully. | +| `tool.call.failed` | Tool call failed. | +| `approval.requested` | A run or tool needs approval. | +| `approval.resolved` | Approval was granted, denied, expired, or cancelled. | +| `question.requested` | Runtime asks the user or host app for input. | +| `question.answered` | Host app supplied an answer. | +| `artifact.created` | New artifact available. | +| `artifact.updated` | Existing artifact changed. | +| `session.created` | Session created. | +| `session.updated` | Session metadata changed. | +| `session.compacted` | Session compaction happened. | +| `task.updated` | Background task state changed. | +| `git.branch` | Runtime observed or changed branch state. | +| `git.diff` | Runtime produced or changed a diff. | +| `git.pr` | Runtime opened, updated, or linked a pull request. | + +Runtime-native payloads should be available through `raw`, but apps should not +have to parse `raw` for normal UI. + +## Result contract + +`Run.wait()` should return a stable result envelope: + +```typescript +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; +}; +``` + +The result should be boring and stable. Timestamp values preserve the Gateway +shape, so current lifecycle-backed runs usually report epoch millisecond +numbers while adapters may still surface ISO strings. Rich UI, tool traces, and +runtime-native details belong in events and artifacts. + +`accepted` is a non-terminal wait result: it means the Gateway wait deadline +expired before the run produced a lifecycle end/error. It must not be treated as +`timed_out`; `timed_out` is reserved for a run that exceeded its own runtime +timeout. + +## Approvals and questions + +Approvals must be first-class because coding agents constantly cross safety +boundaries. + +```typescript +run.onApproval(async (request) => { + if (request.kind === "tool" && request.toolName === "exec") { + return request.approveOnce({ reason: "CI command allowed by policy" }); + } + + return request.askUser(); +}); +``` + +Approval events should carry: + +- approval id +- run id and session id +- request kind +- requested action summary +- tool name or environment action +- risk level +- available decisions +- expiration +- whether the decision can be reused + +Questions are separate from approvals. A question asks the user or host app for +information. An approval asks for permission to perform an action. + +## ToolSpace model + +Apps need to understand the tool surface without importing plugin internals. + +```typescript +const tools = await run.toolSpace(); + +for (const tool of tools.list()) { + console.log(tool.name, tool.source, tool.requiresApproval); +} +``` + +The SDK should expose: + +- normalized tool metadata +- source: OpenClaw, MCP, plugin, channel, runtime, or app +- schema summary +- approval policy +- runtime compatibility +- whether a tool is hidden, readonly, write capable, or host capable + +Tool invocation through the SDK should be explicit and scoped. Most apps should +run agents, not call arbitrary tools directly. + +## Artifact model + +Artifacts should cover more than files. + +```typescript +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; +}; +``` + +Common examples: + +- file edits and generated files +- patch bundles +- VCS diffs +- screenshots and media outputs +- logs and trace bundles +- pull request links +- runtime trajectories +- managed environment workspace snapshots + +Artifact access should support redaction, retention, and download URLs without +assuming every artifact is a normal local file. + +## Security model + +The app SDK must be explicit about authority. + +Recommended token scopes: + +| Scope | Allows | +| ------------------- | --------------------------------------------------- | +| `agent.read` | List and inspect agents. | +| `agent.run` | Start runs. | +| `session.read` | Read session metadata and messages. | +| `session.write` | Create, send to, fork, compact, and abort sessions. | +| `task.read` | Read background task state. | +| `task.write` | Cancel or modify task notification policy. | +| `approval.respond` | Approve or deny requests. | +| `tools.invoke` | Invoke exposed tools directly. | +| `artifacts.read` | List and download artifacts. | +| `environment.write` | Create or destroy managed environments. | +| `admin` | Administrative operations. | + +Defaults: + +- no secret forwarding by default +- no unrestricted environment variable pass-through +- secret references instead of secret values +- explicit sandbox and network policy +- explicit remote environment retention +- approvals for host execution unless policy proves otherwise +- raw runtime events redacted before they leave Gateway unless the caller has a + stronger diagnostic scope + +## Managed environment provider + +Managed agents should be implemented as environment providers. + +```typescript +type EnvironmentProvider = { + id: string; + capabilities: { + checkout?: boolean; + sandbox?: boolean; + networkPolicy?: boolean; + secrets?: boolean; + artifacts?: boolean; + logs?: boolean; + pullRequests?: boolean; + longRunning?: boolean; + }; +}; +``` + +The first implementation does not need to be a hosted SaaS. It can target +existing node hosts, ephemeral workspaces, CI-style runners, or Testbox-style +environments. The important contract is: + +1. prepare workspace +2. bind safe environment and secrets +3. start run +4. stream events +5. collect artifacts +6. clean up or retain by policy + +Once this is stable, a hosted cloud service can implement the same provider +contract. + +## Package structure + +Recommended packages: + +| Package | Purpose | +| ----------------------- | ------------------------------------------------------------- | +| `@openclaw/sdk` | Public high-level SDK and generated low-level Gateway client. | +| `@openclaw/sdk-react` | Optional React hooks for dashboards and app builders. | +| `@openclaw/sdk-testing` | Test helpers and fake Gateway server for app integrations. | + +The repo already has `openclaw/plugin-sdk/*` for plugins. Keep that namespace +separate to avoid confusing plugin authors with app developers. + +## Generated client strategy + +The low-level client should be generated from versioned Gateway protocol +schemas, then wrapped by handwritten ergonomic classes. + +Layering: + +1. Gateway schema source of truth. +2. Generated low-level TypeScript client. +3. Runtime validators for external inputs and event payloads. +4. High-level `OpenClaw`, `Agent`, `Session`, `Run`, `Task`, and `Artifact` + wrappers. +5. Cookbook examples and integration tests. + +Benefits: + +- protocol drift is visible +- tests can compare generated methods with Gateway exports +- app SDK stays independent from plugin SDK internals +- low-level consumers still have full protocol access +- high-level consumers get the small product API + +## Related docs + +- [OpenClaw SDK design](/concepts/openclaw-sdk) +- [Gateway RPC reference](/reference/rpc) +- [Agent loop](/concepts/agent-loop) +- [Agent runtimes](/concepts/agent-runtimes) +- [Background tasks](/automation/tasks) +- [ACP agents](/tools/acp-agents) +- [Plugin SDK overview](/plugins/sdk-overview) diff --git a/docs/vi/tools/skills.md b/docs/vi/tools/skills.md index 880f3a25c..7fcb85d91 100644 --- a/docs/vi/tools/skills.md +++ b/docs/vi/tools/skills.md @@ -76,6 +76,7 @@ cho phép của agent quyết định kỹ năng nào agent thực sự có th - Đặt `agents.list[].skills: []` để không có kỹ năng nào. - Danh sách `agents.list[].skills` không rỗng là tập hợp **cuối cùng** cho agent đó — nó không hợp nhất với mặc định. - Danh sách cho phép hiệu lực áp dụng trên quá trình dựng prompt, khám phá lệnh slash của kỹ năng, đồng bộ sandbox và snapshot kỹ năng. +