mo
feat: enterprise capability expansion — app control, browser control, background execution
fce80d1 Download packages/protocol/src/index.mjs from aiagentmona/mona-agent: direct link, hf CLI and curl.
- Browser
- Download file 3.28 kB
-
https://huggingface.co/aiagentmona/mona-agent/resolve/main/packages/protocol/src/index.mjs
- Command line
-
hf download hf://aiagentmona/mona-agent/packages/protocol/src/index.mjs
-
curl -L -o index.mjs https://huggingface.co/aiagentmona/mona-agent/resolve/main/packages/protocol/src/index.mjs
3.28 kB
| /** | |
| * mona.expert wire contract — the single source of truth for the device gateway | |
| * WebSocket protocol. The daemon (apps/desktop) and the gateway (apps/gateway) | |
| * implement this; `test/protocol.test.mjs` fails if they drift apart. | |
| * | |
| * Every frame is JSON: { v: 1, type, ts, agentId?, data }. `v` is the protocol | |
| * version — always sent, always checked. Unknown versions are rejected at | |
| * connect time, so an old device can never silently speak a broken dialect. | |
| */ | |
| export const PROTOCOL_VERSION = 1; | |
| /** Close codes the gateway uses to permanently reject a connection. */ | |
| export const CLOSE_CODES = Object.freeze({ | |
| UNAUTHORIZED: 4001, // bad / expired key — device must re-login | |
| REVOKED: 4003, // device or agent revoked — terminal | |
| PROTOCOL: 4002, // unsupported protocol version | |
| }); | |
| export const isTerminalClose = (code) => | |
| code === CLOSE_CODES.UNAUTHORIZED || code === CLOSE_CODES.REVOKED || code === CLOSE_CODES.PROTOCOL; | |
| /** Message types. `device ` frames are sent by the daemon; `gateway ` by the control plane. */ | |
| export const TYPES = Object.freeze({ | |
| /* handshake (device ) */ | |
| HELLO: 'hello', | |
| HELLO_OK: 'hello.ok', // gateway { heartbeatIntervalMs, permissions } | |
| /* registration */ | |
| REGISTER: 'register', // device device fingerprint / name | |
| /* commands (gateway device gateway) */ | |
| COMMAND: 'command', // gateway { id, tool, args, timeoutMs, requestId } | |
| COMMAND_RESULT: 'command.result', // device { id, ok, output, error, durationMs } | |
| COMMAND_ERROR: 'command.error', // device { id, error } | |
| /* reasoning stream (device reports steps the engine asked it to take) */ | |
| AGENT_STEP: 'agent.step', // device { runId, name, detail } | |
| AGENT_TOKEN: 'agent.token', // device { runId, text } (kept for TUI streaming) | |
| AGENT_RESULT: 'agent.result', // device { runId, ok, text, usage, error } | |
| /* telemetry (device ) */ | |
| DEVICE_METRICS: 'device.metrics', | |
| /* liveness */ | |
| PING: 'ping', | |
| PONG: 'pong', | |
| /* dashboard chat RPC (legacy docker-platform compatibility) */ | |
| CHAT: 'chat', | |
| CHAT_RESPONSE: 'chat:response', | |
| LLM_REQUEST: 'llm:request', | |
| LLM_RESPONSE: 'llm:response', | |
| LLM_ERROR: 'llm:error', | |
| }); | |
| /** Device capability shape announced in `hello`. The gateway turns this into agent_permissions. */ | |
| export function capabilities({ tools = [], shell = null }) { | |
| return { tools: [...tools], shell: shell ? { ...shell } : null }; | |
| } | |
| /** Build a versioned envelope. */ | |
| export function envelope(type, data = {}, { agentId = null, ts = Date.now() } = {}) { | |
| const msg = { v: PROTOCOL_VERSION, type, ts }; | |
| if (agentId != null) msg.agentId = agentId; | |
| msg.data = data; | |
| return msg; | |
| } | |
| /** Parse a raw frame; returns null for non-protocol JSON (keep-alives, garbage). */ | |
| export function parseFrame(raw) { | |
| try { | |
| const msg = JSON.parse(raw.toString()); | |
| if (typeof msg !== 'object' || msg === null || typeof msg.type !== 'string') return null; | |
| return msg; | |
| } catch { | |
| return null; | |
| } | |
| } | |
| /** Validate the protocol version on a parsed frame. */ | |
| export function checkVersion(msg) { | |
| if (msg.v === undefined) return false; // v1 tolerated as "implicit v1"? No: v is mandatory. | |
| return Number(msg.v) === PROTOCOL_VERSION; | |
| } | |