Concept internals
TypeBox
TypeBox یک کتابخانهٔ طرحواره با رویکرد TypeScript-first است. ما از آن برای تعریف پروتکل Gateway WebSocket (دستدهی، درخواست/پاسخ، رویدادهای سرور) استفاده میکنیم. این طرحوارهها اعتبارسنجی زمان اجرا، خروجی JSON Schema و تولید کد Swift را برای برنامهٔ macOS هدایت میکنند. یک منبع حقیقت؛ بقیهٔ موارد تولید میشوند.
اگر زمینهٔ سطحبالاتر پروتکل را میخواهید، از معماری Gateway شروع کنید.
مدل ذهنی (۳۰ ثانیه)
هر پیام Gateway WS یکی از سه فریم است:
- درخواست:
{ type: "req", id, method, params } - پاسخ:
{ type: "res", id, ok, payload | error } - رویداد:
{ type: "event", event, payload, seq?, stateVersion? }
اولین فریم باید یک درخواست connect باشد. پس از آن، کلاینتها میتوانند
متدها را فراخوانی کنند (مثلاً health، send، chat.send) و در رویدادها مشترک شوند (مثلاً
presence، tick، agent).
جریان اتصال (حداقلی):
Client Gateway
|---- req:connect -------->|
|<---- res:hello-ok --------|
|<---- event:tick ----------|
|---- req:health ---------->|
|<---- res:health ----------|
متدها + رویدادهای رایج:
| دستهبندی | نمونهها | یادداشتها |
|---|---|---|
| هسته | connect, health, status |
connect باید اول باشد |
| پیامرسانی | send, agent, agent.wait, system-event, logs.tail |
اثرات جانبی به idempotencyKey نیاز دارند |
| چت | chat.history, chat.send, chat.abort |
WebChat از اینها استفاده میکند |
| نشستها | sessions.list, sessions.patch, sessions.delete |
مدیریت نشست |
| خودکارسازی | wake, cron.list, cron.run, cron.runs |
بیدارسازی + کنترل cron |
| Nodeها | node.list, node.invoke, node.pair.* |
Gateway WS + کنشهای node |
| رویدادها | tick, presence, agent, chat, health, shutdown |
پوش سرور |
موجودی معتبر کشف تبلیغشده در
src/gateway/server-methods-list.ts (listGatewayMethods, GATEWAY_EVENTS) قرار دارد.
محل قرارگیری طرحوارهها
- منبع:
src/gateway/protocol/schema.ts - اعتبارسنجهای زمان اجرا (AJV):
src/gateway/protocol/index.ts - رجیستری قابلیت/کشف تبلیغشده:
src/gateway/server-methods-list.ts - دستدهی سرور + توزیع متد:
src/gateway/server.impl.ts - کلاینت Node:
src/gateway/client.ts - JSON Schema تولیدشده:
dist/protocol.schema.json - مدلهای Swift تولیدشده:
apps/macos/Sources/OpenClawProtocol/GatewayModels.swift
پایپلاین فعلی
pnpm protocol:gen- JSON Schema (draft-07) را در
dist/protocol.schema.jsonمینویسد
- JSON Schema (draft-07) را در
pnpm protocol:gen:swift- مدلهای Gateway برای Swift را تولید میکند
pnpm protocol:check- هر دو تولیدکننده را اجرا میکند و بررسی میکند خروجی commit شده باشد
نحوهٔ استفاده از طرحوارهها در زمان اجرا
- سمت سرور: هر فریم ورودی با AJV اعتبارسنجی میشود. دستدهی فقط
درخواست
connectای را میپذیرد که params آن باConnectParamsمطابقت داشته باشد. - سمت کلاینت: کلاینت JS فریمهای رویداد و پاسخ را پیش از استفاده اعتبارسنجی میکند.
- کشف قابلیت: Gateway فهرست محافظهکارانهٔ
features.methodsوfeatures.eventsرا درhello-okازlistGatewayMethods()وGATEWAY_EVENTSمیفرستد. - آن فهرست کشف، dump تولیدشده از هر helper قابل فراخوانی در
coreGatewayHandlersنیست؛ برخی helper RPCها درsrc/gateway/server-methods/*.tsپیادهسازی شدهاند بیآنکه در فهرست قابلیت تبلیغشده شمارش شوند.
نمونه فریمها
Connect (اولین پیام):
{
"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"
}
}
}
پاسخ 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 }
}
}
درخواست + پاسخ:
{ "type": "req", "id": "r1", "method": "health" }
{ "type": "res", "id": "r1", "ok": true, "payload": { "ok": true } }
رویداد:
{ "type": "event", "event": "tick", "payload": { "ts": 1730000000 }, "seq": 12 }
کلاینت حداقلی (Node.js)
کوچکترین جریان مفید: اتصال + 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();
}
});
مثال کامل: افزودن یک متد از ابتدا تا انتها
مثال: افزودن درخواست جدید system.echo که { ok: true, text } را برمیگرداند.
- طرحواره (منبع حقیقت)
به 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 },
);
هر دو را به ProtocolSchemas اضافه کنید و typeها را export کنید:
SystemEchoParams: SystemEchoParamsSchema,
SystemEchoResult: SystemEchoResultSchema,
export type SystemEchoParams = Static<typeof SystemEchoParamsSchema>;
export type SystemEchoResult = Static<typeof SystemEchoResultSchema>;
- اعتبارسنجی
در src/gateway/protocol/index.ts، یک اعتبارسنج AJV export کنید:
export const validateSystemEchoParams = ajv.compile<SystemEchoParams>(SystemEchoParamsSchema);
- رفتار سرور
یک handler در src/gateway/server-methods/system.ts اضافه کنید:
export const systemHandlers: GatewayRequestHandlers = {
"system.echo": ({ params, respond }) => {
const text = String(params.text ?? "");
respond(true, { ok: true, text });
},
};
آن را در src/gateway/server-methods.ts ثبت کنید (از قبل systemHandlers را merge میکند)،
سپس "system.echo" را به ورودی listGatewayMethods در
src/gateway/server-methods-list.ts اضافه کنید.
اگر متد توسط کلاینتهای operator یا node قابل فراخوانی است، آن را در
src/gateway/method-scopes.ts نیز طبقهبندی کنید تا اعمال scope و تبلیغ قابلیت
hello-ok همراستا بمانند.
- تولید دوباره
pnpm protocol:check
- تستها + مستندات
یک تست سرور در src/gateway/server.*.test.ts اضافه کنید و متد را در مستندات ذکر کنید.
رفتار تولید کد Swift
تولیدکنندهٔ Swift این موارد را منتشر میکند:
- enum به نام
GatewayFrameبا caseهایreq،res،eventوunknown - structها/enumهای payload با type قوی
- مقادیر
ErrorCodeوGATEWAY_PROTOCOL_VERSION
نوعهای ناشناختهٔ فریم برای سازگاری رو به جلو بهصورت payload خام حفظ میشوند.
نسخهبندی + سازگاری
PROTOCOL_VERSIONدرsrc/gateway/protocol/schema.tsقرار دارد.- کلاینتها
minProtocol+maxProtocolرا میفرستند؛ سرور ناسازگاریها را رد میکند. - مدلهای Swift نوعهای ناشناختهٔ فریم را نگه میدارند تا کلاینتهای قدیمیتر نشکنند.
الگوها و قراردادهای طرحواره
- بیشتر objectها برای payloadهای سختگیرانه از
additionalProperties: falseاستفاده میکنند. NonEmptyStringمقدار پیشفرض برای IDها و نامهای متد/رویداد است.GatewayFrameسطح بالا از یک discriminator رویtypeاستفاده میکند.- متدهایی با اثرات جانبی معمولاً به یک
idempotencyKeyدر params نیاز دارند (مثال:send،poll،agent،chat.send). agentمقدار اختیاریinternalEventsرا برای زمینهٔ ارکستراسیون تولیدشده در زمان اجرا میپذیرد (برای مثال تحویل تکمیل وظیفهٔ subagent/cron)؛ این را بهعنوان سطح API داخلی در نظر بگیرید.
JSON زندهٔ طرحواره
JSON Schema تولیدشده در repo در dist/protocol.schema.json قرار دارد. فایل خام
منتشرشده معمولاً در این آدرس در دسترس است:
وقتی طرحوارهها را تغییر میدهید
- طرحوارههای TypeBox را بهروزرسانی کنید.
- متد/رویداد را در
src/gateway/server-methods-list.tsثبت کنید. - وقتی RPC جدید به طبقهبندی scope مربوط به operator یا
node نیاز دارد،
src/gateway/method-scopes.tsرا بهروزرسانی کنید. pnpm protocol:checkرا اجرا کنید.- طرحوارهٔ تولیدشده + مدلهای Swift را commit کنید.