TypeBox
기준일: 2026-07-26
공식 기준: TypeBox
TypeBox 문서는 OpenClaw 공식 문서(concepts/typebox)를 한국어로 정리한 가이드입니다. TypeBox schemas as the single source of truth for the gateway protocol 명령·설정 키·코드 예시는 공식 문서를 그대로 보존하며, 해석과 절차 안내는 한국어로 제공합니다. 최종 동작은 설치된 CLI 버전과 공식 원문을 확인하세요.
핵심 요약
TypeBox schemas as the single source of truth for the gateway protocol
한국어 가이드 범위: concepts/typebox 경로의 설정·명령·제약·예시를 학습용으로 재구성합니다.
문서 구성
공식 문서의 주요 섹션은 다음과 같습니다.
- Mental model (30 seconds)
- Where the schemas live
- Current pipeline
- How the schemas are used at runtime
- Example frames
- Minimal client (Node.js)
- Worked example: add a method end-to-end
- Swift codegen behavior
- Versioning and compatibility
- Schema patterns and conventions
- Live schema JSON
- When you change schemas
- 관련 문서
상세 내용
본문
TypeBox is a TypeScript-first schema library. OpenClaw uses it to define the Gateway WebSocket protocol (handshake, request/response, server events). Those schemas drive runtime validation (AJV), JSON Schema export, and Swift codegen for the macOS app. One source of truth; everything else is generated.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
Mental model (30 seconds)
Every Gateway WS message is one of three frames:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Request:
{ type: "req", id, method, params } - Response:
{ type: "res", id, ok, payload | error } - Event:
{ type: "event", event, payload, seq?, stateVersion? }
| Category | Examples | Notes |
|---|---|---|
| Core | connect, health, status |
connect must be first |
| Messaging | send, agent, agent.wait, system-event, logs.tail |
side-effecting methods need idempotencyKey |
| Chat | chat.history, chat.send, chat.abort |
WebChat uses these |
| Sessions | sessions.list, sessions.patch, sessions.delete |
session admin |
| Automation | wake, cron.list, cron.run, cron.runs |
wake and cron control |
| Nodes | node.list, node.invoke, node.pair.* |
Gateway WS plus node actions |
| Events | tick, presence, agent, chat, health, shutdown |
server push |
Client Gateway
|---- req:connect -------->|
|<---- res:hello-ok --------|
|<---- event:tick ----------|
|---- req:health ---------->|
|<---- res:health ----------|
Where the schemas live
주요 항목:
- Source barrel:
packages/gateway-protocol/src/schema.tsre-exports domain modules underpackages/gateway-protocol/src/schema/*.ts(frames.tsfor the top-level envelopes and handshake,agent.ts,sessions.ts,cron.ts, etc. per feature area).protocol-schemas.tsis the centralProtocolSchemasregistry mapping schema names to their TypeBox definitions. - Runtime validators (AJV):
packages/gateway-protocol/src/index.ts - Advertised feature/discovery registry:
src/gateway/server-methods-list.ts - Server handshake and method dispatch:
src/gateway/server.impl.ts - Node client:
src/gateway/client.ts - Generated JSON Schema:
dist/protocol.schema.json(build output, not committed) - Generated Swift models:
apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift
Current pipeline
주요 항목:
pnpm protocol:genwrites JSON Schema (draft-07) todist/protocol.schema.json.pnpm protocol:gen:swiftgenerates the Swift gateway models.pnpm protocol:checkruns both generators and verifies the Swift output is committed (the JSON Schema output is a gitignored build artifact).
How the schemas are used at runtime
주요 항목:
- Server side: every inbound frame is validated with AJV. The handshake only accepts a
connectrequest whose params matchConnectParams. - Client side: the JS client validates event and response frames before using them.
- Feature discovery: the Gateway sends a conservative
features.methodsandfeatures.eventslist inhello-ok, fromlistGatewayMethods()andGATEWAY_EVENTS. - That discovery list is not a generated dump of every callable helper in
coreGatewayHandlers; some helper RPCs are implemented insrc/gateway/server-methods/*.tswithout being enumerated in the advertised feature list.
Example frames
{
"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 } }
Minimal client (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();
}
});
Worked example: add a method end-to-end
Example: add a new system.echo request that returns { ok: true, text }.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
{ text: NonEmptyString },
{ additionalProperties: false },
);
{ ok: Type.Boolean(), text: NonEmptyString },
{ additionalProperties: false },
);
SystemEchoParams: SystemEchoParamsSchema,
SystemEchoResult: SystemEchoResultSchema,
Swift codegen behavior
Unknown frame types are preserved as raw payloads for forward compatibility.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- a
GatewayFrameenum withreq,res,event, andunknowncases - strongly typed payload structs/enums
ErrorCodevalues,GATEWAY_PROTOCOL_VERSION, andGATEWAY_MIN_PROTOCOL_VERSION
Versioning and compatibility
주요 항목:
PROTOCOL_VERSIONlives inpackages/gateway-protocol/src/version.ts(current value:4).- Clients send
minProtocolandmaxProtocol; the server rejects ranges that do not include its current protocol. - The Swift models keep unknown frame types to avoid breaking older clients.
Schema patterns and conventions
주요 항목:
- Most objects use
additionalProperties: falsefor strict payloads. NonEmptyString(Type.String({ minLength: 1 })) is the default for IDs and method/event names.- The top-level
GatewayFrameuses a discriminator ontype. - Methods with side effects usually require an
idempotencyKeyin params (example:send,poll,agent,chat.send). agentaccepts optionalinternalEventsfor runtime-generated orchestration context (for example subagent/cron task completion handoff); treat this as internal API surface.
Live schema JSON
Generated JSON Schema is a build artifact, not committed to the repo. The published raw file is typically available at:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
When you change schemas
- Update the TypeBox schemas in the owning
packages/gateway-protocol/src/schema/*.tsmodule and register them inprotocol-schemas.ts. 2. Register the method/event insrc/gateway/server-methods-list.ts. 3. Updatesrc/gateway/method-scopes.tswhen the new RPC needs operator or node scope classification. 4. Runpnpm protocol:check. 5. Commit the regenerated Swift models.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
관련 문서
주요 항목:
- Rich output protocol
- RPC adapters
실습 체크리스트
- 공식 문서와 로컬 버전을 대조합니다:
https://docs.openclaw.ai/concepts/typebox - 관련 CLI는
openclaw --help및 하위 명령--help로 옵션을 확인합니다. - 설정 변경 시
openclaw config/openclaw doctor로 유효성을 검사합니다. - Gateway·채널·플러그인 변경 후에는 필요 시 Gateway를 재시작합니다.
자주 쓰는 명령·설정 예시
Client Gateway
|---- req:connect -------->|
|<---- res:hello-ok --------|
|<---- event:tick ----------|
|---- req:health ---------->|
|<---- res:health ----------|
{
"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 }
관련 링크
- 공식 원문: concepts/typebox
- OpenClaw 문서 홈
이 가이드는 공식 문서를 한국어 학습용으로 재구성한 것입니다. 옵션 기본값·플래그 이름은 설치 버전에 따라 달라질 수 있습니다.