Concept internals
TypeBox
TypeBox là thư viện lược đồ ưu tiên TypeScript. Chúng tôi dùng nó để định nghĩa giao thức Gateway WebSocket (bắt tay, yêu cầu/phản hồi, sự kiện máy chủ). Các lược đồ đó điều khiển xác thực runtime, xuất JSON Schema, và sinh mã Swift cho ứng dụng macOS. Một nguồn chân lý duy nhất; mọi thứ khác đều được tạo sinh.
Nếu bạn muốn ngữ cảnh giao thức cấp cao hơn, hãy bắt đầu với kiến trúc Gateway.
Mô hình tư duy (30 giây)
Mỗi thông điệp Gateway WS là một trong ba khung:
- Yêu cầu:
{ type: "req", id, method, params } - Phản hồi:
{ type: "res", id, ok, payload | error } - Sự kiện:
{ type: "event", event, payload, seq?, stateVersion? }
Khung đầu tiên phải là một yêu cầu connect. Sau đó, client có thể gọi
các phương thức (ví dụ health, send, chat.send) và đăng ký nhận sự kiện (ví dụ
presence, tick, agent).
Luồng kết nối (tối thiểu):
Client Gateway
|---- req:connect -------->|
|<---- res:hello-ok --------|
|<---- event:tick ----------|
|---- req:health ---------->|
|<---- res:health ----------|
Các phương thức + sự kiện phổ biến:
| Danh mục | Ví dụ | Ghi chú |
|---|---|---|
| Cốt lõi | connect, health, status |
connect phải là đầu tiên |
| Nhắn tin | send, agent, agent.wait, system-event, logs.tail |
tác dụng phụ cần idempotencyKey |
| Trò chuyện | chat.history, chat.send, chat.abort |
WebChat dùng các phương thức này |
| Phiên | sessions.list, sessions.patch, sessions.delete |
quản trị phiên |
| Tự động hóa | wake, cron.list, cron.run, cron.runs |
điều khiển wake + cron |
| Node | node.list, node.invoke, node.pair.* |
Gateway WS + hành động node |
| Sự kiện | tick, presence, agent, chat, health, shutdown |
máy chủ đẩy |
Kho discovery được quảng bá có thẩm quyền nằm trong
src/gateway/server-methods-list.ts (listGatewayMethods, GATEWAY_EVENTS).
Nơi đặt các lược đồ
- Nguồn:
src/gateway/protocol/schema.ts - Bộ xác thực runtime (AJV):
src/gateway/protocol/index.ts - Registry tính năng/discovery được quảng bá:
src/gateway/server-methods-list.ts - Bắt tay máy chủ + điều phối phương thức:
src/gateway/server.impl.ts - Client Node:
src/gateway/client.ts - JSON Schema được tạo sinh:
dist/protocol.schema.json - Model Swift được tạo sinh:
apps/macos/Sources/OpenClawProtocol/GatewayModels.swift
Pipeline hiện tại
pnpm protocol:gen- ghi JSON Schema (draft-07) vào
dist/protocol.schema.json
- ghi JSON Schema (draft-07) vào
pnpm protocol:gen:swift- tạo các model Gateway Swift
pnpm protocol:check- chạy cả hai bộ tạo sinh và xác minh đầu ra đã được commit
Cách các lược đồ được dùng ở runtime
- Phía máy chủ: mọi khung đến đều được xác thực bằng AJV. Bắt tay chỉ
chấp nhận một yêu cầu
connectcó params khớp vớiConnectParams. - Phía client: client JS xác thực các khung sự kiện và phản hồi trước khi sử dụng chúng.
- Discovery tính năng: Gateway gửi danh sách
features.methodsvàfeatures.eventsthận trọng tronghello-oktừlistGatewayMethods()vàGATEWAY_EVENTS. - Danh sách discovery đó không phải là bản đổ được tạo sinh của mọi helper có thể gọi trong
coreGatewayHandlers; một số RPC helper được triển khai trongsrc/gateway/server-methods/*.tsmà không được liệt kê trong danh sách tính năng được quảng bá.
Khung ví dụ
Connect (thông điệp đầu tiên):
{
"type": "req",
"id": "c1",
"method": "connect",
"params": {
"minProtocol": 3,
"maxProtocol": 3,
"client": {
"id": "openclaw-macos",
"displayName": "macos",
"version": "1.0.0",
"platform": "macos 15.1",
"mode": "ui",
"instanceId": "A1B2"
}
}
}
Phản hồi hello-ok:
{
"type": "res",
"id": "c1",
"ok": true,
"payload": {
"type": "hello-ok",
"protocol": 3,
"server": { "version": "dev", "connId": "ws-1" },
"features": { "methods": ["health"], "events": ["tick"] },
"snapshot": {
"presence": [],
"health": {},
"stateVersion": { "presence": 0, "health": 0 },
"uptimeMs": 0
},
"policy": { "maxPayload": 1048576, "maxBufferedBytes": 1048576, "tickIntervalMs": 30000 }
}
}
Yêu cầu + phản hồi:
{ "type": "req", "id": "r1", "method": "health" }
{ "type": "res", "id": "r1", "ok": true, "payload": { "ok": true } }
Sự kiện:
{ "type": "event", "event": "tick", "payload": { "ts": 1730000000 }, "seq": 12 }
Client tối thiểu (Node.js)
Luồng hữu ích nhỏ nhất: kết nối + health.
const ws = new WebSocket("ws://127.0.0.1:18789");
ws.on("open", () => {
ws.send(
JSON.stringify({
type: "req",
id: "c1",
method: "connect",
params: {
minProtocol: 3,
maxProtocol: 3,
client: {
id: "cli",
displayName: "example",
version: "dev",
platform: "node",
mode: "cli",
},
},
}),
);
});
ws.on("message", (data) => {
const msg = JSON.parse(String(data));
if (msg.type === "res" && msg.id === "c1" && msg.ok) {
ws.send(JSON.stringify({ type: "req", id: "h1", method: "health" }));
}
if (msg.type === "res" && msg.id === "h1") {
console.log("health:", msg.payload);
ws.close();
}
});
Ví dụ đầy đủ: thêm một phương thức từ đầu đến cuối
Ví dụ: thêm một yêu cầu system.echo mới trả về { ok: true, text }.
- Lược đồ (nguồn chân lý)
Thêm vào src/gateway/protocol/schema.ts:
export const SystemEchoParamsSchema = Type.Object(
{ text: NonEmptyString },
{ additionalProperties: false },
);
export const SystemEchoResultSchema = Type.Object(
{ ok: Type.Boolean(), text: NonEmptyString },
{ additionalProperties: false },
);
Thêm cả hai vào ProtocolSchemas và xuất các kiểu:
SystemEchoParams: SystemEchoParamsSchema,
SystemEchoResult: SystemEchoResultSchema,
export type SystemEchoParams = Static<typeof SystemEchoParamsSchema>;
export type SystemEchoResult = Static<typeof SystemEchoResultSchema>;
- Xác thực
Trong src/gateway/protocol/index.ts, xuất một bộ xác thực AJV:
export const validateSystemEchoParams = ajv.compile<SystemEchoParams>(SystemEchoParamsSchema);
- Hành vi máy chủ
Thêm một handler trong src/gateway/server-methods/system.ts:
export const systemHandlers: GatewayRequestHandlers = {
"system.echo": ({ params, respond }) => {
const text = String(params.text ?? "");
respond(true, { ok: true, text });
},
};
Đăng ký nó trong src/gateway/server-methods.ts (đã hợp nhất systemHandlers),
rồi thêm "system.echo" vào đầu vào listGatewayMethods trong
src/gateway/server-methods-list.ts.
Nếu phương thức có thể được gọi bởi client operator hoặc node, cũng phân loại nó trong
src/gateway/method-scopes.ts để thực thi scope và quảng bá tính năng hello-ok
luôn đồng bộ.
- Tạo sinh lại
pnpm protocol:check
- Kiểm thử + tài liệu
Thêm một kiểm thử máy chủ trong src/gateway/server.*.test.ts và ghi chú phương thức này trong tài liệu.
Hành vi sinh mã Swift
Bộ tạo Swift phát ra:
- enum
GatewayFramevới các casereq,res,event, vàunknown - Các struct/enum payload được định kiểu mạnh
- Giá trị
ErrorCodevàGATEWAY_PROTOCOL_VERSION
Các kiểu khung không xác định được giữ nguyên dưới dạng payload thô để tương thích tiến.
Phiên bản + tương thích
PROTOCOL_VERSIONnằm trongsrc/gateway/protocol/schema.ts.- Client gửi
minProtocol+maxProtocol; máy chủ từ chối khi không khớp. - Các model Swift giữ lại kiểu khung không xác định để tránh làm hỏng client cũ hơn.
Mẫu và quy ước lược đồ
- Hầu hết đối tượng dùng
additionalProperties: falsecho payload nghiêm ngặt. NonEmptyStringlà mặc định cho ID và tên phương thức/sự kiện.GatewayFramecấp cao nhất dùng một discriminator trêntype.- Các phương thức có tác dụng phụ thường yêu cầu
idempotencyKeytrong params (ví dụ:send,poll,agent,chat.send). agentchấp nhậninternalEventstùy chọn cho ngữ cảnh điều phối được tạo ở runtime (ví dụ bàn giao hoàn tất tác vụ subagent/cron); xem đây là bề mặt API nội bộ.
JSON lược đồ live
JSON Schema được tạo sinh nằm trong repo tại dist/protocol.schema.json. Tệp thô
được phát hành thường có tại:
Khi bạn thay đổi lược đồ
- Cập nhật các lược đồ TypeBox.
- Đăng ký phương thức/sự kiện trong
src/gateway/server-methods-list.ts. - Cập nhật
src/gateway/method-scopes.tskhi RPC mới cần phân loại scope operator hoặc node. - Chạy
pnpm protocol:check. - Commit lược đồ được tạo sinh lại + các model Swift.