Concept internals
TypeBox
TypeBox एक TypeScript-प्रथम स्कीमा लाइब्रेरी है। OpenClaw इसका उपयोग Gateway WebSocket प्रोटोकॉल (हैंडशेक, अनुरोध/प्रतिक्रिया, सर्वर इवेंट) को परिभाषित करने के लिए करता है। ये स्कीमा macOS ऐप के लिए रनटाइम सत्यापन (AJV), JSON Schema निर्यात, और Swift कोड जनरेशन संचालित करते हैं। सत्य का एक स्रोत; बाकी सब कुछ जनरेट किया जाता है।
उच्च-स्तरीय प्रोटोकॉल संदर्भ के लिए, Gateway आर्किटेक्चर से शुरू करें।
मानसिक मॉडल (30 सेकंड)
प्रत्येक 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)।
कनेक्शन प्रवाह (न्यूनतम):
क्लाइंट Gateway |---- अनुरोध:कनेक्ट ------->| |<---- प्रतिक्रिया:हेलो-ओके --| |<---- इवेंट:टिक ------------| |---- अनुरोध:हेल्थ --------->| |<---- प्रतिक्रिया:हेल्थ -----|सामान्य मेथड और इवेंट:
| श्रेणी | उदाहरण | टिप्पणियाँ |
|---|---|---|
| कोर | 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) में रहती है।
स्कीमा कहाँ रहते हैं
- स्रोत बैरल:
packages/gateway-protocol/src/schema.ts,packages/gateway-protocol/src/schema/*.tsके अंतर्गत डोमेन मॉड्यूल को पुनः निर्यात करता है (शीर्ष-स्तरीय एनवेलप और हैंडशेक के लिएframes.ts, तथा प्रत्येक फ़ीचर क्षेत्र के लिएagent.ts,sessions.ts,cron.ts, आदि)।protocol-schemas.tsकेंद्रीयProtocolSchemasरजिस्ट्री है, जो स्कीमा नामों को उनकी TypeBox परिभाषाओं से मैप करती है। - रनटाइम वैलिडेटर (AJV):
packages/gateway-protocol/src/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/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift
वर्तमान पाइपलाइन
pnpm protocol:gen, JSON Schema (draft-07) कोdist/protocol.schema.jsonमें लिखता है।pnpm protocol:gen:swift, Swift Gateway मॉडल जनरेट करता है।pnpm protocol:check, दोनों जनरेटर चलाता है और सत्यापित करता है कि Swift आउटपुट कमिट किया गया है (JSON Schema आउटपुट एक gitignored बिल्ड आर्टिफ़ैक्ट है)।
रनटाइम पर स्कीमा का उपयोग कैसे होता है
- सर्वर पक्ष: प्रत्येक इनबाउंड फ़्रेम को AJV से सत्यापित किया जाता है। हैंडशेक केवल ऐसा
connectअनुरोध स्वीकार करता है, जिसके पैरामीटरConnectParamsसे मेल खाते हों। - क्लाइंट पक्ष: JS क्लाइंट इवेंट और प्रतिक्रिया फ़्रेमों का उपयोग करने से पहले उन्हें सत्यापित करता है।
- फ़ीचर डिस्कवरी: Gateway,
listGatewayMethods()औरGATEWAY_EVENTSसे एक सीमितfeatures.methodsऔरfeatures.eventsसूचीhello-okमें भेजता है। - यह डिस्कवरी सूची
coreGatewayHandlersमें मौजूद प्रत्येक कॉल किए जा सकने वाले हेल्पर का जनरेट किया हुआ डंप नहीं है; कुछ हेल्पर RPC, विज्ञापित फ़ीचर सूची में शामिल हुए बिनाsrc/gateway/server-methods/*.tsमें कार्यान्वित होते हैं।
उदाहरण फ़्रेम
कनेक्ट (पहला संदेश):
{ "type": "req", "id": "c1", "method": "connect", "params": { "minProtocol": 3, "maxProtocol": 4, "client": { "id": "openclaw-macos", "displayName": "macos", "version": "1.0.0", "platform": "macos 15.1", "mode": "ui", "instanceId": "A1B2" } }}हेलो-ओके प्रतिक्रिया:
{ "type": "res", "id": "c1", "ok": true, "payload": { "type": "hello-ok", "protocol": 4, "server": { "version": "dev", "connId": "ws-1" }, "features": { "methods": ["health"], "events": ["tick"] }, "snapshot": { "presence": [], "health": {}, "stateVersion": { "presence": 0, "health": 0 }, "uptimeMs": 0 }, "auth": { "role": "operator", "scopes": ["operator.read"] }, "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)
सबसे छोटा उपयोगी प्रवाह: कनेक्ट + हेल्थ।
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: 4, maxProtocol: 4, 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 } लौटाता है।
- स्कीमा (सत्य का स्रोत)
packages/gateway-protocol/src/schema/system.ts (या सबसे निकट मेल खाने वाले फ़ीचर मॉड्यूल) में जोड़ें:
export const SystemEchoParamsSchema = Type.Object( { text: NonEmptyString }, { additionalProperties: false },); export const SystemEchoResultSchema = Type.Object( { ok: Type.Boolean(), text: NonEmptyString }, { additionalProperties: false },);दोनों को packages/gateway-protocol/src/schema/protocol-schemas.ts में आयात करें, उन्हें ProtocolSchemas रजिस्ट्री में जोड़ें, और व्युत्पन्न प्रकार निर्यात करें:
SystemEchoParams: SystemEchoParamsSchema, SystemEchoResult: SystemEchoResultSchema,export type SystemEchoParams = Static<typeof SystemEchoParamsSchema>;export type SystemEchoResult = Static<typeof SystemEchoResultSchema>;- सत्यापन
packages/gateway-protocol/src/index.ts में, एक AJV वैलिडेटर निर्यात करें:
export const validateSystemEchoParams = ajv.compile<SystemEchoParams>(SystemEchoParamsSchema);- सर्वर व्यवहार
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 को मर्ज करता है), फिर src/gateway/server-methods-list.ts में listGatewayMethods इनपुट में "system.echo" जोड़ें।
यदि मेथड को ऑपरेटर या Node क्लाइंट कॉल कर सकते हैं, तो इसे src/gateway/method-scopes.ts में भी वर्गीकृत करें, ताकि स्कोप प्रवर्तन और hello-ok फ़ीचर विज्ञापन समन्वित रहें।
- पुनः जनरेट करें
pnpm protocol:check- परीक्षण और दस्तावेज़
src/gateway/server.*.test.ts में एक सर्वर परीक्षण जोड़ें और दस्तावेज़ों में मेथड का उल्लेख करें।
Swift कोड जनरेशन का व्यवहार
Swift जनरेटर ये उत्सर्जित करता है:
req,res,event, औरunknownकेस वाला एकGatewayFrameenum- दृढ़ता से टाइप किए गए पेलोड स्ट्रक्ट/enum
ErrorCodeमान,GATEWAY_PROTOCOL_VERSION, औरGATEWAY_MIN_PROTOCOL_VERSION
फ़ॉरवर्ड संगतता के लिए अज्ञात फ़्रेम प्रकारों को रॉ पेलोड के रूप में संरक्षित रखा जाता है।
संस्करण निर्धारण और संगतता
PROTOCOL_VERSION,packages/gateway-protocol/src/version.tsमें रहता है (वर्तमान मान:4)।- क्लाइंट
minProtocolऔरmaxProtocolभेजते हैं; सर्वर उन सीमाओं को अस्वीकार करता है जिनमें उसका वर्तमान प्रोटोकॉल शामिल नहीं है। - पुराने क्लाइंट को टूटने से बचाने के लिए Swift मॉडल अज्ञात फ़्रेम प्रकारों को बनाए रखते हैं।
स्कीमा पैटर्न और परंपराएँ
- अधिकांश ऑब्जेक्ट सख्त पेलोड के लिए
additionalProperties: falseका उपयोग करते हैं। NonEmptyString(Type.String({ minLength: 1 })), ID और मेथड/इवेंट नामों के लिए डिफ़ॉल्ट है।- शीर्ष-स्तरीय
GatewayFrame,typeपर एक डिस्क्रिमिनेटर का उपयोग करता है। - दुष्प्रभाव वाले मेथड को आम तौर पर पैरामीटर में एक
idempotencyKeyकी आवश्यकता होती है (उदाहरण:send,poll,agent,chat.send)। agent, रनटाइम द्वारा जनरेट किए गए ऑर्केस्ट्रेशन संदर्भ के लिए वैकल्पिकinternalEventsस्वीकार करता है (उदाहरण के लिए, सबएजेंट/Cron कार्य पूर्णता हैंडऑफ़); इसे आंतरिक API सतह मानें।
लाइव स्कीमा JSON
जनरेट किया गया JSON Schema एक बिल्ड आर्टिफ़ैक्ट है, इसे रेपो में कमिट नहीं किया जाता। प्रकाशित रॉ फ़ाइल सामान्यतः यहाँ उपलब्ध होती है:
स्कीमा बदलते समय
- स्वामी
packages/gateway-protocol/src/schema/*.tsमॉड्यूल में TypeBox स्कीमा अपडेट करें और उन्हेंprotocol-schemas.tsमें पंजीकृत करें। - मेथड/इवेंट को
src/gateway/server-methods-list.tsमें पंजीकृत करें। - जब नए RPC को ऑपरेटर या Node स्कोप वर्गीकरण की आवश्यकता हो, तो
src/gateway/method-scopes.tsअपडेट करें। pnpm protocol:checkचलाएँ।- पुनः जनरेट किए गए Swift मॉडल कमिट करें।