Skip to content

Latest commit

 

History

History
211 lines (164 loc) · 9.36 KB

File metadata and controls

211 lines (164 loc) · 9.36 KB

Protocol Sync Guide

This document explains how to keep openclaw-go in sync when the OpenClaw gateway protocol changes.

Source of Truth

All protocol types are canonically defined in TypeScript using @sinclair/typebox:

TypeScript Schema Go Target
src/gateway/protocol/schema/frames.ts protocol/frames.go
src/gateway/protocol/schema/agent.ts protocol/agent.go
src/gateway/protocol/schema/agents-models-skills.ts protocol/agents.go, protocol/skills.go
src/gateway/protocol/schema/sessions.ts protocol/sessions.go
src/gateway/protocol/schema/config.ts protocol/config.go
src/gateway/protocol/schema/cron.ts protocol/cron.go
src/gateway/protocol/schema/channels.ts protocol/channels.go
src/gateway/protocol/schema/nodes.ts protocol/nodes.go
src/gateway/protocol/schema/devices.ts protocol/devices.go
src/gateway/protocol/schema/exec-approvals.ts protocol/exec_approvals.go
src/gateway/protocol/schema/logs-chat.ts protocol/chat.go
src/gateway/protocol/schema/push.ts protocol/push.go
src/gateway/protocol/schema/snapshot.ts protocol/sessions.go (Presence/Snapshot types)
src/gateway/protocol/schema/wizard.ts protocol/config.go (Wizard types)
src/gateway/protocol/schema/error-codes.ts protocol/constants.go
src/gateway/protocol/schema/protocol-schemas.ts client/methods_*.go (method names)

File Layout

protocol/ — Protocol types & constants

Each file maps to one domain area of the TypeScript schema:

File Domain
frames.go Wire frame types (RequestFrame, ResponseFrame, EventFrame)
agent.go Single-agent request/response types
agents.go Multi-agent listing and management types
skills.go Skill/model listing types
sessions.go Session management + Presence/Snapshot types
config.go Gateway configuration types
cron.go Cron job types
channels.go Channel and Talk types
nodes.go Node management types
devices.go Device types
exec_approvals.go Exec approval types
chat.go Chat history and send types
push.go Push test types
constants.go Protocol version, error codes, frame type constants
models_test.go JSON round-trip tests for all types

client/ — WebSocket client

API methods are split by domain to mirror the protocol files:

File Domain
client.go GatewayClient, connection, read loop
request.go Request / RequestDecoded / RequestVoid helpers
subscribe.go Event channel subscription
methods_agent.go SendAgent, AbortAgent
methods_agents.go Agent listing and management
methods_channels.go Channel operations
methods_chat.go Chat history, send, abort
methods_config.go Config get/patch
methods_cron.go Cron list/run
methods_devices.go Device operations
methods_exec.go Exec approval operations
methods_misc.go Miscellaneous (e.g. Status)
methods_nodes.go Node operations
methods_sessions.go Session list/patch/delete
client_test.go Integration tests

Update Procedures

Adding a New Model (struct)

  1. Locate the new Type.Object(...) definition in the relevant schema/*.ts file.
  2. Translate each field to a Go struct field:
    • Type.String()string
    • Type.Integer()int
    • Type.Boolean()bool
    • Type.Optional(X) → pointer *X + json:",omitempty"
    • Type.Array(X)[]X
    • Type.Record(...) / Type.Unknown()json.RawMessage or map[string]interface{}
    • camelCase JSON key → json:"camelCaseKey"
  3. Add the struct to the matching domain file in protocol/ (see table above).
  4. Add a JSON round-trip test in protocol/models_test.go.

Example: Adding a new FooParams struct:

// TypeScript schema (source)
export const FooParamsSchema = Type.Object({
  sessionKey: NonEmptyString,
  mode: Type.Optional(NonEmptyString),
  limit: Type.Optional(Type.Integer({ minimum: 1 })),
});
// Go translation (e.g. protocol/sessions.go)
type FooParams struct {
    SessionKey string  `json:"sessionKey"`
    Mode       *string `json:"mode,omitempty"`
    Limit      *int    `json:"limit,omitempty"`
}

Adding a New API Method

  1. Find the new method key in src/gateway/protocol/schema/protocol-schemas.ts.
  2. Identify its params and response schema.
  3. Add the typed method to the matching domain file in client/methods_<domain>.go:
func (c *GatewayClient) Foo(ctx context.Context, params protocol.FooParams) (*protocol.FooResult, error) {
    var result protocol.FooResult
    if err := c.RequestDecoded(ctx, "foo.method", params, &result); err != nil {
        return nil, err
    }
    return &result, nil
}
  1. Add a matching test in client/client_test.go.

Detecting What Changed

Use git diff on the schema directory to see what changed since the last SDK update:

# From the repo root — see all schema changes since the last protocol tag
git diff <last-tag>..HEAD -- src/gateway/protocol/schema/

Or watch for additions/removals in types.ts (it exports every public type):

git diff <last-tag>..HEAD -- src/gateway/protocol/schema/types.ts

Automation Roadmap

For a higher level of automation, consider the following tools:

Option A: quicktype (recommended for MVP)

quicktype can generate Go structs from JSON Schema. The typebox schemas can be exported to JSON Schema via:

# In src/gateway/protocol — add a script:
npx ts-node export-schemas.ts > schemas.json
quicktype --lang go --src-lang schema schemas.json -o ../openclaw-go/protocol/generated.go

Option B: Custom Go code generator

Write a small TypeScript/Node script (scripts/gen-go-protocol.ts) that:

  1. Imports all *Schema values from schema/*.ts.
  2. Uses @sinclair/typebox + JSON.stringify to emit the JSON Schema.
  3. Maps each field type to a Go type string.
  4. Writes one file per domain under protocol/.

This gives the tightest control over the output format, including per-file domain grouping and struct ordering.

Option C: CI diff check

Add a GitHub Actions step that:

  1. Computes a SHA of all src/gateway/protocol/schema/*.ts files.
  2. Compares to a .protocol-hash file committed in openclaw-go/.
  3. Fails the check and prints a diff if hashes diverge.
# .github/workflows/protocol-sync.yml
- name: Check protocol sync
  run: |
    NEW_HASH=$(sha256sum src/gateway/protocol/schema/*.ts | sha256sum | awk '{print $1}')
    STORED=$(cat openclaw-go/.protocol-hash)
    if [ "$NEW_HASH" != "$STORED" ]; then
      echo "Protocol schema changed — run sync and update openclaw-go/.protocol-hash"
      git diff HEAD -- src/gateway/protocol/schema/
      exit 1
    fi

Quick Checklist for Each Protocol Update

  • git diff the relevant schema/*.ts files
  • Add/update Go structs in the matching protocol/<domain>.go file
  • Add/update methods in the matching client/methods_<domain>.go file
  • Add/update tests (protocol/models_test.go, client/client_test.go)
  • Run go build ./... && go test ./...
  • Update the .protocol-hash file (if using Option C)