Compare commits
No commits in common. "main_sync" and "main" have entirely different histories.
61
AGENTS.md
61
AGENTS.md
|
|
@ -3,25 +3,6 @@
|
||||||
- Repo: https://github.com/openclaw/openclaw
|
- Repo: https://github.com/openclaw/openclaw
|
||||||
- GitHub issues/comments/PR comments: use literal multiline strings or `-F - <<'EOF'` (or $'...') for real newlines; never embed "\\n".
|
- GitHub issues/comments/PR comments: use literal multiline strings or `-F - <<'EOF'` (or $'...') for real newlines; never embed "\\n".
|
||||||
|
|
||||||
## Quick Reference
|
|
||||||
|
|
||||||
**Build & Test:**
|
|
||||||
```bash
|
|
||||||
pnpm build # Type-check and build
|
|
||||||
pnpm check # Run all checks (tsgo + lint + format)
|
|
||||||
pnpm test # Run all unit tests
|
|
||||||
pnpm test:coverage # Run tests with coverage report
|
|
||||||
vitest run path/to/file.test.ts # Run single test file
|
|
||||||
vitest run -t "test name" # Run tests matching pattern
|
|
||||||
```
|
|
||||||
|
|
||||||
**Dev Commands:**
|
|
||||||
```bash
|
|
||||||
pnpm openclaw ... # Run CLI in dev mode
|
|
||||||
pnpm gateway:watch # Auto-reload gateway on changes
|
|
||||||
pnpm dev # Run node in dev mode
|
|
||||||
```
|
|
||||||
|
|
||||||
## Project Structure & Module Organization
|
## Project Structure & Module Organization
|
||||||
|
|
||||||
- Source code: `src/` (CLI wiring in `src/cli`, commands in `src/commands`, web provider in `src/provider-web.ts`, infra in `src/infra`, media pipeline in `src/media`).
|
- Source code: `src/` (CLI wiring in `src/cli`, commands in `src/commands`, web provider in `src/provider-web.ts`, infra in `src/infra`, media pipeline in `src/media`).
|
||||||
|
|
@ -86,50 +67,10 @@ pnpm dev # Run node in dev mode
|
||||||
- Language: TypeScript (ESM). Prefer strict typing; avoid `any`.
|
- Language: TypeScript (ESM). Prefer strict typing; avoid `any`.
|
||||||
- Formatting/linting via Oxlint and Oxfmt; run `pnpm check` before commits.
|
- Formatting/linting via Oxlint and Oxfmt; run `pnpm check` before commits.
|
||||||
- Add brief code comments for tricky or non-obvious logic.
|
- Add brief code comments for tricky or non-obvious logic.
|
||||||
- Keep files concise; extract helpers instead of "V2" copies. Use existing patterns for CLI options and dependency injection via `createDefaultDeps`.
|
- Keep files concise; extract helpers instead of “V2” copies. Use existing patterns for CLI options and dependency injection via `createDefaultDeps`.
|
||||||
- Aim to keep files under ~700 LOC; guideline only (not a hard guardrail). Split/refactor when it improves clarity or testability.
|
- Aim to keep files under ~700 LOC; guideline only (not a hard guardrail). Split/refactor when it improves clarity or testability.
|
||||||
- Naming: use **OpenClaw** for product/app/docs headings; use `openclaw` for CLI command, package/binary, paths, and config keys.
|
- Naming: use **OpenClaw** for product/app/docs headings; use `openclaw` for CLI command, package/binary, paths, and config keys.
|
||||||
|
|
||||||
### Import Style
|
|
||||||
|
|
||||||
- Group imports: Node.js built-ins → external packages → local modules
|
|
||||||
- Use `node:` prefix for built-in modules: `import fs from "node:fs";`
|
|
||||||
- Always use `.js` extensions for local imports: `import { foo } from "./utils.js";`
|
|
||||||
- Type-only imports: use `import type { ... }` when importing only types
|
|
||||||
|
|
||||||
### Type Definitions
|
|
||||||
|
|
||||||
- Prefer `type` over `interface` for most cases
|
|
||||||
- Use strict typing; avoid `any` - use `unknown` and narrow with type guards instead
|
|
||||||
- Export types that may be needed by other modules
|
|
||||||
- Use TypeBox (`@sinclair/typebox`) for runtime validation schemas
|
|
||||||
- Function return types: explicit when non-obvious, inferred for simple functions
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
- Prefer explicit error handling over silent failures
|
|
||||||
- Use try/catch for async operations that may fail
|
|
||||||
- Create descriptive error messages with context
|
|
||||||
- For expected errors, throw with meaningful messages
|
|
||||||
- Log errors at appropriate levels using the tslog logger
|
|
||||||
|
|
||||||
### Naming Conventions
|
|
||||||
|
|
||||||
- **Files**: kebab-case (e.g., `agent-paths.ts`, `session-key.ts`)
|
|
||||||
- **Test files**: `*.test.ts` (colocated), `*.e2e.test.ts` (e2e tests), `*.live.test.ts` (live integration tests)
|
|
||||||
- **Functions**: camelCase (e.g., `resolveOpenClawAgentDir`, `ensureDir`)
|
|
||||||
- **Classes**: PascalCase (e.g., `SessionManager`)
|
|
||||||
- **Constants**: SCREAMING_SNAKE_CASE for true constants (e.g., `DEFAULT_AGENT_ID`)
|
|
||||||
- **Types/Interfaces**: PascalCase (e.g., `JidToE164Options`)
|
|
||||||
- **Variables**: camelCase (e.g., `tempStateDir`, `normalizedSelf`)
|
|
||||||
|
|
||||||
### Documentation & Comments
|
|
||||||
|
|
||||||
- Add JSDoc for public APIs and exported functions
|
|
||||||
- Use inline comments for complex logic or non-obvious code
|
|
||||||
- Keep comments concise and focused on "why" rather than "what"
|
|
||||||
- Document function parameters and return types when non-obvious
|
|
||||||
|
|
||||||
## Release Channels (Naming)
|
## Release Channels (Naming)
|
||||||
|
|
||||||
- stable: tagged releases only (e.g. `vYYYY.M.D`), npm dist-tag `latest`.
|
- stable: tagged releases only (e.g. `vYYYY.M.D`), npm dist-tag `latest`.
|
||||||
|
|
|
||||||
|
|
@ -1,812 +0,0 @@
|
||||||
# OpenClaw 架构蓝图
|
|
||||||
|
|
||||||
> 完整的系统架构可视化
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. 整体系统架构
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph TB
|
|
||||||
subgraph "客户端层 Clients"
|
|
||||||
APP1[macOS App]
|
|
||||||
APP2[iOS App]
|
|
||||||
APP3[Android App]
|
|
||||||
UI[Web UI]
|
|
||||||
CLI[CLI Tool]
|
|
||||||
NODES[Nodes<br/>macOS/iOS/Android]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "网关层 Gateway (18789)"
|
|
||||||
WS[WebSocket Server]
|
|
||||||
HTTP[HTTP Server]
|
|
||||||
PROTO[Protocol Validator<br/>AJV]
|
|
||||||
CHANNELS[Channel Manager]
|
|
||||||
EVENTS[Event Dispatcher]
|
|
||||||
METHODS[Method Handlers]
|
|
||||||
CRON[Cron Service]
|
|
||||||
CANVAS["Canvas Host<br/>a2ui (18793)"]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "通道层 Channels"
|
|
||||||
WA[WhatsApp Web<br/>Baileys]
|
|
||||||
TG[Telegram<br/>grammY]
|
|
||||||
DC[Discord]
|
|
||||||
SL[Slack]
|
|
||||||
SG[Signal]
|
|
||||||
IM[iMessage]
|
|
||||||
LN[LINE]
|
|
||||||
GO[Google Chat]
|
|
||||||
MS[MS Teams]
|
|
||||||
EXT[Extensions<br/>Matrix/Zalo/etc]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Agent 层"
|
|
||||||
ROUTER[Message Router<br/>Bindings]
|
|
||||||
SESSION[Session Manager]
|
|
||||||
AGENT[Agent Runtime]
|
|
||||||
TOOLS[Tool Execution]
|
|
||||||
MEMORY[Memory Store]
|
|
||||||
PROVIDERS[Model Providers<br/>OpenAI/Anthropic/etc]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "基础设施层Infrastructure"
|
|
||||||
MEDIA[Media Pipeline<br/>Store/Fetch/Process]
|
|
||||||
CONFIG[Config System<br/>JSON5/Zod]
|
|
||||||
PAIRING[Device Pairing]
|
|
||||||
AUTH[Authentication]
|
|
||||||
LOGS[Logging System]
|
|
||||||
DIAG[Diagnostic Events]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "扩展层Plugins"
|
|
||||||
PLUGINSDK[Plugin SDK]
|
|
||||||
CHANNEL_PLG[Channel Plugins]
|
|
||||||
MEMORY_PLG[Memory Plugins]
|
|
||||||
PROVIDER_PLG[Provider Plugins]
|
|
||||||
HOOKS[Lifecycle Hooks]
|
|
||||||
end
|
|
||||||
|
|
||||||
%% 连接关系
|
|
||||||
APP1 -->|WebSocket| WS
|
|
||||||
APP2 -->|WebSocket| WS
|
|
||||||
APP3 -->|WebSocket| WS
|
|
||||||
UI -->|WebSocket| WS
|
|
||||||
CLI -->|WebSocket| WS
|
|
||||||
NODES -->|WebSocket| WS
|
|
||||||
|
|
||||||
WS --> PROTO
|
|
||||||
PROTO --> METHODS
|
|
||||||
PROTO --> EVENTS
|
|
||||||
|
|
||||||
HTTP --> METHODS
|
|
||||||
|
|
||||||
METHODS --> CHANNELS
|
|
||||||
METHODS --> ROUTER
|
|
||||||
METHODS --> CONFIG
|
|
||||||
METHODS --> MEDIA
|
|
||||||
|
|
||||||
CHANNELS --> WA
|
|
||||||
CHANNELS --> TG
|
|
||||||
CHANNELS --> DC
|
|
||||||
CHANNELS --> SL
|
|
||||||
CHANNELS --> SG
|
|
||||||
CHANNELS --> IM
|
|
||||||
CHANNELS --> LN
|
|
||||||
CHANNELS --> GO
|
|
||||||
CHANNELS --> MS
|
|
||||||
CHANNELS --> EXT
|
|
||||||
|
|
||||||
CHANNELS -.->|事件| EVENTS
|
|
||||||
EVENTS -.->|广播| WS
|
|
||||||
|
|
||||||
CRON -.->|触发| EVENTS
|
|
||||||
|
|
||||||
WA -->|入站| CHANNELS
|
|
||||||
TG -->|入站| CHANNELS
|
|
||||||
DC -->|入站| CHANNELS
|
|
||||||
SL -->|入站| CHANNELS
|
|
||||||
SG -->|入站| CHANNELS
|
|
||||||
IM -->|入站| CHANNELS
|
|
||||||
LN -->|入站| CHANNELS
|
|
||||||
GO -->|入站| CHANNELS
|
|
||||||
MS -->|入站| CHANNELS
|
|
||||||
EXT -->|入站| CHANNELS
|
|
||||||
|
|
||||||
CHANNELS -->|路由| ROUTER
|
|
||||||
ROUTER --> AGENT
|
|
||||||
|
|
||||||
AGENT --> TOOLS
|
|
||||||
AGENT --> MEMORY
|
|
||||||
AGENT --> PROVIDERS
|
|
||||||
|
|
||||||
AGENT -->|出站| CHANNELS
|
|
||||||
AGENT -.->|事件| EVENTS
|
|
||||||
|
|
||||||
SESSION -->|持久化| ROUTER
|
|
||||||
|
|
||||||
METHODS --> MEDIA
|
|
||||||
CONFIG -->|加载| CHANNELS
|
|
||||||
CONFIG -->|加载| ROUTER
|
|
||||||
|
|
||||||
WS --> AUTH
|
|
||||||
PAIRING --> AUTH
|
|
||||||
|
|
||||||
LOGS -->| everywhere | *
|
|
||||||
DIAG -->| everywhere | *
|
|
||||||
|
|
||||||
PLUGINSDK --> CHANNEL_PLG
|
|
||||||
PLUGINSDK --> MEMORY_PLG
|
|
||||||
PLUGINSDK --> PROVIDER_PLG
|
|
||||||
|
|
||||||
CHANNEL_PLG --> CHANNELS
|
|
||||||
MEMORY_PLG --> MEMORY
|
|
||||||
PROVIDER_PLG --> PROVIDERS
|
|
||||||
|
|
||||||
HOOKS --> AGENT
|
|
||||||
HOOKS --> CHANNELS
|
|
||||||
HOOKS --> EVENTS
|
|
||||||
|
|
||||||
style Gateway fill:#e1f5fe
|
|
||||||
style Clients fill:#f3e5f5
|
|
||||||
style Channels fill:#fff3e0
|
|
||||||
style Agent fill:#e8f5e9
|
|
||||||
style Infrastructure fill:#fce4ec
|
|
||||||
style Plugins fill:#fff9c4
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Gateway 详细架构
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph TB
|
|
||||||
subgraph "Gateway Server:端口 18789"
|
|
||||||
ENTER[客户端连接] --> WS_CONN
|
|
||||||
|
|
||||||
subgraph "WebSocket 层"
|
|
||||||
WS_CONN[WebSocket Server]
|
|
||||||
WS_HANDLER[WS Handler]
|
|
||||||
FRAME_PARSER[Frame Parser]
|
|
||||||
FRAME_VALIDATOR[Frame Validator<br/>JSON Schema]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "连接管理 Connect Management"
|
|
||||||
HELLO[req:connect]
|
|
||||||
AUTH_CHECK[Auth Check<br/>Token Check]
|
|
||||||
PAIRING_CHECK[Pairing Check<br/>Device Approval]
|
|
||||||
CLIENT_REGISTRY[Client Registry]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "方法层 Method Layer"
|
|
||||||
METHOD_DISPATCH[Method Dispatcher]
|
|
||||||
CORE_HANDLERS[Core Handlers<br/>health/status/send/agent]
|
|
||||||
GATEWAY_METHODS[Gateway Methods<br/>channels.* / media.*]
|
|
||||||
PLUGIN_METHODS[Plugin Methods]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "状态层 State Layer"
|
|
||||||
RUNTIME_STATE[Runtime State<br/>健康查看 / 缓冲]
|
|
||||||
CHANNEL_STATE[Channel State<br/>运行时实例]
|
|
||||||
NODE_REGISTRY[Node Registry]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "事件层 Event Layer"
|
|
||||||
EVENT_EMITTER[Event Emitter]
|
|
||||||
AGENT_EVENTS[agent Events]
|
|
||||||
CHAT_EVENTS[chat Events]
|
|
||||||
PRESENCE_EVENTS[presence Events]
|
|
||||||
HEARTBEAT[heartbeat Events]
|
|
||||||
DIAGNOSTICS[diagnostic Events]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "资源层 Resource Layer"
|
|
||||||
CONFIG_RELOAD[Config Reloader]
|
|
||||||
CHANNEL_MANAGER[Channel Manager]
|
|
||||||
CANVAS_HOST[Canvas Host<br/>a2ui:18793]
|
|
||||||
MEDIA_SERVER[Media Server]
|
|
||||||
CRON_SCHEDULER[Cron Scheduler]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
%% 连接关系
|
|
||||||
WS_CONN --> WS_HANDLER
|
|
||||||
WS_HANDLER --> FRAME_PARSER
|
|
||||||
FRAME_PARSER --> FRAME_VALIDATOR
|
|
||||||
|
|
||||||
FRAME_VALIDATOR --> HELLO
|
|
||||||
FRAME_VALIDATOR --> METHOD_DISPATCH
|
|
||||||
|
|
||||||
HELLO --> AUTH_CHECK
|
|
||||||
AUTH_CHECK --> PAIRING_CHECK
|
|
||||||
PAIRING_CHECK --> CLIENT_REGISTRY
|
|
||||||
CLIENT_REGISTRY --> RUNTIME_STATE
|
|
||||||
|
|
||||||
METHOD_DISPATCH --> CORE_HANDLERS
|
|
||||||
METHOD_DISPATCH --> GATEWAY_METHODS
|
|
||||||
METHOD_DISPATCH --> PLUGIN_METHODS
|
|
||||||
|
|
||||||
CORE_HANDLERS -->|使用| RUNTIME_STATE
|
|
||||||
CORE_HANDLERS -->|使用| CHANNEL_STATE
|
|
||||||
CORE_HANDLERS -->|使用| CHANNEL_MANAGER
|
|
||||||
|
|
||||||
GATEWAY_METHODS --> CHANNEL_MANAGER
|
|
||||||
GATEWAY_METHODS --> MEDIA_SERVER
|
|
||||||
GATEWAY_METHODS --> NODE_REGISTRY
|
|
||||||
|
|
||||||
CHANNEL_MANAGER --> CHANNEL_STATE
|
|
||||||
CHANNEL_MANAGER -->|启动/停止| WA_SVC
|
|
||||||
CHANNEL_MANAGER -->|启动/停止| TG_SVC
|
|
||||||
CHANNEL_MANAGER -->|启动/停止| DC_SVC
|
|
||||||
|
|
||||||
RLGA_EVENTS -.->|广播| WS_HANDLER
|
|
||||||
HEARTBEAT -.->|广播| WS_HANDLER
|
|
||||||
DIAGNOSTICS -.->|广播| WS_HANDLER
|
|
||||||
|
|
||||||
CONFIG_RELOAD -.->|通知| CORE_HANDLERS
|
|
||||||
CONFIG_RELOAD -.->|通知| CHANNEL_MANAGER
|
|
||||||
|
|
||||||
CRON_SCHEDULER -.->|触发| EVENT_EMITTER
|
|
||||||
CRON_SCHEDULER -.->|触发| CANVAS_HOST
|
|
||||||
|
|
||||||
subgraph "外部服务 External Services"
|
|
||||||
WA_SVC[WhatsApp Service]
|
|
||||||
TG_SVC[Telegram Service]
|
|
||||||
DC_SVC[Discord Service]
|
|
||||||
end
|
|
||||||
|
|
||||||
style GatewayServer fill:#e1f5fe
|
|
||||||
style WebSocket层 fill:#e3f2fd
|
|
||||||
style MethodLayer fill:#bbdefb
|
|
||||||
style StateLayer fill:#90caf9
|
|
||||||
style EventLayer fill:#64b5f6
|
|
||||||
style ResourceLayer fill:#42a5f5
|
|
||||||
style ExternalServices fill:#ffecb3
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. 消息流转图 Message Flow
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
participant USER as 用户
|
|
||||||
participant CH as 通道通道<br/>WhatsApp/Telegram/etc
|
|
||||||
participant GATEWAY as Gateway
|
|
||||||
participant ROUTER as Message Router
|
|
||||||
participant AGENT as Agent Runtime
|
|
||||||
participant PROVIDER as AI Provider
|
|
||||||
participant TOOLS as Tools
|
|
||||||
|
|
||||||
%% 入站消息流
|
|
||||||
USER->>CH: 发送消息
|
|
||||||
CH->>GATEWAY: 接入事件
|
|
||||||
GATEWAY->>ROUTER: 解析路由<br/>(channel/account/peer)
|
|
||||||
ROUTER-->>GATEWAY: 返回匹配结果<br/>(agentId, sessionKey)
|
|
||||||
GATEWAY->>AGENT: 调用 agent.execute
|
|
||||||
|
|
||||||
AGENT->>AGENT: 加载会话历史
|
|
||||||
AGENT->>AGENT: 构建系统提示
|
|
||||||
AGENT->>PROVIDER: 发起 LLM 调用
|
|
||||||
|
|
||||||
alt 需要工具调用
|
|
||||||
PROVIDER-->>AGENT: 返回 tool_calls
|
|
||||||
AGENT->>TOOLS: 执行工具
|
|
||||||
TOOLS-->>AGENT: 返回工具结果
|
|
||||||
AGENT->>PROVIDER: 继续调用 (with tool results)
|
|
||||||
end
|
|
||||||
|
|
||||||
PROVIDER-->>AGENT: 返回完整响应
|
|
||||||
AGENT->>AGENT: 更新会话历史
|
|
||||||
AGENT-->>GATEWAY: 返回响应 (events: agent)
|
|
||||||
|
|
||||||
GATEWAY->>CH: 发送消息 (channel.message.send)
|
|
||||||
CH->>USER: 接收回复
|
|
||||||
|
|
||||||
%% 出站消息流 (CLI/Web/App 触发)
|
|
||||||
rect rgb(255, 255, 200)
|
|
||||||
Note over GATEWAY,USER: 出站消息流 (从客户端触发)
|
|
||||||
USER->>GATEWAY: 调用 gateway.send
|
|
||||||
GATEWAY->>ROUTER: 解析路由
|
|
||||||
ROUTER-->>GATEWAY: 返回匹配结果
|
|
||||||
GATEWAY->>CH: 发送消息
|
|
||||||
CH->>USER: 接收消息
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. 插件系统架构 Plugin System
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph TB
|
|
||||||
subgraph "插件 API Plugin SDK"
|
|
||||||
API[OpenClawPluginApi]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "插件运行时 Plugin Runtime"
|
|
||||||
RUNTIME[Plugin Runtime]
|
|
||||||
CONFIG_API[Config API<br/>loadConfig/writeConfigFile]
|
|
||||||
SYSTEM_API[System API<br/>enqueueSystemEvent]
|
|
||||||
MEDIA_API[Media API<br/>loadWebMedia/detectMime]
|
|
||||||
TTS_API[TTS API<br/>textToSpeechTelephony]
|
|
||||||
TOOLS_API[Tools API<br/>createMemoryGetTool]
|
|
||||||
CHANNEL_API[Channel API<br/>routing/network/session]
|
|
||||||
LOGGING_API[Logging API<br/>getChildLogger]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "注册接口 Registrations"
|
|
||||||
REG_TOOL[registerTool]
|
|
||||||
REG_HOOK[registerHook]
|
|
||||||
REG_HTTP[registerHttpRoute/registerHttpHandler]
|
|
||||||
REG_CHANNEL[registerChannel]
|
|
||||||
REG_GW_METHOD[registerGatewayMethod]
|
|
||||||
REG_CLI[registerCli]
|
|
||||||
REG_SERVICE[registerService]
|
|
||||||
REG_PROVIDER[registerProvider]
|
|
||||||
REG_CMD[registerCommand]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "钩子系统 Hook System"
|
|
||||||
H_BEFORE_AGENT[before_agent_start]
|
|
||||||
H_AFTER_AGENT[after_agent_start]
|
|
||||||
H_BEFORE_SEND[before_message_send]
|
|
||||||
H_AFTER_SEND[after_message_send]
|
|
||||||
H_RECEIVED[message_received]
|
|
||||||
H_TOOL[tool_called]
|
|
||||||
H_CONFIG[config_changed]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "插件类型 Plugin Types"
|
|
||||||
P_CHANNEL[Channel Plugin<br/>must implement ChannelPlugin]
|
|
||||||
P_MEMORY[Memory Plugin<br/>LanceDB/etc]
|
|
||||||
P_PROVIDER[Provider Plugin<br/>Custom AI API]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "插件生命周期 Plugin Lifecycle"
|
|
||||||
LOAD[loadPlugin]
|
|
||||||
VALIDATE[validateConfig]
|
|
||||||
REGISTER[register]
|
|
||||||
ACTIVATE[activate]
|
|
||||||
DISPOSE[dispose]
|
|
||||||
end
|
|
||||||
|
|
||||||
%% 连接关系
|
|
||||||
API --> RUNTIME
|
|
||||||
RUNTIME --> CONFIG_API
|
|
||||||
RUNTIME --> SYSTEM_API
|
|
||||||
RUNTIME --> MEDIA_API
|
|
||||||
RUNTIME --> TTS_API
|
|
||||||
RUNTIME --> TOOLS_API
|
|
||||||
RUNTIME --> CHANNEL_API
|
|
||||||
RUNTIME --> LOGGING_API
|
|
||||||
|
|
||||||
API --> REG_TOOL
|
|
||||||
API --> REG_HOOK
|
|
||||||
API --> REG_HTTP
|
|
||||||
API --> REG_CHANNEL
|
|
||||||
API --> REG_GW_METHOD
|
|
||||||
API --> REG_CLI
|
|
||||||
API --> REG_SERVICE
|
|
||||||
API --> REG_PROVIDER
|
|
||||||
API --> REG_CMD
|
|
||||||
|
|
||||||
REG_HOOK --> H_BEFORE_AGENT
|
|
||||||
REG_HOOK --> H_AFTER_AGENT
|
|
||||||
REG_HOOK --> H_BEFORE_SEND
|
|
||||||
REG_HOOK --> H_AFTER_SEND
|
|
||||||
REG_HOOK --> H_RECEIVED
|
|
||||||
REG_HOOK --> H_TOOL
|
|
||||||
REG_HOOK --> H_CONFIG
|
|
||||||
|
|
||||||
REG_CHANNEL --> P_CHANNEL
|
|
||||||
|
|
||||||
LOAD --> VALIDATE
|
|
||||||
VALIDATE --> REGISTER
|
|
||||||
REGISTER --> ACTIVATE
|
|
||||||
ACTIVATE --> DISPOSE
|
|
||||||
|
|
||||||
P_CHANNEL -.->|loose coupling| H_RECEIVED
|
|
||||||
P_CHANNEL -.->|loose coupling| H_BEFORE_SEND
|
|
||||||
|
|
||||||
style PluginSDK fill:#fff9c4
|
|
||||||
style PluginRuntime fill:#fff59d
|
|
||||||
style Registrations fill:#ffee58
|
|
||||||
style HookSystem fill:#fdd835
|
|
||||||
style PluginTypes fill:#fbc02d
|
|
||||||
style PluginLifecycle fill:#f9a825
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. 路与绑定系统 Routing & Bindings
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph TD
|
|
||||||
subgraph "路由输入 Route Input"
|
|
||||||
CFG[User Config<br/>bindings 数组]
|
|
||||||
IN_CHANNEL[channel<br/>消息来源]
|
|
||||||
IN_ACCOUNT[accountId<br/>账户 ID]
|
|
||||||
IN_PEER[peer<br/>用户/组 ID]
|
|
||||||
IN_GUILD[guildId<br/>Discord 服务器]
|
|
||||||
IN_TEAM[teamId<br/>Slack/Teams]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "路由匹配优先级 Matching Priority"
|
|
||||||
P1[1. peer<br/>具体用户/组]
|
|
||||||
P2[2. peer.parent<br/>线程继承]
|
|
||||||
P3[3. guildId<br/>Discord 服务器]
|
|
||||||
P4[4. teamId<br/>Slack/Teams]
|
|
||||||
P5[5. account<br/>非通配符账户]
|
|
||||||
P6[6. account<br/>通配符账户]
|
|
||||||
P7[7. default<br/>默认绑定]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "路由输出 Route Output"
|
|
||||||
AGENT_ID[agentId<br/>目标 Agent]
|
|
||||||
SESSION_KEY[sessionKey<br/>会话唯一标识]
|
|
||||||
MAIN_KEY[mainSessionKey<br/>主会话]
|
|
||||||
MATCHED_BY[matchedBy<br/>匹配方式]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "会话管理 Session Management"
|
|
||||||
SESSION_STORE[Session Store<br/>~/.openclaw/sessions/]
|
|
||||||
SESSION_FILE[.jsonl 文件<br/>role/content/timestamp]
|
|
||||||
HISTORY[上下文历史<br/>消息 turnover]
|
|
||||||
end
|
|
||||||
|
|
||||||
%% 连接关系
|
|
||||||
CFG -->|解析| P1
|
|
||||||
IN_CHANNEL -->|输入| P1
|
|
||||||
IN_ACCOUNT -->|输入| P1
|
|
||||||
IN_PEER -->|输入| P1
|
|
||||||
IN_GUILD -->|输入| P1
|
|
||||||
IN_TEAM -->|输入| P1
|
|
||||||
|
|
||||||
P1 -->|无匹配| P2
|
|
||||||
P2 -->|无匹配| P3
|
|
||||||
P3 -->|无匹配| P4
|
|
||||||
P4 -->|无匹配| P5
|
|
||||||
P5 -->|无匹配| P6
|
|
||||||
P6 -->|无匹配| P7
|
|
||||||
|
|
||||||
P1 -->|匹配| AGENT_ID
|
|
||||||
P2 -->|匹配| AGENT_ID
|
|
||||||
P3 -->|匹配| AGENT_ID
|
|
||||||
P4 -->|匹配| AGENT_ID
|
|
||||||
P5 -->|匹配| AGENT_ID
|
|
||||||
P6 -->|匹配| AGENT_ID
|
|
||||||
P7 -->|匹配| AGENT_ID
|
|
||||||
|
|
||||||
AGENT_ID -->|构建| SESSION_KEY
|
|
||||||
AGENT_ID -->|构建| MAIN_KEY
|
|
||||||
P1 -->|设置| MATCHED_BY
|
|
||||||
P2 -->|设置| MATCHED_BY
|
|
||||||
P3 -->|设置| MATCHED_BY
|
|
||||||
P4 -->|设置| MATCHED_BY
|
|
||||||
P5 -->|设置| MATCHED_BY
|
|
||||||
P6 -->|设置| MATCHED_BY
|
|
||||||
P7 -->|设置| MATCHED_BY
|
|
||||||
|
|
||||||
SESSION_KEY -->|读写| SESSION_STORE
|
|
||||||
MAIN_KEY -->|读写| SESSION_STORE
|
|
||||||
|
|
||||||
SESSION_STORE -->|包含| SESSION_FILE
|
|
||||||
SESSION_FILE -->|构建| HISTORY
|
|
||||||
|
|
||||||
style RouteInput fill:#e8f5e9
|
|
||||||
style MatchingPriority fill:#c8e6c9
|
|
||||||
style RouteOutput fill:#a5d6a7
|
|
||||||
style SessionManagement fill:#81c784
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. 媒体管道架构 Media Pipeline
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph LR
|
|
||||||
subgraph "入站 Inbound"
|
|
||||||
A[收到媒体] --> B[parse<br/>提取媒体]
|
|
||||||
B --> C[mime.ts<br/>检测 MIME]
|
|
||||||
C -->|magic number<br/>+ content type| MIME_TYPE{MIME 类型?}
|
|
||||||
MIME_TYPE -->|image| D[store.ts<br/>保存到磁盘]
|
|
||||||
MIME_TYPE -->|audio| D
|
|
||||||
MIME_TYPE -->|video| D
|
|
||||||
MIME_TYPE -->|unknown| DROP[丢弃/警告]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "存储 Storage"
|
|
||||||
D --> STORAGE[~/.openclaw/media/inbound/]
|
|
||||||
STORAGE --> FILES["{original}---{uuid}.ext"]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "处理 Processing (可选)"
|
|
||||||
FILES --> E[image_ops.ts<br/>image/image-ops.ts]
|
|
||||||
E -->|resizeToJpeg| RESIZED[调整大小的 JPEG]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "出站 Outbound"
|
|
||||||
OUT_REQ[出站请求] --> OUT_MIME[mime.ts<br/>检测 MIME]
|
|
||||||
OUT_MIME -->|需要处理?| OUT_PROC[image_ops/audio.ts]
|
|
||||||
OUT_MIME -->|不需要处理| OUT_STORE[store.ts<br/>保存到磁盘]
|
|
||||||
OUT_PROC --> OUT_STORE
|
|
||||||
OUT_STORE --> OUT_STORAGE[~/.openclaw/media/outbound/]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "服务服务 & Fetch"
|
|
||||||
STORAGE --> HOST[host.ts<br/>HTTP 服务]
|
|
||||||
OUT_STORAGE --> HOST
|
|
||||||
HOST -->|GET /media/*| CLIENT[客户端]
|
|
||||||
FETCH[fetch.ts<br/>远程获取] --> STORAGE
|
|
||||||
end
|
|
||||||
|
|
||||||
style Inbound fill:#e3f2fd
|
|
||||||
style Storage fill:#bbdefb
|
|
||||||
style Processing fill:#90caf9
|
|
||||||
style Outbound fill:#64b5f6
|
|
||||||
style ServeFetch fill:#42a5f5
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Gateway 通信协议 Gateway Protocol
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
stateDiagram-v2
|
|
||||||
direction LR
|
|
||||||
|
|
||||||
%% 定义带有复杂描述的状态名(规避连线上的解析Bug)
|
|
||||||
state "Authenticated (已认证)" as Authenticated
|
|
||||||
state "Connected (已就绪)" as Connected
|
|
||||||
state "Requesting (请求中)" as Requesting
|
|
||||||
state "Streaming (流式传输中)" as Streaming
|
|
||||||
state "Waiting (异步等待中)" as Waiting
|
|
||||||
state "Error (发生错误)" as Error
|
|
||||||
state "Closed (连接关闭)" as Closed
|
|
||||||
|
|
||||||
[*] --> Disconnected
|
|
||||||
|
|
||||||
note right of Disconnected
|
|
||||||
未连接状态
|
|
||||||
end note
|
|
||||||
|
|
||||||
Disconnected --> Connecting: 客户端发起WS连接
|
|
||||||
|
|
||||||
%% 连线描述尽量保持简洁,避开特殊字符
|
|
||||||
Connecting --> Authenticated: req_connect_auth_ok
|
|
||||||
Connecting --> Closed: 认证失败
|
|
||||||
Connecting --> Closed: 非首帧为connect
|
|
||||||
|
|
||||||
Authenticated --> Connected: res_hello_ok
|
|
||||||
|
|
||||||
Connected --> Requesting: req_method
|
|
||||||
Connected --> Streaming: event_stream
|
|
||||||
|
|
||||||
Requesting --> Connected: res_ok_sync
|
|
||||||
Requesting --> Waiting: method_processing
|
|
||||||
|
|
||||||
Waiting --> Connected: res_ok
|
|
||||||
Waiting --> Error: res_error
|
|
||||||
|
|
||||||
Streaming --> Connected: stream_end
|
|
||||||
Streaming --> Streaming: stream_continue
|
|
||||||
|
|
||||||
Connected --> Closed: 客户端断开
|
|
||||||
Error --> Connected: error_recovery
|
|
||||||
Authenticated --> Closed: connection_close
|
|
||||||
Closed --> [*]
|
|
||||||
|
|
||||||
note right of Streaming
|
|
||||||
agent 事件流示例:
|
|
||||||
{
|
|
||||||
"type": "event",
|
|
||||||
"event": "agent",
|
|
||||||
"payload": {
|
|
||||||
"agentId": "xxx",
|
|
||||||
"runId": "yyy",
|
|
||||||
"status": "running"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end note
|
|
||||||
|
|
||||||
note right of Requesting
|
|
||||||
request 示例:
|
|
||||||
{
|
|
||||||
"type": "req",
|
|
||||||
"id": 1,
|
|
||||||
"method": "send",
|
|
||||||
"params": {
|
|
||||||
"channel": "whatsapp",
|
|
||||||
"target": "...",
|
|
||||||
"text": "..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end note
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. 认证与配对流程 Authentication & Pairing
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
participant DEV as 设备(Device)<br/>CLI/App/Node
|
|
||||||
participant WS as Gateway<br/>WebSocket Server
|
|
||||||
participant AUTH as Auth Module
|
|
||||||
participant PAIRING as Pairing Store
|
|
||||||
participant USER as 操作员
|
|
||||||
|
|
||||||
%% 首次连接 - 本地
|
|
||||||
rect rgb(200, 255, 200)
|
|
||||||
Note over DEV,USER: 场景:首次本地连接 (自动批准)
|
|
||||||
DEV->>WS: WS connect
|
|
||||||
WS->>AUTH: 生成 deviceIdentity
|
|
||||||
AUTH-->>WS: deviceIdentity (含 deviceID)
|
|
||||||
WS-->>DEV: res:connect + deviceIdentity
|
|
||||||
DEV->>WS: req:connect (带 deviceID)
|
|
||||||
WS->>AUTH: 验证 deviceID 是否本地
|
|
||||||
AUTH->>PAIRING: 检查 pairing 状态
|
|
||||||
PAIRING-->>AUTH: 新设备 (需要批准)
|
|
||||||
AUTH->>AUTH: 本地地址 -> 自动批准
|
|
||||||
AUTH->>PAIRING: 生成 deviceToken
|
|
||||||
AUTH-->>WS: 设备已批准
|
|
||||||
WS-->>DEV: res:hello-ok (带 deviceToken)
|
|
||||||
end
|
|
||||||
|
|
||||||
%% 首次连接 - 远程
|
|
||||||
rect rgb(255, 200, 200)
|
|
||||||
Note over DEV,USER: 场景:首次远程连接 (需要批准)
|
|
||||||
DEV->>WS: WS connect (via Tailscale/VPN)
|
|
||||||
WS->>AUTH: 生成 deviceIdentity (带 challenge)
|
|
||||||
AUTH-->>WS: deviceIdentity + challenge
|
|
||||||
WS-->>DEV: res:connect + deviceIdentity + challenge
|
|
||||||
DEV->>DEV: 签名 challenge
|
|
||||||
DEV->>WS: req:connect (带 deviceID + signature)
|
|
||||||
WS->>AUTH: 验证签名
|
|
||||||
AUTH->>PAIRING: 检查 pairing 状态
|
|
||||||
PAIRING-->>AUTH: 新设备,非本地
|
|
||||||
AUTH-->>USER: 通知等待批准
|
|
||||||
USER-->>AUTH: 批准设备
|
|
||||||
AUTH->>PAIRING: 生成并保存 deviceToken
|
|
||||||
AUTH-->>WS: 设备已批准
|
|
||||||
WS-->>DEV: res:hello-ok (带 deviceToken)
|
|
||||||
end
|
|
||||||
|
|
||||||
%% 后续连接
|
|
||||||
rect rgb(200, 200, 255)
|
|
||||||
Note over DEV,USER: 场景:后续连接
|
|
||||||
DEV->>WS: WS connect
|
|
||||||
DEV->>WS: req:connect (带 deviceID + deviceToken)
|
|
||||||
WS->>PAIRING: 验证 deviceToken
|
|
||||||
PAIRING-->>WS: Token 有效
|
|
||||||
WS-->>DEV: res:hello-ok
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. 完整组件关系图 Component Relationships
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph TB
|
|
||||||
%% CLI 层
|
|
||||||
CLI[openclaw CLI<br/>openclaw.mjs]
|
|
||||||
PROG[src/index.ts<br/>buildProgram]
|
|
||||||
CMDS[src/commands/]
|
|
||||||
|
|
||||||
CLI --> PROG
|
|
||||||
PROG --> CMD_DEPS[createDefaultDeps]
|
|
||||||
|
|
||||||
%% Gateway 层
|
|
||||||
GW_SERVER[src/gateway/server.impl.ts<br/>startGatewayServer]
|
|
||||||
GW_PROT[src/gateway/protocol/]
|
|
||||||
GW_METHODS[src/gateway/server-methods/]
|
|
||||||
GW_CHAN[src/gateway/server-channels.ts]
|
|
||||||
|
|
||||||
GW_SERVER --> GW_PROT
|
|
||||||
GW_SERVER --> GW_METHODS
|
|
||||||
GW_SERVER --> GW_CHAN
|
|
||||||
|
|
||||||
%% 通道层
|
|
||||||
CHAN_SYS[src/channels/]
|
|
||||||
PLUG_TYPES[src/channels/plugins/types.plugin.ts]
|
|
||||||
PLUG_ADAPTER[src/channels/plugins/types.adapters.ts]
|
|
||||||
|
|
||||||
WHAST[whatsapp.ts]
|
|
||||||
TELEG[telegram.ts]
|
|
||||||
DISC[discord.ts]
|
|
||||||
SLACK[slack.ts]
|
|
||||||
SIGNL[signal.ts]
|
|
||||||
IMMSG[imessage.ts]
|
|
||||||
|
|
||||||
CHAN_SYS --> PLUG_TYPES
|
|
||||||
CHAN_SYS --> PLUG_ADAPTER
|
|
||||||
CHAN_SYS --> WA
|
|
||||||
CHAN_SYS --> TG
|
|
||||||
CHAN_SYS --> DC
|
|
||||||
CHAN_SYS --> SL
|
|
||||||
CHAN_SYS --> SI
|
|
||||||
CHAN_SYS --> IM
|
|
||||||
|
|
||||||
GW_CHAN --> CHAN_SYS
|
|
||||||
|
|
||||||
%% Agent 层
|
|
||||||
AGENT_RT[src/agents/runtime.ts]
|
|
||||||
AGENT_TOOLS[src/agents/tools/]
|
|
||||||
ROUTER[src/routing/resolve-route.ts]
|
|
||||||
|
|
||||||
ROUTER --> AGENT_RT
|
|
||||||
AGENT_RT --> AGENT_TOOLS
|
|
||||||
GW_METHODS --> ROUTER
|
|
||||||
|
|
||||||
%% 配置层
|
|
||||||
CONFIG[src/config/]
|
|
||||||
ZOD_TYPES[src/config/zod-schema.*.ts]
|
|
||||||
|
|
||||||
CONFIG --> ZOD_TYPES
|
|
||||||
GW_SERVER --> CONFIG
|
|
||||||
ROUTER --> CONFIG
|
|
||||||
|
|
||||||
%% 媒体层
|
|
||||||
MEDIA[src/media/]
|
|
||||||
MIME[mime.ts]
|
|
||||||
STORE[store.ts]
|
|
||||||
FETCH[fetch.ts]
|
|
||||||
|
|
||||||
MEDIA --> MIME
|
|
||||||
MEDIA --> STORE
|
|
||||||
MEDIA --> FETCH
|
|
||||||
GW_METHODS --> MEDIA
|
|
||||||
|
|
||||||
%% 插件层
|
|
||||||
PLUG_SYS[src/plugins/]
|
|
||||||
PLUG_SDK[src/plugin-sdk/]
|
|
||||||
|
|
||||||
PLUG_SYS --> PLUG_SDK
|
|
||||||
GW_SERVER --> PLUG_SYS
|
|
||||||
|
|
||||||
%% 钩子
|
|
||||||
HOOKS[src/hooks/types.ts]
|
|
||||||
|
|
||||||
HOOKS --> AGENT_RT
|
|
||||||
PLUG_SDK --> HOOKS
|
|
||||||
|
|
||||||
%% 基础设施
|
|
||||||
INFRA[src/infra/]
|
|
||||||
PORTS[ports.ts]
|
|
||||||
LOGG[logging/]
|
|
||||||
|
|
||||||
INFRA --> PORTS
|
|
||||||
INFRA --> LOGG
|
|
||||||
GW_SERVER --> INFRA
|
|
||||||
|
|
||||||
style CLI fill:#e1f5fe
|
|
||||||
style GatewayServer fill:#bbdefb
|
|
||||||
style ChannelLayer fill:#90caf9
|
|
||||||
style AgentLayer fill:#64b5f6
|
|
||||||
style ConfigLayer fill:#42a5f5
|
|
||||||
style MediaLayer fill:#1e88e5
|
|
||||||
style PluginLayer fill:#0d47a1
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 附录:组件职责
|
|
||||||
|
|
||||||
| 组件 | 职责 |
|
|
||||||
| ------------------ | ---------------------------------------------- |
|
|
||||||
| **CLI** | 命令行界面,启动 gateway、发送消息、配置管理等 |
|
|
||||||
| **Gateway** | WebSocket 服务器,协议验证,事件广播,通道管理 |
|
|
||||||
| **Channels** | 消息平台适配器,入站/出站消息,状态管理 |
|
|
||||||
| **Routing** | 消息路由解析,绑定匹配,会话键构建 |
|
|
||||||
| **Agent Runtime** | AI Agent 执行,工具调用,会话管理 |
|
|
||||||
| **Media Pipeline** | 媒体上传、存储、处理、服务 |
|
|
||||||
| **Config System** | 配置加载、验证、迁移、监听 |
|
|
||||||
| **Plugin SDK** | 插件开发接口,运行时 API |
|
|
||||||
| **Hooks** | 生命周期钩子,插件扩展点 |
|
|
||||||
| **Infrastructure** | 端口管理、日志、诊断事件、SSRF 防护 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**文档结束**
|
|
||||||
12541
Node-invoke-process.md
12541
Node-invoke-process.md
File diff suppressed because one or more lines are too long
|
|
@ -1,126 +0,0 @@
|
||||||
# OpenClaw Mac 节点配置与云端控制完全指南
|
|
||||||
|
|
||||||
本文档汇总了关于将 Mac 注册为 OpenClaw Gateway 节点的操作指南,以及在云端部署 Gateway 控制本地 Mac 的场景可行性分析。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. 核心概念:Gateway 与 Node
|
|
||||||
|
|
||||||
在 OpenClaw 架构中:
|
|
||||||
- **Gateway (网关)**: 系统的"大脑"与控制中心。负责运行 AI 智能体、管理会话、连接消息平台(如 WhatsApp/Telegram)。它可以部署在任何地方(本地 Manjaro、云端 Ubuntu 服务器等)。
|
|
||||||
- **Node (节点)**: 系统的"手脚"与执行单元。它连接到 Gateway,暴露本地设备的能力(如屏幕显示、摄像头、执行系统命令)。Mac 可以作为一个高权限节点加入网络。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. 实操指南:将 Mac 注册到 Gateway
|
|
||||||
|
|
||||||
无论 Gateway 运行在本地局域网(Manjaro)还是云端(Ubuntu),连接 Mac 的步骤基本一致。
|
|
||||||
|
|
||||||
### 方案选择
|
|
||||||
|
|
||||||
| 方案 | 适用场景 | 优势 | 劣势 |
|
|
||||||
| :--- | :--- | :--- | :--- |
|
|
||||||
| **A. macOS App (Remote 模式)** | **推荐** | ✅ 支持 Canvas (网页显示)<br>✅ 支持摄像头/录屏<br>✅ 完整的权限管理 (TCC)<br>✅ 系统通知 | 需要安装 App |
|
|
||||||
| **B. 纯 CLI (无头模式)** | 服务器/轻量级 | ✅ 无需 GUI<br>✅ 部署简单 | ❌ 无 Canvas/摄像头/录屏支持 |
|
|
||||||
|
|
||||||
### 详细配置步骤
|
|
||||||
|
|
||||||
#### 第一步:环境准备
|
|
||||||
1. **Gateway 端 (Manjaro/Ubuntu)**:
|
|
||||||
- 确保 Gateway 已启动。
|
|
||||||
- 获取连接 Token:
|
|
||||||
```bash
|
|
||||||
openclaw config get gateway.auth.token
|
|
||||||
# 记录下输出的 Token
|
|
||||||
```
|
|
||||||
- 确保网络可达(云端需开放端口或使用 Tailscale/SSH 隧道)。
|
|
||||||
|
|
||||||
2. **Mac 端 (节点)**:
|
|
||||||
- 安装 OpenClaw CLI: `npm install -g openclaw`
|
|
||||||
- (推荐) 下载并安装 **OpenClaw.app**。
|
|
||||||
|
|
||||||
#### 第二步:连接 Gateway
|
|
||||||
|
|
||||||
**方式 A: 使用 macOS App (推荐)**
|
|
||||||
1. 打开 OpenClaw.app,进入 **Settings** -> **General**。
|
|
||||||
2. **Mode**: 选择 **Remote**。
|
|
||||||
3. **Gateway Host**: 输入 Gateway 的 IP 或域名(如 `1.2.3.4` 或 `myserver.tailscale.net`)。
|
|
||||||
4. **Gateway Port**: 默认为 `18789`。
|
|
||||||
5. **Gateway Token**: 填入第一步获取的 Token。
|
|
||||||
6. 应用会自动启动本地节点服务并尝试连接。
|
|
||||||
|
|
||||||
**方式 B: 使用 CLI**
|
|
||||||
在 Mac 终端运行:
|
|
||||||
```bash
|
|
||||||
# 前台运行测试
|
|
||||||
openclaw node run --host <gateway-ip> --port 18789 --token <token> --display-name "MyMac"
|
|
||||||
|
|
||||||
# 或安装为后台服务
|
|
||||||
openclaw node install --host <gateway-ip> --port 18789 --token <token> --display-name "MyMac"
|
|
||||||
openclaw node start
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 第三步:批准连接 (在 Gateway 端)
|
|
||||||
出于安全考虑,新节点连接需要批准。
|
|
||||||
```bash
|
|
||||||
# 在 Gateway 机器上运行
|
|
||||||
openclaw devices list # 查看待批准请求
|
|
||||||
openclaw devices approve <request-id>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 第四步:验证
|
|
||||||
```bash
|
|
||||||
# 在 Gateway 机器上运行
|
|
||||||
openclaw nodes status # 应显示 Mac 节点在线
|
|
||||||
openclaw nodes describe --node "MyMac"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. 功能手册:Gateway 可控制 Mac 做什么
|
|
||||||
|
|
||||||
连接成功后,Gateway 上的 AI Agent 可以通过 `node.invoke` 调用 Mac 的能力:
|
|
||||||
|
|
||||||
### 基础能力
|
|
||||||
- **执行命令**: `system.run` (如 `uname -a`, `ls -la`)
|
|
||||||
- *安全提示*: 需在 Mac 的 `~/.openclaw/exec-approvals.json` 中配置允许列表。
|
|
||||||
- **系统通知**: `system.notify` (发送弹窗通知到 Mac 桌面)
|
|
||||||
- **获取位置**: `location.get`
|
|
||||||
|
|
||||||
### 多媒体与 UI (需 macOS App)
|
|
||||||
- **浏览器控制 (Canvas)**:
|
|
||||||
- 打开网页: `canvas.present --target https://google.com`
|
|
||||||
- 执行 JS: `canvas.eval --js "document.title"`
|
|
||||||
- 截图: `canvas.snapshot`
|
|
||||||
- **摄像头**: `camera.snap` (拍照), `camera.clip` (录短视频)
|
|
||||||
- **屏幕录制**: `screen.record`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. 场景深度分析:云端 Gateway + Mac Node
|
|
||||||
|
|
||||||
**问题**: 如果 Gateway 在云端 Ubuntu,Mac 作为节点,OpenClaw 能否"像人一样"使用 Mac(如写代码、做 PPT)?
|
|
||||||
|
|
||||||
**结论**: **可以做到,但更像是"远程脚本专家",而非"人类操作员"。**
|
|
||||||
|
|
||||||
由于网络延迟和架构限制,AI 的操作模式与人类不同:
|
|
||||||
|
|
||||||
### 场景 A: 修改代码 (Code Modification)
|
|
||||||
* **人类模式 (不推荐)**: 打开 VS Code GUI,点击光标,输入字符。
|
|
||||||
* *AI 限制*: 视觉识别+模拟点击在云端到本地的高延迟下体验极差。
|
|
||||||
* **OpenClaw 模式 (推荐)**:
|
|
||||||
1. **Git流**: AI 在云端修改代码 -> Push 到仓库 -> 指挥 Mac 节点 `git pull` -> 指挥 Mac 运行 `npm run dev` 预览。
|
|
||||||
2. **命令行流**: AI 通过 `system.run` 发送 `sed`/`echo` 命令直接修改 Mac 文件(风险较高,容易改错)。
|
|
||||||
|
|
||||||
### 场景 B: 制作 PPT (Presentation)
|
|
||||||
* **人类模式 (不推荐)**: 打开 Keynote,鼠标拖拽文本框,调整字体。
|
|
||||||
* *AI 限制*: 无法精准控制鼠标拖拽,且无法实时"看"到效果。
|
|
||||||
* **OpenClaw 模式 (推荐 - AppleScript)**:
|
|
||||||
* Mac 节点支持执行 AppleScript。AI 可以编写脚本直接控制 Keynote/PowerPoint。
|
|
||||||
* *指令示例*: `tell application "Keynote" to make new slide with title "AI Report"`。
|
|
||||||
* *优势*: 速度极快,精确,无需视觉反馈。
|
|
||||||
|
|
||||||
### 关键限制与建议
|
|
||||||
1. **网络延迟**: 云端控制本地 UI 会有显著延迟。如果需要频繁的"看屏幕-点击"交互,建议将 Gateway 部署在本地。
|
|
||||||
2. **文件访问**: Gateway 默认无法直接读取 Mac 文件系统(除非通过 `cat` 命令回传)。建议通过 Git 或云同步文件夹共享工作区。
|
|
||||||
3. **最佳实践**: 让 AI 充当**指挥官**(在云端思考、规划、写脚本),让 Mac 充当**执行器**(运行脚本、渲染 UI、跑测试),而不是让 AI 模拟鼠标键盘。
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,42 +0,0 @@
|
||||||
Q: 现在我们需要基于openclaw做二开,提供企业级的办公助手。希望这个应用能够提供端云协同的能力,我们可以脑暴下端云协同指的什么能力。 我的理解: 端云协同的一个理解:我可以在工作电脑上使用这个助手,通过助手工作台,比如让他帮我写代码、给他提数据分析的需求,这些需求会被分配到云端执行,执行过程中可能会需要询问用户,当前遇到的问题,让用户补充一些信息之类的。 用户也可以看到当前执行的任务,任务执行过程等。 用户离开电脑,可以通过手机办公软件,如钉钉,通过对话的方式继续协同助手办公
|
|
||||||
|
|
||||||
关于端云协同,你有什么好的想法吗
|
|
||||||
|
|
||||||
A:
|
|
||||||
基于 OpenClaw 进行企业级二次开发是一个非常务实的路径。你提到的“任务云端执行、移动端交互协同”已经抓住了端云协同的核心——“算力在云,交互在端,状态同步”。
|
|
||||||
|
|
||||||
为了让这个“办公助手”真正达到企业级深度,我们可以从环境感知、隐私边界、异步执行这几个维度进一步拓展“端云协同”的内涵:
|
|
||||||
|
|
||||||
1. 环境与上下文的“无缝接力” (Seamless Context Handoff)
|
|
||||||
端云协同不应只是消息同步,更应该是**“执行环境”**的同步。
|
|
||||||
|
|
||||||
端侧快照: 当你在电脑上给助手发指令(如“分析这段代码的 Bug”)时,端侧插件可以自动抓取当前的 IDE 状态、打开的文件列表、甚至是报错日志,打包发送到云端。
|
|
||||||
|
|
||||||
移动端“数字孪生”: 当你切换到手机钉钉时,助手不仅是回复文字,它能通过一张“状态卡片”让你看到云端容器里正在运行的终端界面或代码 Demo。你可以在手机上点一下“继续运行”或“终止”。
|
|
||||||
|
|
||||||
2. 隐私与安全的“离岸闸口” (Privacy Gatekeeper)
|
|
||||||
企业级应用中,数据安全是第一生命线。端侧可以作为一个**“脱敏层”**。
|
|
||||||
|
|
||||||
本地脱敏: 在需求发送到云端大模型之前,端侧助手先在本地扫描:是否含有代码秘钥(API Key)、客户手机号、内部服务器 IP。
|
|
||||||
|
|
||||||
端侧替换/云端还原: 端侧将敏感信息替换为占位符,云端执行完后再传回端侧,由端侧助手在本地环境将信息“填补”回来。这样核心数据从未真正离开过用户的内网环境。
|
|
||||||
|
|
||||||
3. 异步任务的“长跑协同” (Asynchronous Long-running Tasks)
|
|
||||||
很多企业需求(如:生成一份 50 页的行业调研报告、跑一个大型自动化测试)不是秒回的。
|
|
||||||
|
|
||||||
云端常驻 Agent: 云端助手是一个长驻进程。你在下班路上通过手机问一句:“下午交代的那个数据清洗任务跑完没?”
|
|
||||||
|
|
||||||
主动推送到端: 任务执行到关键节点(如:发现数据源格式错误),云端助手主动通过钉钉向你发送一条“紧急弹窗”,询问:“我发现有 10% 的数据缺失,是跳过还是取平均值填充?”
|
|
||||||
|
|
||||||
4. 资源调度协同 (Resource Orchestration)
|
|
||||||
根据任务的性质动态分配“在哪里干活”: | 任务类型 | 执行位置 | 协同逻辑 | | :--- | :--- | :--- | | UI 操作/本地文件改写 | 端侧 (Local) | 云端下达指令(类似 MCP 协议),端侧助手操控本地 Playwright 或文件系统执行。 | | 大规模计算/复杂逻辑推理 | 云端 (Cloud) | 端侧提供上下文,云端利用高性能算力进行深度思考。 | | 即时通讯/审批提醒 | 移动端 (Mobile) | 作为指令入口和结果反馈的轻量化界面。 |
|
|
||||||
|
|
||||||
5. 多模态的交互分工
|
|
||||||
端侧(PC): 强于“输入”,适合处理复杂的代码编写、多文档对比、窗口拖拽。
|
|
||||||
|
|
||||||
移动端: 强于“反馈”,利用语音、拍照、快捷卡片。
|
|
||||||
|
|
||||||
例子: 你在云端跑了一个数据分析,助手在手机上给你推了一张可视化图表,你对着手机说:“把那两个异常点剔除掉重新跑一下”,这比在手机上敲代码快得多。
|
|
||||||
|
|
||||||
核心价值总结
|
|
||||||
这种端云协同的本质是:把 PC 端作为“作业车间”,把云端作为“超级大脑”,把移动端作为“遥控器”和“对讲机”。
|
|
||||||
14618
openclaw_sandbox.md
14618
openclaw_sandbox.md
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue