@agentchatme/openclaw 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config-schema.ts","../src/errors.ts","../src/setup-client.ts","../src/setup-wizard.ts","../src/channel.ts","../src/channel.setup.ts","../src/configured-state.ts","../src/log.ts","../src/metrics.ts","../src/state-machine.ts","../src/ws-client.ts","../src/inbound.ts","../src/retry.ts","../src/version.ts","../src/outbound.ts","../src/runtime.ts"],"names":["z","MIN_API_KEY_LENGTH","readAccountRaw","buildChannelConfigSchema","defineChannelPluginEntry","defineSetupPluginEntry","pino","NodeWebSocket","jitter"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Zod schema for AgentChat channel config.\r\n *\r\n * Source of truth: this file. The JSON Schema inlined in `openclaw.plugin.json`\r\n * MUST stay in sync (P1 adds a build step that emits it via zod-to-json-schema).\r\n *\r\n * `.strict()` rejects unknown keys — a common source of \"the config silently\r\n * ignored my setting\" bugs.\r\n */\r\n\r\nimport { z } from 'zod'\r\n\r\nexport const reconnectConfigSchema = z\r\n .object({\r\n initialBackoffMs: z.number().int().min(100).max(10_000).default(1_000),\r\n maxBackoffMs: z.number().int().min(1_000).max(300_000).default(30_000),\r\n jitterRatio: z.number().min(0).max(1).default(0.2),\r\n })\r\n .strict()\r\n\r\nexport const pingConfigSchema = z\r\n .object({\r\n intervalMs: z.number().int().min(5_000).max(120_000).default(30_000),\r\n timeoutMs: z.number().int().min(1_000).max(30_000).default(10_000),\r\n })\r\n .strict()\r\n\r\nexport const outboundConfigSchema = z\r\n .object({\r\n maxInFlight: z.number().int().min(1).max(10_000).default(256),\r\n sendTimeoutMs: z.number().int().min(1_000).max(60_000).default(15_000),\r\n })\r\n .strict()\r\n\r\nexport const observabilityConfigSchema = z\r\n .object({\r\n logLevel: z.enum(['trace', 'debug', 'info', 'warn', 'error']).default('info'),\r\n redactKeys: z\r\n .array(z.string())\r\n .default(['apiKey', 'authorization', 'cookie', 'set-cookie']),\r\n })\r\n .strict()\r\n\r\nexport const agentHandleSchema = z\r\n .string()\r\n .regex(/^[a-z0-9_.-]{3,32}$/, 'handle must be 3-32 chars, lowercase alphanumeric + . _ -')\r\n\r\nexport const agentchatChannelConfigSchema = z\r\n .object({\r\n apiBase: z.string().url().default('https://api.agentchat.me'),\r\n apiKey: z.string().min(20, 'apiKey looks too short for an AgentChat API key'),\r\n agentHandle: agentHandleSchema.optional(),\r\n // `.prefault({})` — Zod 4 idiom: when the key is missing from input, parse\r\n // `{}` through the inner schema so its own per-field defaults kick in.\r\n // Using `.default({})` here fails in Zod 4 because the output type's fields\r\n // are non-optional once the inner schema has defaults.\r\n reconnect: reconnectConfigSchema.prefault({}),\r\n ping: pingConfigSchema.prefault({}),\r\n outbound: outboundConfigSchema.prefault({}),\r\n observability: observabilityConfigSchema.prefault({}),\r\n })\r\n .strict()\r\n\r\nexport type AgentchatChannelConfig = z.infer<typeof agentchatChannelConfigSchema>\r\nexport type AgentchatChannelConfigInput = z.input<typeof agentchatChannelConfigSchema>\r\n\r\n/**\r\n * Parse + validate config at plugin startup.\r\n *\r\n * Fails fast on invalid config rather than waiting until the first request.\r\n * The `AgentChatChannelError` wrapper makes validation failures classifiable\r\n * by the gateway's error handler (`terminal-user` — operator fix required).\r\n */\r\nexport function parseChannelConfig(input: unknown): AgentchatChannelConfig {\r\n return agentchatChannelConfigSchema.parse(input)\r\n}\r\n","/**\r\n * Error taxonomy for the AgentChat channel plugin.\r\n *\r\n * Every error that crosses a pipeline boundary (inbound receive, outbound\r\n * send, config validation, transport) must be classifiable as one of:\r\n *\r\n * terminal-auth — 401/403. API key invalid or revoked. Do not retry.\r\n * Move state machine to AUTH_FAIL.\r\n * terminal-user — 400/422 (client-side validation). Bug in this plugin\r\n * or malformed outbound. Log at error level, drop,\r\n * do not retry.\r\n * retry-rate — 429. Retry after `retryAfterMs` (or jittered\r\n * exponential backoff if header absent).\r\n * retry-transient — 5xx, ECONNRESET, ETIMEDOUT, network flap.\r\n * Exponential backoff + jitter. Open circuit after N.\r\n * idempotent-replay — 409 on POST /v1/messages with duplicate\r\n * client_msg_id. Treat as success, log at info.\r\n * validation — Zod schema failed on inbound payload. Likely a\r\n * server change. Log at error, drop, alert.\r\n */\r\n\r\nexport type ErrorClass =\r\n | 'terminal-auth'\r\n | 'terminal-user'\r\n | 'retry-rate'\r\n | 'retry-transient'\r\n | 'idempotent-replay'\r\n | 'validation'\r\n\r\nexport class AgentChatChannelError extends Error {\r\n readonly class_: ErrorClass\r\n readonly retryAfterMs: number | undefined\r\n readonly statusCode: number | undefined\r\n\r\n constructor(\r\n class_: ErrorClass,\r\n message: string,\r\n options: {\r\n cause?: unknown\r\n retryAfterMs?: number\r\n statusCode?: number\r\n } = {},\r\n ) {\r\n super(message, { cause: options.cause })\r\n this.name = 'AgentChatChannelError'\r\n this.class_ = class_\r\n this.retryAfterMs = options.retryAfterMs\r\n this.statusCode = options.statusCode\r\n }\r\n}\r\n\r\n/** Classify an HTTP status code from the AgentChat REST API. */\r\nexport function classifyHttpStatus(status: number, retryAfterHeader?: string | null): ErrorClass {\r\n if (status === 401 || status === 403) return 'terminal-auth'\r\n if (status === 409) return 'idempotent-replay'\r\n if (status === 429) return 'retry-rate'\r\n if (status >= 500 && status <= 599) return 'retry-transient'\r\n if (status >= 400 && status <= 499) return 'terminal-user'\r\n return 'retry-transient' // unexpected — prefer retry over silent drop\r\n}\r\n\r\n/** Parse a `Retry-After` header to milliseconds. Accepts seconds or HTTP-date. */\r\nexport function parseRetryAfter(header: string | null | undefined, nowMs: number): number | undefined {\r\n if (!header) return undefined\r\n const seconds = Number(header)\r\n if (Number.isFinite(seconds) && seconds >= 0) return Math.floor(seconds * 1000)\r\n const when = Date.parse(header)\r\n if (Number.isFinite(when)) return Math.max(0, when - nowMs)\r\n return undefined\r\n}\r\n\r\n/** Classify a low-level transport error (from `ws` or `fetch`). */\r\nexport function classifyNetworkError(err: unknown): ErrorClass {\r\n if (!err || typeof err !== 'object') return 'retry-transient'\r\n const code = (err as { code?: unknown }).code\r\n if (typeof code === 'string') {\r\n if (code === 'ECONNRESET' || code === 'ETIMEDOUT' || code === 'ECONNREFUSED') {\r\n return 'retry-transient'\r\n }\r\n if (code === 'ENOTFOUND' || code === 'EAI_AGAIN') return 'retry-transient'\r\n }\r\n return 'retry-transient'\r\n}\r\n\r\n/** True iff the error class should trigger a retry. */\r\nexport function isRetryable(class_: ErrorClass): boolean {\r\n return class_ === 'retry-rate' || class_ === 'retry-transient'\r\n}\r\n\r\n/** True iff the error class is terminal (no retry, operator action needed). */\r\nexport function isTerminal(class_: ErrorClass): boolean {\r\n return class_ === 'terminal-auth' || class_ === 'terminal-user' || class_ === 'validation'\r\n}\r\n","/**\r\n * Minimal HTTP client used by the setup plugin (P7) to:\r\n * - verify an API key is live before finalizing setup (`validateApiKey`)\r\n * - drive the email-OTP self-registration flow for agents without a key yet\r\n * (`registerAgentStart` → `registerAgentVerify`)\r\n *\r\n * Why this lives separately from `outbound.ts`:\r\n * - `outbound.ts` is the hot-path message sender. It wants retries, a circuit\r\n * breaker, metrics, and a long-lived `fetch`. Setup is one-shot, low-rate,\r\n * user-interactive — a 200ms validation call doesn't need any of that.\r\n * - Setup runs before the runtime exists; coupling it to `OutboundAdapter`\r\n * (which expects a parsed `AgentchatChannelConfig`) would force an odd\r\n * partial-config path during registration.\r\n *\r\n * The server endpoints this module targets are stable AgentChat REST calls:\r\n * - `GET /v1/agents/me` → 200 OK when the key authenticates\r\n * - `POST /v1/register` → 200 with `{ pending_id }`\r\n * - `POST /v1/register/verify` → 201 with `{ agent, api_key }` on success\r\n *\r\n * All methods return strongly-typed result unions — setup UIs can `switch` on\r\n * the discriminant without guessing at HTTP status codes.\r\n */\r\n\r\nimport { AgentChatChannelError } from './errors.js'\r\n\r\nconst DEFAULT_API_BASE = 'https://api.agentchat.me'\r\nconst DEFAULT_TIMEOUT_MS = 10_000\r\n\r\n/** Subset of the AgentChat agent row the setup surface needs to show the user. */\r\nexport interface AgentchatAgentIdentity {\r\n readonly handle: string\r\n readonly displayName: string | null\r\n readonly email: string\r\n readonly createdAt: string\r\n}\r\n\r\nexport type ValidateApiKeyResult =\r\n | { readonly ok: true; readonly agent: AgentchatAgentIdentity }\r\n | {\r\n readonly ok: false\r\n /** High-level reason code the UI can map to a localized message. */\r\n readonly reason:\r\n | 'unauthorized'\r\n | 'forbidden'\r\n | 'deleted'\r\n | 'network-error'\r\n | 'unreachable'\r\n | 'server-error'\r\n | 'unexpected-shape'\r\n readonly message: string\r\n readonly status?: number\r\n }\r\n\r\nexport interface ValidateApiKeyOptions {\r\n readonly apiBase?: string\r\n readonly fetch?: typeof fetch\r\n readonly timeoutMs?: number\r\n}\r\n\r\n/**\r\n * Probe the API key against `GET /v1/agents/me`. Returns a discriminated\r\n * result — never throws on HTTP or network errors. The caller decides how\r\n * to surface each failure mode to the user.\r\n */\r\nexport async function validateApiKey(\r\n apiKey: string,\r\n opts: ValidateApiKeyOptions = {},\r\n): Promise<ValidateApiKeyResult> {\r\n if (!apiKey || typeof apiKey !== 'string') {\r\n return { ok: false, reason: 'unauthorized', message: 'API key is empty' }\r\n }\r\n const base = (opts.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, '')\r\n const url = `${base}/v1/agents/me`\r\n const controller = new AbortController()\r\n const fetchImpl = opts.fetch ?? fetch\r\n const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\r\n const timer = setTimeout(() => controller.abort(), timeoutMs)\r\n\r\n let res: Response\r\n try {\r\n res = await fetchImpl(url, {\r\n method: 'GET',\r\n headers: {\r\n Authorization: `Bearer ${apiKey}`,\r\n Accept: 'application/json',\r\n },\r\n signal: controller.signal,\r\n })\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : String(err)\r\n const unreachable =\r\n err instanceof Error &&\r\n (err.name === 'AbortError' || /ECONN|ETIMEDOUT|ENOTFOUND|EAI_AGAIN/i.test(message))\r\n return {\r\n ok: false,\r\n reason: unreachable ? 'unreachable' : 'network-error',\r\n message: `agentchat: GET /v1/agents/me failed: ${message}`,\r\n }\r\n } finally {\r\n clearTimeout(timer)\r\n }\r\n\r\n if (res.status === 401) {\r\n return { ok: false, reason: 'unauthorized', status: 401, message: 'API key is invalid or revoked' }\r\n }\r\n if (res.status === 403) {\r\n return { ok: false, reason: 'forbidden', status: 403, message: 'API key lacks permission to read /agents/me' }\r\n }\r\n if (res.status === 410) {\r\n return { ok: false, reason: 'deleted', status: 410, message: 'Agent account has been deleted' }\r\n }\r\n if (res.status >= 500) {\r\n return { ok: false, reason: 'server-error', status: res.status, message: `AgentChat API returned ${res.status}` }\r\n }\r\n if (!res.ok) {\r\n return {\r\n ok: false,\r\n reason: 'server-error',\r\n status: res.status,\r\n message: `AgentChat API returned ${res.status}`,\r\n }\r\n }\r\n\r\n const body = (await res.json().catch(() => null)) as {\r\n handle?: unknown\r\n display_name?: unknown\r\n email?: unknown\r\n email_masked?: unknown\r\n created_at?: unknown\r\n } | null\r\n // The live `GET /v1/agents/me` endpoint masks PII: it returns\r\n // `email_masked` (e.g. `a****@agentchat.local`), never the real `email`.\r\n // Accept either so tests that stub an unmasked body still pass, but the\r\n // caller should expect a masked value in production.\r\n const email =\r\n typeof body?.email === 'string'\r\n ? body.email\r\n : typeof body?.email_masked === 'string'\r\n ? body.email_masked\r\n : null\r\n if (!body || typeof body.handle !== 'string' || email === null || typeof body.created_at !== 'string') {\r\n return {\r\n ok: false,\r\n reason: 'unexpected-shape',\r\n status: res.status,\r\n message: 'AgentChat /agents/me returned an unrecognized shape',\r\n }\r\n }\r\n return {\r\n ok: true,\r\n agent: {\r\n handle: body.handle,\r\n displayName: typeof body.display_name === 'string' ? body.display_name : null,\r\n email,\r\n createdAt: body.created_at,\r\n },\r\n }\r\n}\r\n\r\n// ─── Self-registration (email + OTP) ───────────────────────────────────\r\n\r\nexport interface RegisterAgentStartInput {\r\n readonly email: string\r\n readonly handle: string\r\n readonly displayName?: string\r\n readonly description?: string\r\n}\r\n\r\nexport type RegisterStartResult =\r\n | { readonly ok: true; readonly pendingId: string }\r\n | {\r\n readonly ok: false\r\n readonly reason:\r\n | 'invalid-handle'\r\n | 'handle-taken'\r\n | 'email-taken'\r\n | 'email-is-owner'\r\n | 'email-exhausted'\r\n | 'rate-limited'\r\n | 'otp-failed'\r\n | 'network-error'\r\n | 'server-error'\r\n | 'validation'\r\n readonly message: string\r\n readonly status?: number\r\n readonly retryAfterSeconds?: number\r\n }\r\n\r\nexport interface RegisterAgentVerifyInput {\r\n readonly pendingId: string\r\n readonly code: string\r\n}\r\n\r\nexport type RegisterVerifyResult =\r\n | {\r\n readonly ok: true\r\n readonly apiKey: string\r\n readonly agent: AgentchatAgentIdentity\r\n }\r\n | {\r\n readonly ok: false\r\n readonly reason:\r\n | 'expired'\r\n | 'invalid-code'\r\n | 'rate-limited'\r\n | 'handle-taken'\r\n | 'email-taken'\r\n | 'email-is-owner'\r\n | 'network-error'\r\n | 'server-error'\r\n | 'unexpected-shape'\r\n | 'validation'\r\n readonly message: string\r\n readonly status?: number\r\n readonly retryAfterSeconds?: number\r\n }\r\n\r\nexport interface RegisterOptions {\r\n readonly apiBase?: string\r\n readonly fetch?: typeof fetch\r\n readonly timeoutMs?: number\r\n}\r\n\r\n/**\r\n * Kick off an email-OTP registration. Server caches the intent under a\r\n * `pending_id` for 10 minutes and emails a 6-digit code to `email`.\r\n */\r\nexport async function registerAgentStart(\r\n input: RegisterAgentStartInput,\r\n opts: RegisterOptions = {},\r\n): Promise<RegisterStartResult> {\r\n const res = await post('/v1/register', input, opts)\r\n if (res.kind === 'network') {\r\n return { ok: false, reason: 'network-error', message: res.message }\r\n }\r\n if (res.kind === 'timeout') {\r\n return { ok: false, reason: 'network-error', message: 'request timed out' }\r\n }\r\n\r\n const body = (res.body as { pending_id?: unknown; code?: unknown; message?: unknown }) ?? {}\r\n\r\n if (res.status === 200) {\r\n if (typeof body.pending_id !== 'string') {\r\n return {\r\n ok: false,\r\n reason: 'server-error',\r\n status: 200,\r\n message: 'AgentChat /register returned no pending_id',\r\n }\r\n }\r\n return { ok: true, pendingId: body.pending_id }\r\n }\r\n\r\n const code = typeof body.code === 'string' ? body.code : ''\r\n const message = typeof body.message === 'string' ? body.message : `status ${res.status}`\r\n\r\n if (res.status === 400 && code === 'INVALID_HANDLE') return { ok: false, reason: 'invalid-handle', message, status: 400 }\r\n if (res.status === 400 && code === 'VALIDATION_ERROR') return { ok: false, reason: 'validation', message, status: 400 }\r\n if (res.status === 409 && code === 'HANDLE_TAKEN') return { ok: false, reason: 'handle-taken', message, status: 409 }\r\n if (res.status === 409 && code === 'EMAIL_TAKEN') return { ok: false, reason: 'email-taken', message, status: 409 }\r\n if (res.status === 409 && code === 'EMAIL_IS_OWNER') return { ok: false, reason: 'email-is-owner', message, status: 409 }\r\n if (res.status === 409 && code === 'EMAIL_EXHAUSTED') return { ok: false, reason: 'email-exhausted', message, status: 409 }\r\n if (res.status === 429) {\r\n return {\r\n ok: false,\r\n reason: 'rate-limited',\r\n message,\r\n status: 429,\r\n retryAfterSeconds: res.retryAfterSeconds,\r\n }\r\n }\r\n if (res.status >= 500 || code === 'OTP_FAILED') return { ok: false, reason: 'otp-failed', message, status: res.status }\r\n return { ok: false, reason: 'server-error', status: res.status, message }\r\n}\r\n\r\n/** Verify the OTP the user received by email and mint the API key. */\r\nexport async function registerAgentVerify(\r\n input: RegisterAgentVerifyInput,\r\n opts: RegisterOptions = {},\r\n): Promise<RegisterVerifyResult> {\r\n const res = await post('/v1/register/verify', { pending_id: input.pendingId, code: input.code }, opts)\r\n if (res.kind === 'network') return { ok: false, reason: 'network-error', message: res.message }\r\n if (res.kind === 'timeout') return { ok: false, reason: 'network-error', message: 'request timed out' }\r\n\r\n const body = (res.body ?? {}) as {\r\n code?: unknown\r\n message?: unknown\r\n agent?: { handle?: unknown; display_name?: unknown; email?: unknown; created_at?: unknown }\r\n api_key?: unknown\r\n }\r\n\r\n if (res.status === 201) {\r\n const agent = body.agent\r\n if (\r\n typeof body.api_key !== 'string' ||\r\n !agent ||\r\n typeof agent.handle !== 'string' ||\r\n typeof agent.email !== 'string' ||\r\n typeof agent.created_at !== 'string'\r\n ) {\r\n return {\r\n ok: false,\r\n reason: 'unexpected-shape',\r\n status: 201,\r\n message: 'AgentChat /register/verify returned an unrecognized shape',\r\n }\r\n }\r\n return {\r\n ok: true,\r\n apiKey: body.api_key,\r\n agent: {\r\n handle: agent.handle,\r\n displayName: typeof agent.display_name === 'string' ? agent.display_name : null,\r\n email: agent.email,\r\n createdAt: agent.created_at,\r\n },\r\n }\r\n }\r\n\r\n const code = typeof body.code === 'string' ? body.code : ''\r\n const message = typeof body.message === 'string' ? body.message : `status ${res.status}`\r\n\r\n if (res.status === 400 && code === 'EXPIRED') return { ok: false, reason: 'expired', message, status: 400 }\r\n if (res.status === 400 && code === 'INVALID_CODE') return { ok: false, reason: 'invalid-code', message, status: 400 }\r\n if (res.status === 400 && code === 'VALIDATION_ERROR') return { ok: false, reason: 'validation', message, status: 400 }\r\n if (res.status === 409 && code === 'HANDLE_TAKEN') return { ok: false, reason: 'handle-taken', message, status: 409 }\r\n if (res.status === 409 && code === 'EMAIL_TAKEN') return { ok: false, reason: 'email-taken', message, status: 409 }\r\n if (res.status === 409 && code === 'EMAIL_IS_OWNER') return { ok: false, reason: 'email-is-owner', message, status: 409 }\r\n if (res.status === 429) {\r\n return { ok: false, reason: 'rate-limited', message, status: 429, retryAfterSeconds: res.retryAfterSeconds }\r\n }\r\n return { ok: false, reason: 'server-error', status: res.status, message }\r\n}\r\n\r\n// ─── Internals ─────────────────────────────────────────────────────────\r\n\r\ntype PostOutcome =\r\n | { kind: 'http'; status: number; body: unknown; retryAfterSeconds?: number }\r\n | { kind: 'network'; message: string }\r\n | { kind: 'timeout' }\r\n\r\nasync function post(path: string, body: unknown, opts: RegisterOptions): Promise<PostOutcome> {\r\n const base = (opts.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, '')\r\n const url = `${base}${path}`\r\n const controller = new AbortController()\r\n const fetchImpl = opts.fetch ?? fetch\r\n const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\r\n const timer = setTimeout(() => controller.abort(), timeoutMs)\r\n try {\r\n const res = await fetchImpl(url, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json', accept: 'application/json' },\r\n body: JSON.stringify(body),\r\n signal: controller.signal,\r\n })\r\n const parsed = await res.json().catch(() => null)\r\n const retryAfterHeader = res.headers.get('retry-after')\r\n const retryAfterSeconds = retryAfterHeader ? Number(retryAfterHeader) : undefined\r\n return {\r\n kind: 'http',\r\n status: res.status,\r\n body: parsed,\r\n retryAfterSeconds: Number.isFinite(retryAfterSeconds) ? retryAfterSeconds : undefined,\r\n }\r\n } catch (err) {\r\n if (err instanceof Error && err.name === 'AbortError') return { kind: 'timeout' }\r\n return { kind: 'network', message: err instanceof Error ? err.message : String(err) }\r\n } finally {\r\n clearTimeout(timer)\r\n }\r\n}\r\n\r\n/**\r\n * Throw-flavored wrapper used by callers that prefer exception control flow\r\n * (the setup plugin's `afterAccountConfigWritten` hook). Converts a failure\r\n * result into an `AgentChatChannelError` with an appropriate class.\r\n */\r\nexport async function assertApiKeyValid(\r\n apiKey: string,\r\n opts: ValidateApiKeyOptions = {},\r\n): Promise<AgentchatAgentIdentity> {\r\n const result = await validateApiKey(apiKey, opts)\r\n if (result.ok) return result.agent\r\n const class_ =\r\n result.reason === 'unauthorized' || result.reason === 'forbidden' || result.reason === 'deleted'\r\n ? 'terminal-auth'\r\n : result.reason === 'server-error'\r\n ? 'retry-transient'\r\n : 'retry-transient'\r\n throw new AgentChatChannelError(class_, `${result.message} [reason=${result.reason}]`, {\r\n statusCode: result.status,\r\n })\r\n}\r\n","/**\n * Interactive setup wizard for the AgentChat channel.\n *\n * Invoked by `openclaw channels add --channel agentchat`. Drives three branches:\n *\n * - edit — existing config → re-validate OR rotate OR change API base\n * - have-key — user pastes an existing ac_live_* key → /agents/me probe → write\n * - register — email + handle + description → /register + OTP → /register/verify\n *\n * All branches converge on `writeAccountPatch` which mutates\n * `channels.agentchat.<accountId>` in either flat or multi-account form.\n *\n * Every server-side failure mode surfaces as actionable copy — there are no\n * silent failures. The wizard only returns when the user has either finished\n * or explicitly chosen to abort.\n */\n\nimport type { ChannelSetupWizard } from 'openclaw/plugin-sdk/channel-setup'\nimport type { OpenClawConfig } from 'openclaw/plugin-sdk/channel-core'\n\nimport { AGENTCHAT_CHANNEL_ID, AGENTCHAT_DEFAULT_ACCOUNT_ID } from './channel.js'\nimport {\n registerAgentStart,\n registerAgentVerify,\n validateApiKey,\n type RegisterStartResult,\n type RegisterVerifyResult,\n} from './setup-client.js'\n\n// WizardPrompter is not exported by name from any public subpath; we borrow\n// it off the finalize parameter shape, same idiom first-party extensions use.\ntype WizardPrompter = Parameters<NonNullable<ChannelSetupWizard['finalize']>>[0]['prompter']\n\nconst HANDLE_PATTERN = /^[a-z0-9_.-]{3,32}$/\nconst MIN_API_KEY_LENGTH = 20\nconst OTP_ATTEMPTS = 3\n\ntype FlowKind = 'edit' | 'new'\n\n// ─── Config read / write helpers ────────────────────────────────────────\n\nfunction readSection(cfg: OpenClawConfig): Record<string, unknown> | undefined {\n const channels = (cfg as { channels?: Record<string, unknown> } | undefined)?.channels\n const sec = channels?.[AGENTCHAT_CHANNEL_ID]\n return sec && typeof sec === 'object' && !Array.isArray(sec)\n ? (sec as Record<string, unknown>)\n : undefined\n}\n\nfunction readAccountRaw(\n cfg: OpenClawConfig,\n accountId: string,\n): Record<string, unknown> | undefined {\n const sec = readSection(cfg)\n if (!sec) return undefined\n const accounts = (sec as { accounts?: Record<string, unknown> }).accounts\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const entry = (accounts as Record<string, unknown>)[accountId]\n if (entry && typeof entry === 'object') return entry as Record<string, unknown>\n }\n if (accountId === AGENTCHAT_DEFAULT_ACCOUNT_ID) {\n const { accounts: _accounts, ...rest } = sec as Record<string, unknown>\n void _accounts\n return rest\n }\n return undefined\n}\n\nfunction readAccountApiKey(cfg: OpenClawConfig, accountId: string): string | undefined {\n const raw = readAccountRaw(cfg, accountId)\n const value = raw?.apiKey\n return typeof value === 'string' && value.length >= MIN_API_KEY_LENGTH ? value : undefined\n}\n\nfunction readAccountApiBase(cfg: OpenClawConfig, accountId: string): string | undefined {\n const raw = readAccountRaw(cfg, accountId)\n const value = raw?.apiBase\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction writeAccountPatch(\n cfg: OpenClawConfig,\n accountId: string,\n patch: { apiKey?: string; apiBase?: string; agentHandle?: string },\n): OpenClawConfig {\n const channels = {\n ...((cfg as { channels?: Record<string, unknown> } | undefined)?.channels ?? {}),\n }\n const existing = channels[AGENTCHAT_CHANNEL_ID]\n const section =\n existing && typeof existing === 'object' && !Array.isArray(existing)\n ? { ...(existing as Record<string, unknown>) }\n : ({} as Record<string, unknown>)\n\n const clean: Record<string, unknown> = {}\n if (patch.apiKey !== undefined) clean.apiKey = patch.apiKey\n if (patch.apiBase !== undefined) clean.apiBase = patch.apiBase\n if (patch.agentHandle !== undefined) clean.agentHandle = patch.agentHandle\n\n const hasAccountsMap =\n typeof section.accounts === 'object' &&\n section.accounts !== null &&\n !Array.isArray(section.accounts)\n if (accountId === AGENTCHAT_DEFAULT_ACCOUNT_ID && !hasAccountsMap) {\n Object.assign(section, clean)\n } else {\n const accounts = {\n ...((section.accounts as Record<string, unknown> | undefined) ?? {}),\n }\n const prev =\n typeof accounts[accountId] === 'object' && accounts[accountId] !== null\n ? (accounts[accountId] as Record<string, unknown>)\n : {}\n accounts[accountId] = { ...prev, ...clean }\n section.accounts = accounts\n }\n\n channels[AGENTCHAT_CHANNEL_ID] = section\n return { ...cfg, channels } as OpenClawConfig\n}\n\nfunction isAccountConfigured(cfg: OpenClawConfig, accountId: string | undefined): boolean {\n return Boolean(readAccountApiKey(cfg, accountId ?? AGENTCHAT_DEFAULT_ACCOUNT_ID))\n}\n\n// ─── Prompt primitives ──────────────────────────────────────────────────\n\nasync function promptApiKey(prompter: WizardPrompter): Promise<string> {\n const value = await prompter.text({\n message: 'Paste your AgentChat API key',\n placeholder: 'ac_live_...',\n validate: (v) => {\n const trimmed = v.trim()\n if (!trimmed) return 'API key is required'\n if (trimmed.length < MIN_API_KEY_LENGTH)\n return `Looks too short (${trimmed.length} chars — expect ≥${MIN_API_KEY_LENGTH})`\n return undefined\n },\n })\n return value.trim()\n}\n\nasync function promptEmail(prompter: WizardPrompter): Promise<string> {\n const value = await prompter.text({\n message: 'Your email address (for OTP verification)',\n placeholder: 'you@example.com',\n validate: (v) => {\n const trimmed = v.trim()\n if (!trimmed) return 'Email is required'\n if (!/.+@.+\\..+/.test(trimmed)) return 'Not a valid email address'\n return undefined\n },\n })\n return value.trim()\n}\n\nasync function promptHandle(prompter: WizardPrompter, initial?: string): Promise<string> {\n const value = await prompter.text({\n message: 'Pick a handle for your agent',\n placeholder: 'alice',\n initialValue: initial,\n validate: (v) => {\n const trimmed = v.trim().toLowerCase()\n if (!trimmed) return 'Handle is required'\n if (!HANDLE_PATTERN.test(trimmed))\n return '3–32 chars; lowercase a-z / 0-9 / dot / underscore / dash'\n return undefined\n },\n })\n return value.trim().toLowerCase()\n}\n\nasync function promptOtp(prompter: WizardPrompter): Promise<string> {\n const value = await prompter.text({\n message: 'Enter the 6-digit code we emailed you',\n placeholder: '123456',\n validate: (v) => (/^\\d{6}$/.test(v.trim()) ? undefined : '6-digit numeric code required'),\n })\n return value.trim()\n}\n\nasync function promptOptionalText(\n prompter: WizardPrompter,\n message: string,\n placeholder: string,\n): Promise<string> {\n const value = await prompter.text({\n message,\n placeholder,\n validate: () => undefined,\n })\n return value.trim()\n}\n\n// ─── Failure-copy helpers ───────────────────────────────────────────────\n\nfunction describeRegisterStartFailure(r: Extract<RegisterStartResult, { ok: false }>): string {\n switch (r.reason) {\n case 'invalid-handle':\n return 'That handle is not valid. Use 3–32 chars, lowercase a-z / 0-9 / . _ -.'\n case 'handle-taken':\n return 'That handle is already taken. Pick another.'\n case 'email-taken':\n return 'That email already has an agent. Sign in with the existing key instead, or use a different email.'\n case 'email-is-owner':\n return 'That email is reserved. Use a different address.'\n case 'email-exhausted':\n return 'This email has hit the per-address agent limit. Use a different email or delete an old agent.'\n case 'rate-limited':\n return r.retryAfterSeconds\n ? `Too many attempts. Try again in ${r.retryAfterSeconds}s.`\n : 'Too many attempts. Try again in a few minutes.'\n case 'otp-failed':\n return 'Could not send the verification email. Check the address and retry.'\n case 'network-error':\n return `Network error: ${r.message}`\n case 'validation':\n return `Validation error: ${r.message}`\n case 'server-error':\n return `AgentChat API error (${r.status ?? '??'}): ${r.message}`\n }\n}\n\nfunction describeRegisterVerifyFailure(r: Extract<RegisterVerifyResult, { ok: false }>): string {\n switch (r.reason) {\n case 'expired':\n return \"That code has expired. We'll request a new one — restart registration.\"\n case 'invalid-code':\n return 'Wrong code. Check the email and try again.'\n case 'rate-limited':\n return r.retryAfterSeconds\n ? `Too many attempts. Wait ${r.retryAfterSeconds}s before retrying.`\n : 'Too many attempts. Try again in a few minutes.'\n case 'handle-taken':\n return 'Someone else just took that handle. Restart and pick another.'\n case 'email-taken':\n return 'That email was registered by someone else between these steps. Start over.'\n case 'email-is-owner':\n return 'That email is reserved.'\n case 'network-error':\n return `Network error: ${r.message}`\n case 'unexpected-shape':\n return `Server returned an unexpected response (${r.status ?? '??'}). Try again shortly.`\n case 'validation':\n return `Validation error: ${r.message}`\n case 'server-error':\n return `AgentChat API error (${r.status ?? '??'}): ${r.message}`\n }\n}\n\n// ─── Sub-flows ──────────────────────────────────────────────────────────\n\nasync function runHaveKeyFlow(\n cfg: OpenClawConfig,\n accountId: string,\n prompter: WizardPrompter,\n apiBase: string | undefined,\n): Promise<{ cfg: OpenClawConfig }> {\n const apiKey = await promptApiKey(prompter)\n const progress = prompter.progress('Validating key against AgentChat…')\n const result = await validateApiKey(apiKey, { apiBase })\n if (!result.ok) {\n progress.stop('Key rejected.')\n await prompter.note(\n [\n `AgentChat rejected the key (${result.reason}):`,\n ` ${result.message}`,\n '',\n result.reason === 'unauthorized' || result.reason === 'deleted'\n ? 'The key is invalid, revoked, or the agent was deleted. Grab a fresh key from agentchat.me/dashboard.'\n : result.reason === 'unreachable' || result.reason === 'network-error'\n ? 'Could not reach the API. Check your network, then run setup again.'\n : 'Try again, or pick the register flow.',\n ].join('\\n'),\n 'Validation failed',\n )\n return runNewAccountFlow(cfg, accountId, prompter, apiBase)\n }\n progress.stop(`Authenticated as @${result.agent.handle}.`)\n const next = writeAccountPatch(cfg, accountId, {\n apiKey,\n agentHandle: result.agent.handle,\n ...(apiBase ? { apiBase } : {}),\n })\n await prompter.note(\n [\n `Connected to AgentChat as @${result.agent.handle}.`,\n `Email: ${result.agent.email}`,\n result.agent.displayName ? `Display name: ${result.agent.displayName}` : undefined,\n ]\n .filter((v): v is string => Boolean(v))\n .join('\\n'),\n 'AgentChat configured',\n )\n return { cfg: next }\n}\n\nasync function runRegisterFlow(\n cfg: OpenClawConfig,\n accountId: string,\n prompter: WizardPrompter,\n apiBase: string | undefined,\n): Promise<{ cfg: OpenClawConfig }> {\n await prompter.note(\n [\n 'We will email a 6-digit code to verify ownership of this address.',\n 'The email is hashed server-side and used only for account recovery.',\n ].join('\\n'),\n 'New-agent registration',\n )\n const email = await promptEmail(prompter)\n const handle = await promptHandle(prompter)\n const displayName = await promptOptionalText(\n prompter,\n 'Display name (optional, press Enter to skip)',\n handle,\n )\n const description = await promptOptionalText(\n prompter,\n 'Short description of your agent (optional)',\n 'Research assistant that summarises papers',\n )\n\n const startProgress = prompter.progress('Requesting OTP…')\n const start = await registerAgentStart(\n {\n email,\n handle,\n displayName: displayName || undefined,\n description: description || undefined,\n },\n { apiBase },\n )\n if (!start.ok) {\n startProgress.stop('Registration could not start.')\n await prompter.note(describeRegisterStartFailure(start), 'Registration failed')\n const retry = await prompter.confirm({\n message:\n start.reason === 'handle-taken' || start.reason === 'invalid-handle'\n ? 'Try a different handle?'\n : 'Try again?',\n initialValue: true,\n })\n if (!retry) return { cfg }\n return runRegisterFlow(cfg, accountId, prompter, apiBase)\n }\n startProgress.stop(`OTP sent to ${email}.`)\n\n const pendingId = start.pendingId\n for (let attempt = 1; attempt <= OTP_ATTEMPTS; attempt += 1) {\n const code = await promptOtp(prompter)\n const verifyProgress = prompter.progress('Verifying code…')\n const verify = await registerAgentVerify({ pendingId, code }, { apiBase })\n if (verify.ok) {\n verifyProgress.stop(`Verified. Agent @${verify.agent.handle} created.`)\n const next = writeAccountPatch(cfg, accountId, {\n apiKey: verify.apiKey,\n agentHandle: verify.agent.handle,\n ...(apiBase ? { apiBase } : {}),\n })\n await prompter.note(\n [\n 'Your AgentChat API key has been written to config.',\n '',\n ` handle: @${verify.agent.handle}`,\n ` email: ${verify.agent.email}`,\n '',\n 'Keep the key safe — it authenticates sends as this agent.',\n 'You can rotate it any time from agentchat.me/dashboard.',\n ].join('\\n'),\n 'Registration complete',\n )\n return { cfg: next }\n }\n verifyProgress.stop(`Attempt ${attempt}/${OTP_ATTEMPTS} failed (${verify.reason}).`)\n await prompter.note(describeRegisterVerifyFailure(verify), 'Code rejected')\n if (verify.reason === 'expired') {\n return runRegisterFlow(cfg, accountId, prompter, apiBase)\n }\n if (verify.reason !== 'invalid-code') {\n const retry = await prompter.confirm({\n message: 'Start over with different details?',\n initialValue: true,\n })\n if (!retry) return { cfg }\n return runRegisterFlow(cfg, accountId, prompter, apiBase)\n }\n // invalid-code → loop and re-prompt\n }\n await prompter.note(\n 'Too many invalid codes. Restart setup to request a new one.',\n 'Registration aborted',\n )\n return { cfg }\n}\n\nasync function runEditFlow(\n cfg: OpenClawConfig,\n accountId: string,\n prompter: WizardPrompter,\n): Promise<{ cfg: OpenClawConfig }> {\n const currentKey = readAccountApiKey(cfg, accountId)\n const currentBase = readAccountApiBase(cfg, accountId)\n\n const choice = await prompter.select<'validate' | 'rotate' | 'change-base' | 'skip'>({\n message: 'AgentChat is already configured. What would you like to do?',\n options: [\n {\n value: 'validate',\n label: 'Re-validate the current key',\n hint: 'Hit /agents/me to confirm it still authenticates',\n },\n {\n value: 'rotate',\n label: 'Rotate to a new API key',\n hint: 'Paste a freshly generated key or register a new agent',\n },\n {\n value: 'change-base',\n label: 'Change API base URL',\n hint: 'Only for self-hosted AgentChat deployments',\n },\n { value: 'skip', label: 'Leave as is', hint: 'No changes' },\n ],\n initialValue: 'validate',\n })\n\n if (choice === 'skip') return { cfg }\n\n if (choice === 'validate') {\n if (!currentKey) {\n await prompter.note('No API key is currently set.', 'Nothing to validate')\n return runNewAccountFlow(cfg, accountId, prompter, currentBase)\n }\n const progress = prompter.progress('Probing /agents/me…')\n const result = await validateApiKey(currentKey, { apiBase: currentBase })\n if (result.ok) {\n progress.stop(`Still authenticated as @${result.agent.handle}.`)\n return { cfg }\n }\n progress.stop('Key no longer works.')\n await prompter.note(`${result.message} [reason=${result.reason}]`, 'Re-validation failed')\n const doRotate = await prompter.confirm({\n message: 'Rotate to a new key now?',\n initialValue: true,\n })\n if (doRotate) return runNewAccountFlow(cfg, accountId, prompter, currentBase)\n return { cfg }\n }\n\n if (choice === 'rotate') {\n return runNewAccountFlow(cfg, accountId, prompter, currentBase)\n }\n\n // change-base\n const nextBase = await promptOptionalText(\n prompter,\n 'New API base URL (blank to reset to default)',\n currentBase ?? 'https://api.agentchat.me',\n )\n if (nextBase) {\n try {\n const url = new URL(nextBase)\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n await prompter.note('API base must use http:// or https://. Not updated.', 'Ignored')\n return { cfg }\n }\n } catch {\n await prompter.note('Not a valid URL. API base not updated.', 'Ignored')\n return { cfg }\n }\n }\n const next = writeAccountPatch(cfg, accountId, { apiBase: nextBase || undefined })\n await prompter.note(\n nextBase ? `API base set to ${nextBase}` : 'API base reset to default',\n 'Updated',\n )\n return { cfg: next }\n}\n\nasync function runNewAccountFlow(\n cfg: OpenClawConfig,\n accountId: string,\n prompter: WizardPrompter,\n apiBase: string | undefined,\n): Promise<{ cfg: OpenClawConfig }> {\n const choice = await prompter.select<'register' | 'have-key'>({\n message: 'How do you want to connect this agent?',\n options: [\n {\n value: 'register',\n label: 'Register a new agent (email + OTP)',\n hint: 'Mint a fresh API key — ~60 seconds',\n },\n {\n value: 'have-key',\n label: 'I already have an API key',\n hint: 'Paste ac_live_...',\n },\n ],\n initialValue: 'register',\n })\n if (choice === 'have-key') return runHaveKeyFlow(cfg, accountId, prompter, apiBase)\n return runRegisterFlow(cfg, accountId, prompter, apiBase)\n}\n\n// ─── The wizard ─────────────────────────────────────────────────────────\n\nexport const agentchatSetupWizard: ChannelSetupWizard = {\n channel: AGENTCHAT_CHANNEL_ID,\n\n resolveShouldPromptAccountIds: () => false,\n\n status: {\n configuredLabel: 'connected',\n unconfiguredLabel: 'needs API key',\n configuredHint: 'configured',\n unconfiguredHint: 'needs agent credentials',\n configuredScore: 2,\n unconfiguredScore: 0,\n resolveConfigured: ({ cfg, accountId }) => isAccountConfigured(cfg, accountId),\n resolveStatusLines: async ({ cfg, accountId, configured }) => {\n if (!configured) return ['AgentChat: needs API key — run setup to register or paste one']\n const id = accountId ?? AGENTCHAT_DEFAULT_ACCOUNT_ID\n const key = readAccountApiKey(cfg, id)\n const apiBase = readAccountApiBase(cfg, id)\n if (!key) return ['AgentChat: configured (no key visible)']\n try {\n const result = await validateApiKey(key, { apiBase, timeoutMs: 3000 })\n if (result.ok) return [`AgentChat: connected as @${result.agent.handle}`]\n return [`AgentChat: configured (live probe failed: ${result.reason})`]\n } catch {\n return ['AgentChat: configured (live probe unreachable)']\n }\n },\n },\n\n introNote: {\n title: 'AgentChat',\n lines: [\n 'A messaging platform for AI agents — handle-based routing, realtime WebSocket,',\n 'typed error taxonomy, idempotent sends.',\n '',\n 'You can paste an existing API key, or register a new agent inline (email + OTP).',\n ],\n },\n\n prepare: async ({ cfg, accountId, credentialValues }) => {\n const flow: FlowKind = isAccountConfigured(cfg, accountId) ? 'edit' : 'new'\n return { credentialValues: { ...credentialValues, _flow: flow } }\n },\n\n credentials: [],\n\n finalize: async ({ cfg, accountId, prompter, credentialValues }) => {\n const rawFlow = credentialValues._flow\n const flow: FlowKind = rawFlow === 'edit' ? 'edit' : 'new'\n const apiBase = readAccountApiBase(cfg, accountId)\n return flow === 'edit'\n ? await runEditFlow(cfg, accountId, prompter)\n : await runNewAccountFlow(cfg, accountId, prompter, apiBase)\n },\n\n completionNote: {\n title: 'AgentChat is ready',\n lines: [\n 'The channel runtime will auto-connect on the next `openclaw` boot.',\n 'Messages addressed to your handle arrive over WebSocket; sends go out',\n 'over HTTPS with at-least-once + idempotent semantics.',\n ],\n },\n\n disable: (cfg) => {\n const channels = {\n ...((cfg as { channels?: Record<string, unknown> } | undefined)?.channels ?? {}),\n }\n const existing = channels[AGENTCHAT_CHANNEL_ID]\n const section =\n existing && typeof existing === 'object' && !Array.isArray(existing)\n ? { ...(existing as Record<string, unknown>) }\n : ({} as Record<string, unknown>)\n section.enabled = false\n channels[AGENTCHAT_CHANNEL_ID] = section\n return { ...cfg, channels } as OpenClawConfig\n },\n}\n\n// Internal exports for unit tests (`@agentchatme/openclaw/internal/wizard`\n// is not a public export — these are deep-imported from test files only).\nexport const __testables = {\n readAccountApiKey,\n readAccountApiBase,\n writeAccountPatch,\n isAccountConfigured,\n describeRegisterStartFailure,\n describeRegisterVerifyFailure,\n runHaveKeyFlow,\n runRegisterFlow,\n runEditFlow,\n runNewAccountFlow,\n}\n","/**\r\n * AgentChat channel plugin — entry point.\r\n *\r\n * P1 (this file): wires the real OpenClaw SDK contracts — builds a\r\n * `ChannelPlugin<AgentchatResolvedAccount>` with id / meta / capabilities /\r\n * config-adapter / config-schema / setup, and wraps it via\r\n * `defineChannelPluginEntry(...)` for OpenClaw's extension loader.\r\n *\r\n * Config adapter supports both:\r\n * - single-account flat form: `channels.agentchat.{ apiKey, apiBase, ... }`\r\n * - multi-account form: `channels.agentchat.accounts.<id>.{ apiKey, ... }`\r\n *\r\n * Runtime (WS client, inbound normalizer, outbound adapter) arrives in P2+.\r\n *\r\n * Loaded by OpenClaw via `package.json`'s `openclaw.extensions` entry.\r\n */\r\n\r\nimport {\r\n buildChannelConfigSchema,\r\n defineChannelPluginEntry,\r\n type ChannelConfigUiHint,\r\n type ChannelPlugin,\r\n type OpenClawConfig,\r\n} from 'openclaw/plugin-sdk/channel-core'\r\n\r\nimport {\r\n agentchatChannelConfigSchema,\r\n parseChannelConfig,\r\n type AgentchatChannelConfig,\r\n} from './config-schema.js'\r\nimport { validateApiKey } from './setup-client.js'\r\nimport { agentchatSetupWizard } from './setup-wizard.js'\r\n\r\nexport const AGENTCHAT_CHANNEL_ID = 'agentchat' as const\r\nexport const AGENTCHAT_DEFAULT_ACCOUNT_ID = 'default'\r\n\r\nconst MIN_API_KEY_LENGTH = 20\r\n\r\nexport interface AgentchatResolvedAccount {\r\n accountId: string\r\n enabled: boolean\r\n configured: boolean\r\n config: AgentchatChannelConfig | null\r\n parseError: string | null\r\n}\r\n\r\ntype ChannelSectionRaw = Record<string, unknown> & {\r\n accounts?: Record<string, unknown>\r\n enabled?: unknown\r\n apiKey?: unknown\r\n apiBase?: unknown\r\n agentHandle?: unknown\r\n}\r\n\r\nfunction readChannelSection(cfg: OpenClawConfig | undefined): ChannelSectionRaw | undefined {\r\n const channels = (cfg as { channels?: Record<string, unknown> } | undefined)?.channels\r\n const section = channels?.[AGENTCHAT_CHANNEL_ID]\r\n return section && typeof section === 'object' && !Array.isArray(section)\r\n ? (section as ChannelSectionRaw)\r\n : undefined\r\n}\r\n\r\nfunction readAccountRaw(\r\n section: ChannelSectionRaw | undefined,\r\n accountId: string,\r\n): Record<string, unknown> | undefined {\r\n if (!section) return undefined\r\n const { accounts } = section\r\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\r\n const entry = (accounts as Record<string, unknown>)[accountId]\r\n if (entry && typeof entry === 'object') return entry as Record<string, unknown>\r\n }\r\n // Single-account fallback: treat section-level fields as the 'default' account,\r\n // stripping the `accounts` subsection (but preserving `enabled`, which the\r\n // caller extracts before Zod parsing).\r\n if (accountId === AGENTCHAT_DEFAULT_ACCOUNT_ID) {\r\n const { accounts: _accounts, ...rest } = section\r\n void _accounts\r\n return rest as Record<string, unknown>\r\n }\r\n return undefined\r\n}\r\n\r\n/**\r\n * Pulls the `enabled` flag out of a raw account record and returns a copy\r\n * safe to feed into `parseChannelConfig` (which enforces `.strict()` — an\r\n * unknown `enabled` key would otherwise reject).\r\n */\r\nfunction splitEnabledFromRaw(\r\n raw: Record<string, unknown> | undefined,\r\n): { enabled: boolean; forParse: Record<string, unknown> | undefined } {\r\n if (!raw) return { enabled: true, forParse: undefined }\r\n const { enabled, ...rest } = raw\r\n return { enabled: enabled !== false, forParse: rest }\r\n}\r\n\r\nfunction isApiKeyPresent(value: unknown): value is string {\r\n return typeof value === 'string' && value.length >= MIN_API_KEY_LENGTH\r\n}\r\n\r\nconst uiHints: Record<string, ChannelConfigUiHint> = {\r\n apiKey: {\r\n label: 'AgentChat API key',\r\n placeholder: 'ac_live_...',\r\n sensitive: true,\r\n help: 'Obtain from AgentChat dashboard → Settings → API keys.',\r\n },\r\n apiBase: {\r\n label: 'API base URL',\r\n placeholder: 'https://api.agentchat.me',\r\n help: 'Override only when targeting a self-hosted AgentChat instance.',\r\n advanced: true,\r\n },\r\n agentHandle: {\r\n label: 'Agent handle',\r\n placeholder: 'my-agent',\r\n help: '3–32 chars, lowercase alphanumeric plus . _ -',\r\n },\r\n reconnect: { label: 'Reconnect backoff', advanced: true },\r\n ping: { label: 'WebSocket ping cadence', advanced: true },\r\n outbound: { label: 'Outbound send tuning', advanced: true },\r\n observability: { label: 'Logs & metrics', advanced: true },\r\n}\r\n\r\nexport const agentchatPlugin: ChannelPlugin<AgentchatResolvedAccount> = {\r\n id: AGENTCHAT_CHANNEL_ID,\r\n\r\n meta: {\r\n id: AGENTCHAT_CHANNEL_ID,\r\n label: 'AgentChat',\r\n selectionLabel: 'AgentChat (messaging platform for agents)',\r\n detailLabel: 'AgentChat',\r\n docsPath: '/channels/agentchat',\r\n docsLabel: 'agentchat',\r\n blurb:\r\n 'connect your agent to the AgentChat messaging platform — handles, contacts, groups, presence, attachments.',\r\n systemImage: 'message',\r\n markdownCapable: true,\r\n order: 100,\r\n },\r\n\r\n capabilities: {\r\n chatTypes: ['direct', 'group'],\r\n media: true,\r\n reactions: false,\r\n edit: false,\r\n unsend: true,\r\n reply: true,\r\n threads: false,\r\n nativeCommands: false,\r\n },\r\n\r\n reload: {\r\n configPrefixes: [`channels.${AGENTCHAT_CHANNEL_ID}.`],\r\n },\r\n\r\n configSchema: buildChannelConfigSchema(agentchatChannelConfigSchema, { uiHints }),\r\n\r\n setupWizard: agentchatSetupWizard,\r\n\r\n config: {\r\n listAccountIds(cfg) {\r\n const section = readChannelSection(cfg)\r\n if (!section) return []\r\n const { accounts } = section\r\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\r\n const ids = Object.keys(accounts as Record<string, unknown>)\r\n if (ids.length > 0) return ids\r\n }\r\n const hasFlatFields =\r\n typeof section.apiKey === 'string' ||\r\n typeof section.apiBase === 'string' ||\r\n typeof section.agentHandle === 'string'\r\n return hasFlatFields ? [AGENTCHAT_DEFAULT_ACCOUNT_ID] : []\r\n },\r\n\r\n resolveAccount(cfg, accountId) {\r\n const id = accountId ?? AGENTCHAT_DEFAULT_ACCOUNT_ID\r\n const section = readChannelSection(cfg)\r\n const raw = readAccountRaw(section, id)\r\n const { enabled, forParse } = splitEnabledFromRaw(raw)\r\n let config: AgentchatChannelConfig | null = null\r\n let parseError: string | null = null\r\n if (forParse && Object.keys(forParse).length > 0) {\r\n try {\r\n config = parseChannelConfig(forParse)\r\n } catch (e) {\r\n parseError = e instanceof Error ? e.message : String(e)\r\n }\r\n }\r\n const configured = Boolean(config && isApiKeyPresent(config.apiKey))\r\n return { accountId: id, enabled, configured, config, parseError }\r\n },\r\n\r\n defaultAccountId() {\r\n return AGENTCHAT_DEFAULT_ACCOUNT_ID\r\n },\r\n\r\n isEnabled(account) {\r\n return account.enabled\r\n },\r\n\r\n disabledReason(account) {\r\n return account.enabled ? '' : 'channel disabled via channels.agentchat.enabled=false'\r\n },\r\n\r\n isConfigured(account) {\r\n return account.configured\r\n },\r\n\r\n unconfiguredReason(account) {\r\n if (account.parseError) return `config invalid: ${account.parseError}`\r\n if (!account.config) return 'missing channels.agentchat configuration'\r\n if (!isApiKeyPresent(account.config.apiKey)) return 'missing or too-short channels.agentchat.apiKey'\r\n return ''\r\n },\r\n\r\n hasConfiguredState({ cfg }) {\r\n const section = readChannelSection(cfg)\r\n if (!section) return false\r\n const { accounts } = section\r\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\r\n for (const entry of Object.values(accounts as Record<string, unknown>)) {\r\n if (entry && typeof entry === 'object') {\r\n const candidate = (entry as Record<string, unknown>).apiKey\r\n if (isApiKeyPresent(candidate)) return true\r\n }\r\n }\r\n }\r\n return isApiKeyPresent(section.apiKey)\r\n },\r\n\r\n describeAccount(account) {\r\n return {\r\n accountId: account.accountId,\r\n enabled: account.enabled,\r\n configured: account.configured,\r\n linked: account.configured,\r\n }\r\n },\r\n },\r\n\r\n setup: {\r\n /**\r\n * Pre-write gate: cheap, sync check that the caller supplied an API key\r\n * that's at least plausibly shaped. Real authentication happens in\r\n * `afterAccountConfigWritten` via a live /agents/me probe.\r\n */\r\n validateInput({ input }) {\r\n if (typeof input.token !== 'string' || input.token.trim().length === 0) {\r\n return 'apiKey is required — pass via --token or run the register flow'\r\n }\r\n if (input.token.length < MIN_API_KEY_LENGTH) {\r\n return `apiKey looks too short (got ${input.token.length} chars, expect ≥${MIN_API_KEY_LENGTH})`\r\n }\r\n if (typeof input.url === 'string' && input.url.length > 0) {\r\n try {\r\n const parsed = new URL(input.url)\r\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {\r\n return 'apiBase must be http(s) — e.g. https://api.agentchat.me'\r\n }\r\n } catch {\r\n return 'apiBase is not a valid URL'\r\n }\r\n }\r\n return null\r\n },\r\n\r\n applyAccountConfig({ cfg, accountId, input }) {\r\n const channels: Record<string, unknown> = {\r\n ...((cfg as { channels?: Record<string, unknown> } | undefined)?.channels ?? {}),\r\n }\r\n const currentSection = channels[AGENTCHAT_CHANNEL_ID]\r\n const section: ChannelSectionRaw =\r\n currentSection && typeof currentSection === 'object' && !Array.isArray(currentSection)\r\n ? { ...(currentSection as ChannelSectionRaw) }\r\n : {}\r\n\r\n const patch: Record<string, unknown> = {}\r\n if (typeof input.token === 'string' && input.token.length > 0) patch.apiKey = input.token\r\n if (typeof input.url === 'string' && input.url.length > 0) patch.apiBase = input.url\r\n\r\n if (accountId === AGENTCHAT_DEFAULT_ACCOUNT_ID && !section.accounts) {\r\n // Flat form for the simple single-account case.\r\n Object.assign(section, patch)\r\n } else {\r\n const accounts: Record<string, unknown> = {\r\n ...((section.accounts as Record<string, unknown> | undefined) ?? {}),\r\n }\r\n const prevAccount =\r\n typeof accounts[accountId] === 'object' && accounts[accountId] !== null\r\n ? (accounts[accountId] as Record<string, unknown>)\r\n : {}\r\n accounts[accountId] = { ...prevAccount, ...patch }\r\n section.accounts = accounts\r\n }\r\n\r\n channels[AGENTCHAT_CHANNEL_ID] = section\r\n return { ...cfg, channels } as OpenClawConfig\r\n },\r\n\r\n /**\r\n * Post-write probe: call `GET /v1/agents/me` with the key we just wrote\r\n * so the operator sees a clear \"✓ authenticated as @handle\" on success\r\n * — or a specific failure reason (invalid, revoked, unreachable) they\r\n * can act on *before* the runtime starts flapping reconnects in prod.\r\n *\r\n * Never throws: setup-time UX is \"warn and proceed\". If the probe can't\r\n * reach the API (airgapped CI, corp proxy during first boot), we still\r\n * want the config written so the user can retry without reconfiguring.\r\n */\r\n async afterAccountConfigWritten({ cfg, accountId, input, runtime }) {\r\n const apiKey = typeof input.token === 'string' ? input.token : undefined\r\n if (!apiKey) return\r\n const apiBase = typeof input.url === 'string' && input.url.length > 0 ? input.url : undefined\r\n void cfg\r\n const logger = (runtime as { logger?: { info?: (...args: unknown[]) => void; warn?: (...args: unknown[]) => void } } | undefined)?.logger\r\n try {\r\n const result = await validateApiKey(apiKey, { apiBase })\r\n if (result.ok) {\r\n logger?.info?.(\r\n `[agentchat:${accountId}] authenticated as @${result.agent.handle} (${result.agent.email})`,\r\n )\r\n } else {\r\n logger?.warn?.(\r\n `[agentchat:${accountId}] api key did not pass live check (${result.reason}): ${result.message}`,\r\n )\r\n }\r\n } catch (err) {\r\n logger?.warn?.(\r\n `[agentchat:${accountId}] live key validation failed: ${err instanceof Error ? err.message : String(err)}`,\r\n )\r\n }\r\n },\r\n },\r\n}\r\n\r\n/**\r\n * Canonical channel-entry descriptor consumed by OpenClaw's extension loader.\r\n * Exported as `default` because `openclaw.extensions` in package.json points to\r\n * this module and the loader reads the default export.\r\n *\r\n * The explicit `ReturnType<...>` annotation pins the emitted `.d.ts` to the\r\n * function signature instead of the structural shape — otherwise the inferred\r\n * type references `ChannelConfigSchema` through a non-exported path and TS\r\n * fails with TS2742 (\"cannot be named without a reference to ...\").\r\n */\r\nexport const agentchatChannelEntry: ReturnType<\r\n typeof defineChannelPluginEntry<typeof agentchatPlugin>\r\n> = defineChannelPluginEntry({\r\n id: AGENTCHAT_CHANNEL_ID,\r\n name: 'AgentChat',\r\n description: 'Connect OpenClaw agents to the AgentChat messaging platform.',\r\n plugin: agentchatPlugin,\r\n})\r\n\r\nexport default agentchatChannelEntry\r\n\r\nexport { parseChannelConfig }\r\nexport type { AgentchatChannelConfig }\r\n","/**\r\n * AgentChat setup plugin — onboarding entry.\r\n *\r\n * P1 (this file): wraps the same `agentchatPlugin` from `channel.ts` with\r\n * `defineSetupPluginEntry(...)`. OpenClaw's setup-entry loader reads the\r\n * `plugin` field, then invokes the plugin's `setup` adapter during\r\n * `openclaw setup` runs.\r\n * P7: real interactive wizard — prompts for API key, validates against\r\n * `GET /v1/agents/me`, or registers a new agent via `POST /v1/agents`.\r\n *\r\n * Loaded by OpenClaw via `package.json`'s `openclaw.setupEntry`.\r\n */\r\n\r\nimport { defineSetupPluginEntry } from 'openclaw/plugin-sdk/channel-core'\r\n\r\nimport { agentchatPlugin } from './channel.js'\r\n\r\nexport const agentchatSetupEntry = defineSetupPluginEntry(agentchatPlugin)\r\n\r\nexport default agentchatSetupEntry\r\n\r\nexport { agentchatPlugin as agentchatSetupPlugin }\r\n","/**\r\n * Configured-state predicate for the AgentChat channel.\r\n *\r\n * OpenClaw calls this to decide whether the channel has \"enough\" config to\r\n * be considered active (counts toward enabled channels, shown in UI, etc.).\r\n *\r\n * Minimum bar: an `apiKey` of plausible length is present.\r\n */\r\n\r\nexport interface MaybeConfigured {\r\n readonly apiKey?: unknown\r\n}\r\n\r\nexport function hasAgentChatConfiguredState(config: MaybeConfigured | undefined): boolean {\r\n if (!config || typeof config !== 'object') return false\r\n const key = config.apiKey\r\n return typeof key === 'string' && key.length >= 20\r\n}\r\n","/**\r\n * Structured logger for the channel plugin.\r\n *\r\n * Wraps pino with:\r\n * - Secret redaction (`apiKey`, `authorization`, `cookie`, `set-cookie` by default)\r\n * - A `child({ correlationId })` helper for per-operation logs\r\n * - Graceful integration: when OpenClaw's channel runtime context provides\r\n * a logger, we delegate to it so logs stream through the gateway's sink.\r\n *\r\n * Never logs the API key. Never logs message bodies above `debug` level.\r\n */\r\n\r\nimport pino from 'pino'\r\n\r\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error'\r\n\r\nexport interface Logger {\r\n trace(obj: object, msg?: string): void\r\n debug(obj: object, msg?: string): void\r\n info(obj: object, msg?: string): void\r\n warn(obj: object, msg?: string): void\r\n error(obj: object, msg?: string): void\r\n child(bindings: Record<string, unknown>): Logger\r\n}\r\n\r\nexport interface CreateLoggerOptions {\r\n level: LogLevel\r\n redactKeys: readonly string[]\r\n /** If provided, delegates to the gateway's logger instead of creating our own. */\r\n delegate?: Logger | undefined\r\n}\r\n\r\nexport function createLogger(options: CreateLoggerOptions): Logger {\r\n if (options.delegate) {\r\n return options.delegate\r\n }\r\n\r\n const pinoLogger = pino({\r\n level: options.level,\r\n base: { plugin: '@agentchatme/openclaw' },\r\n redact: {\r\n paths: buildRedactPaths(options.redactKeys),\r\n censor: '[REDACTED]',\r\n },\r\n timestamp: pino.stdTimeFunctions.isoTime,\r\n })\r\n\r\n return wrapPino(pinoLogger)\r\n}\r\n\r\nfunction buildRedactPaths(keys: readonly string[]): string[] {\r\n // Cover common shapes: top-level, nested under `config.*`, nested under\r\n // `headers.*`, nested under `context.*`. Pino redact paths are JSON-path-ish.\r\n const prefixes = ['', 'config.', 'headers.', 'context.', 'req.headers.', 'res.headers.']\r\n const paths: string[] = []\r\n for (const key of keys) {\r\n for (const prefix of prefixes) {\r\n paths.push(`${prefix}${key}`)\r\n }\r\n }\r\n // Also redact under `*` wildcard at top level for deeply nested cases.\r\n paths.push(...keys.map((k) => `*.${k}`))\r\n return paths\r\n}\r\n\r\nfunction wrapPino(p: pino.Logger): Logger {\r\n return {\r\n trace: (obj, msg) => p.trace(obj, msg),\r\n debug: (obj, msg) => p.debug(obj, msg),\r\n info: (obj, msg) => p.info(obj, msg),\r\n warn: (obj, msg) => p.warn(obj, msg),\r\n error: (obj, msg) => p.error(obj, msg),\r\n child: (bindings) => wrapPino(p.child(bindings)),\r\n }\r\n}\r\n\r\n/**\r\n * Redact a string for display in logs — shows first 8 and last 4 chars,\r\n * masks the middle. Useful for surfacing \"which key\" without leaking it.\r\n */\r\nexport function maskSecret(value: string): string {\r\n if (value.length <= 12) return '[REDACTED]'\r\n return `${value.slice(0, 8)}••••${value.slice(-4)}`\r\n}\r\n","/**\r\n * Optional Prometheus metrics for the channel plugin.\r\n *\r\n * Design: the gateway owns the `/metrics` endpoint. Plugins do not expose\r\n * their own port. If the user passes a `prom-client` Registry via channel\r\n * runtime context, we register our counters/gauges/histograms into it.\r\n * Otherwise, we return a no-op recorder — zero overhead, zero config.\r\n *\r\n * Names are prefixed with `agentchat_channel_` for easy scraping.\r\n */\r\n\r\nexport interface MetricsRecorder {\r\n /** Incremented on every successfully delivered inbound message. */\r\n incInboundDelivered(labels: { kind: InboundKind }): void\r\n /** Incremented on every successfully sent outbound message. */\r\n incOutboundSent(labels: { kind: OutboundKind }): void\r\n /** Incremented on every send failure, labeled by error class. */\r\n incOutboundFailed(labels: { errorClass: string }): void\r\n /** Incremented on every reconnect attempt. */\r\n incReconnect(labels: { reason: string }): void\r\n /** Observe end-to-end send latency (ms). */\r\n observeSendLatency(ms: number): void\r\n /** Set the current connection state (cardinality bounded by state kinds). */\r\n setConnectionState(kind: string): void\r\n /** Set the current in-flight send queue depth. */\r\n setInFlightDepth(n: number): void\r\n}\r\n\r\nexport type InboundKind = 'message' | 'group-message' | 'typing' | 'read' | 'presence' | 'rate-limit-warning'\r\nexport type OutboundKind = 'message' | 'typing' | 'read'\r\n\r\n/**\r\n * Minimal contract for a prom-client-compatible registry. We accept anything\r\n * that exposes the `registerMetric` shape so consumers can pass their own\r\n * custom registry or a bare `Registry` from `prom-client`.\r\n */\r\nexport interface PromRegistryLike {\r\n registerMetric(metric: unknown): void\r\n}\r\n\r\n/**\r\n * Minimal contract for a prom-client factory. Keeping this abstract lets us\r\n * avoid a hard dep on `prom-client` while still being production-capable.\r\n * The caller passes `{ Counter, Gauge, Histogram }` from their own import.\r\n */\r\nexport interface PromFactory {\r\n Counter: new (cfg: MetricConfig) => {\r\n inc(labels?: Record<string, string>, value?: number): void\r\n }\r\n Gauge: new (cfg: MetricConfig) => {\r\n set(labelsOrValue: Record<string, string> | number, value?: number): void\r\n }\r\n Histogram: new (cfg: MetricConfig) => {\r\n observe(labelsOrValue: Record<string, string> | number, value?: number): void\r\n }\r\n}\r\n\r\ninterface MetricConfig {\r\n name: string\r\n help: string\r\n labelNames?: readonly string[]\r\n buckets?: readonly number[]\r\n registers?: readonly unknown[]\r\n}\r\n\r\nexport interface CreateMetricsOptions {\r\n registry: PromRegistryLike\r\n factory: PromFactory\r\n}\r\n\r\nexport function createMetrics(options: CreateMetricsOptions): MetricsRecorder {\r\n const { registry, factory } = options\r\n\r\n const inboundDelivered = new factory.Counter({\r\n name: 'agentchat_channel_inbound_delivered_total',\r\n help: 'Inbound messages delivered to OpenClaw runtime.',\r\n labelNames: ['kind'],\r\n registers: [registry],\r\n })\r\n\r\n const outboundSent = new factory.Counter({\r\n name: 'agentchat_channel_outbound_sent_total',\r\n help: 'Outbound messages successfully sent to AgentChat.',\r\n labelNames: ['kind'],\r\n registers: [registry],\r\n })\r\n\r\n const outboundFailed = new factory.Counter({\r\n name: 'agentchat_channel_outbound_failed_total',\r\n help: 'Outbound send failures, labeled by error class.',\r\n labelNames: ['errorClass'],\r\n registers: [registry],\r\n })\r\n\r\n const reconnects = new factory.Counter({\r\n name: 'agentchat_channel_reconnect_total',\r\n help: 'WebSocket reconnect attempts.',\r\n labelNames: ['reason'],\r\n registers: [registry],\r\n })\r\n\r\n const sendLatency = new factory.Histogram({\r\n name: 'agentchat_channel_send_latency_ms',\r\n help: 'End-to-end latency of outbound send (ms).',\r\n buckets: [10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10_000, 30_000],\r\n registers: [registry],\r\n })\r\n\r\n const connectionState = new factory.Gauge({\r\n name: 'agentchat_channel_connection_state',\r\n help: 'Current connection state (1 = active kind, 0 = otherwise).',\r\n labelNames: ['kind'],\r\n registers: [registry],\r\n })\r\n\r\n const inFlightDepth = new factory.Gauge({\r\n name: 'agentchat_channel_inflight_depth',\r\n help: 'Current in-flight outbound send queue depth.',\r\n registers: [registry],\r\n })\r\n\r\n return {\r\n incInboundDelivered: ({ kind }) => inboundDelivered.inc({ kind }),\r\n incOutboundSent: ({ kind }) => outboundSent.inc({ kind }),\r\n incOutboundFailed: ({ errorClass }) => outboundFailed.inc({ errorClass }),\r\n incReconnect: ({ reason }) => reconnects.inc({ reason }),\r\n observeSendLatency: (ms) => sendLatency.observe(ms),\r\n setConnectionState: (kind) => connectionState.set({ kind }, 1),\r\n setInFlightDepth: (n) => inFlightDepth.set(n),\r\n }\r\n}\r\n\r\n/** No-op recorder — used when the user does not provide a Prometheus registry. */\r\nexport function createNoopMetrics(): MetricsRecorder {\r\n return {\r\n incInboundDelivered: () => undefined,\r\n incOutboundSent: () => undefined,\r\n incOutboundFailed: () => undefined,\r\n incReconnect: () => undefined,\r\n observeSendLatency: () => undefined,\r\n setConnectionState: () => undefined,\r\n setInFlightDepth: () => undefined,\r\n }\r\n}\r\n","/**\r\n * Connection state machine for the AgentChat WebSocket.\r\n *\r\n * Pure functions only — no I/O, no timers. The runtime (P2) owns the socket\r\n * and drives transitions by emitting events.\r\n *\r\n * States:\r\n * DISCONNECTED — initial, and after a clean close\r\n * CONNECTING — TCP/TLS handshake + WS upgrade in flight\r\n * AUTHENTICATING — socket open, waiting for `hello.ok` from server\r\n * READY — authenticated, receiving + sending normally\r\n * DEGRADED — heartbeat missed or send buffer full; still connected but impaired\r\n * DRAINING — SIGTERM received; flush in-flight sends, then close\r\n * CLOSED — terminal after clean shutdown\r\n * AUTH_FAIL — terminal after 401/403; operator action required (rotate key)\r\n *\r\n * Invariants:\r\n * - From AUTH_FAIL, no event can move us back to CONNECTING without\r\n * an explicit RECONFIGURED event (operator rotated key).\r\n * - From CLOSED, only SHUTDOWN is a no-op; anything else is a bug.\r\n * - DRAINING has a deadline (ms timestamp) after which we force-close.\r\n */\r\n\r\nimport type { UnixMillis } from './types.js'\r\n\r\nexport type ConnectionState =\r\n | { readonly kind: 'DISCONNECTED' }\r\n | { readonly kind: 'CONNECTING'; readonly attempt: number; readonly startedAt: UnixMillis }\r\n | { readonly kind: 'AUTHENTICATING'; readonly startedAt: UnixMillis }\r\n | { readonly kind: 'READY'; readonly connectedAt: UnixMillis }\r\n | { readonly kind: 'DEGRADED'; readonly since: UnixMillis; readonly reason: string }\r\n | { readonly kind: 'DRAINING'; readonly since: UnixMillis; readonly deadline: UnixMillis }\r\n | { readonly kind: 'CLOSED' }\r\n | { readonly kind: 'AUTH_FAIL'; readonly reason: string }\r\n\r\nexport type ConnectionEvent =\r\n | { readonly type: 'CONNECT'; readonly now: UnixMillis; readonly attempt: number }\r\n | { readonly type: 'SOCKET_OPEN'; readonly now: UnixMillis }\r\n | { readonly type: 'HELLO_OK'; readonly now: UnixMillis }\r\n | { readonly type: 'AUTH_REJECTED'; readonly reason: string }\r\n | { readonly type: 'SOCKET_CLOSED'; readonly code: number; readonly reason: string }\r\n | { readonly type: 'PING_TIMEOUT'; readonly now: UnixMillis }\r\n | { readonly type: 'BACKPRESSURE'; readonly now: UnixMillis; readonly reason: string }\r\n | { readonly type: 'RECOVERED'; readonly now: UnixMillis }\r\n | { readonly type: 'DRAIN_REQUESTED'; readonly now: UnixMillis; readonly deadline: UnixMillis }\r\n | { readonly type: 'DRAIN_COMPLETED' }\r\n | { readonly type: 'RECONFIGURED' }\r\n\r\n/**\r\n * Apply an event to a state. Returns a new state.\r\n *\r\n * Illegal transitions (e.g. HELLO_OK while in DISCONNECTED) fall through to\r\n * the current state — the runtime should log them as `transition.invalid`\r\n * so they become visible in telemetry without crashing the process.\r\n */\r\nexport function transition(state: ConnectionState, event: ConnectionEvent): ConnectionState {\r\n switch (state.kind) {\r\n case 'DISCONNECTED': {\r\n if (event.type === 'CONNECT') {\r\n return { kind: 'CONNECTING', attempt: event.attempt, startedAt: event.now }\r\n }\r\n if (event.type === 'DRAIN_REQUESTED') return { kind: 'CLOSED' }\r\n // Reconnect hard-cap elevation — the runtime has given up on transport\r\n // retries and wants to force operator attention. Treat the same as a\r\n // genuine auth reject: terminal until RECONFIGURED.\r\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\r\n return state\r\n }\r\n\r\n case 'CONNECTING': {\r\n if (event.type === 'SOCKET_OPEN') return { kind: 'AUTHENTICATING', startedAt: event.now }\r\n if (event.type === 'SOCKET_CLOSED') return { kind: 'DISCONNECTED' }\r\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\r\n if (event.type === 'DRAIN_REQUESTED') return { kind: 'CLOSED' }\r\n return state\r\n }\r\n\r\n case 'AUTHENTICATING': {\r\n if (event.type === 'HELLO_OK') return { kind: 'READY', connectedAt: event.now }\r\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\r\n if (event.type === 'SOCKET_CLOSED') return { kind: 'DISCONNECTED' }\r\n if (event.type === 'DRAIN_REQUESTED') return { kind: 'CLOSED' }\r\n return state\r\n }\r\n\r\n case 'READY': {\r\n if (event.type === 'PING_TIMEOUT') {\r\n return { kind: 'DEGRADED', since: event.now, reason: 'ping-timeout' }\r\n }\r\n if (event.type === 'BACKPRESSURE') {\r\n return { kind: 'DEGRADED', since: event.now, reason: event.reason }\r\n }\r\n if (event.type === 'SOCKET_CLOSED') return { kind: 'DISCONNECTED' }\r\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\r\n if (event.type === 'DRAIN_REQUESTED') {\r\n return { kind: 'DRAINING', since: event.now, deadline: event.deadline }\r\n }\r\n return state\r\n }\r\n\r\n case 'DEGRADED': {\r\n if (event.type === 'RECOVERED') return { kind: 'READY', connectedAt: event.now }\r\n if (event.type === 'SOCKET_CLOSED') return { kind: 'DISCONNECTED' }\r\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\r\n if (event.type === 'DRAIN_REQUESTED') {\r\n return { kind: 'DRAINING', since: event.now, deadline: event.deadline }\r\n }\r\n return state\r\n }\r\n\r\n case 'DRAINING': {\r\n if (event.type === 'DRAIN_COMPLETED') return { kind: 'CLOSED' }\r\n if (event.type === 'SOCKET_CLOSED') return { kind: 'CLOSED' }\r\n return state\r\n }\r\n\r\n case 'AUTH_FAIL': {\r\n // Only an explicit reconfig (operator rotated key) can leave AUTH_FAIL.\r\n if (event.type === 'RECONFIGURED') return { kind: 'DISCONNECTED' }\r\n if (event.type === 'DRAIN_REQUESTED') return { kind: 'CLOSED' }\r\n return state\r\n }\r\n\r\n case 'CLOSED': {\r\n return state\r\n }\r\n }\r\n}\r\n\r\n/** True iff sends may be attempted in this state. */\r\nexport function canSend(state: ConnectionState): boolean {\r\n return state.kind === 'READY' || state.kind === 'DEGRADED' || state.kind === 'DRAINING'\r\n}\r\n\r\n/** True iff the state indicates a transport-level problem the runtime should recover from. */\r\nexport function shouldReconnect(state: ConnectionState): boolean {\r\n return state.kind === 'DISCONNECTED'\r\n}\r\n\r\n/** True iff the state is terminal and no further transitions are expected. */\r\nexport function isTerminal(state: ConnectionState): boolean {\r\n return state.kind === 'CLOSED' || state.kind === 'AUTH_FAIL'\r\n}\r\n","/**\r\n * AgentChat WebSocket client — state-machine-driven, production-grade.\r\n *\r\n * Responsibilities:\r\n * - Own the WS transport and HELLO handshake lifecycle.\r\n * - Drive the connection state machine (`./state-machine.ts`) by emitting\r\n * events in response to socket/auth/heartbeat transitions.\r\n * - Maintain native WS PING/PONG heartbeat at `ping.intervalMs`; declare\r\n * DEGRADED on `ping.timeoutMs` miss, then force-reconnect.\r\n * - Schedule reconnect with exponential backoff + ±`jitterRatio` jitter\r\n * per `reconnect.*` config. Thundering-herd-safe across a fleet.\r\n * - Emit typed events upwards (`inboundFrame`, `stateChanged`, `error`)\r\n * so the normalizer (P3) and outbound adapter (P4) can consume them.\r\n *\r\n * Intentional design choices:\r\n * - Uses the `ws` package directly (not `globalThis.WebSocket`) because\r\n * OpenClaw runs on Node — `ws` exposes `.ping()` / `.pong()` / event\r\n * hooks that native WebSocket omits. Every major agent-hosting target\r\n * (Fly, Render, Vercel functions, Lambda) is Node.\r\n * - Authenticates via HELLO frame (`{type: \"hello\", api_key}`), never via\r\n * URL query string. Keeps the key out of access logs and Referers.\r\n * - `RECONNECT_HARD_CAP_ATTEMPTS` guards against runaway reconnect loops\r\n * after catastrophic network events; crosses into `AUTH_FAIL` so the\r\n * operator sees a clear signal instead of silent retry forever.\r\n * - Frame parsing is defensive: malformed JSON, unknown `type`, missing\r\n * payload — all classified as `validation` errors (non-terminal for\r\n * the connection, but dropped with a metric + log).\r\n * - No message-layer ordering here. Per-conversation seq ordering + gap\r\n * recovery belong to the SDK's `RealtimeClient` and the drain layer\r\n * (P3 consumers). This module is strictly the transport.\r\n */\r\n\r\nimport type { RawData, WebSocket as WsInstance } from 'ws'\r\nimport { WebSocket as NodeWebSocket } from 'ws'\r\n\r\nimport {\r\n AgentChatChannelError,\r\n classifyNetworkError,\r\n type ErrorClass,\r\n} from './errors.js'\r\nimport type { Logger } from './log.js'\r\nimport type { MetricsRecorder } from './metrics.js'\r\nimport {\r\n canSend,\r\n isTerminal,\r\n transition,\r\n type ConnectionEvent,\r\n type ConnectionState,\r\n} from './state-machine.js'\r\nimport type { AgentchatChannelConfig } from './config-schema.js'\r\nimport type { UnixMillis } from './types.js'\r\n\r\n// HELLO handshake must resolve faster than the server's 5s cutoff — we give\r\n// ourselves 4s so a clean close + reconnect happens before the server drops.\r\nconst HELLO_ACK_TIMEOUT_MS = 4_000\r\n\r\n// Reconnect attempts above this threshold almost certainly mean the network\r\n// is partitioned from the AgentChat control plane, or the API key was\r\n// revoked at the edge (without a terminal 401). Surface AUTH_FAIL so the\r\n// operator has a clear signal rather than silent forever-retry.\r\nconst RECONNECT_HARD_CAP_ATTEMPTS = 60\r\n\r\n// Maximum frame size we'll accept from the server. Matches AgentChat's\r\n// own server-side outbound cap (2 MiB — large attachments go via the REST\r\n// upload flow, not inline in WS frames).\r\nconst MAX_FRAME_BYTES = 2 * 1024 * 1024\r\n\r\n// WebSocket close codes we treat as auth failures (terminal until operator\r\n// reconfigures). 1008 = policy violation; AgentChat uses it + 4401/4403 for\r\n// auth-related rejects. Other 4xxx codes are treated as retry-transient.\r\nconst AUTH_CLOSE_CODES = new Set([1008, 4401, 4403])\r\n\r\n/** One parsed inbound server frame. */\r\nexport interface InboundFrame {\r\n readonly type: string\r\n readonly payload: Record<string, unknown>\r\n readonly receivedAt: UnixMillis\r\n readonly raw: unknown\r\n}\r\n\r\n/** One client-action frame the caller wants to push. */\r\nexport interface OutboundFrame {\r\n readonly type: string\r\n readonly payload: Record<string, unknown>\r\n readonly id?: string\r\n}\r\n\r\nexport interface WsClientEvents {\r\n stateChanged: (next: ConnectionState, prev: ConnectionState) => void\r\n inboundFrame: (frame: InboundFrame) => void\r\n error: (error: AgentChatChannelError) => void\r\n /** Fired once per `hello.ok` — useful for triggering a /v1/messages/sync drain upstream. */\r\n authenticated: (at: UnixMillis) => void\r\n /** Fired after a clean close + CLOSED state (after stop() or terminal auth failure). */\r\n closed: () => void\r\n}\r\n\r\nexport interface WsClientOptions {\r\n readonly config: AgentchatChannelConfig\r\n readonly logger: Logger\r\n readonly metrics: MetricsRecorder\r\n /** Clock source — override in tests. Default: `Date.now`. */\r\n readonly now?: () => UnixMillis\r\n /** WebSocket constructor override — tests inject a mock. Default: `ws`. */\r\n readonly webSocketCtor?: typeof NodeWebSocket\r\n /** Random source for jitter — override in tests. Default: `Math.random`. */\r\n readonly random?: () => number\r\n /** timer.setTimeout override for tests. */\r\n readonly setTimeout?: (fn: () => void, ms: number) => NodeJS.Timeout\r\n readonly clearTimeout?: (h: NodeJS.Timeout) => void\r\n readonly setInterval?: (fn: () => void, ms: number) => NodeJS.Timeout\r\n readonly clearInterval?: (h: NodeJS.Timeout) => void\r\n}\r\n\r\ntype Listener<E extends keyof WsClientEvents> = WsClientEvents[E]\r\n\r\n/**\r\n * AgentChat channel WebSocket client.\r\n *\r\n * Lifecycle:\r\n * 1. `start()` — DISCONNECTED → CONNECTING. Transport opens, HELLO is sent.\r\n * 2. `hello.ok` → READY. Heartbeat timer starts. Upstream consumers begin.\r\n * 3. On socket drop → DISCONNECTED → CONNECTING (with backoff).\r\n * 4. `stop(deadlineMs)` → DRAINING. Wait for in-flight drains, then CLOSED.\r\n *\r\n * Thread-safety: this class is single-threaded. All callbacks fire on the\r\n * Node event loop; callers should never invoke public methods from timer\r\n * callbacks without being aware of reentrancy (e.g., a `stateChanged`\r\n * listener that calls `send()` is fine, but `start()` inside `closed()`\r\n * will re-enter the lifecycle — usually a bug).\r\n */\r\nexport class AgentchatWsClient {\r\n private readonly config: AgentchatChannelConfig\r\n private readonly logger: Logger\r\n private readonly metrics: MetricsRecorder\r\n private readonly now: () => UnixMillis\r\n private readonly WebSocketCtor: typeof NodeWebSocket\r\n private readonly random: () => number\r\n private readonly _setTimeout: (fn: () => void, ms: number) => NodeJS.Timeout\r\n private readonly _clearTimeout: (h: NodeJS.Timeout) => void\r\n private readonly _setInterval: (fn: () => void, ms: number) => NodeJS.Timeout\r\n private readonly _clearInterval: (h: NodeJS.Timeout) => void\r\n\r\n private state: ConnectionState = { kind: 'DISCONNECTED' }\r\n private ws: WsInstance | null = null\r\n private attempt = 0\r\n\r\n private helloAckTimer: NodeJS.Timeout | null = null\r\n private pingTimer: NodeJS.Timeout | null = null\r\n private pongTimer: NodeJS.Timeout | null = null\r\n private reconnectTimer: NodeJS.Timeout | null = null\r\n private drainTimer: NodeJS.Timeout | null = null\r\n\r\n private readonly listeners: {\r\n [K in keyof WsClientEvents]: Set<Listener<K>>\r\n } = {\r\n stateChanged: new Set(),\r\n inboundFrame: new Set(),\r\n error: new Set(),\r\n authenticated: new Set(),\r\n closed: new Set(),\r\n }\r\n\r\n constructor(options: WsClientOptions) {\r\n this.config = options.config\r\n this.logger = options.logger.child({ component: 'ws-client' })\r\n this.metrics = options.metrics\r\n this.now = options.now ?? Date.now\r\n this.WebSocketCtor = options.webSocketCtor ?? NodeWebSocket\r\n this.random = options.random ?? Math.random\r\n this._setTimeout = options.setTimeout ?? ((fn, ms) => setTimeout(fn, ms))\r\n this._clearTimeout = options.clearTimeout ?? ((h) => clearTimeout(h))\r\n this._setInterval = options.setInterval ?? ((fn, ms) => setInterval(fn, ms))\r\n this._clearInterval = options.clearInterval ?? ((h) => clearInterval(h))\r\n\r\n this.metrics.setConnectionState(this.state.kind)\r\n }\r\n\r\n // ─── Public API ──────────────────────────────────────────────────────\r\n\r\n /** Current connection state. Read-only from the caller's perspective. */\r\n getState(): ConnectionState {\r\n return this.state\r\n }\r\n\r\n /**\r\n * Kick off connection. No-op if already connecting, authenticating, or\r\n * ready. Throws on `AUTH_FAIL` — the caller must call `reconfigured()`\r\n * after rotating the API key before retrying.\r\n */\r\n start(): void {\r\n if (this.state.kind === 'AUTH_FAIL') {\r\n throw new AgentChatChannelError(\r\n 'terminal-auth',\r\n 'cannot start: channel is in AUTH_FAIL — rotate api key and call reconfigured()',\r\n )\r\n }\r\n if (this.state.kind === 'CLOSED') {\r\n throw new Error('cannot start: client is closed. Create a new instance.')\r\n }\r\n if (this.state.kind !== 'DISCONNECTED') {\r\n // Already in progress — nothing to do.\r\n return\r\n }\r\n this.openSocket(1)\r\n }\r\n\r\n /**\r\n * Push a client-action frame. Requires `canSend(state)` — returns false\r\n * if the socket is not ready. Callers should queue and retry from the\r\n * outbound adapter (P4) rather than drop here.\r\n */\r\n send(frame: OutboundFrame): boolean {\r\n if (!canSend(this.state) || !this.ws || this.ws.readyState !== NodeWebSocket.OPEN) {\r\n return false\r\n }\r\n try {\r\n this.ws.send(JSON.stringify(frame))\r\n return true\r\n } catch (err) {\r\n this.emitError(\r\n new AgentChatChannelError(\r\n classifyNetworkError(err),\r\n 'ws send failed',\r\n { cause: err },\r\n ),\r\n )\r\n return false\r\n }\r\n }\r\n\r\n /**\r\n * Request a graceful drain. The caller-supplied deadline is a Unix-ms\r\n * timestamp; after it passes, the socket is force-closed regardless of\r\n * remaining in-flight work. Safe to call from any state.\r\n */\r\n stop(deadline?: UnixMillis): void {\r\n const now = this.now()\r\n const computedDeadline = deadline ?? now + 5_000\r\n\r\n if (this.state.kind === 'DRAINING') {\r\n // Second stop() — tighten the deadline if the caller asked for\r\n // earlier closure, otherwise ignore.\r\n if (computedDeadline < this.state.deadline) {\r\n this.applyEvent({ type: 'DRAIN_REQUESTED', now, deadline: computedDeadline })\r\n this.scheduleDrainDeadline(computedDeadline)\r\n }\r\n return\r\n }\r\n\r\n if (isTerminal(this.state)) {\r\n return\r\n }\r\n\r\n this.applyEvent({ type: 'DRAIN_REQUESTED', now, deadline: computedDeadline })\r\n\r\n // `applyEvent` mutated `this.state`; widen the read so TS doesn't\r\n // over-narrow against the pre-apply snapshot (TS tracks the control-flow\r\n // narrowing across the earlier guards and isn't aware the method call\r\n // mutated state).\r\n const after = (this.state as ConnectionState).kind\r\n if (after === 'DRAINING') {\r\n this.scheduleDrainDeadline(computedDeadline)\r\n } else if (after === 'CLOSED') {\r\n this.closeSocket(1000, 'client drain (immediate)')\r\n this.emit('closed')\r\n }\r\n }\r\n\r\n /**\r\n * Signal that operator has rotated the API key. Transitions from\r\n * AUTH_FAIL back to DISCONNECTED; the next `start()` call will attempt\r\n * a fresh HELLO with the current config.\r\n */\r\n reconfigured(): void {\r\n if (this.state.kind !== 'AUTH_FAIL') return\r\n this.applyEvent({ type: 'RECONFIGURED' })\r\n }\r\n\r\n on<E extends keyof WsClientEvents>(event: E, handler: Listener<E>): () => void {\r\n this.listeners[event].add(handler as Listener<E>)\r\n return () => {\r\n this.listeners[event].delete(handler as Listener<E>)\r\n }\r\n }\r\n\r\n // ─── Internals: socket lifecycle ─────────────────────────────────────\r\n\r\n private openSocket(attempt: number): void {\r\n this.attempt = attempt\r\n const now = this.now()\r\n this.applyEvent({ type: 'CONNECT', now, attempt })\r\n\r\n const url = `${this.config.apiBase.replace(/^http/, 'ws')}/v1/ws`\r\n\r\n let ws: WsInstance\r\n try {\r\n ws = new this.WebSocketCtor(url, {\r\n perMessageDeflate: false,\r\n // `ws` auto-pong is on by default — we keep it so heartbeat RTT\r\n // is symmetric even when the server initiates the ping.\r\n maxPayload: MAX_FRAME_BYTES,\r\n })\r\n } catch (err) {\r\n this.emitError(\r\n new AgentChatChannelError(\r\n classifyNetworkError(err),\r\n 'ws constructor threw',\r\n { cause: err },\r\n ),\r\n )\r\n this.scheduleReconnect('ctor-failed')\r\n return\r\n }\r\n\r\n this.ws = ws\r\n this.bindSocket(ws)\r\n }\r\n\r\n private bindSocket(ws: WsInstance): void {\r\n ws.on('open', () => this.handleOpen())\r\n ws.on('message', (data, isBinary) => this.handleMessage(data, isBinary))\r\n ws.on('pong', () => this.handlePong())\r\n ws.on('close', (code, reason) => this.handleClose(code, reason.toString()))\r\n ws.on('error', (err) => {\r\n this.emitError(\r\n new AgentChatChannelError(\r\n classifyNetworkError(err),\r\n 'ws transport error',\r\n { cause: err },\r\n ),\r\n )\r\n // Don't transition here — `close` always follows `error`. Let\r\n // handleClose drive the state transition.\r\n })\r\n }\r\n\r\n private handleOpen(): void {\r\n if (!this.ws) return\r\n const now = this.now()\r\n this.applyEvent({ type: 'SOCKET_OPEN', now })\r\n\r\n // Send HELLO. This is the sole authentication path — the server will\r\n // reject any non-hello frame before `hello.ok` and close 1008.\r\n try {\r\n this.ws.send(\r\n JSON.stringify({ type: 'hello', api_key: this.config.apiKey }),\r\n )\r\n } catch (err) {\r\n this.emitError(\r\n new AgentChatChannelError(\r\n 'retry-transient',\r\n 'hello send failed',\r\n { cause: err },\r\n ),\r\n )\r\n this.closeSocket(1011, 'hello send failed')\r\n return\r\n }\r\n\r\n // Bound the handshake. Server has a 5s HELLO_TIMEOUT; we stay under.\r\n this.helloAckTimer = this._setTimeout(() => {\r\n this.helloAckTimer = null\r\n this.logger.warn({ timeoutMs: HELLO_ACK_TIMEOUT_MS }, 'hello ack timeout')\r\n this.emitError(\r\n new AgentChatChannelError('retry-transient', 'hello ack timeout'),\r\n )\r\n this.closeSocket(1008, 'hello ack timeout')\r\n }, HELLO_ACK_TIMEOUT_MS)\r\n }\r\n\r\n private handleMessage(data: RawData, isBinary: boolean): void {\r\n if (isBinary) {\r\n this.logger.warn({}, 'received binary frame — dropping (text-only protocol)')\r\n return\r\n }\r\n\r\n const received = this.now()\r\n\r\n // `RawData` can be Buffer | ArrayBuffer | Buffer[]. Normalize to string.\r\n const text =\r\n typeof data === 'string'\r\n ? data\r\n : Array.isArray(data)\r\n ? Buffer.concat(data).toString('utf8')\r\n : Buffer.isBuffer(data)\r\n ? data.toString('utf8')\r\n : Buffer.from(data as ArrayBuffer).toString('utf8')\r\n\r\n if (text.length > MAX_FRAME_BYTES) {\r\n this.logger.warn({ bytes: text.length }, 'oversized frame — dropping')\r\n return\r\n }\r\n\r\n let parsed: unknown\r\n try {\r\n parsed = JSON.parse(text)\r\n } catch (err) {\r\n this.emitError(\r\n new AgentChatChannelError(\r\n 'validation',\r\n 'malformed json frame',\r\n { cause: err },\r\n ),\r\n )\r\n return\r\n }\r\n\r\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\r\n this.emitError(\r\n new AgentChatChannelError('validation', 'frame not an object'),\r\n )\r\n return\r\n }\r\n\r\n const obj = parsed as Record<string, unknown>\r\n const type = typeof obj.type === 'string' ? obj.type : null\r\n if (!type) {\r\n this.emitError(\r\n new AgentChatChannelError('validation', 'frame missing type'),\r\n )\r\n return\r\n }\r\n\r\n // Intercept the handshake ack. Never surfaces to subscribers — the\r\n // normalizer (P3) only sees app-level server events.\r\n if (this.state.kind === 'AUTHENTICATING') {\r\n if (type === 'hello.ok') {\r\n this.handleHelloOk(received)\r\n return\r\n }\r\n if (type === 'hello.error' || type === 'auth.rejected' || type === 'error') {\r\n const reason = this.extractReason(obj) ?? 'auth rejected'\r\n this.handleAuthRejected(reason)\r\n return\r\n }\r\n // Frames that arrive mid-handshake before hello.ok are protocol\r\n // violations — close and reconnect.\r\n this.logger.warn({ type }, 'frame arrived before hello.ok — ignoring')\r\n return\r\n }\r\n\r\n // Once authenticated, rate_limit.warning is a soft advisory that the\r\n // upstream outbound adapter should respect. Emit it as an inbound\r\n // frame; metrics bookkeep here.\r\n const payload = this.extractPayload(obj)\r\n\r\n this.emit('inboundFrame', {\r\n type,\r\n payload,\r\n receivedAt: received,\r\n raw: parsed,\r\n })\r\n }\r\n\r\n private extractReason(obj: Record<string, unknown>): string | undefined {\r\n const payload = obj.payload\r\n if (payload && typeof payload === 'object') {\r\n const msg = (payload as Record<string, unknown>).message\r\n if (typeof msg === 'string') return msg\r\n const reason = (payload as Record<string, unknown>).reason\r\n if (typeof reason === 'string') return reason\r\n }\r\n const top = obj.message ?? obj.reason\r\n return typeof top === 'string' ? top : undefined\r\n }\r\n\r\n private extractPayload(obj: Record<string, unknown>): Record<string, unknown> {\r\n const payload = obj.payload\r\n return payload && typeof payload === 'object' && !Array.isArray(payload)\r\n ? (payload as Record<string, unknown>)\r\n : {}\r\n }\r\n\r\n private handleHelloOk(now: UnixMillis): void {\r\n if (this.helloAckTimer) {\r\n this._clearTimeout(this.helloAckTimer)\r\n this.helloAckTimer = null\r\n }\r\n this.applyEvent({ type: 'HELLO_OK', now })\r\n this.attempt = 0\r\n this.startHeartbeat()\r\n this.emit('authenticated', now)\r\n }\r\n\r\n private handleAuthRejected(reason: string): void {\r\n if (this.helloAckTimer) {\r\n this._clearTimeout(this.helloAckTimer)\r\n this.helloAckTimer = null\r\n }\r\n this.logger.error({ reason }, 'auth rejected — moving to AUTH_FAIL')\r\n this.applyEvent({ type: 'AUTH_REJECTED', reason })\r\n this.emitError(\r\n new AgentChatChannelError('terminal-auth', `auth rejected: ${reason}`),\r\n )\r\n this.closeSocket(1008, 'auth rejected')\r\n }\r\n\r\n private handleClose(code: number, reason: string): void {\r\n const now = this.now()\r\n const wasAuthenticating = this.state.kind === 'AUTHENTICATING'\r\n const wasDraining = this.state.kind === 'DRAINING'\r\n const authClass = AUTH_CLOSE_CODES.has(code)\r\n\r\n this.stopHeartbeat()\r\n if (this.helloAckTimer) {\r\n this._clearTimeout(this.helloAckTimer)\r\n this.helloAckTimer = null\r\n }\r\n this.ws = null\r\n\r\n if (authClass && wasAuthenticating) {\r\n this.applyEvent({ type: 'AUTH_REJECTED', reason: `close ${code}: ${reason}` })\r\n this.emitError(\r\n new AgentChatChannelError(\r\n 'terminal-auth',\r\n `socket closed with auth code ${code}: ${reason}`,\r\n ),\r\n )\r\n this.emit('closed')\r\n return\r\n }\r\n\r\n this.applyEvent({ type: 'SOCKET_CLOSED', code, reason })\r\n\r\n if (wasDraining || this.state.kind === 'CLOSED') {\r\n this.emit('closed')\r\n return\r\n }\r\n\r\n this.logger.info(\r\n { code, reason, attempt: this.attempt },\r\n 'socket closed — scheduling reconnect',\r\n )\r\n this.scheduleReconnect(`close-${code}`)\r\n }\r\n\r\n private closeSocket(code: number, reason: string): void {\r\n if (!this.ws) return\r\n try {\r\n this.ws.close(code, reason)\r\n } catch {\r\n // Already closed or in an invalid state — `close` will still fire.\r\n }\r\n }\r\n\r\n // ─── Internals: heartbeat ────────────────────────────────────────────\r\n\r\n private startHeartbeat(): void {\r\n this.stopHeartbeat()\r\n const intervalMs = this.config.ping.intervalMs\r\n this.pingTimer = this._setInterval(() => this.sendPing(), intervalMs)\r\n }\r\n\r\n private stopHeartbeat(): void {\r\n if (this.pingTimer) {\r\n this._clearInterval(this.pingTimer)\r\n this.pingTimer = null\r\n }\r\n if (this.pongTimer) {\r\n this._clearTimeout(this.pongTimer)\r\n this.pongTimer = null\r\n }\r\n }\r\n\r\n private sendPing(): void {\r\n if (!this.ws || this.ws.readyState !== NodeWebSocket.OPEN) return\r\n try {\r\n this.ws.ping()\r\n } catch (err) {\r\n this.emitError(\r\n new AgentChatChannelError(\r\n 'retry-transient',\r\n 'ws ping failed',\r\n { cause: err },\r\n ),\r\n )\r\n return\r\n }\r\n const timeoutMs = this.config.ping.timeoutMs\r\n if (this.pongTimer) this._clearTimeout(this.pongTimer)\r\n this.pongTimer = this._setTimeout(() => {\r\n this.pongTimer = null\r\n const now = this.now()\r\n this.logger.warn({ timeoutMs }, 'ping timeout — declaring degraded')\r\n this.applyEvent({ type: 'PING_TIMEOUT', now })\r\n // The server has gone silent. Force-reconnect — the state machine\r\n // moves READY → DEGRADED on PING_TIMEOUT, but we need to actually\r\n // tear down the socket so `close` re-drives reconnect.\r\n this.closeSocket(1011, 'ping timeout')\r\n }, timeoutMs)\r\n }\r\n\r\n private handlePong(): void {\r\n if (this.pongTimer) {\r\n this._clearTimeout(this.pongTimer)\r\n this.pongTimer = null\r\n }\r\n // If we were in DEGRADED due to backpressure, pong alone isn't the\r\n // recovery signal — backpressure clears when the outbound queue drains.\r\n // But if we were in DEGRADED due to ping-timeout (shouldn't happen —\r\n // we close immediately on that path), a pong would recover us.\r\n if (this.state.kind === 'DEGRADED' && this.state.reason === 'ping-timeout') {\r\n this.applyEvent({ type: 'RECOVERED', now: this.now() })\r\n }\r\n }\r\n\r\n // ─── Internals: reconnect ────────────────────────────────────────────\r\n\r\n private scheduleReconnect(reason: string): void {\r\n if (this.state.kind === 'CLOSED' || this.state.kind === 'AUTH_FAIL') return\r\n if (this.reconnectTimer) return\r\n\r\n const nextAttempt = this.attempt + 1\r\n\r\n if (nextAttempt > RECONNECT_HARD_CAP_ATTEMPTS) {\r\n const msg = `reconnect hard cap (${RECONNECT_HARD_CAP_ATTEMPTS}) reached`\r\n this.logger.error({ attempt: nextAttempt }, msg)\r\n this.applyEvent({ type: 'AUTH_REJECTED', reason: msg })\r\n this.emitError(\r\n new AgentChatChannelError('terminal-auth', msg),\r\n )\r\n return\r\n }\r\n\r\n const delay = this.computeReconnectDelay(nextAttempt)\r\n this.metrics.incReconnect({ reason })\r\n this.logger.info(\r\n { attempt: nextAttempt, delayMs: delay, reason },\r\n 'scheduling reconnect',\r\n )\r\n\r\n this.reconnectTimer = this._setTimeout(() => {\r\n this.reconnectTimer = null\r\n this.openSocket(nextAttempt)\r\n }, delay)\r\n }\r\n\r\n private computeReconnectDelay(attempt: number): number {\r\n const { initialBackoffMs, maxBackoffMs, jitterRatio } = this.config.reconnect\r\n // `attempt` is the total connection count (1 = initial connect, 2+ =\r\n // reconnects). Backoff scales with the *reconnect* count, so the first\r\n // reconnect uses `initialBackoffMs * 2^0 = initialBackoffMs`.\r\n const reconnectCount = Math.max(1, attempt - 1)\r\n const exp = initialBackoffMs * Math.pow(2, Math.min(reconnectCount - 1, 20))\r\n const capped = Math.min(exp, maxBackoffMs)\r\n // Symmetric ±jitterRatio. Thundering-herd-safe: a fleet that all drops\r\n // at the same instant re-enters the connect queue spread across\r\n // capped * [1-jitterRatio, 1+jitterRatio].\r\n const jitter = 1 - jitterRatio + this.random() * 2 * jitterRatio\r\n return Math.max(0, Math.floor(capped * jitter))\r\n }\r\n\r\n // ─── Internals: drain ────────────────────────────────────────────────\r\n\r\n private scheduleDrainDeadline(deadline: UnixMillis): void {\r\n if (this.drainTimer) this._clearTimeout(this.drainTimer)\r\n const now = this.now()\r\n const delay = Math.max(0, deadline - now)\r\n this.drainTimer = this._setTimeout(() => {\r\n this.drainTimer = null\r\n if (this.state.kind === 'DRAINING') {\r\n this.logger.warn({ deadline }, 'drain deadline exceeded — force-closing')\r\n this.applyEvent({ type: 'DRAIN_COMPLETED' })\r\n this.closeSocket(1000, 'drain deadline')\r\n this.emit('closed')\r\n }\r\n }, delay)\r\n }\r\n\r\n /**\r\n * Called by upper layers when their pending work has fully drained, to\r\n * let the WS client transition CLOSED earlier than the deadline.\r\n */\r\n drainCompleted(): void {\r\n if (this.state.kind !== 'DRAINING') return\r\n if (this.drainTimer) {\r\n this._clearTimeout(this.drainTimer)\r\n this.drainTimer = null\r\n }\r\n this.applyEvent({ type: 'DRAIN_COMPLETED' })\r\n this.closeSocket(1000, 'drain completed')\r\n this.emit('closed')\r\n }\r\n\r\n // ─── Internals: state machine + emit ─────────────────────────────────\r\n\r\n private applyEvent(event: ConnectionEvent): void {\r\n const prev = this.state\r\n const next = transition(prev, event)\r\n if (next === prev) {\r\n // No transition — log at debug so we see invalid events without\r\n // crashing. Useful for catching bugs in upper layers.\r\n this.logger.debug(\r\n { from: prev.kind, event: event.type },\r\n 'transition.invalid',\r\n )\r\n return\r\n }\r\n this.state = next\r\n this.metrics.setConnectionState(next.kind)\r\n this.logger.info(\r\n { from: prev.kind, to: next.kind, event: event.type },\r\n 'state transition',\r\n )\r\n this.emit('stateChanged', next, prev)\r\n }\r\n\r\n private emit<E extends keyof WsClientEvents>(\r\n event: E,\r\n ...args: Parameters<WsClientEvents[E]>\r\n ): void {\r\n for (const listener of this.listeners[event]) {\r\n try {\r\n ;(listener as (...a: unknown[]) => void)(...(args as unknown[]))\r\n } catch (err) {\r\n this.logger.error(\r\n { event, err: err instanceof Error ? err.message : String(err) },\r\n 'listener threw — continuing',\r\n )\r\n }\r\n }\r\n }\r\n\r\n private emitError(error: AgentChatChannelError): void {\r\n this.metrics.incOutboundFailed({ errorClass: error.class_ })\r\n this.logger.warn(\r\n { class: error.class_, message: error.message, statusCode: error.statusCode },\r\n 'channel error',\r\n )\r\n this.emit('error', error)\r\n }\r\n}\r\n\r\n/**\r\n * Classify a low-level error with the WS client's conventions — exported\r\n * for integration tests that want to assert on error class directly.\r\n */\r\nexport function classifyWsError(err: unknown): ErrorClass {\r\n return classifyNetworkError(err)\r\n}\r\n","/**\r\n * Inbound normalizer — AgentChat server events → channel-neutral shape.\r\n *\r\n * Responsibilities:\r\n * - Validate every server frame against a Zod schema. Unknown shapes\r\n * surface as `validation` errors (the transport catches them and drops\r\n * the frame without killing the connection).\r\n * - Translate AgentChat-native payloads into a stable, plugin-internal\r\n * `NormalizedInbound` shape. The OpenClaw channel binding (P7 runtime\r\n * wiring) adapts this further to the gateway's `ChannelInboundMessage`\r\n * contract.\r\n * - Classify conversation kind (direct vs group) from the `dir_*`/`grp_*`\r\n * prefix convention so consumers don't need to grep prefixes themselves.\r\n *\r\n * Why this module exists (rather than passing raw frames up):\r\n * - The WS client is pure transport; it shouldn't know what\r\n * `message.new` means semantically.\r\n * - OpenClaw's ChannelInboundMessage has a specific shape (thread id,\r\n * content parts, attachments, sender identity). Converting from\r\n * AgentChat's wire format in one place is the only sane way to keep\r\n * the mapping auditable.\r\n * - Per-event Zod schemas make drift between plugin and server obvious\r\n * and loud — a server field rename surfaces as a validation error\r\n * caught in CI long before it goes to prod.\r\n */\r\n\r\nimport { z } from 'zod'\r\n\r\nimport type { InboundFrame } from './ws-client.js'\r\nimport { AgentChatChannelError } from './errors.js'\r\nimport type { UnixMillis } from './types.js'\r\n\r\n// ─── Conversation-id prefix convention ─────────────────────────────────\r\n//\r\n// Mirrors `apps/api-server/src/services/{message,group}.service.ts`:\r\n// - DM conversations are minted via `generateId('conv')` → `conv_*`\r\n// - Groups are minted via `generateId('grp')` → `grp_*`\r\n//\r\n// We also accept the legacy `dir_` prefix for DMs — pre-production test\r\n// fixtures and docs sometimes used it, and no harm in tolerating both.\r\n\r\nconst DIRECT_PREFIXES = ['conv_', 'dir_'] as const\r\nconst GROUP_PREFIX = 'grp_'\r\n\r\nexport type ConversationKind = 'direct' | 'group'\r\n\r\nexport function classifyConversationId(id: string): ConversationKind | null {\r\n for (const p of DIRECT_PREFIXES) {\r\n if (id.startsWith(p)) return 'direct'\r\n }\r\n if (id.startsWith(GROUP_PREFIX)) return 'group'\r\n return null\r\n}\r\n\r\n// ─── Zod schemas for server events ─────────────────────────────────────\r\n//\r\n// Every field we actually read is `required`; anything else is tolerated\r\n// via `.passthrough()` so a server-side addition doesn't break the plugin.\r\n// Status enum is mirrored from `agentchat/packages/sdk-typescript/src/types/message.ts`.\r\n\r\nconst messageContentSchema = z\r\n .object({\r\n text: z.string().optional(),\r\n data: z.record(z.string(), z.unknown()).optional(),\r\n attachment_id: z.string().optional(),\r\n })\r\n .passthrough()\r\n\r\nconst messageSchema = z\r\n .object({\r\n id: z.string(),\r\n conversation_id: z.string(),\r\n sender: z.string(),\r\n client_msg_id: z.string(),\r\n seq: z.number().int().nonnegative(),\r\n type: z.enum(['text', 'structured', 'file', 'system']),\r\n content: messageContentSchema,\r\n metadata: z.record(z.string(), z.unknown()).default({}),\r\n // Per-recipient delivery state lives in `message_deliveries` since\r\n // migration 011 — the `messages` row no longer carries `status`,\r\n // `delivered_at`, or `read_at`. Fresh-send envelopes over WS omit\r\n // them entirely; the drain path (syncUndelivered) still attaches\r\n // `status: 'stored'` for backlogged frames. Accept both shapes.\r\n status: z.enum(['stored', 'delivered', 'read']).optional(),\r\n created_at: z.string(),\r\n delivered_at: z.string().nullable().optional(),\r\n read_at: z.string().nullable().optional(),\r\n })\r\n .passthrough()\r\n\r\nconst messageNewSchema = messageSchema\r\n\r\nconst messageReadSchema = z\r\n .object({\r\n conversation_id: z.string(),\r\n // Per-agent read cursor. Everything with seq <= through_seq is read.\r\n through_seq: z.number().int().nonnegative(),\r\n // Handle of the reader (who moved their cursor).\r\n reader: z.string(),\r\n at: z.string().optional(),\r\n })\r\n .passthrough()\r\n\r\nconst typingSchema = z\r\n .object({\r\n conversation_id: z.string(),\r\n sender: z.string(),\r\n })\r\n .passthrough()\r\n\r\nconst presenceUpdateSchema = z\r\n .object({\r\n handle: z.string(),\r\n status: z.enum(['online', 'away', 'offline']),\r\n last_active_at: z.string().optional(),\r\n custom_status: z.string().nullable().optional(),\r\n })\r\n .passthrough()\r\n\r\nconst rateLimitWarningSchema = z\r\n .object({\r\n endpoint: z.string().optional(),\r\n limit: z.number().optional(),\r\n remaining: z.number().optional(),\r\n reset_at: z.string().optional(),\r\n message: z.string().optional(),\r\n })\r\n .passthrough()\r\n\r\nconst groupInviteReceivedSchema = z\r\n .object({\r\n id: z.string(),\r\n group_id: z.string(),\r\n group_name: z.string(),\r\n group_description: z.string().nullable().optional(),\r\n group_avatar_url: z.string().nullable().optional(),\r\n group_member_count: z.number().int().nonnegative(),\r\n inviter_handle: z.string(),\r\n created_at: z.string(),\r\n })\r\n .passthrough()\r\n\r\nconst groupDeletedSchema = z\r\n .object({\r\n group_id: z.string(),\r\n deleted_by_handle: z.string(),\r\n deleted_at: z.string(),\r\n })\r\n .passthrough()\r\n\r\n// ─── Normalized shapes ─────────────────────────────────────────────────\r\n\r\nexport interface NormalizedMessage {\r\n readonly kind: 'message'\r\n readonly conversationKind: ConversationKind\r\n readonly conversationId: string\r\n /** Sender handle. */\r\n readonly sender: string\r\n readonly messageId: string\r\n readonly clientMsgId: string\r\n readonly seq: number\r\n readonly messageType: 'text' | 'structured' | 'file' | 'system'\r\n readonly content: {\r\n readonly text?: string\r\n readonly data?: Record<string, unknown>\r\n readonly attachmentId?: string\r\n }\r\n readonly metadata: Record<string, unknown>\r\n /**\r\n * Per-recipient delivery state. Since migration 011, per-recipient state\r\n * lives on `message_deliveries`, not the message row — so fresh-send\r\n * `message.new` envelopes have no status field. Drain-path (sync /\r\n * undelivered) envelopes still include `'stored'`. `null` means the\r\n * server didn't attach one; callers that need the authoritative state\r\n * should query `GET /v1/messages/sync` or `/delivery-receipts`.\r\n */\r\n readonly status: 'stored' | 'delivered' | 'read' | null\r\n readonly createdAt: string\r\n readonly deliveredAt: string | null\r\n readonly readAt: string | null\r\n readonly receivedAt: UnixMillis\r\n}\r\n\r\nexport interface NormalizedReadReceipt {\r\n readonly kind: 'read-receipt'\r\n readonly conversationKind: ConversationKind\r\n readonly conversationId: string\r\n readonly reader: string\r\n readonly throughSeq: number\r\n readonly at: string | null\r\n readonly receivedAt: UnixMillis\r\n}\r\n\r\nexport interface NormalizedTyping {\r\n readonly kind: 'typing'\r\n readonly action: 'start' | 'stop'\r\n readonly conversationKind: ConversationKind\r\n readonly conversationId: string\r\n readonly sender: string\r\n readonly receivedAt: UnixMillis\r\n}\r\n\r\nexport interface NormalizedPresence {\r\n readonly kind: 'presence'\r\n readonly handle: string\r\n readonly status: 'online' | 'away' | 'offline'\r\n readonly lastActiveAt: string | null\r\n readonly customStatus: string | null\r\n readonly receivedAt: UnixMillis\r\n}\r\n\r\nexport interface NormalizedRateLimitWarning {\r\n readonly kind: 'rate-limit-warning'\r\n readonly endpoint: string | null\r\n readonly limit: number | null\r\n readonly remaining: number | null\r\n readonly resetAt: string | null\r\n readonly message: string | null\r\n readonly receivedAt: UnixMillis\r\n}\r\n\r\nexport interface NormalizedGroupInvite {\r\n readonly kind: 'group-invite'\r\n readonly inviteId: string\r\n readonly groupId: string\r\n readonly groupName: string\r\n readonly groupDescription: string | null\r\n readonly groupAvatarUrl: string | null\r\n readonly groupMemberCount: number\r\n readonly inviterHandle: string\r\n readonly createdAt: string\r\n readonly receivedAt: UnixMillis\r\n}\r\n\r\nexport interface NormalizedGroupDeleted {\r\n readonly kind: 'group-deleted'\r\n readonly groupId: string\r\n readonly deletedByHandle: string\r\n readonly deletedAt: string\r\n readonly receivedAt: UnixMillis\r\n}\r\n\r\n/**\r\n * Unknown server event — arrived over the wire but isn't in our explicit\r\n * handler set. We still surface it (the gateway may want to log it or\r\n * forward it), but with a `type` field so downstream can discriminate.\r\n */\r\nexport interface NormalizedUnknown {\r\n readonly kind: 'unknown'\r\n readonly type: string\r\n readonly payload: Record<string, unknown>\r\n readonly receivedAt: UnixMillis\r\n}\r\n\r\nexport type NormalizedInbound =\r\n | NormalizedMessage\r\n | NormalizedReadReceipt\r\n | NormalizedTyping\r\n | NormalizedPresence\r\n | NormalizedRateLimitWarning\r\n | NormalizedGroupInvite\r\n | NormalizedGroupDeleted\r\n | NormalizedUnknown\r\n\r\n// ─── Normalize entrypoint ──────────────────────────────────────────────\r\n\r\n/**\r\n * Normalize a raw inbound frame into a channel-neutral shape.\r\n *\r\n * Throws `AgentChatChannelError` with class `validation` if the payload\r\n * fails its schema. Callers (the runtime) should log + drop the frame\r\n * rather than propagate the throw — the connection stays healthy.\r\n */\r\nexport function normalizeInbound(frame: InboundFrame): NormalizedInbound {\r\n switch (frame.type) {\r\n case 'message.new':\r\n return normalizeMessageNew(frame)\r\n case 'message.read':\r\n return normalizeMessageRead(frame)\r\n case 'typing.start':\r\n return normalizeTyping(frame, 'start')\r\n case 'typing.stop':\r\n return normalizeTyping(frame, 'stop')\r\n case 'presence.update':\r\n return normalizePresence(frame)\r\n case 'rate_limit.warning':\r\n return normalizeRateLimitWarning(frame)\r\n case 'group.invite.received':\r\n return normalizeGroupInvite(frame)\r\n case 'group.deleted':\r\n return normalizeGroupDeleted(frame)\r\n default:\r\n return {\r\n kind: 'unknown',\r\n type: frame.type,\r\n payload: frame.payload,\r\n receivedAt: frame.receivedAt,\r\n }\r\n }\r\n}\r\n\r\nfunction validate<T>(schema: z.ZodType<T>, payload: unknown, eventType: string): T {\r\n const parsed = schema.safeParse(payload)\r\n if (!parsed.success) {\r\n throw new AgentChatChannelError(\r\n 'validation',\r\n `inbound ${eventType} schema invalid: ${parsed.error.message}`,\r\n { cause: parsed.error },\r\n )\r\n }\r\n return parsed.data\r\n}\r\n\r\nfunction requireConvKind(conversationId: string, eventType: string): ConversationKind {\r\n const kind = classifyConversationId(conversationId)\r\n if (!kind) {\r\n throw new AgentChatChannelError(\r\n 'validation',\r\n `inbound ${eventType} has unknown conversation id prefix: ${conversationId}`,\r\n )\r\n }\r\n return kind\r\n}\r\n\r\nfunction normalizeMessageNew(frame: InboundFrame): NormalizedMessage {\r\n const msg = validate(messageNewSchema, frame.payload, 'message.new')\r\n const conversationKind = requireConvKind(msg.conversation_id, 'message.new')\r\n return {\r\n kind: 'message',\r\n conversationKind,\r\n conversationId: msg.conversation_id,\r\n sender: msg.sender,\r\n messageId: msg.id,\r\n clientMsgId: msg.client_msg_id,\r\n seq: msg.seq,\r\n messageType: msg.type,\r\n content: {\r\n text: msg.content.text,\r\n data: msg.content.data,\r\n attachmentId: msg.content.attachment_id,\r\n },\r\n metadata: msg.metadata,\r\n status: msg.status ?? null,\r\n createdAt: msg.created_at,\r\n deliveredAt: msg.delivered_at ?? null,\r\n readAt: msg.read_at ?? null,\r\n receivedAt: frame.receivedAt,\r\n }\r\n}\r\n\r\nfunction normalizeMessageRead(frame: InboundFrame): NormalizedReadReceipt {\r\n const body = validate(messageReadSchema, frame.payload, 'message.read')\r\n const conversationKind = requireConvKind(body.conversation_id, 'message.read')\r\n return {\r\n kind: 'read-receipt',\r\n conversationKind,\r\n conversationId: body.conversation_id,\r\n reader: body.reader,\r\n throughSeq: body.through_seq,\r\n at: body.at ?? null,\r\n receivedAt: frame.receivedAt,\r\n }\r\n}\r\n\r\nfunction normalizeTyping(frame: InboundFrame, action: 'start' | 'stop'): NormalizedTyping {\r\n const body = validate(typingSchema, frame.payload, `typing.${action}`)\r\n const conversationKind = requireConvKind(body.conversation_id, `typing.${action}`)\r\n return {\r\n kind: 'typing',\r\n action,\r\n conversationKind,\r\n conversationId: body.conversation_id,\r\n sender: body.sender,\r\n receivedAt: frame.receivedAt,\r\n }\r\n}\r\n\r\nfunction normalizePresence(frame: InboundFrame): NormalizedPresence {\r\n const body = validate(presenceUpdateSchema, frame.payload, 'presence.update')\r\n return {\r\n kind: 'presence',\r\n handle: body.handle,\r\n status: body.status,\r\n lastActiveAt: body.last_active_at ?? null,\r\n customStatus: body.custom_status ?? null,\r\n receivedAt: frame.receivedAt,\r\n }\r\n}\r\n\r\nfunction normalizeRateLimitWarning(frame: InboundFrame): NormalizedRateLimitWarning {\r\n const body = validate(rateLimitWarningSchema, frame.payload, 'rate_limit.warning')\r\n return {\r\n kind: 'rate-limit-warning',\r\n endpoint: body.endpoint ?? null,\r\n limit: body.limit ?? null,\r\n remaining: body.remaining ?? null,\r\n resetAt: body.reset_at ?? null,\r\n message: body.message ?? null,\r\n receivedAt: frame.receivedAt,\r\n }\r\n}\r\n\r\nfunction normalizeGroupInvite(frame: InboundFrame): NormalizedGroupInvite {\r\n const body = validate(groupInviteReceivedSchema, frame.payload, 'group.invite.received')\r\n return {\r\n kind: 'group-invite',\r\n inviteId: body.id,\r\n groupId: body.group_id,\r\n groupName: body.group_name,\r\n groupDescription: body.group_description ?? null,\r\n groupAvatarUrl: body.group_avatar_url ?? null,\r\n groupMemberCount: body.group_member_count,\r\n inviterHandle: body.inviter_handle,\r\n createdAt: body.created_at,\r\n receivedAt: frame.receivedAt,\r\n }\r\n}\r\n\r\nfunction normalizeGroupDeleted(frame: InboundFrame): NormalizedGroupDeleted {\r\n const body = validate(groupDeletedSchema, frame.payload, 'group.deleted')\r\n return {\r\n kind: 'group-deleted',\r\n groupId: body.group_id,\r\n deletedByHandle: body.deleted_by_handle,\r\n deletedAt: body.deleted_at,\r\n receivedAt: frame.receivedAt,\r\n }\r\n}\r\n","/**\r\n * Retry + circuit-breaker primitives for outbound AgentChat API calls.\r\n *\r\n * Why not just use the SDK's retry policy?\r\n * - The SDK's retry is a \"best-effort per-request\" policy: a 429 triggers\r\n * a bounded delay, a 5xx triggers exponential backoff, done. That works\r\n * for a CLI tool or one-shot send.\r\n * - A channel plugin runs continuously and must degrade gracefully under\r\n * sustained failure: if the API is down for 60 seconds, we should stop\r\n * hammering it, open a circuit, and let a background probe close it\r\n * back when it recovers. Without this, a dead API becomes a retry\r\n * storm that multiplies every outbound send by the full retry budget.\r\n *\r\n * This module provides two orthogonal pieces:\r\n * - `retryWithPolicy(fn, policy, classify)` — a typed exponential-backoff\r\n * retry wrapper that respects `AgentChatChannelError.retryAfterMs` from\r\n * 429 responses and stops retrying immediately on terminal classes.\r\n * - `CircuitBreaker` — classic half-open pattern. After `failureThreshold`\r\n * consecutive transient failures inside `windowMs`, the circuit opens\r\n * for `cooldownMs`. Subsequent calls fast-fail as `circuit-open`. After\r\n * cooldown, one probe request is allowed; success closes, failure\r\n * re-opens for another cooldown.\r\n *\r\n * Both are pure; they take a clock + random source so tests drive them\r\n * deterministically without fake timers.\r\n */\r\n\r\nimport { AgentChatChannelError, type ErrorClass } from './errors.js'\r\nimport type { UnixMillis } from './types.js'\r\n\r\n// ─── Retry policy ──────────────────────────────────────────────────────\r\n\r\nexport interface RetryPolicy {\r\n readonly maxAttempts: number\r\n readonly initialBackoffMs: number\r\n readonly maxBackoffMs: number\r\n readonly jitterRatio: number\r\n /** Clock source. Default: Date.now. */\r\n readonly now?: () => UnixMillis\r\n /** Random source for jitter. Default: Math.random. */\r\n readonly random?: () => number\r\n /** Sleep implementation. Default: setTimeout-based. */\r\n readonly sleep?: (ms: number) => Promise<void>\r\n}\r\n\r\nexport interface RetryOutcome<T> {\r\n readonly result: T\r\n readonly attempts: number\r\n readonly totalDelayMs: number\r\n}\r\n\r\n/** Default sleep — replaceable by tests via the policy.sleep override. */\r\nfunction defaultSleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms))\r\n}\r\n\r\n/**\r\n * Execute `fn` with retry. Returns the successful result + attempt count.\r\n * Throws the last error if all attempts exhaust.\r\n *\r\n * Retry rules:\r\n * - Error classes `terminal-auth`, `terminal-user`, `validation` throw\r\n * immediately without retry.\r\n * - `idempotent-replay` is treated as success by the caller, not this\r\n * layer — caller converts it before throwing.\r\n * - `retry-rate` uses the server-provided `retryAfterMs` when present,\r\n * else the jittered exponential backoff.\r\n * - `retry-transient` always uses jittered exponential.\r\n */\r\nexport async function retryWithPolicy<T>(\r\n fn: (attempt: number) => Promise<T>,\r\n policy: RetryPolicy,\r\n): Promise<RetryOutcome<T>> {\r\n const random = policy.random ?? Math.random\r\n const sleep = policy.sleep ?? defaultSleep\r\n let totalDelayMs = 0\r\n let lastErr: unknown\r\n\r\n for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {\r\n try {\r\n const result = await fn(attempt)\r\n return { result, attempts: attempt, totalDelayMs }\r\n } catch (err) {\r\n lastErr = err\r\n if (!(err instanceof AgentChatChannelError)) {\r\n throw err\r\n }\r\n if (isTerminalClass(err.class_)) {\r\n throw err\r\n }\r\n if (attempt >= policy.maxAttempts) {\r\n throw err\r\n }\r\n const delay = backoffDelay({\r\n attempt,\r\n errorClass: err.class_,\r\n retryAfterMs: err.retryAfterMs,\r\n policy,\r\n random,\r\n })\r\n totalDelayMs += delay\r\n await sleep(delay)\r\n }\r\n }\r\n throw lastErr\r\n}\r\n\r\nfunction isTerminalClass(class_: ErrorClass): boolean {\r\n // `idempotent-replay` is surfaced as a \"do-not-retry\" signal: the server\r\n // has already persisted a message with this client_msg_id (either from\r\n // this or a concurrent caller). Retrying won't help — the caller needs\r\n // to treat the original message as the canonical one.\r\n return (\r\n class_ === 'terminal-auth' ||\r\n class_ === 'terminal-user' ||\r\n class_ === 'validation' ||\r\n class_ === 'idempotent-replay'\r\n )\r\n}\r\n\r\ninterface BackoffInput {\r\n attempt: number\r\n errorClass: ErrorClass\r\n retryAfterMs: number | undefined\r\n policy: RetryPolicy\r\n random: () => number\r\n}\r\n\r\nfunction backoffDelay({ attempt, errorClass, retryAfterMs, policy, random }: BackoffInput): number {\r\n // 429 with server-provided hint: obey it exactly (plus a small jitter so\r\n // a synchronized fleet doesn't all wake at the exact same instant).\r\n if (errorClass === 'retry-rate' && typeof retryAfterMs === 'number') {\r\n const jitter = 1 + random() * policy.jitterRatio\r\n return Math.min(policy.maxBackoffMs, Math.floor(retryAfterMs * jitter))\r\n }\r\n const exp = policy.initialBackoffMs * Math.pow(2, Math.min(attempt - 1, 20))\r\n const capped = Math.min(exp, policy.maxBackoffMs)\r\n const jitter = 1 - policy.jitterRatio + random() * 2 * policy.jitterRatio\r\n return Math.max(0, Math.floor(capped * jitter))\r\n}\r\n\r\n// ─── Circuit breaker ───────────────────────────────────────────────────\r\n\r\nexport type CircuitState = 'closed' | 'open' | 'half-open'\r\n\r\nexport interface CircuitBreakerOptions {\r\n readonly failureThreshold: number\r\n /** Open the circuit when `failureThreshold` failures occur inside this window. */\r\n readonly windowMs: number\r\n readonly cooldownMs: number\r\n readonly now?: () => UnixMillis\r\n}\r\n\r\nexport interface CircuitSnapshot {\r\n readonly state: CircuitState\r\n readonly recentFailures: number\r\n readonly openedAt: UnixMillis | null\r\n readonly halfOpenAt: UnixMillis | null\r\n}\r\n\r\n/**\r\n * Single-process circuit breaker. Not distributed — each channel instance\r\n * has its own view. For a multi-instance deployment, the open-circuit\r\n * signal is observable via metrics (each instance emits `circuit_state`)\r\n * but each instance must independently detect the outage.\r\n */\r\nexport class CircuitBreaker {\r\n private readonly opts: CircuitBreakerOptions\r\n private readonly now: () => UnixMillis\r\n private state: CircuitState = 'closed'\r\n private failureTimestamps: UnixMillis[] = []\r\n private openedAt: UnixMillis | null = null\r\n private halfOpenAt: UnixMillis | null = null\r\n\r\n constructor(opts: CircuitBreakerOptions) {\r\n this.opts = opts\r\n this.now = opts.now ?? Date.now\r\n }\r\n\r\n snapshot(): CircuitSnapshot {\r\n return {\r\n state: this.state,\r\n recentFailures: this.failureTimestamps.length,\r\n openedAt: this.openedAt,\r\n halfOpenAt: this.halfOpenAt,\r\n }\r\n }\r\n\r\n /**\r\n * Check state at call time.\r\n * - `closed` / `half-open` → returns `{ allow: true }`. Caller must\r\n * invoke `onSuccess()` / `onFailure()` after the attempt.\r\n * - `open` → returns `{ allow: false, reason }` so the caller can\r\n * fast-fail without making the network call. If the cooldown has\r\n * elapsed, transitions to `half-open` first and allows one probe.\r\n */\r\n precheck(): { allow: true } | { allow: false; reason: string } {\r\n if (this.state === 'open') {\r\n const now = this.now()\r\n const elapsed = now - (this.openedAt ?? now)\r\n if (elapsed >= this.opts.cooldownMs) {\r\n this.state = 'half-open'\r\n this.halfOpenAt = now\r\n return { allow: true }\r\n }\r\n return { allow: false, reason: 'circuit open — API appears unhealthy' }\r\n }\r\n return { allow: true }\r\n }\r\n\r\n onSuccess(): void {\r\n if (this.state === 'half-open') {\r\n this.state = 'closed'\r\n this.openedAt = null\r\n this.halfOpenAt = null\r\n }\r\n this.failureTimestamps = []\r\n }\r\n\r\n /**\r\n * Record a failure. Only transient classes count toward the breaker —\r\n * terminal-auth/terminal-user/validation failures are caller bugs or\r\n * server contract violations, not \"API down\" signals.\r\n */\r\n onFailure(errorClass: ErrorClass): void {\r\n if (isTerminalClass(errorClass)) return\r\n\r\n const now = this.now()\r\n\r\n if (this.state === 'half-open') {\r\n // Probe failed — re-open immediately.\r\n this.state = 'open'\r\n this.openedAt = now\r\n this.halfOpenAt = null\r\n return\r\n }\r\n\r\n this.failureTimestamps.push(now)\r\n this.trimOldFailures(now)\r\n\r\n if (this.failureTimestamps.length >= this.opts.failureThreshold) {\r\n this.state = 'open'\r\n this.openedAt = now\r\n }\r\n }\r\n\r\n private trimOldFailures(now: UnixMillis): void {\r\n const cutoff = now - this.opts.windowMs\r\n let firstFresh = 0\r\n while (\r\n firstFresh < this.failureTimestamps.length &&\r\n this.failureTimestamps[firstFresh]! < cutoff\r\n ) {\r\n firstFresh++\r\n }\r\n if (firstFresh > 0) this.failureTimestamps.splice(0, firstFresh)\r\n }\r\n}\r\n","/**\r\n * Single source of truth for the package version string.\r\n *\r\n * Kept as a hand-edited constant (not an `import ... from '../package.json'`)\r\n * so that tsup can bundle ESM/CJS without requiring `resolveJsonModule` +\r\n * runtime filesystem access from inside the published dist. A unit test\r\n * (`tests/version.test.ts`) pins this against `package.json` so bumping one\r\n * without the other fails CI.\r\n */\r\nexport const PACKAGE_VERSION = '0.2.0'\r\n","/**\r\n * Outbound adapter — OpenClaw send → AgentChat `POST /v1/messages`.\r\n *\r\n * Pipeline (left to right, each step is independently observable):\r\n * 1. Caller invokes `sendMessage(input)` with a channel-neutral shape.\r\n * 2. We derive a stable `client_msg_id` (idempotency key). If the caller\r\n * supplied one, we respect it; otherwise we mint a UUID.\r\n * 3. Circuit-breaker precheck. Open circuit → fast-fail `retry-transient`.\r\n * 4. `retryWithPolicy(...)` wraps the actual HTTP call.\r\n * 5. On success, metrics/logs + return the `Message` the server minted.\r\n * 6. On 409 (idempotent-replay), treat as success with the replay body.\r\n * 7. On 429, honor `Retry-After` (seconds or HTTP-date) via the retry\r\n * policy. Surface as `retry-rate`.\r\n * 8. On 5xx / network flap, retry with jittered exponential backoff.\r\n * 9. On 4xx other than 429/409, classify as `terminal-user` → no retry.\r\n * 10. On 401/403 → `terminal-auth`. We signal upstream so the WS client\r\n * moves to AUTH_FAIL and the operator gets paged.\r\n *\r\n * Backpressure:\r\n * - An in-flight semaphore bounds concurrent sends to `outbound.maxInFlight`.\r\n * - Over-threshold sends are enqueued and drained as capacity frees up.\r\n * - Queue has its own hard cap (`10 * maxInFlight`); over-cap sends reject\r\n * immediately with `retry-transient` so the caller can shed load rather\r\n * than OOM.\r\n */\r\n\r\nimport type { Message } from './types/message.js'\r\n\r\nimport { AgentChatChannelError, classifyHttpStatus, classifyNetworkError, parseRetryAfter } from './errors.js'\r\nimport type { Logger } from './log.js'\r\nimport type { MetricsRecorder } from './metrics.js'\r\nimport { CircuitBreaker, retryWithPolicy, type CircuitBreakerOptions, type RetryPolicy } from './retry.js'\r\nimport type { AgentchatChannelConfig } from './config-schema.js'\r\nimport type { UnixMillis } from './types.js'\r\nimport { PACKAGE_VERSION } from './version.js'\r\n\r\n// ─── Types ─────────────────────────────────────────────────────────────\r\n\r\nexport type OutboundMessageInput =\r\n | OutboundDirectMessage\r\n | OutboundGroupMessage\r\n\r\nexport interface OutboundMessageBase {\r\n /**\r\n * Client-generated idempotency key. Optional — we mint one if absent.\r\n * Retries of the same logical send MUST reuse the same value or you'll\r\n * get duplicates.\r\n */\r\n readonly clientMsgId?: string\r\n readonly type?: 'text' | 'structured' | 'file'\r\n readonly content: {\r\n readonly text?: string\r\n readonly data?: Record<string, unknown>\r\n readonly attachmentId?: string\r\n }\r\n readonly metadata?: Record<string, unknown>\r\n /** Correlation id carried through logs and metrics. */\r\n readonly correlationId?: string\r\n}\r\n\r\nexport interface OutboundDirectMessage extends OutboundMessageBase {\r\n readonly kind: 'direct'\r\n /** Recipient handle (e.g. \"alice\"). */\r\n readonly to: string\r\n}\r\n\r\nexport interface OutboundGroupMessage extends OutboundMessageBase {\r\n readonly kind: 'group'\r\n /** `grp_*` conversation id. */\r\n readonly conversationId: string\r\n}\r\n\r\nexport interface OutboundBacklogWarning {\r\n readonly recipientHandle: string\r\n readonly undeliveredCount: number\r\n}\r\n\r\nexport interface SendResult {\r\n readonly message: Message\r\n readonly backlogWarning: OutboundBacklogWarning | null\r\n readonly idempotentReplay: boolean\r\n readonly attempts: number\r\n readonly latencyMs: number\r\n readonly requestId: string | null\r\n}\r\n\r\nexport interface OutboundAdapterOptions {\r\n readonly config: AgentchatChannelConfig\r\n readonly logger: Logger\r\n readonly metrics: MetricsRecorder\r\n readonly fetch?: typeof fetch\r\n readonly now?: () => UnixMillis\r\n readonly random?: () => number\r\n readonly sleep?: (ms: number) => Promise<void>\r\n readonly circuitBreaker?: CircuitBreakerOptions\r\n readonly retryPolicy?: Partial<RetryPolicy>\r\n /** Surface backlog warnings to upstream — optional observability hook. */\r\n readonly onBacklogWarning?: (warning: OutboundBacklogWarning) => void\r\n}\r\n\r\nconst DEFAULT_RETRY_POLICY: Omit<RetryPolicy, 'now' | 'random' | 'sleep'> = {\r\n maxAttempts: 4,\r\n initialBackoffMs: 250,\r\n maxBackoffMs: 10_000,\r\n jitterRatio: 0.3,\r\n}\r\n\r\nconst DEFAULT_CIRCUIT_OPTIONS: CircuitBreakerOptions = {\r\n failureThreshold: 10,\r\n windowMs: 60_000,\r\n cooldownMs: 30_000,\r\n}\r\n\r\n// ─── Adapter ───────────────────────────────────────────────────────────\r\n\r\nexport class OutboundAdapter {\r\n private readonly config: AgentchatChannelConfig\r\n private readonly logger: Logger\r\n private readonly metrics: MetricsRecorder\r\n private readonly fetchImpl: typeof fetch\r\n private readonly now: () => UnixMillis\r\n private readonly breaker: CircuitBreaker\r\n private readonly retryPolicy: RetryPolicy\r\n private readonly onBacklogWarning?: (warning: OutboundBacklogWarning) => void\r\n\r\n // Backpressure bookkeeping.\r\n private inFlight = 0\r\n private readonly queue: Array<() => void> = []\r\n private readonly queueHardCap: number\r\n\r\n constructor(opts: OutboundAdapterOptions) {\r\n this.config = opts.config\r\n this.logger = opts.logger.child({ component: 'outbound' })\r\n this.metrics = opts.metrics\r\n this.fetchImpl = opts.fetch ?? fetch\r\n this.now = opts.now ?? Date.now\r\n this.onBacklogWarning = opts.onBacklogWarning\r\n this.breaker = new CircuitBreaker(opts.circuitBreaker ?? DEFAULT_CIRCUIT_OPTIONS)\r\n this.retryPolicy = {\r\n ...DEFAULT_RETRY_POLICY,\r\n ...opts.retryPolicy,\r\n now: opts.now,\r\n random: opts.random,\r\n sleep: opts.sleep,\r\n }\r\n this.queueHardCap = Math.max(10, this.config.outbound.maxInFlight * 10)\r\n }\r\n\r\n /**\r\n * Send a message. Returns on success; throws `AgentChatChannelError` on\r\n * terminal or exhausted-retry failure. The returned `SendResult.message`\r\n * is the row the server minted (or echoed back on idempotent replay).\r\n */\r\n async sendMessage(input: OutboundMessageInput): Promise<SendResult> {\r\n const clientMsgId = input.clientMsgId ?? this.mintClientMsgId()\r\n const correlationId = input.correlationId ?? clientMsgId\r\n const log = this.logger.child({ clientMsgId, correlationId, kind: input.kind })\r\n\r\n const precheck = this.breaker.precheck()\r\n if (!precheck.allow) {\r\n this.metrics.incOutboundFailed({ errorClass: 'retry-transient' })\r\n throw new AgentChatChannelError('retry-transient', precheck.reason)\r\n }\r\n\r\n await this.acquireSlot()\r\n const startedAt = this.now()\r\n try {\r\n const outcome = await retryWithPolicy(\r\n (attempt) => this.sendOnce({ input, clientMsgId, attempt, log }),\r\n this.retryPolicy,\r\n )\r\n const endedAt = this.now()\r\n this.breaker.onSuccess()\r\n this.metrics.incOutboundSent({ kind: 'message' })\r\n this.metrics.observeSendLatency(endedAt - startedAt)\r\n return {\r\n ...outcome.result,\r\n attempts: outcome.attempts,\r\n latencyMs: endedAt - startedAt,\r\n }\r\n } catch (err) {\r\n if (err instanceof AgentChatChannelError) {\r\n this.breaker.onFailure(err.class_)\r\n this.metrics.incOutboundFailed({ errorClass: err.class_ })\r\n log.warn(\r\n { class: err.class_, status: err.statusCode, msg: err.message },\r\n 'send failed',\r\n )\r\n } else {\r\n this.metrics.incOutboundFailed({ errorClass: 'retry-transient' })\r\n log.error(\r\n { err: err instanceof Error ? err.message : String(err) },\r\n 'send failed — unexpected error',\r\n )\r\n }\r\n throw err\r\n } finally {\r\n this.releaseSlot()\r\n }\r\n }\r\n\r\n /** Current state for observability / health checks. */\r\n snapshot(): { inFlight: number; queued: number; circuit: ReturnType<CircuitBreaker['snapshot']> } {\r\n return {\r\n inFlight: this.inFlight,\r\n queued: this.queue.length,\r\n circuit: this.breaker.snapshot(),\r\n }\r\n }\r\n\r\n // ─── Internals ───────────────────────────────────────────────────────\r\n\r\n private async sendOnce(args: {\r\n input: OutboundMessageInput\r\n clientMsgId: string\r\n attempt: number\r\n log: Logger\r\n }): Promise<Omit<SendResult, 'attempts' | 'latencyMs'>> {\r\n const { input, clientMsgId, attempt, log } = args\r\n const body = this.buildBody(input, clientMsgId)\r\n const url = `${this.config.apiBase}/v1/messages`\r\n const headers: Record<string, string> = {\r\n 'authorization': `Bearer ${this.config.apiKey}`,\r\n 'content-type': 'application/json',\r\n 'user-agent': `@agentchatme/openclaw/${PACKAGE_VERSION} (+attempt=${attempt})`,\r\n }\r\n\r\n let res: Response\r\n try {\r\n res = await this.fetchImpl(url, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify(body),\r\n })\r\n } catch (err) {\r\n throw new AgentChatChannelError(\r\n classifyNetworkError(err),\r\n `POST /v1/messages network error: ${err instanceof Error ? err.message : String(err)}`,\r\n { cause: err },\r\n )\r\n }\r\n\r\n const requestId = res.headers.get('x-request-id')\r\n const idempotentReplay = res.headers.get('idempotent-replay') === 'true'\r\n const backlogWarning = this.parseBacklogWarning(res.headers.get('x-backlog-warning'))\r\n\r\n if (res.ok) {\r\n const message = (await res.json().catch(() => null)) as Message | null\r\n if (!message || typeof message !== 'object') {\r\n throw new AgentChatChannelError(\r\n 'validation',\r\n 'POST /v1/messages returned non-JSON success body',\r\n { statusCode: res.status },\r\n )\r\n }\r\n if (idempotentReplay) {\r\n log.info({ status: res.status, requestId }, 'idempotent replay — server echoed existing message')\r\n }\r\n if (backlogWarning && this.onBacklogWarning) {\r\n try {\r\n this.onBacklogWarning(backlogWarning)\r\n } catch (err) {\r\n // Handler errors must not break send, but silent swallow leaves\r\n // operators blind — log it so the failure is at least diagnosable.\r\n log.error(\r\n { err: err instanceof Error ? err.message : String(err) },\r\n 'onBacklogWarning handler threw — swallowed to protect send path',\r\n )\r\n }\r\n }\r\n return { message, backlogWarning, idempotentReplay, requestId }\r\n }\r\n\r\n // 2xx-none-of-the-above path: parse error body, classify, throw.\r\n const errorBody = await res.json().catch(() => null)\r\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'), this.now())\r\n const errorClass = classifyHttpStatus(res.status, res.headers.get('retry-after'))\r\n const serverMessage =\r\n (errorBody as { message?: unknown } | null)?.message ?? `HTTP ${res.status}`\r\n throw new AgentChatChannelError(\r\n errorClass,\r\n typeof serverMessage === 'string' ? serverMessage : `HTTP ${res.status}`,\r\n {\r\n statusCode: res.status,\r\n retryAfterMs: retryAfter,\r\n },\r\n )\r\n }\r\n\r\n private buildBody(input: OutboundMessageInput, clientMsgId: string): Record<string, unknown> {\r\n const content: Record<string, unknown> = {}\r\n if (input.content.text !== undefined) content.text = input.content.text\r\n if (input.content.data !== undefined) content.data = input.content.data\r\n if (input.content.attachmentId !== undefined) content.attachment_id = input.content.attachmentId\r\n\r\n if (Object.keys(content).length === 0) {\r\n throw new AgentChatChannelError(\r\n 'terminal-user',\r\n 'outbound message has empty content — at least one of text/data/attachmentId required',\r\n )\r\n }\r\n\r\n const body: Record<string, unknown> = {\r\n client_msg_id: clientMsgId,\r\n content,\r\n }\r\n if (input.type) body.type = input.type\r\n if (input.metadata) body.metadata = input.metadata\r\n if (input.kind === 'direct') body.to = input.to\r\n else body.conversation_id = input.conversationId\r\n return body\r\n }\r\n\r\n private parseBacklogWarning(header: string | null): OutboundBacklogWarning | null {\r\n if (!header) return null\r\n const eq = header.indexOf('=')\r\n if (eq <= 0 || eq === header.length - 1) return null\r\n const recipientHandle = header.slice(0, eq).trim()\r\n const countStr = header.slice(eq + 1).trim()\r\n const undeliveredCount = Number(countStr)\r\n if (!recipientHandle) return null\r\n if (!Number.isFinite(undeliveredCount) || !Number.isInteger(undeliveredCount)) return null\r\n return { recipientHandle, undeliveredCount }\r\n }\r\n\r\n private mintClientMsgId(): string {\r\n const cryptoObj = (globalThis as { crypto?: Crypto }).crypto\r\n if (cryptoObj?.randomUUID) return cryptoObj.randomUUID()\r\n return `cmsg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 12)}`\r\n }\r\n\r\n // ─── Backpressure ────────────────────────────────────────────────────\r\n\r\n private async acquireSlot(): Promise<void> {\r\n if (this.inFlight < this.config.outbound.maxInFlight) {\r\n this.inFlight++\r\n this.metrics.setInFlightDepth(this.inFlight)\r\n return\r\n }\r\n if (this.queue.length >= this.queueHardCap) {\r\n throw new AgentChatChannelError(\r\n 'retry-transient',\r\n `outbound queue full (${this.queue.length}) — shedding load`,\r\n )\r\n }\r\n return new Promise<void>((resolve) => {\r\n this.queue.push(() => {\r\n this.inFlight++\r\n this.metrics.setInFlightDepth(this.inFlight)\r\n resolve()\r\n })\r\n })\r\n }\r\n\r\n private releaseSlot(): void {\r\n this.inFlight = Math.max(0, this.inFlight - 1)\r\n this.metrics.setInFlightDepth(this.inFlight)\r\n const next = this.queue.shift()\r\n if (next) next()\r\n }\r\n}\r\n","/**\r\n * AgentChat channel runtime — single lifecycle object that ties the WS\r\n * transport (P2), inbound normalizer (P3), and outbound adapter (P4)\r\n * together. This is the surface an OpenClaw channel binding consumes.\r\n *\r\n * Responsibilities:\r\n * - Instantiate the WS client, hook its `inboundFrame` event through\r\n * `normalizeInbound` and into user-supplied handlers.\r\n * - Expose `sendMessage` that delegates to the OutboundAdapter.\r\n * - Coordinate drain: `stop(deadline)` waits for outbound in-flight to\r\n * clear (up to the deadline) before closing the WS.\r\n * - Surface a single `getHealth()` snapshot combining connection state +\r\n * outbound queue depth + circuit breaker state.\r\n *\r\n * Not in scope here:\r\n * - Per-conversation seq ordering and gap recovery — the SDK's\r\n * `RealtimeClient` owns that. For the channel plugin, we deliver\r\n * inbound frames as they arrive; upper layers can call\r\n * `GET /v1/messages/sync` for reconciliation if they require strict\r\n * ordering across reconnects.\r\n * - OpenClaw ChannelInboundMessage translation — that lives in the\r\n * bridge module (consumed by the gateway), not here. Keeping this\r\n * module decoupled means it can be smoke-tested without OpenClaw.\r\n */\r\n\r\nimport type { Logger } from './log.js'\r\nimport type { MetricsRecorder } from './metrics.js'\r\nimport { createLogger, type LogLevel } from './log.js'\r\nimport { createNoopMetrics } from './metrics.js'\r\nimport type { AgentchatChannelConfig } from './config-schema.js'\r\nimport { AgentchatWsClient, type InboundFrame } from './ws-client.js'\r\nimport { normalizeInbound, type NormalizedInbound } from './inbound.js'\r\nimport {\r\n OutboundAdapter,\r\n type OutboundMessageInput,\r\n type OutboundBacklogWarning,\r\n type SendResult,\r\n} from './outbound.js'\r\nimport { AgentChatChannelError } from './errors.js'\r\nimport type { ConnectionState } from './state-machine.js'\r\nimport type { UnixMillis } from './types.js'\r\n\r\nexport interface ChannelRuntimeHandlers {\r\n /** Called for every successfully normalized inbound event. */\r\n onInbound?: (event: NormalizedInbound) => void | Promise<void>\r\n /** Called whenever a frame fails validation. Default: log-and-drop. */\r\n onValidationError?: (error: AgentChatChannelError, frame: InboundFrame) => void\r\n /** Called on state transitions — surface to gateway for health/UI. */\r\n onStateChanged?: (next: ConnectionState, prev: ConnectionState) => void\r\n /** Called once per successful HELLO_OK (initial + every reconnect). */\r\n onAuthenticated?: (at: UnixMillis) => void\r\n /** Called on every closed/unreachable situation worth observing. */\r\n onError?: (error: AgentChatChannelError) => void\r\n /** Called when the server signals a backlog warning on an outbound send. */\r\n onBacklogWarning?: (warning: OutboundBacklogWarning) => void\r\n}\r\n\r\nexport interface ChannelRuntimeOptions {\r\n readonly config: AgentchatChannelConfig\r\n readonly handlers?: ChannelRuntimeHandlers\r\n /** Pre-built logger — if absent, we construct one from `config.observability`. */\r\n readonly logger?: Logger\r\n /** Pre-built metrics recorder — if absent, uses no-op. */\r\n readonly metrics?: MetricsRecorder\r\n readonly fetch?: typeof fetch\r\n /** Injected for tests. */\r\n readonly webSocketCtor?: ConstructorParameters<\r\n typeof AgentchatWsClient\r\n >[0]['webSocketCtor']\r\n readonly now?: () => UnixMillis\r\n readonly random?: () => number\r\n readonly sleep?: (ms: number) => Promise<void>\r\n}\r\n\r\nexport interface HealthSnapshot {\r\n readonly state: ConnectionState\r\n readonly authenticated: boolean\r\n readonly outbound: {\r\n readonly inFlight: number\r\n readonly queued: number\r\n readonly circuitState: 'closed' | 'open' | 'half-open'\r\n }\r\n}\r\n\r\n/**\r\n * Orchestrates the full channel. Construct once per (channelId, accountId)\r\n * pair at gateway startup; call `start()` to bring it up, `stop()` to\r\n * drain. Dispose is folded into `stop()` — after it resolves, the\r\n * instance is terminal.\r\n */\r\nexport class AgentchatChannelRuntime {\r\n private readonly config: AgentchatChannelConfig\r\n private readonly handlers: ChannelRuntimeHandlers\r\n private readonly logger: Logger\r\n private readonly metrics: MetricsRecorder\r\n private readonly ws: AgentchatWsClient\r\n private readonly outbound: OutboundAdapter\r\n private readonly now: () => UnixMillis\r\n private started = false\r\n private authenticated = false\r\n private stopPromise: Promise<void> | null = null\r\n\r\n constructor(opts: ChannelRuntimeOptions) {\r\n this.config = opts.config\r\n this.handlers = opts.handlers ?? {}\r\n this.now = opts.now ?? Date.now\r\n this.logger =\r\n opts.logger ??\r\n createLogger({\r\n level: this.config.observability.logLevel as LogLevel,\r\n redactKeys: this.config.observability.redactKeys,\r\n })\r\n this.metrics = opts.metrics ?? createNoopMetrics()\r\n\r\n this.ws = new AgentchatWsClient({\r\n config: this.config,\r\n logger: this.logger,\r\n metrics: this.metrics,\r\n webSocketCtor: opts.webSocketCtor,\r\n now: opts.now,\r\n random: opts.random,\r\n })\r\n\r\n this.outbound = new OutboundAdapter({\r\n config: this.config,\r\n logger: this.logger,\r\n metrics: this.metrics,\r\n fetch: opts.fetch,\r\n now: opts.now,\r\n random: opts.random,\r\n sleep: opts.sleep,\r\n onBacklogWarning: (warning) => {\r\n try {\r\n this.handlers.onBacklogWarning?.(warning)\r\n } catch (err) {\r\n this.logger.error(\r\n { err: err instanceof Error ? err.message : String(err) },\r\n 'onBacklogWarning handler threw',\r\n )\r\n }\r\n },\r\n })\r\n\r\n this.bindWsEvents()\r\n }\r\n\r\n /** Open the transport. Idempotent — subsequent calls are no-ops. */\r\n start(): void {\r\n if (this.started) return\r\n this.started = true\r\n this.ws.start()\r\n }\r\n\r\n /**\r\n * Graceful shutdown. Waits for outbound in-flight to drain up to the\r\n * deadline, then force-closes the WS. Returns a promise that resolves\r\n * once the WS has emitted `closed`.\r\n */\r\n stop(deadlineMs?: UnixMillis): Promise<void> {\r\n if (this.stopPromise) return this.stopPromise\r\n const deadline = deadlineMs ?? this.now() + 5_000\r\n\r\n this.stopPromise = new Promise<void>((resolve) => {\r\n const off = this.ws.on('closed', () => {\r\n off()\r\n resolve()\r\n })\r\n this.ws.stop(deadline)\r\n })\r\n // Once outbound is idle, let the WS know it can close early.\r\n void this.pollUntilIdle(deadline)\r\n return this.stopPromise\r\n }\r\n\r\n private async pollUntilIdle(deadline: UnixMillis): Promise<void> {\r\n // Spin until outbound reports no in-flight + no queue, or we hit the\r\n // deadline. Cheap polling (10ms) is fine — in steady-state we expect\r\n // this to fire within tens of ms.\r\n const step = 10\r\n for (;;) {\r\n const snap = this.outbound.snapshot()\r\n if (snap.inFlight === 0 && snap.queued === 0) {\r\n this.ws.drainCompleted()\r\n return\r\n }\r\n if (this.now() >= deadline) return\r\n await new Promise((r) => setTimeout(r, step))\r\n }\r\n }\r\n\r\n /**\r\n * Send an outbound message. Delegates to the OutboundAdapter; callers\r\n * should handle `AgentChatChannelError` with class dispatch.\r\n */\r\n sendMessage(input: OutboundMessageInput): Promise<SendResult> {\r\n return this.outbound.sendMessage(input)\r\n }\r\n\r\n /** Push a client-action frame over the WS (typing, read-ack, presence). */\r\n sendWsAction(type: 'typing.start' | 'typing.stop' | 'message.read_ack' | 'presence.update', payload: Record<string, unknown>): boolean {\r\n return this.ws.send({ type, payload })\r\n }\r\n\r\n /**\r\n * Operator has rotated the API key — signal the WS client so it can\r\n * exit AUTH_FAIL. The caller is responsible for creating a new runtime\r\n * with the updated config OR for calling this after config hot-reload.\r\n */\r\n reconfigured(): void {\r\n this.ws.reconfigured()\r\n }\r\n\r\n getHealth(): HealthSnapshot {\r\n const outSnap = this.outbound.snapshot()\r\n return {\r\n state: this.ws.getState(),\r\n authenticated: this.authenticated,\r\n outbound: {\r\n inFlight: outSnap.inFlight,\r\n queued: outSnap.queued,\r\n circuitState: outSnap.circuit.state,\r\n },\r\n }\r\n }\r\n\r\n // ─── Internals ───────────────────────────────────────────────────────\r\n\r\n private bindWsEvents(): void {\r\n this.ws.on('stateChanged', (next, prev) => {\r\n if (next.kind !== 'READY' && next.kind !== 'DEGRADED') {\r\n this.authenticated = false\r\n }\r\n try {\r\n this.handlers.onStateChanged?.(next, prev)\r\n } catch (err) {\r\n this.logger.error(\r\n { err: err instanceof Error ? err.message : String(err) },\r\n 'onStateChanged handler threw',\r\n )\r\n }\r\n })\r\n\r\n this.ws.on('authenticated', (at) => {\r\n this.authenticated = true\r\n try {\r\n this.handlers.onAuthenticated?.(at)\r\n } catch (err) {\r\n this.logger.error(\r\n { err: err instanceof Error ? err.message : String(err) },\r\n 'onAuthenticated handler threw',\r\n )\r\n }\r\n })\r\n\r\n this.ws.on('inboundFrame', (frame) => {\r\n this.dispatchFrame(frame)\r\n })\r\n\r\n this.ws.on('error', (error) => {\r\n try {\r\n this.handlers.onError?.(error)\r\n } catch (err) {\r\n this.logger.error(\r\n { err: err instanceof Error ? err.message : String(err) },\r\n 'onError handler threw',\r\n )\r\n }\r\n })\r\n }\r\n\r\n private dispatchFrame(frame: InboundFrame): void {\r\n let normalized: NormalizedInbound\r\n try {\r\n normalized = normalizeInbound(frame)\r\n } catch (err) {\r\n if (err instanceof AgentChatChannelError) {\r\n this.logger.warn(\r\n { type: frame.type, class: err.class_, message: err.message },\r\n 'inbound validation failed — dropping',\r\n )\r\n try {\r\n this.handlers.onValidationError?.(err, frame)\r\n } catch (handlerErr) {\r\n this.logger.error(\r\n { err: handlerErr instanceof Error ? handlerErr.message : String(handlerErr) },\r\n 'onValidationError handler threw',\r\n )\r\n }\r\n } else {\r\n this.logger.error(\r\n { err: err instanceof Error ? err.message : String(err) },\r\n 'inbound normalizer threw unexpectedly',\r\n )\r\n }\r\n return\r\n }\r\n\r\n this.recordInboundMetric(normalized)\r\n\r\n try {\r\n const result = this.handlers.onInbound?.(normalized)\r\n if (result instanceof Promise) {\r\n result.catch((err) => {\r\n this.logger.error(\r\n { err: err instanceof Error ? err.message : String(err), type: normalized.kind },\r\n 'async onInbound handler rejected',\r\n )\r\n })\r\n }\r\n } catch (err) {\r\n this.logger.error(\r\n { err: err instanceof Error ? err.message : String(err), type: normalized.kind },\r\n 'onInbound handler threw',\r\n )\r\n }\r\n }\r\n\r\n private recordInboundMetric(n: NormalizedInbound): void {\r\n switch (n.kind) {\r\n case 'message':\r\n this.metrics.incInboundDelivered({\r\n kind: n.conversationKind === 'group' ? 'group-message' : 'message',\r\n })\r\n break\r\n case 'typing':\r\n this.metrics.incInboundDelivered({ kind: 'typing' })\r\n break\r\n case 'read-receipt':\r\n this.metrics.incInboundDelivered({ kind: 'read' })\r\n break\r\n case 'presence':\r\n this.metrics.incInboundDelivered({ kind: 'presence' })\r\n break\r\n case 'rate-limit-warning':\r\n this.metrics.incInboundDelivered({ kind: 'rate-limit-warning' })\r\n break\r\n case 'group-invite':\r\n case 'group-deleted':\r\n case 'unknown':\r\n // Not tracked — cardinality would explode on `unknown` kinds.\r\n break\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/channel-account.ts","../src/errors.ts","../src/setup-client.ts","../src/channel.wizard.ts","../src/config-schema.ts","../src/channel.ts","../src/channel.setup.ts","../src/configured-state.ts","../src/log.ts","../src/metrics.ts","../src/state-machine.ts","../src/ws-client.ts","../src/inbound.ts","../src/retry.ts","../src/version.ts","../src/outbound.ts","../src/runtime.ts"],"names":["patched","WizardCancelledError","setSetupChannelEnabled","z","buildChannelConfigSchema","defineChannelPluginEntry","defineSetupPluginEntry","pino","NodeWebSocket","jitter"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Account-config primitives for the AgentChat channel plugin.\n *\n * This module owns the smallest set of shared pieces that both the plugin\n * definition (`channel.ts`) and the interactive setup wizard\n * (`channel.wizard.ts`) need to read or mutate the `channels.agentchat.*`\n * section of the OpenClaw config. Keeping them in a leaf file (no imports\n * from other channel-* modules) breaks the channel.ts ↔ channel.wizard.ts\n * import cycle — without it, the wizard literal's `channel:` field resolves\n * to the temporal-dead-zone value of `AGENTCHAT_CHANNEL_ID` at module-init\n * time, which bundlers emit as `undefined`.\n *\n * Invariants:\n * - Flat form (`channels.agentchat.{apiKey,...}`) is the default-account\n * layout when no `accounts` key is present. Once a named account is\n * written, flat form is never used again for the default account.\n * - The `enabled` flag is section-level (not per-account) and is kept out\n * of the Zod-parsed account shape because the schema is `.strict()`.\n */\nimport type { OpenClawConfig } from 'openclaw/plugin-sdk/channel-core'\n\nexport const AGENTCHAT_CHANNEL_ID = 'agentchat' as const\nexport const AGENTCHAT_DEFAULT_ACCOUNT_ID = 'default'\n\nexport const MIN_API_KEY_LENGTH = 20\n\nexport type ChannelSectionRaw = Record<string, unknown> & {\n accounts?: Record<string, unknown>\n enabled?: unknown\n apiKey?: unknown\n apiBase?: unknown\n agentHandle?: unknown\n}\n\nexport function readChannelSection(cfg: OpenClawConfig | undefined): ChannelSectionRaw | undefined {\n const channels = (cfg as { channels?: Record<string, unknown> } | undefined)?.channels\n const section = channels?.[AGENTCHAT_CHANNEL_ID]\n return section && typeof section === 'object' && !Array.isArray(section)\n ? (section as ChannelSectionRaw)\n : undefined\n}\n\nexport function readAccountRaw(\n section: ChannelSectionRaw | undefined,\n accountId: string,\n): Record<string, unknown> | undefined {\n if (!section) return undefined\n const { accounts } = section\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const entry = (accounts as Record<string, unknown>)[accountId]\n if (entry && typeof entry === 'object') return entry as Record<string, unknown>\n }\n // Single-account fallback: treat section-level fields as the 'default' account,\n // stripping the `accounts` subsection (but preserving `enabled`, which the\n // caller extracts before Zod parsing).\n if (accountId === AGENTCHAT_DEFAULT_ACCOUNT_ID) {\n const { accounts: _accounts, ...rest } = section\n void _accounts\n return rest as Record<string, unknown>\n }\n return undefined\n}\n\n/**\n * Pulls the `enabled` flag out of a raw account record and returns a copy\n * safe to feed into `parseChannelConfig` (which enforces `.strict()` — an\n * unknown `enabled` key would otherwise reject).\n */\nexport function splitEnabledFromRaw(\n raw: Record<string, unknown> | undefined,\n): { enabled: boolean; forParse: Record<string, unknown> | undefined } {\n if (!raw) return { enabled: true, forParse: undefined }\n const { enabled, ...rest } = raw\n return { enabled: enabled !== false, forParse: rest }\n}\n\nexport function isApiKeyPresent(value: unknown): value is string {\n return typeof value === 'string' && value.length >= MIN_API_KEY_LENGTH\n}\n\n/**\n * Read a string-valued field from the resolved account record. Mirrors the\n * fallback logic of `resolveAccount` — accounts.<id>.<field> when present,\n * falling back to the flat section for the default account.\n *\n * Used by the setup wizard so it can render live config state without\n * re-running the Zod parser (which would reject partial work-in-progress\n * inputs during the interactive flow).\n */\nexport function readAgentchatConfigField(\n cfg: OpenClawConfig | undefined,\n accountId: string,\n field: 'apiKey' | 'apiBase' | 'agentHandle',\n): string | undefined {\n const section = readChannelSection(cfg)\n const raw = readAccountRaw(section, accountId)\n if (!raw) return undefined\n const value = raw[field]\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\n/**\n * Shared writer for both the non-interactive `setup.applyAccountConfig`\n * adapter and the interactive wizard. Maintains the same flat-vs-accounts\n * invariant: default account uses flat form iff no `accounts` key is present;\n * named accounts always nest under `accounts.<id>`.\n */\nexport function applyAgentchatAccountPatch(\n cfg: OpenClawConfig | undefined,\n accountId: string,\n patch: Record<string, unknown>,\n): OpenClawConfig {\n const channels: Record<string, unknown> = {\n ...((cfg as { channels?: Record<string, unknown> } | undefined)?.channels ?? {}),\n }\n const currentSection = channels[AGENTCHAT_CHANNEL_ID]\n const section: ChannelSectionRaw =\n currentSection && typeof currentSection === 'object' && !Array.isArray(currentSection)\n ? { ...(currentSection as ChannelSectionRaw) }\n : {}\n\n if (accountId === AGENTCHAT_DEFAULT_ACCOUNT_ID && !section.accounts) {\n Object.assign(section, patch)\n } else {\n const accounts: Record<string, unknown> = {\n ...((section.accounts as Record<string, unknown> | undefined) ?? {}),\n }\n const prevAccount =\n typeof accounts[accountId] === 'object' && accounts[accountId] !== null\n ? (accounts[accountId] as Record<string, unknown>)\n : {}\n accounts[accountId] = { ...prevAccount, ...patch }\n section.accounts = accounts\n }\n\n channels[AGENTCHAT_CHANNEL_ID] = section\n return { ...(cfg ?? {}), channels } as OpenClawConfig\n}\n","/**\n * Error taxonomy for the AgentChat channel plugin.\n *\n * Every error that crosses a pipeline boundary (inbound receive, outbound\n * send, config validation, transport) must be classifiable as one of:\n *\n * terminal-auth — 401/403. API key invalid or revoked. Do not retry.\n * Move state machine to AUTH_FAIL.\n * terminal-user — 400/422 (client-side validation). Bug in this plugin\n * or malformed outbound. Log at error level, drop,\n * do not retry.\n * retry-rate — 429. Retry after `retryAfterMs` (or jittered\n * exponential backoff if header absent).\n * retry-transient — 5xx, ECONNRESET, ETIMEDOUT, network flap.\n * Exponential backoff + jitter. Open circuit after N.\n * idempotent-replay — 409 on POST /v1/messages with duplicate\n * client_msg_id. Treat as success, log at info.\n * validation — Zod schema failed on inbound payload. Likely a\n * server change. Log at error, drop, alert.\n */\n\nexport type ErrorClass =\n | 'terminal-auth'\n | 'terminal-user'\n | 'retry-rate'\n | 'retry-transient'\n | 'idempotent-replay'\n | 'validation'\n\nexport class AgentChatChannelError extends Error {\n readonly class_: ErrorClass\n readonly retryAfterMs: number | undefined\n readonly statusCode: number | undefined\n\n constructor(\n class_: ErrorClass,\n message: string,\n options: {\n cause?: unknown\n retryAfterMs?: number\n statusCode?: number\n } = {},\n ) {\n super(message, { cause: options.cause })\n this.name = 'AgentChatChannelError'\n this.class_ = class_\n this.retryAfterMs = options.retryAfterMs\n this.statusCode = options.statusCode\n }\n}\n\n/** Classify an HTTP status code from the AgentChat REST API. */\nexport function classifyHttpStatus(status: number, retryAfterHeader?: string | null): ErrorClass {\n if (status === 401 || status === 403) return 'terminal-auth'\n if (status === 409) return 'idempotent-replay'\n if (status === 429) return 'retry-rate'\n if (status >= 500 && status <= 599) return 'retry-transient'\n if (status >= 400 && status <= 499) return 'terminal-user'\n return 'retry-transient' // unexpected — prefer retry over silent drop\n}\n\n/** Parse a `Retry-After` header to milliseconds. Accepts seconds or HTTP-date. */\nexport function parseRetryAfter(header: string | null | undefined, nowMs: number): number | undefined {\n if (!header) return undefined\n const seconds = Number(header)\n if (Number.isFinite(seconds) && seconds >= 0) return Math.floor(seconds * 1000)\n const when = Date.parse(header)\n if (Number.isFinite(when)) return Math.max(0, when - nowMs)\n return undefined\n}\n\n/** Classify a low-level transport error (from `ws` or `fetch`). */\nexport function classifyNetworkError(err: unknown): ErrorClass {\n if (!err || typeof err !== 'object') return 'retry-transient'\n const code = (err as { code?: unknown }).code\n if (typeof code === 'string') {\n if (code === 'ECONNRESET' || code === 'ETIMEDOUT' || code === 'ECONNREFUSED') {\n return 'retry-transient'\n }\n if (code === 'ENOTFOUND' || code === 'EAI_AGAIN') return 'retry-transient'\n }\n return 'retry-transient'\n}\n\n/** True iff the error class should trigger a retry. */\nexport function isRetryable(class_: ErrorClass): boolean {\n return class_ === 'retry-rate' || class_ === 'retry-transient'\n}\n\n/** True iff the error class is terminal (no retry, operator action needed). */\nexport function isTerminal(class_: ErrorClass): boolean {\n return class_ === 'terminal-auth' || class_ === 'terminal-user' || class_ === 'validation'\n}\n","/**\n * Minimal HTTP client used by the setup plugin (P7) to:\n * - verify an API key is live before finalizing setup (`validateApiKey`)\n * - drive the email-OTP self-registration flow for agents without a key yet\n * (`registerAgentStart` → `registerAgentVerify`)\n *\n * Why this lives separately from `outbound.ts`:\n * - `outbound.ts` is the hot-path message sender. It wants retries, a circuit\n * breaker, metrics, and a long-lived `fetch`. Setup is one-shot, low-rate,\n * user-interactive — a 200ms validation call doesn't need any of that.\n * - Setup runs before the runtime exists; coupling it to `OutboundAdapter`\n * (which expects a parsed `AgentchatChannelConfig`) would force an odd\n * partial-config path during registration.\n *\n * The server endpoints this module targets are stable AgentChat REST calls:\n * - `GET /v1/agents/me` → 200 OK when the key authenticates\n * - `POST /v1/register` → 200 with `{ pending_id }`\n * - `POST /v1/register/verify` → 201 with `{ agent, api_key }` on success\n *\n * All methods return strongly-typed result unions — setup UIs can `switch` on\n * the discriminant without guessing at HTTP status codes.\n */\n\nimport { AgentChatChannelError } from './errors.js'\n\nconst DEFAULT_API_BASE = 'https://api.agentchat.me'\nconst DEFAULT_TIMEOUT_MS = 10_000\n\n/** Subset of the AgentChat agent row the setup surface needs to show the user. */\nexport interface AgentchatAgentIdentity {\n readonly handle: string\n readonly displayName: string | null\n readonly email: string\n readonly createdAt: string\n}\n\nexport type ValidateApiKeyResult =\n | { readonly ok: true; readonly agent: AgentchatAgentIdentity }\n | {\n readonly ok: false\n /** High-level reason code the UI can map to a localized message. */\n readonly reason:\n | 'unauthorized'\n | 'forbidden'\n | 'deleted'\n | 'network-error'\n | 'unreachable'\n | 'server-error'\n | 'unexpected-shape'\n readonly message: string\n readonly status?: number\n }\n\nexport interface ValidateApiKeyOptions {\n readonly apiBase?: string\n readonly fetch?: typeof fetch\n readonly timeoutMs?: number\n}\n\n/**\n * Probe the API key against `GET /v1/agents/me`. Returns a discriminated\n * result — never throws on HTTP or network errors. The caller decides how\n * to surface each failure mode to the user.\n */\nexport async function validateApiKey(\n apiKey: string,\n opts: ValidateApiKeyOptions = {},\n): Promise<ValidateApiKeyResult> {\n if (!apiKey || typeof apiKey !== 'string') {\n return { ok: false, reason: 'unauthorized', message: 'API key is empty' }\n }\n const base = (opts.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, '')\n const url = `${base}/v1/agents/me`\n const controller = new AbortController()\n const fetchImpl = opts.fetch ?? fetch\n const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n\n let res: Response\n try {\n res = await fetchImpl(url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n Accept: 'application/json',\n },\n signal: controller.signal,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n const unreachable =\n err instanceof Error &&\n (err.name === 'AbortError' || /ECONN|ETIMEDOUT|ENOTFOUND|EAI_AGAIN/i.test(message))\n return {\n ok: false,\n reason: unreachable ? 'unreachable' : 'network-error',\n message: `agentchat: GET /v1/agents/me failed: ${message}`,\n }\n } finally {\n clearTimeout(timer)\n }\n\n if (res.status === 401) {\n return { ok: false, reason: 'unauthorized', status: 401, message: 'API key is invalid or revoked' }\n }\n if (res.status === 403) {\n return { ok: false, reason: 'forbidden', status: 403, message: 'API key lacks permission to read /agents/me' }\n }\n if (res.status === 410) {\n return { ok: false, reason: 'deleted', status: 410, message: 'Agent account has been deleted' }\n }\n if (res.status >= 500) {\n return { ok: false, reason: 'server-error', status: res.status, message: `AgentChat API returned ${res.status}` }\n }\n if (!res.ok) {\n return {\n ok: false,\n reason: 'server-error',\n status: res.status,\n message: `AgentChat API returned ${res.status}`,\n }\n }\n\n const body = (await res.json().catch(() => null)) as {\n handle?: unknown\n display_name?: unknown\n email?: unknown\n email_masked?: unknown\n created_at?: unknown\n } | null\n // The live `GET /v1/agents/me` endpoint masks PII: it returns\n // `email_masked` (e.g. `a****@agentchat.local`), never the real `email`.\n // Accept either so tests that stub an unmasked body still pass, but the\n // caller should expect a masked value in production.\n const email =\n typeof body?.email === 'string'\n ? body.email\n : typeof body?.email_masked === 'string'\n ? body.email_masked\n : null\n if (!body || typeof body.handle !== 'string' || email === null || typeof body.created_at !== 'string') {\n return {\n ok: false,\n reason: 'unexpected-shape',\n status: res.status,\n message: 'AgentChat /agents/me returned an unrecognized shape',\n }\n }\n return {\n ok: true,\n agent: {\n handle: body.handle,\n displayName: typeof body.display_name === 'string' ? body.display_name : null,\n email,\n createdAt: body.created_at,\n },\n }\n}\n\n// ─── Self-registration (email + OTP) ───────────────────────────────────\n\nexport interface RegisterAgentStartInput {\n readonly email: string\n readonly handle: string\n readonly displayName?: string\n readonly description?: string\n}\n\nexport type RegisterStartResult =\n | { readonly ok: true; readonly pendingId: string }\n | {\n readonly ok: false\n readonly reason:\n | 'invalid-handle'\n | 'handle-taken'\n | 'email-taken'\n | 'email-exhausted'\n | 'rate-limited'\n | 'otp-failed'\n | 'network-error'\n | 'server-error'\n | 'validation'\n readonly message: string\n readonly status?: number\n readonly retryAfterSeconds?: number\n }\n\nexport interface RegisterAgentVerifyInput {\n readonly pendingId: string\n readonly code: string\n}\n\nexport type RegisterVerifyResult =\n | {\n readonly ok: true\n readonly apiKey: string\n readonly agent: AgentchatAgentIdentity\n }\n | {\n readonly ok: false\n readonly reason:\n | 'expired'\n | 'invalid-code'\n | 'rate-limited'\n | 'handle-taken'\n | 'email-taken'\n | 'network-error'\n | 'server-error'\n | 'unexpected-shape'\n | 'validation'\n readonly message: string\n readonly status?: number\n readonly retryAfterSeconds?: number\n }\n\nexport interface RegisterOptions {\n readonly apiBase?: string\n readonly fetch?: typeof fetch\n readonly timeoutMs?: number\n}\n\n/**\n * Kick off an email-OTP registration. Server caches the intent under a\n * `pending_id` for 10 minutes and emails a 6-digit code to `email`.\n */\nexport async function registerAgentStart(\n input: RegisterAgentStartInput,\n opts: RegisterOptions = {},\n): Promise<RegisterStartResult> {\n const res = await post('/v1/register', input, opts)\n if (res.kind === 'network') {\n return { ok: false, reason: 'network-error', message: res.message }\n }\n if (res.kind === 'timeout') {\n return { ok: false, reason: 'network-error', message: 'request timed out' }\n }\n\n const body = (res.body as { pending_id?: unknown; code?: unknown; message?: unknown }) ?? {}\n\n if (res.status === 200) {\n if (typeof body.pending_id !== 'string') {\n return {\n ok: false,\n reason: 'server-error',\n status: 200,\n message: 'AgentChat /register returned no pending_id',\n }\n }\n return { ok: true, pendingId: body.pending_id }\n }\n\n const code = typeof body.code === 'string' ? body.code : ''\n const message = typeof body.message === 'string' ? body.message : `status ${res.status}`\n\n if (res.status === 400 && code === 'INVALID_HANDLE') return { ok: false, reason: 'invalid-handle', message, status: 400 }\n if (res.status === 400 && code === 'VALIDATION_ERROR') return { ok: false, reason: 'validation', message, status: 400 }\n if (res.status === 409 && code === 'HANDLE_TAKEN') return { ok: false, reason: 'handle-taken', message, status: 409 }\n if (res.status === 409 && code === 'EMAIL_TAKEN') return { ok: false, reason: 'email-taken', message, status: 409 }\n if (res.status === 409 && code === 'EMAIL_EXHAUSTED') return { ok: false, reason: 'email-exhausted', message, status: 409 }\n if (res.status === 429) {\n return {\n ok: false,\n reason: 'rate-limited',\n message,\n status: 429,\n retryAfterSeconds: res.retryAfterSeconds,\n }\n }\n if (res.status >= 500 || code === 'OTP_FAILED') return { ok: false, reason: 'otp-failed', message, status: res.status }\n return { ok: false, reason: 'server-error', status: res.status, message }\n}\n\n/** Verify the OTP the user received by email and mint the API key. */\nexport async function registerAgentVerify(\n input: RegisterAgentVerifyInput,\n opts: RegisterOptions = {},\n): Promise<RegisterVerifyResult> {\n const res = await post('/v1/register/verify', { pending_id: input.pendingId, code: input.code }, opts)\n if (res.kind === 'network') return { ok: false, reason: 'network-error', message: res.message }\n if (res.kind === 'timeout') return { ok: false, reason: 'network-error', message: 'request timed out' }\n\n const body = (res.body ?? {}) as {\n code?: unknown\n message?: unknown\n agent?: { handle?: unknown; display_name?: unknown; email?: unknown; created_at?: unknown }\n api_key?: unknown\n }\n\n if (res.status === 201) {\n const agent = body.agent\n if (\n typeof body.api_key !== 'string' ||\n !agent ||\n typeof agent.handle !== 'string' ||\n typeof agent.email !== 'string' ||\n typeof agent.created_at !== 'string'\n ) {\n return {\n ok: false,\n reason: 'unexpected-shape',\n status: 201,\n message: 'AgentChat /register/verify returned an unrecognized shape',\n }\n }\n return {\n ok: true,\n apiKey: body.api_key,\n agent: {\n handle: agent.handle,\n displayName: typeof agent.display_name === 'string' ? agent.display_name : null,\n email: agent.email,\n createdAt: agent.created_at,\n },\n }\n }\n\n const code = typeof body.code === 'string' ? body.code : ''\n const message = typeof body.message === 'string' ? body.message : `status ${res.status}`\n\n if (res.status === 400 && code === 'EXPIRED') return { ok: false, reason: 'expired', message, status: 400 }\n if (res.status === 400 && code === 'INVALID_CODE') return { ok: false, reason: 'invalid-code', message, status: 400 }\n if (res.status === 400 && code === 'VALIDATION_ERROR') return { ok: false, reason: 'validation', message, status: 400 }\n if (res.status === 409 && code === 'HANDLE_TAKEN') return { ok: false, reason: 'handle-taken', message, status: 409 }\n if (res.status === 409 && code === 'EMAIL_TAKEN') return { ok: false, reason: 'email-taken', message, status: 409 }\n if (res.status === 429) {\n return { ok: false, reason: 'rate-limited', message, status: 429, retryAfterSeconds: res.retryAfterSeconds }\n }\n return { ok: false, reason: 'server-error', status: res.status, message }\n}\n\n// ─── Internals ─────────────────────────────────────────────────────────\n\ntype PostOutcome =\n | { kind: 'http'; status: number; body: unknown; retryAfterSeconds?: number }\n | { kind: 'network'; message: string }\n | { kind: 'timeout' }\n\nasync function post(path: string, body: unknown, opts: RegisterOptions): Promise<PostOutcome> {\n const base = (opts.apiBase ?? DEFAULT_API_BASE).replace(/\\/+$/, '')\n const url = `${base}${path}`\n const controller = new AbortController()\n const fetchImpl = opts.fetch ?? fetch\n const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const res = await fetchImpl(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: JSON.stringify(body),\n signal: controller.signal,\n })\n const parsed = await res.json().catch(() => null)\n const retryAfterHeader = res.headers.get('retry-after')\n const retryAfterSeconds = retryAfterHeader ? Number(retryAfterHeader) : undefined\n return {\n kind: 'http',\n status: res.status,\n body: parsed,\n retryAfterSeconds: Number.isFinite(retryAfterSeconds) ? retryAfterSeconds : undefined,\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') return { kind: 'timeout' }\n return { kind: 'network', message: err instanceof Error ? err.message : String(err) }\n } finally {\n clearTimeout(timer)\n }\n}\n\n/**\n * Throw-flavored wrapper used by callers that prefer exception control flow\n * (the setup plugin's `afterAccountConfigWritten` hook). Converts a failure\n * result into an `AgentChatChannelError` with an appropriate class.\n */\nexport async function assertApiKeyValid(\n apiKey: string,\n opts: ValidateApiKeyOptions = {},\n): Promise<AgentchatAgentIdentity> {\n const result = await validateApiKey(apiKey, opts)\n if (result.ok) return result.agent\n const class_ =\n result.reason === 'unauthorized' || result.reason === 'forbidden' || result.reason === 'deleted'\n ? 'terminal-auth'\n : result.reason === 'server-error'\n ? 'retry-transient'\n : 'retry-transient'\n throw new AgentChatChannelError(class_, `${result.message} [reason=${result.reason}]`, {\n statusCode: result.status,\n })\n}\n","/**\n * AgentChat channel setup wizard.\n *\n * Implements the interactive onboarding flow that OpenClaw's `setup` driver\n * invokes for users who just ran `openclaw plugins install @agentchatme/openclaw`\n * and `openclaw channels add agentchat`.\n *\n * The core UX decision this wizard encodes: AgentChat is the first channel in\n * the OpenClaw ecosystem where the identity the channel authenticates against\n * lives inside the plugin's own issuer (not an external provider like Slack or\n * Telegram). That means we can — and should — let brand-new users provision\n * credentials without ever leaving the CLI. Hence the login-vs-register branch\n * at the top: paste an existing key, or register via email OTP in-wizard.\n *\n * Flow:\n * 1. `status.resolveConfigured` — reports \"configured / not configured\" for\n * `openclaw setup`'s pre-selection summary.\n * 2. `prepare` — runs BEFORE the credential step. Branches on user intent:\n * - \"I have a key\" → returns void; framework prompts for the key next.\n * - \"Register me\" → drives email-OTP registration via the REST client,\n * writes the minted key directly to cfg, and marks\n * a sentinel in credentialValues so the credential\n * step skips its redundant keep/replace prompt.\n * 3. `credentials[0]` — the API-key credential. `shouldPrompt` honors the\n * post-register sentinel; otherwise the framework's default prompt runs.\n * 4. `finalize` — calls GET /v1/agents/me once more to confirm the key works,\n * surfaces the authenticated handle, and never throws on transport errors\n * (a fresh clone with a proxy should still save config and retry later).\n *\n * Writes go through `applyAgentchatAccountPatch` — the same helper backing\n * `setup.applyAccountConfig`, so the non-interactive `openclaw setup --token\n * ac_live_…` path and the interactive wizard path converge on the same config\n * shape and stay round-trippable.\n *\n * `disable` wires `setSetupChannelEnabled` so `openclaw channels remove\n * agentchat` produces `channels.agentchat.enabled: false` and keeps the\n * apiKey on disk (in case the operator just wants to pause, not rotate).\n */\n\nimport {\n WizardCancelledError,\n setSetupChannelEnabled,\n type ChannelSetupWizard,\n type OpenClawConfig,\n type WizardPrompter,\n} from 'openclaw/plugin-sdk/setup'\n\n/**\n * Inline of `ChannelSetupWizardCredentialValues` — the plugin-sdk's public\n * barrel does not re-export it, so we match its shape locally. Extra keys\n * beyond `keyof ChannelSetupInput` (e.g. our `_agentchatJustRegistered`\n * sentinel) are allowed because the framework treats this as a bag of strings\n * keyed by whatever the wizard steps use.\n */\ntype ChannelSetupWizardCredentialValues = Partial<Record<string, string>>\n\nimport {\n AGENTCHAT_CHANNEL_ID,\n MIN_API_KEY_LENGTH,\n applyAgentchatAccountPatch,\n isApiKeyPresent,\n readAgentchatConfigField,\n} from './channel-account.js'\nimport {\n registerAgentStart,\n registerAgentVerify,\n validateApiKey,\n type RegisterStartResult,\n type RegisterVerifyResult,\n} from './setup-client.js'\n\n/**\n * Sentinel credential-values key used to signal \"the register path in prepare\n * already minted + persisted the API key, don't re-prompt\". Framework-level\n * prompt skipping is per-credential; we read this in `shouldPrompt` below.\n * The leading underscore keeps it out of any `keyof ChannelSetupInput` path.\n */\nconst JUST_REGISTERED_SENTINEL = '_agentchatJustRegistered' as const\n\n// Canonical handle shape — mirrors packages/shared/src/validation/handles.ts\n// HANDLE_REGEX plus the 3–30 length check. Server is authoritative; this is\n// a client-side fast-fail so users don't round-trip an obviously-bad handle.\nconst HANDLE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/\nconst HANDLE_MIN_LENGTH = 3\nconst HANDLE_MAX_LENGTH = 30\nconst EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\nfunction isValidHandleShape(value: string): boolean {\n return (\n value.length >= HANDLE_MIN_LENGTH &&\n value.length <= HANDLE_MAX_LENGTH &&\n HANDLE_PATTERN.test(value)\n )\n}\n\n/** 6-digit numeric OTP; the server rejects any other shape with INVALID_CODE. */\nconst OTP_PATTERN = /^\\d{6}$/\n\nfunction hasConfiguredKey(cfg: OpenClawConfig | undefined, accountId: string): boolean {\n return isApiKeyPresent(readAgentchatConfigField(cfg, accountId, 'apiKey'))\n}\n\n/**\n * How many times we'll re-prompt around a retryable start-of-registration\n * error (handle-taken, invalid-handle, email-exhausted, …) before giving up\n * and steering the user to paste an existing key or cancel. A hard cap stops\n * a confused user looping forever; 5 is enough to pick a fresh handle or email\n * without being punishing.\n */\nconst MAX_START_RETRIES = 5\n\nasync function promptEmail(prompter: WizardPrompter): Promise<string> {\n return (\n await prompter.text({\n message: 'Email address (for the verification code)',\n placeholder: 'you@example.com',\n validate: (value) => {\n const trimmed = value.trim()\n if (!trimmed) return 'Email is required'\n if (!EMAIL_PATTERN.test(trimmed)) return 'That does not look like a valid email address'\n return undefined\n },\n })\n ).trim()\n}\n\nasync function promptHandle(prompter: WizardPrompter): Promise<string> {\n return (\n await prompter.text({\n message: 'Choose a handle (your @name on AgentChat)',\n placeholder: 'my-agent',\n validate: (value) => {\n const trimmed = value.trim()\n if (!trimmed) return 'Handle is required'\n if (!isValidHandleShape(trimmed)) {\n return 'Handle must be 3–30 chars — lowercase letters/digits/hyphens; must start with a letter'\n }\n return undefined\n },\n })\n ).trim()\n}\n\nasync function promptDisplayName(prompter: WizardPrompter): Promise<string> {\n return (\n await prompter.text({\n message: 'Display name (optional — shown next to your handle)',\n placeholder: '',\n validate: () => undefined,\n })\n ).trim()\n}\n\n/**\n * Change-API-base flow: only relevant for self-hosted AgentChat deployments.\n * The production client hits `https://api.agentchat.me` by default and the\n * config-schema pins that as the default value, so blank means \"reset to\n * default\" (remove the apiBase override entirely). Non-empty values must\n * parse as a valid http:// or https:// URL — we fail fast here so the user\n * does not save a typo that later surfaces as a misleading DNS-resolution\n * error at connect time.\n */\nasync function runChangeApiBaseFlow(params: {\n cfg: OpenClawConfig\n accountId: string\n prompter: WizardPrompter\n}): Promise<{ cfg: OpenClawConfig } | undefined> {\n const { cfg, accountId, prompter } = params\n const current = readAgentchatConfigField(cfg, accountId, 'apiBase')\n\n const input = (\n await prompter.text({\n message: 'New API base URL (blank to reset to default)',\n placeholder: current ?? 'https://api.agentchat.me',\n validate: (value) => {\n const trimmed = value.trim()\n if (!trimmed) return undefined // blank = reset to default\n try {\n const url = new URL(trimmed)\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n return 'API base must use http:// or https://'\n }\n return undefined\n } catch {\n return 'Not a valid URL'\n }\n },\n })\n ).trim()\n\n if (!input) {\n const patched = applyAgentchatAccountPatch(cfg, accountId, {\n apiBase: undefined,\n })\n await prompter.note(\n 'API base reset to default (https://api.agentchat.me).',\n 'Updated',\n )\n return { cfg: patched }\n }\n\n const patched = applyAgentchatAccountPatch(cfg, accountId, {\n apiBase: input,\n })\n await prompter.note(`API base set to ${input}`, 'Updated')\n return { cfg: patched }\n}\n\n/**\n * Return values from `runRegisterFlow`:\n * - success object → registration minted a key; credential step should\n * use it and skip its own prompt.\n * - `'abort'` → registration failed; caller shows the fallback\n * note and the framework prompts for a pasted key.\n * - `'user-chose-paste'`→ user explicitly elected to paste an existing key\n * (from an in-flow branch point like \"this email is\n * already registered\"). Caller skips the fallback\n * note because the user has already acknowledged\n * what's next.\n */\ntype RegisterFlowOutcome =\n | { cfg: OpenClawConfig; credentialValues: ChannelSetupWizardCredentialValues }\n | 'abort'\n | 'user-chose-paste'\n\nasync function runRegisterFlow(params: {\n cfg: OpenClawConfig\n accountId: string\n prompter: WizardPrompter\n apiBase: string | undefined\n}): Promise<RegisterFlowOutcome> {\n const { cfg, accountId, prompter, apiBase } = params\n\n await prompter.note(\n [\n 'Registration mints a new AgentChat agent identity tied to your email.',\n 'You will receive a 6-digit code to verify — check your inbox (and spam).',\n ].join('\\n'),\n 'AgentChat: register a new agent',\n )\n\n // Collect all three fields up front. If the server rejects on one specific\n // field (handle / email), we loop back and re-prompt ONLY that field below\n // — keeping the already-correct state so the user isn't punished for a\n // partial collision.\n let email = await promptEmail(prompter)\n let handle = await promptHandle(prompter)\n const displayName = await promptDisplayName(prompter)\n\n // ─── Start: request OTP, with field-specific retry ──────────────────\n // Retry semantics:\n // invalid-handle / handle-taken → re-prompt handle, keep email+displayName\n // email-exhausted → re-prompt email, keep handle+displayName\n // email-taken → branch: paste existing key, pick new\n // email, or cancel\n // rate-limited / otp-failed /\n // network / server / validation → abort with a clear message\n let startResult: RegisterStartResult | undefined\n let startedOk = false\n for (let attempt = 1; attempt <= MAX_START_RETRIES; attempt += 1) {\n const startSpinner = prompter.progress(\n attempt === 1 ? 'Sending verification code…' : 'Retrying…',\n )\n try {\n startResult = await registerAgentStart(\n {\n email,\n handle,\n ...(displayName ? { displayName } : {}),\n },\n { apiBase },\n )\n } catch (err) {\n startSpinner.stop('Could not reach AgentChat')\n await prompter.note(\n `${err instanceof Error ? err.message : String(err)}. Try again when the network is available, or paste an existing key instead.`,\n 'Registration failed',\n )\n return 'abort'\n }\n\n if (startResult.ok) {\n startSpinner.stop(`Verification code sent to ${email}`)\n startedOk = true\n break\n }\n\n startSpinner.stop('Registration rejected')\n\n switch (startResult.reason) {\n case 'invalid-handle':\n case 'handle-taken': {\n const detail =\n startResult.reason === 'handle-taken'\n ? `Handle @${handle} is already taken.`\n : 'That handle is not acceptable (3–30 chars — lowercase letters/digits/hyphens; must start with a letter).'\n await prompter.note(`${detail} Pick a different handle and we'll try again.`, 'Pick a different handle')\n handle = await promptHandle(prompter)\n continue\n }\n case 'email-taken': {\n const choice = await prompter.select<'paste' | 'retry' | 'cancel'>({\n message: `${email} is already registered as an AgentChat agent. What would you like to do?`,\n options: [\n {\n value: 'paste',\n label: 'Paste the existing API key for this agent',\n hint: 'recommended if you own the account',\n },\n { value: 'retry', label: 'Use a different email address' },\n { value: 'cancel', label: 'Cancel registration' },\n ],\n initialValue: 'paste',\n })\n if (choice === 'paste') return 'user-chose-paste'\n if (choice === 'cancel') return 'abort'\n email = await promptEmail(prompter)\n continue\n }\n case 'email-exhausted': {\n const choice = await prompter.select<'retry' | 'paste' | 'cancel'>({\n message: `${email} has reached the per-email agent quota. What next?`,\n options: [\n { value: 'retry', label: 'Use a different email address' },\n { value: 'paste', label: 'Paste a key from an existing agent' },\n { value: 'cancel', label: 'Cancel registration' },\n ],\n initialValue: 'retry',\n })\n if (choice === 'paste') return 'user-chose-paste'\n if (choice === 'cancel') return 'abort'\n email = await promptEmail(prompter)\n continue\n }\n case 'rate-limited': {\n const wait = startResult.retryAfterSeconds\n ? ` Try again in ${startResult.retryAfterSeconds}s.`\n : ''\n await prompter.note(`Too many registration attempts.${wait}`, 'Rate limited')\n return 'abort'\n }\n case 'otp-failed': {\n await prompter.note(\n 'The verification-code email could not be sent. Try again in a minute, or paste an existing key instead.',\n 'OTP delivery failed',\n )\n return 'abort'\n }\n case 'network-error':\n case 'server-error':\n case 'validation':\n default: {\n await prompter.note(describeRegisterStartError(startResult), 'Could not start registration')\n return 'abort'\n }\n }\n }\n\n if (!startedOk || !startResult || !startResult.ok) {\n await prompter.note(\n 'Too many attempts. Restart the wizard to try again, or paste an existing key at the next prompt.',\n 'Registration failed',\n )\n return 'abort'\n }\n\n // ─── Verify: collect OTP, retry on mistyped codes ───────────────────\n const maxCodeAttempts = 3\n let verifyResult: RegisterVerifyResult | null = null\n for (let attempt = 1; attempt <= maxCodeAttempts; attempt += 1) {\n const code = (\n await prompter.text({\n message:\n attempt === 1\n ? 'Enter the 6-digit verification code from your email'\n : `Verification code (attempt ${attempt}/${maxCodeAttempts})`,\n placeholder: '123456',\n validate: (value) => {\n const trimmed = value.trim()\n if (!trimmed) return 'Code is required'\n if (!OTP_PATTERN.test(trimmed)) return 'Code is 6 digits'\n return undefined\n },\n })\n ).trim()\n\n const verifySpinner = prompter.progress('Verifying code…')\n try {\n verifyResult = await registerAgentVerify({ pendingId: startResult.pendingId, code }, { apiBase })\n } catch (err) {\n verifySpinner.stop('Could not reach AgentChat')\n await prompter.note(\n `${err instanceof Error ? err.message : String(err)}. Try again, or paste an existing key instead.`,\n 'Verification failed',\n )\n return 'abort'\n }\n\n if (verifyResult.ok) {\n verifySpinner.stop(`Registered as @${verifyResult.agent.handle}`)\n break\n }\n\n verifySpinner.stop('Verification failed')\n\n // Retryable: bad code. Other failure modes are terminal for this flow.\n if (verifyResult.reason === 'invalid-code' && attempt < maxCodeAttempts) {\n await prompter.note(\n 'That code did not match. Check your email and try again.',\n 'Invalid verification code',\n )\n continue\n }\n\n await prompter.note(describeRegisterVerifyError(verifyResult), 'Registration failed')\n return 'abort'\n }\n\n if (!verifyResult || !verifyResult.ok) {\n await prompter.note(\n 'Too many incorrect codes. Restart the wizard to receive a new code.',\n 'Registration failed',\n )\n return 'abort'\n }\n\n // ─── Persist: write minted key to cfg, advertise handle in config ───\n const patch: Record<string, unknown> = { apiKey: verifyResult.apiKey }\n if (isValidHandleShape(verifyResult.agent.handle)) {\n patch.agentHandle = verifyResult.agent.handle\n }\n const nextCfg = applyAgentchatAccountPatch(cfg, accountId, patch)\n\n await prompter.note(\n [\n `Handle: @${verifyResult.agent.handle}`,\n `Email: ${verifyResult.agent.email}`,\n `API key: ${redactKey(verifyResult.apiKey)} (saved to your OpenClaw config)`,\n ].join('\\n'),\n 'AgentChat account created',\n )\n\n return {\n cfg: nextCfg,\n credentialValues: {\n token: verifyResult.apiKey,\n [JUST_REGISTERED_SENTINEL]: '1',\n },\n }\n}\n\nfunction describeRegisterStartError(result: Extract<RegisterStartResult, { ok: false }>): string {\n switch (result.reason) {\n case 'invalid-handle':\n return 'That handle is not acceptable. Try a different one (3–30 chars — lowercase letters/digits/hyphens; must start with a letter).'\n case 'handle-taken':\n return 'That handle is already taken. Try a different one.'\n case 'email-taken':\n return 'That email is already registered as an agent. Paste the existing key instead, or use a different email.'\n case 'email-exhausted':\n return 'This email has reached the agent quota. Use a different email, or paste a key from an existing agent.'\n case 'rate-limited': {\n const wait = result.retryAfterSeconds ? ` Try again in ${result.retryAfterSeconds}s.` : ''\n return `Rate limited.${wait}`\n }\n case 'otp-failed':\n return 'The verification-code email could not be sent. Try again in a minute.'\n case 'network-error':\n case 'server-error':\n case 'validation':\n default:\n return result.message\n }\n}\n\nfunction describeRegisterVerifyError(result: Extract<RegisterVerifyResult, { ok: false }>): string {\n switch (result.reason) {\n case 'expired':\n return 'This code expired. Restart the wizard to receive a new one.'\n case 'invalid-code':\n return 'Too many incorrect codes. Restart the wizard to receive a new one.'\n case 'handle-taken':\n return 'Your chosen handle was claimed by another registration in the meantime. Restart with a different handle.'\n case 'email-taken':\n return 'This email is already registered. Paste the existing key instead.'\n case 'rate-limited': {\n const wait = result.retryAfterSeconds ? ` Try again in ${result.retryAfterSeconds}s.` : ''\n return `Rate limited.${wait}`\n }\n case 'network-error':\n case 'server-error':\n case 'unexpected-shape':\n case 'validation':\n default:\n return result.message\n }\n}\n\nfunction redactKey(apiKey: string): string {\n if (apiKey.length < 12) return '••••'\n return `${apiKey.slice(0, 8)}…${apiKey.slice(-4)}`\n}\n\nexport const agentchatSetupWizard: ChannelSetupWizard = {\n channel: AGENTCHAT_CHANNEL_ID,\n\n status: {\n configuredLabel: 'configured',\n unconfiguredLabel: 'not configured',\n configuredHint: 'AgentChat agent is ready to receive messages',\n unconfiguredHint: 'connect your agent to the AgentChat messaging platform',\n configuredScore: 90,\n unconfiguredScore: 30,\n resolveConfigured: ({ cfg, accountId }) => {\n return hasConfiguredKey(cfg, accountId ?? 'default')\n },\n resolveStatusLines: ({ cfg, accountId, configured }) => {\n const id = accountId ?? 'default'\n if (!configured) {\n return ['AgentChat: not configured — the wizard will register you or accept an existing key.']\n }\n const handle = readAgentchatConfigField(cfg, id, 'agentHandle')\n return [`AgentChat: configured${handle ? ` (@${handle})` : ''}`]\n },\n },\n\n introNote: {\n title: 'AgentChat',\n lines: [\n 'AgentChat is a messaging platform for AI agents — direct messages,',\n 'groups, presence, attachments. Registration is free.',\n '',\n 'This wizard will either mint a new account via email OTP, or accept',\n 'an existing API key — your choice in the next prompt.',\n ],\n },\n\n prepare: async ({ cfg, accountId, credentialValues, prompter }) => {\n // Re-run against an already-configured account: offer the edit menu\n // (keep / change-base / replace-key). `change-base` is the only action\n // that cannot be driven through the framework's credential UX — it has\n // to mutate `apiBase`, which is not a credential field. `keep` and\n // `replace-key` both fall through to the framework's keep/replace prompt\n // on the credential step; the only difference is that `replace-key`\n // surfaces the register-or-paste menu below so the user gets the\n // in-wizard register path instead of just a paste box.\n if (hasConfiguredKey(cfg, accountId) && typeof credentialValues.token === 'string') {\n const editChoice = await prompter.select<'keep' | 'change-base' | 'replace-key'>({\n message: 'AgentChat is already configured. What would you like to do?',\n options: [\n {\n value: 'keep',\n label: 'Keep current config',\n hint: 'the credential step will still re-validate on the next run',\n },\n {\n value: 'change-base',\n label: 'Change API base URL',\n hint: 'only for self-hosted AgentChat deployments',\n },\n {\n value: 'replace-key',\n label: 'Replace the API key',\n hint: 'paste a new key, or register a new agent',\n },\n ],\n initialValue: 'keep',\n })\n\n if (editChoice === 'keep') return\n if (editChoice === 'change-base') {\n return await runChangeApiBaseFlow({ cfg, accountId, prompter })\n }\n // 'replace-key' falls through to the register-or-paste menu below.\n }\n\n const choice = await prompter.select<'register' | 'paste'>({\n message: 'How would you like to configure AgentChat?',\n options: [\n {\n value: 'register',\n label: 'Register a new agent (email OTP)',\n hint: 'no account yet — the wizard creates one',\n },\n {\n value: 'paste',\n label: 'I already have an API key',\n hint: 'paste ac_live_… on the next prompt',\n },\n ],\n initialValue: 'register',\n })\n\n if (choice === 'paste') {\n return\n }\n\n const apiBase = readAgentchatConfigField(cfg, accountId, 'apiBase')\n try {\n const result = await runRegisterFlow({ cfg, accountId, prompter, apiBase })\n if (result === 'abort') {\n // User can still paste an existing key at the credential step.\n await prompter.note(\n 'Registration was not completed. You can still paste an existing API key at the next prompt, or cancel the wizard.',\n 'Falling back to credential entry',\n )\n return\n }\n if (result === 'user-chose-paste') {\n // User picked the \"paste my existing key\" branch from inside the\n // register flow — they already acknowledged what's next, so don't\n // re-surface the generic fallback note. Fall through to the\n // credential step which will prompt for the key.\n return\n }\n return result\n } catch (err) {\n if (err instanceof WizardCancelledError) throw err\n await prompter.note(\n `${err instanceof Error ? err.message : String(err)}`,\n 'Registration flow failed',\n )\n return\n }\n },\n\n credentials: [\n {\n inputKey: 'token',\n providerHint: 'agentchat',\n credentialLabel: 'API key',\n preferredEnvVar: 'AGENTCHAT_API_KEY',\n envPrompt: 'AGENTCHAT_API_KEY detected in env. Use it?',\n keepPrompt: 'AgentChat API key already configured. Keep it?',\n inputPrompt: 'Paste your AgentChat API key (ac_live_…)',\n helpTitle: 'AgentChat API key',\n helpLines: [\n 'Format: ac_live_<base64>, ≥20 chars. Validated against',\n 'GET /v1/agents/me during this wizard — bad keys fail fast instead',\n 'of flapping reconnects at runtime.',\n ],\n allowEnv: () => true,\n shouldPrompt: ({ credentialValues, currentValue }) => {\n // Post-register: we already minted + persisted the key in prepare.\n if (credentialValues[JUST_REGISTERED_SENTINEL] === '1') return false\n // No key yet: always prompt.\n if (!currentValue) return true\n // Existing key + user didn't choose register: show keep/replace.\n return true\n },\n inspect: ({ cfg, accountId }) => {\n const apiKey = readAgentchatConfigField(cfg, accountId, 'apiKey')\n const configured = isApiKeyPresent(apiKey)\n const envValue = process.env.AGENTCHAT_API_KEY?.trim()\n return {\n accountConfigured: configured,\n hasConfiguredValue: configured,\n resolvedValue: configured ? apiKey : undefined,\n envValue: envValue && envValue.length >= MIN_API_KEY_LENGTH ? envValue : undefined,\n }\n },\n },\n ],\n\n finalize: async ({ cfg, accountId, credentialValues, prompter }) => {\n const apiKey =\n typeof credentialValues.token === 'string' && credentialValues.token.length >= MIN_API_KEY_LENGTH\n ? credentialValues.token\n : readAgentchatConfigField(cfg, accountId, 'apiKey')\n\n if (!apiKey || !isApiKeyPresent(apiKey)) {\n // Nothing to validate — prepare aborted and credential step got skipped\n // or the user bailed mid-flow. The `configure` call above will still\n // write whatever cfg we return; nothing more to do here.\n return\n }\n\n const apiBase = readAgentchatConfigField(cfg, accountId, 'apiBase')\n const spinner = prompter.progress('Validating API key against AgentChat…')\n try {\n const result = await validateApiKey(apiKey, { apiBase })\n if (result.ok) {\n spinner.stop(`Authenticated as @${result.agent.handle}`)\n\n // If the wizard registered fresh, agentHandle is already in cfg.\n // If the user pasted an existing key, capture the server-known handle\n // so status/log lines render nicely without a manual config edit.\n const existingHandle = readAgentchatConfigField(cfg, accountId, 'agentHandle')\n if (!existingHandle && isValidHandleShape(result.agent.handle)) {\n return {\n cfg: applyAgentchatAccountPatch(cfg, accountId, {\n agentHandle: result.agent.handle,\n }),\n }\n }\n return\n }\n\n spinner.stop(`API key did not pass the live check (${result.reason})`)\n await prompter.note(\n [\n result.message,\n '',\n 'The config was saved — you can re-run `openclaw channels add agentchat`',\n 'to replace the key, or edit ~/.openclaw/config.yaml directly.',\n ].join('\\n'),\n 'AgentChat validation warning',\n )\n } catch (err) {\n spinner.stop('Could not reach AgentChat for validation')\n await prompter.note(\n [\n err instanceof Error ? err.message : String(err),\n '',\n 'The config was saved — the runtime will retry on startup.',\n ].join('\\n'),\n 'AgentChat API unreachable',\n )\n }\n return\n },\n\n completionNote: {\n title: 'AgentChat is ready',\n lines: [\n 'Next steps:',\n ' • Start OpenClaw — the AgentChat channel auto-connects via WebSocket.',\n ' • DM another agent: @<handle> <message>',\n ' • Docs: https://agentchat.me/docs',\n ],\n },\n\n disable: (cfg) => setSetupChannelEnabled(cfg, AGENTCHAT_CHANNEL_ID, false),\n}\n","/**\n * Zod schema for AgentChat channel config.\n *\n * Source of truth: this file. The JSON Schema inlined in `openclaw.plugin.json`\n * MUST stay in sync (P1 adds a build step that emits it via zod-to-json-schema).\n *\n * `.strict()` rejects unknown keys — a common source of \"the config silently\n * ignored my setting\" bugs.\n */\n\nimport { z } from 'zod'\n\nexport const reconnectConfigSchema = z\n .object({\n initialBackoffMs: z.number().int().min(100).max(10_000).default(1_000),\n maxBackoffMs: z.number().int().min(1_000).max(300_000).default(30_000),\n jitterRatio: z.number().min(0).max(1).default(0.2),\n })\n .strict()\n\nexport const pingConfigSchema = z\n .object({\n intervalMs: z.number().int().min(5_000).max(120_000).default(30_000),\n timeoutMs: z.number().int().min(1_000).max(30_000).default(10_000),\n })\n .strict()\n\nexport const outboundConfigSchema = z\n .object({\n maxInFlight: z.number().int().min(1).max(10_000).default(256),\n sendTimeoutMs: z.number().int().min(1_000).max(60_000).default(15_000),\n })\n .strict()\n\nexport const observabilityConfigSchema = z\n .object({\n logLevel: z.enum(['trace', 'debug', 'info', 'warn', 'error']).default('info'),\n redactKeys: z\n .array(z.string())\n .default(['apiKey', 'authorization', 'cookie', 'set-cookie']),\n })\n .strict()\n\nexport const agentHandleSchema = z\n .string()\n .regex(\n /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,\n 'handle must be lowercase letters/digits/hyphens; start with a letter; no trailing or doubled hyphens',\n )\n .min(3, 'handle must be at least 3 characters')\n .max(30, 'handle must be at most 30 characters')\n\nexport const agentchatChannelConfigSchema = z\n .object({\n apiBase: z.string().url().default('https://api.agentchat.me'),\n apiKey: z.string().min(20, 'apiKey looks too short for an AgentChat API key'),\n agentHandle: agentHandleSchema.optional(),\n // `.prefault({})` — Zod 4 idiom: when the key is missing from input, parse\n // `{}` through the inner schema so its own per-field defaults kick in.\n // Using `.default({})` here fails in Zod 4 because the output type's fields\n // are non-optional once the inner schema has defaults.\n reconnect: reconnectConfigSchema.prefault({}),\n ping: pingConfigSchema.prefault({}),\n outbound: outboundConfigSchema.prefault({}),\n observability: observabilityConfigSchema.prefault({}),\n })\n .strict()\n\nexport type AgentchatChannelConfig = z.infer<typeof agentchatChannelConfigSchema>\nexport type AgentchatChannelConfigInput = z.input<typeof agentchatChannelConfigSchema>\n\n/**\n * Parse + validate config at plugin startup.\n *\n * Fails fast on invalid config rather than waiting until the first request.\n * The `AgentChatChannelError` wrapper makes validation failures classifiable\n * by the gateway's error handler (`terminal-user` — operator fix required).\n */\nexport function parseChannelConfig(input: unknown): AgentchatChannelConfig {\n return agentchatChannelConfigSchema.parse(input)\n}\n","/**\n * AgentChat channel plugin — entry point.\n *\n * Wires the real OpenClaw SDK contracts — builds a\n * `ChannelPlugin<AgentchatResolvedAccount>` with id / meta / capabilities /\n * config-adapter / config-schema / setup + setupWizard, and wraps it via\n * `defineChannelPluginEntry(...)` for OpenClaw's extension loader.\n *\n * Config adapter supports both:\n * - single-account flat form: `channels.agentchat.{ apiKey, apiBase, ... }`\n * - multi-account form: `channels.agentchat.accounts.<id>.{ apiKey, ... }`\n *\n * Loaded by OpenClaw via `package.json`'s `openclaw.extensions` entry.\n */\n\nimport {\n buildChannelConfigSchema,\n defineChannelPluginEntry,\n type ChannelConfigUiHint,\n type ChannelPlugin,\n} from 'openclaw/plugin-sdk/channel-core'\n\nimport {\n AGENTCHAT_CHANNEL_ID,\n AGENTCHAT_DEFAULT_ACCOUNT_ID,\n MIN_API_KEY_LENGTH,\n applyAgentchatAccountPatch,\n isApiKeyPresent,\n readAccountRaw,\n readChannelSection,\n splitEnabledFromRaw,\n} from './channel-account.js'\nimport { agentchatSetupWizard } from './channel.wizard.js'\nimport {\n agentchatChannelConfigSchema,\n parseChannelConfig,\n type AgentchatChannelConfig,\n} from './config-schema.js'\nimport { validateApiKey } from './setup-client.js'\n\nexport {\n AGENTCHAT_CHANNEL_ID,\n AGENTCHAT_DEFAULT_ACCOUNT_ID,\n MIN_API_KEY_LENGTH,\n applyAgentchatAccountPatch,\n isApiKeyPresent,\n readAgentchatConfigField,\n} from './channel-account.js'\n\nexport interface AgentchatResolvedAccount {\n accountId: string\n enabled: boolean\n configured: boolean\n config: AgentchatChannelConfig | null\n parseError: string | null\n}\n\nconst uiHints: Record<string, ChannelConfigUiHint> = {\n apiKey: {\n label: 'AgentChat API key',\n placeholder: 'ac_live_...',\n sensitive: true,\n help: 'The setup wizard registers you via email OTP and mints a key — or paste an existing ac_live_… key.',\n },\n apiBase: {\n label: 'API base URL',\n placeholder: 'https://api.agentchat.me',\n help: 'Override only when targeting a self-hosted AgentChat instance.',\n advanced: true,\n },\n agentHandle: {\n label: 'Agent handle',\n placeholder: 'my-agent',\n help: '3–30 chars, lowercase letters/digits/hyphens; must start with a letter.',\n },\n reconnect: { label: 'Reconnect backoff', advanced: true },\n ping: { label: 'WebSocket ping cadence', advanced: true },\n outbound: { label: 'Outbound send tuning', advanced: true },\n observability: { label: 'Logs & metrics', advanced: true },\n}\n\nexport const agentchatPlugin: ChannelPlugin<AgentchatResolvedAccount> = {\n id: AGENTCHAT_CHANNEL_ID,\n\n meta: {\n id: AGENTCHAT_CHANNEL_ID,\n label: 'AgentChat',\n selectionLabel: 'AgentChat (messaging platform for agents)',\n detailLabel: 'AgentChat',\n docsPath: '/channels/agentchat',\n docsLabel: 'agentchat',\n blurb:\n 'connect your agent to the AgentChat messaging platform — handles, contacts, groups, presence, attachments.',\n systemImage: 'message',\n markdownCapable: true,\n order: 100,\n },\n\n capabilities: {\n chatTypes: ['direct', 'group'],\n media: true,\n reactions: false,\n edit: false,\n unsend: true,\n reply: true,\n threads: false,\n nativeCommands: false,\n },\n\n reload: {\n configPrefixes: [`channels.${AGENTCHAT_CHANNEL_ID}.`],\n },\n\n configSchema: buildChannelConfigSchema(agentchatChannelConfigSchema, { uiHints }),\n\n setupWizard: agentchatSetupWizard,\n\n config: {\n listAccountIds(cfg) {\n const section = readChannelSection(cfg)\n if (!section) return []\n const { accounts } = section\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const ids = Object.keys(accounts as Record<string, unknown>)\n if (ids.length > 0) return ids\n }\n const hasFlatFields =\n typeof section.apiKey === 'string' ||\n typeof section.apiBase === 'string' ||\n typeof section.agentHandle === 'string'\n return hasFlatFields ? [AGENTCHAT_DEFAULT_ACCOUNT_ID] : []\n },\n\n resolveAccount(cfg, accountId) {\n const id = accountId ?? AGENTCHAT_DEFAULT_ACCOUNT_ID\n const section = readChannelSection(cfg)\n const raw = readAccountRaw(section, id)\n const { enabled, forParse } = splitEnabledFromRaw(raw)\n let config: AgentchatChannelConfig | null = null\n let parseError: string | null = null\n if (forParse && Object.keys(forParse).length > 0) {\n try {\n config = parseChannelConfig(forParse)\n } catch (e) {\n parseError = e instanceof Error ? e.message : String(e)\n }\n }\n const configured = Boolean(config && isApiKeyPresent(config.apiKey))\n return { accountId: id, enabled, configured, config, parseError }\n },\n\n defaultAccountId() {\n return AGENTCHAT_DEFAULT_ACCOUNT_ID\n },\n\n isEnabled(account) {\n return account.enabled\n },\n\n disabledReason(account) {\n return account.enabled ? '' : 'channel disabled via channels.agentchat.enabled=false'\n },\n\n isConfigured(account) {\n return account.configured\n },\n\n unconfiguredReason(account) {\n if (account.parseError) return `config invalid: ${account.parseError}`\n if (!account.config) return 'missing channels.agentchat configuration'\n if (!isApiKeyPresent(account.config.apiKey)) return 'missing or too-short channels.agentchat.apiKey'\n return ''\n },\n\n hasConfiguredState({ cfg }) {\n const section = readChannelSection(cfg)\n if (!section) return false\n const { accounts } = section\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n for (const entry of Object.values(accounts as Record<string, unknown>)) {\n if (entry && typeof entry === 'object') {\n const candidate = (entry as Record<string, unknown>).apiKey\n if (isApiKeyPresent(candidate)) return true\n }\n }\n }\n return isApiKeyPresent(section.apiKey)\n },\n\n describeAccount(account) {\n return {\n accountId: account.accountId,\n enabled: account.enabled,\n configured: account.configured,\n linked: account.configured,\n }\n },\n },\n\n setup: {\n /**\n * Pre-write gate: cheap, sync check that the caller supplied an API key\n * that's at least plausibly shaped. Real authentication happens in\n * `afterAccountConfigWritten` via a live /agents/me probe.\n */\n validateInput({ input }) {\n if (typeof input.token !== 'string' || input.token.trim().length === 0) {\n return 'apiKey is required — pass via --token or run the register flow'\n }\n if (input.token.length < MIN_API_KEY_LENGTH) {\n return `apiKey looks too short (got ${input.token.length} chars, expect ≥${MIN_API_KEY_LENGTH})`\n }\n if (typeof input.url === 'string' && input.url.length > 0) {\n try {\n const parsed = new URL(input.url)\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {\n return 'apiBase must be http(s) — e.g. https://api.agentchat.me'\n }\n } catch {\n return 'apiBase is not a valid URL'\n }\n }\n return null\n },\n\n applyAccountConfig({ cfg, accountId, input }) {\n const patch: Record<string, unknown> = {}\n if (typeof input.token === 'string' && input.token.length > 0) patch.apiKey = input.token\n if (typeof input.url === 'string' && input.url.length > 0) patch.apiBase = input.url\n return applyAgentchatAccountPatch(cfg, accountId, patch)\n },\n\n /**\n * Post-write probe: call `GET /v1/agents/me` with the key we just wrote\n * so the operator sees a clear \"✓ authenticated as @handle\" on success\n * — or a specific failure reason (invalid, revoked, unreachable) they\n * can act on *before* the runtime starts flapping reconnects in prod.\n *\n * Never throws: setup-time UX is \"warn and proceed\". If the probe can't\n * reach the API (airgapped CI, corp proxy during first boot), we still\n * want the config written so the user can retry without reconfiguring.\n */\n async afterAccountConfigWritten({ cfg, accountId, input, runtime }) {\n const apiKey = typeof input.token === 'string' ? input.token : undefined\n if (!apiKey) return\n const apiBase = typeof input.url === 'string' && input.url.length > 0 ? input.url : undefined\n void cfg\n const logger = (runtime as { logger?: { info?: (...args: unknown[]) => void; warn?: (...args: unknown[]) => void } } | undefined)?.logger\n try {\n const result = await validateApiKey(apiKey, { apiBase })\n if (result.ok) {\n logger?.info?.(\n `[agentchat:${accountId}] authenticated as @${result.agent.handle} (${result.agent.email})`,\n )\n } else {\n logger?.warn?.(\n `[agentchat:${accountId}] api key did not pass live check (${result.reason}): ${result.message}`,\n )\n }\n } catch (err) {\n logger?.warn?.(\n `[agentchat:${accountId}] live key validation failed: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n },\n },\n}\n\n/**\n * Canonical channel-entry descriptor consumed by OpenClaw's extension loader.\n * Exported as `default` because `openclaw.extensions` in package.json points to\n * this module and the loader reads the default export.\n *\n * The explicit `ReturnType<...>` annotation pins the emitted `.d.ts` to the\n * function signature instead of the structural shape — otherwise the inferred\n * type references `ChannelConfigSchema` through a non-exported path and TS\n * fails with TS2742 (\"cannot be named without a reference to ...\").\n */\nexport const agentchatChannelEntry: ReturnType<\n typeof defineChannelPluginEntry<typeof agentchatPlugin>\n> = defineChannelPluginEntry({\n id: AGENTCHAT_CHANNEL_ID,\n name: 'AgentChat',\n description: 'Connect OpenClaw agents to the AgentChat messaging platform.',\n plugin: agentchatPlugin,\n})\n\nexport default agentchatChannelEntry\n\nexport { parseChannelConfig }\nexport type { AgentchatChannelConfig }\n","/**\n * AgentChat setup plugin — onboarding entry.\n *\n * Wraps the same `agentchatPlugin` from `channel.ts` with\n * `defineSetupPluginEntry(...)` so OpenClaw's setup-entry loader can pick it\n * up from `package.json`'s `openclaw.setupEntry` field.\n *\n * The plugin itself carries both:\n * - `plugin.setup` — the non-interactive adapter used by\n * `openclaw setup --channel agentchat --token …`\n * - `plugin.setupWizard` — the interactive login-vs-register wizard used by\n * `openclaw channels add agentchat`\n *\n * Both paths write through the same `applyAgentchatAccountPatch` helper, so\n * the resulting config is identical regardless of entry point.\n */\n\nimport { defineSetupPluginEntry } from 'openclaw/plugin-sdk/channel-core'\n\nimport { agentchatPlugin } from './channel.js'\n\nexport const agentchatSetupEntry = defineSetupPluginEntry(agentchatPlugin)\n\nexport default agentchatSetupEntry\n\nexport { agentchatPlugin as agentchatSetupPlugin }\n","/**\n * Configured-state predicate for the AgentChat channel.\n *\n * OpenClaw calls this to decide whether the channel has \"enough\" config to\n * be considered active (counts toward enabled channels, shown in UI, etc.).\n *\n * Minimum bar: an `apiKey` of plausible length is present.\n */\n\nexport interface MaybeConfigured {\n readonly apiKey?: unknown\n}\n\nexport function hasAgentChatConfiguredState(config: MaybeConfigured | undefined): boolean {\n if (!config || typeof config !== 'object') return false\n const key = config.apiKey\n return typeof key === 'string' && key.length >= 20\n}\n","/**\n * Structured logger for the channel plugin.\n *\n * Wraps pino with:\n * - Secret redaction (`apiKey`, `authorization`, `cookie`, `set-cookie` by default)\n * - A `child({ correlationId })` helper for per-operation logs\n * - Graceful integration: when OpenClaw's channel runtime context provides\n * a logger, we delegate to it so logs stream through the gateway's sink.\n *\n * Never logs the API key. Never logs message bodies above `debug` level.\n */\n\nimport pino from 'pino'\n\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error'\n\nexport interface Logger {\n trace(obj: object, msg?: string): void\n debug(obj: object, msg?: string): void\n info(obj: object, msg?: string): void\n warn(obj: object, msg?: string): void\n error(obj: object, msg?: string): void\n child(bindings: Record<string, unknown>): Logger\n}\n\nexport interface CreateLoggerOptions {\n level: LogLevel\n redactKeys: readonly string[]\n /** If provided, delegates to the gateway's logger instead of creating our own. */\n delegate?: Logger | undefined\n}\n\nexport function createLogger(options: CreateLoggerOptions): Logger {\n if (options.delegate) {\n return options.delegate\n }\n\n const pinoLogger = pino({\n level: options.level,\n base: { plugin: '@agentchatme/openclaw' },\n redact: {\n paths: buildRedactPaths(options.redactKeys),\n censor: '[REDACTED]',\n },\n timestamp: pino.stdTimeFunctions.isoTime,\n })\n\n return wrapPino(pinoLogger)\n}\n\nfunction buildRedactPaths(keys: readonly string[]): string[] {\n // Cover common shapes: top-level, nested under `config.*`, nested under\n // `headers.*`, nested under `context.*`. Pino redact paths are JSON-path-ish.\n const prefixes = ['', 'config.', 'headers.', 'context.', 'req.headers.', 'res.headers.']\n const paths: string[] = []\n for (const key of keys) {\n for (const prefix of prefixes) {\n paths.push(`${prefix}${key}`)\n }\n }\n // Also redact under `*` wildcard at top level for deeply nested cases.\n paths.push(...keys.map((k) => `*.${k}`))\n return paths\n}\n\nfunction wrapPino(p: pino.Logger): Logger {\n return {\n trace: (obj, msg) => p.trace(obj, msg),\n debug: (obj, msg) => p.debug(obj, msg),\n info: (obj, msg) => p.info(obj, msg),\n warn: (obj, msg) => p.warn(obj, msg),\n error: (obj, msg) => p.error(obj, msg),\n child: (bindings) => wrapPino(p.child(bindings)),\n }\n}\n\n/**\n * Redact a string for display in logs — shows first 8 and last 4 chars,\n * masks the middle. Useful for surfacing \"which key\" without leaking it.\n */\nexport function maskSecret(value: string): string {\n if (value.length <= 12) return '[REDACTED]'\n return `${value.slice(0, 8)}••••${value.slice(-4)}`\n}\n","/**\n * Optional Prometheus metrics for the channel plugin.\n *\n * Design: the gateway owns the `/metrics` endpoint. Plugins do not expose\n * their own port. If the user passes a `prom-client` Registry via channel\n * runtime context, we register our counters/gauges/histograms into it.\n * Otherwise, we return a no-op recorder — zero overhead, zero config.\n *\n * Names are prefixed with `agentchat_channel_` for easy scraping.\n */\n\nexport interface MetricsRecorder {\n /** Incremented on every successfully delivered inbound message. */\n incInboundDelivered(labels: { kind: InboundKind }): void\n /** Incremented on every successfully sent outbound message. */\n incOutboundSent(labels: { kind: OutboundKind }): void\n /** Incremented on every send failure, labeled by error class. */\n incOutboundFailed(labels: { errorClass: string }): void\n /** Incremented on every reconnect attempt. */\n incReconnect(labels: { reason: string }): void\n /** Observe end-to-end send latency (ms). */\n observeSendLatency(ms: number): void\n /** Set the current connection state (cardinality bounded by state kinds). */\n setConnectionState(kind: string): void\n /** Set the current in-flight send queue depth. */\n setInFlightDepth(n: number): void\n}\n\nexport type InboundKind = 'message' | 'group-message' | 'typing' | 'read' | 'presence' | 'rate-limit-warning'\nexport type OutboundKind = 'message' | 'typing' | 'read'\n\n/**\n * Minimal contract for a prom-client-compatible registry. We accept anything\n * that exposes the `registerMetric` shape so consumers can pass their own\n * custom registry or a bare `Registry` from `prom-client`.\n */\nexport interface PromRegistryLike {\n registerMetric(metric: unknown): void\n}\n\n/**\n * Minimal contract for a prom-client factory. Keeping this abstract lets us\n * avoid a hard dep on `prom-client` while still being production-capable.\n * The caller passes `{ Counter, Gauge, Histogram }` from their own import.\n */\nexport interface PromFactory {\n Counter: new (cfg: MetricConfig) => {\n inc(labels?: Record<string, string>, value?: number): void\n }\n Gauge: new (cfg: MetricConfig) => {\n set(labelsOrValue: Record<string, string> | number, value?: number): void\n }\n Histogram: new (cfg: MetricConfig) => {\n observe(labelsOrValue: Record<string, string> | number, value?: number): void\n }\n}\n\ninterface MetricConfig {\n name: string\n help: string\n labelNames?: readonly string[]\n buckets?: readonly number[]\n registers?: readonly unknown[]\n}\n\nexport interface CreateMetricsOptions {\n registry: PromRegistryLike\n factory: PromFactory\n}\n\nexport function createMetrics(options: CreateMetricsOptions): MetricsRecorder {\n const { registry, factory } = options\n\n const inboundDelivered = new factory.Counter({\n name: 'agentchat_channel_inbound_delivered_total',\n help: 'Inbound messages delivered to OpenClaw runtime.',\n labelNames: ['kind'],\n registers: [registry],\n })\n\n const outboundSent = new factory.Counter({\n name: 'agentchat_channel_outbound_sent_total',\n help: 'Outbound messages successfully sent to AgentChat.',\n labelNames: ['kind'],\n registers: [registry],\n })\n\n const outboundFailed = new factory.Counter({\n name: 'agentchat_channel_outbound_failed_total',\n help: 'Outbound send failures, labeled by error class.',\n labelNames: ['errorClass'],\n registers: [registry],\n })\n\n const reconnects = new factory.Counter({\n name: 'agentchat_channel_reconnect_total',\n help: 'WebSocket reconnect attempts.',\n labelNames: ['reason'],\n registers: [registry],\n })\n\n const sendLatency = new factory.Histogram({\n name: 'agentchat_channel_send_latency_ms',\n help: 'End-to-end latency of outbound send (ms).',\n buckets: [10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10_000, 30_000],\n registers: [registry],\n })\n\n const connectionState = new factory.Gauge({\n name: 'agentchat_channel_connection_state',\n help: 'Current connection state (1 = active kind, 0 = otherwise).',\n labelNames: ['kind'],\n registers: [registry],\n })\n\n const inFlightDepth = new factory.Gauge({\n name: 'agentchat_channel_inflight_depth',\n help: 'Current in-flight outbound send queue depth.',\n registers: [registry],\n })\n\n return {\n incInboundDelivered: ({ kind }) => inboundDelivered.inc({ kind }),\n incOutboundSent: ({ kind }) => outboundSent.inc({ kind }),\n incOutboundFailed: ({ errorClass }) => outboundFailed.inc({ errorClass }),\n incReconnect: ({ reason }) => reconnects.inc({ reason }),\n observeSendLatency: (ms) => sendLatency.observe(ms),\n setConnectionState: (kind) => connectionState.set({ kind }, 1),\n setInFlightDepth: (n) => inFlightDepth.set(n),\n }\n}\n\n/** No-op recorder — used when the user does not provide a Prometheus registry. */\nexport function createNoopMetrics(): MetricsRecorder {\n return {\n incInboundDelivered: () => undefined,\n incOutboundSent: () => undefined,\n incOutboundFailed: () => undefined,\n incReconnect: () => undefined,\n observeSendLatency: () => undefined,\n setConnectionState: () => undefined,\n setInFlightDepth: () => undefined,\n }\n}\n","/**\n * Connection state machine for the AgentChat WebSocket.\n *\n * Pure functions only — no I/O, no timers. The runtime (P2) owns the socket\n * and drives transitions by emitting events.\n *\n * States:\n * DISCONNECTED — initial, and after a clean close\n * CONNECTING — TCP/TLS handshake + WS upgrade in flight\n * AUTHENTICATING — socket open, waiting for `hello.ok` from server\n * READY — authenticated, receiving + sending normally\n * DEGRADED — heartbeat missed or send buffer full; still connected but impaired\n * DRAINING — SIGTERM received; flush in-flight sends, then close\n * CLOSED — terminal after clean shutdown\n * AUTH_FAIL — terminal after 401/403; operator action required (rotate key)\n *\n * Invariants:\n * - From AUTH_FAIL, no event can move us back to CONNECTING without\n * an explicit RECONFIGURED event (operator rotated key).\n * - From CLOSED, only SHUTDOWN is a no-op; anything else is a bug.\n * - DRAINING has a deadline (ms timestamp) after which we force-close.\n */\n\nimport type { UnixMillis } from './types.js'\n\nexport type ConnectionState =\n | { readonly kind: 'DISCONNECTED' }\n | { readonly kind: 'CONNECTING'; readonly attempt: number; readonly startedAt: UnixMillis }\n | { readonly kind: 'AUTHENTICATING'; readonly startedAt: UnixMillis }\n | { readonly kind: 'READY'; readonly connectedAt: UnixMillis }\n | { readonly kind: 'DEGRADED'; readonly since: UnixMillis; readonly reason: string }\n | { readonly kind: 'DRAINING'; readonly since: UnixMillis; readonly deadline: UnixMillis }\n | { readonly kind: 'CLOSED' }\n | { readonly kind: 'AUTH_FAIL'; readonly reason: string }\n\nexport type ConnectionEvent =\n | { readonly type: 'CONNECT'; readonly now: UnixMillis; readonly attempt: number }\n | { readonly type: 'SOCKET_OPEN'; readonly now: UnixMillis }\n | { readonly type: 'HELLO_OK'; readonly now: UnixMillis }\n | { readonly type: 'AUTH_REJECTED'; readonly reason: string }\n | { readonly type: 'SOCKET_CLOSED'; readonly code: number; readonly reason: string }\n | { readonly type: 'PING_TIMEOUT'; readonly now: UnixMillis }\n | { readonly type: 'BACKPRESSURE'; readonly now: UnixMillis; readonly reason: string }\n | { readonly type: 'RECOVERED'; readonly now: UnixMillis }\n | { readonly type: 'DRAIN_REQUESTED'; readonly now: UnixMillis; readonly deadline: UnixMillis }\n | { readonly type: 'DRAIN_COMPLETED' }\n | { readonly type: 'RECONFIGURED' }\n\n/**\n * Apply an event to a state. Returns a new state.\n *\n * Illegal transitions (e.g. HELLO_OK while in DISCONNECTED) fall through to\n * the current state — the runtime should log them as `transition.invalid`\n * so they become visible in telemetry without crashing the process.\n */\nexport function transition(state: ConnectionState, event: ConnectionEvent): ConnectionState {\n switch (state.kind) {\n case 'DISCONNECTED': {\n if (event.type === 'CONNECT') {\n return { kind: 'CONNECTING', attempt: event.attempt, startedAt: event.now }\n }\n if (event.type === 'DRAIN_REQUESTED') return { kind: 'CLOSED' }\n // Reconnect hard-cap elevation — the runtime has given up on transport\n // retries and wants to force operator attention. Treat the same as a\n // genuine auth reject: terminal until RECONFIGURED.\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\n return state\n }\n\n case 'CONNECTING': {\n if (event.type === 'SOCKET_OPEN') return { kind: 'AUTHENTICATING', startedAt: event.now }\n if (event.type === 'SOCKET_CLOSED') return { kind: 'DISCONNECTED' }\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\n if (event.type === 'DRAIN_REQUESTED') return { kind: 'CLOSED' }\n return state\n }\n\n case 'AUTHENTICATING': {\n if (event.type === 'HELLO_OK') return { kind: 'READY', connectedAt: event.now }\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\n if (event.type === 'SOCKET_CLOSED') return { kind: 'DISCONNECTED' }\n if (event.type === 'DRAIN_REQUESTED') return { kind: 'CLOSED' }\n return state\n }\n\n case 'READY': {\n if (event.type === 'PING_TIMEOUT') {\n return { kind: 'DEGRADED', since: event.now, reason: 'ping-timeout' }\n }\n if (event.type === 'BACKPRESSURE') {\n return { kind: 'DEGRADED', since: event.now, reason: event.reason }\n }\n if (event.type === 'SOCKET_CLOSED') return { kind: 'DISCONNECTED' }\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\n if (event.type === 'DRAIN_REQUESTED') {\n return { kind: 'DRAINING', since: event.now, deadline: event.deadline }\n }\n return state\n }\n\n case 'DEGRADED': {\n if (event.type === 'RECOVERED') return { kind: 'READY', connectedAt: event.now }\n if (event.type === 'SOCKET_CLOSED') return { kind: 'DISCONNECTED' }\n if (event.type === 'AUTH_REJECTED') return { kind: 'AUTH_FAIL', reason: event.reason }\n if (event.type === 'DRAIN_REQUESTED') {\n return { kind: 'DRAINING', since: event.now, deadline: event.deadline }\n }\n return state\n }\n\n case 'DRAINING': {\n if (event.type === 'DRAIN_COMPLETED') return { kind: 'CLOSED' }\n if (event.type === 'SOCKET_CLOSED') return { kind: 'CLOSED' }\n return state\n }\n\n case 'AUTH_FAIL': {\n // Only an explicit reconfig (operator rotated key) can leave AUTH_FAIL.\n if (event.type === 'RECONFIGURED') return { kind: 'DISCONNECTED' }\n if (event.type === 'DRAIN_REQUESTED') return { kind: 'CLOSED' }\n return state\n }\n\n case 'CLOSED': {\n return state\n }\n }\n}\n\n/** True iff sends may be attempted in this state. */\nexport function canSend(state: ConnectionState): boolean {\n return state.kind === 'READY' || state.kind === 'DEGRADED' || state.kind === 'DRAINING'\n}\n\n/** True iff the state indicates a transport-level problem the runtime should recover from. */\nexport function shouldReconnect(state: ConnectionState): boolean {\n return state.kind === 'DISCONNECTED'\n}\n\n/** True iff the state is terminal and no further transitions are expected. */\nexport function isTerminal(state: ConnectionState): boolean {\n return state.kind === 'CLOSED' || state.kind === 'AUTH_FAIL'\n}\n","/**\n * AgentChat WebSocket client — state-machine-driven, production-grade.\n *\n * Responsibilities:\n * - Own the WS transport and HELLO handshake lifecycle.\n * - Drive the connection state machine (`./state-machine.ts`) by emitting\n * events in response to socket/auth/heartbeat transitions.\n * - Maintain native WS PING/PONG heartbeat at `ping.intervalMs`; declare\n * DEGRADED on `ping.timeoutMs` miss, then force-reconnect.\n * - Schedule reconnect with exponential backoff + ±`jitterRatio` jitter\n * per `reconnect.*` config. Thundering-herd-safe across a fleet.\n * - Emit typed events upwards (`inboundFrame`, `stateChanged`, `error`)\n * so the normalizer (P3) and outbound adapter (P4) can consume them.\n *\n * Intentional design choices:\n * - Uses the `ws` package directly (not `globalThis.WebSocket`) because\n * OpenClaw runs on Node — `ws` exposes `.ping()` / `.pong()` / event\n * hooks that native WebSocket omits. Every major agent-hosting target\n * (Fly, Render, Vercel functions, Lambda) is Node.\n * - Authenticates via HELLO frame (`{type: \"hello\", api_key}`), never via\n * URL query string. Keeps the key out of access logs and Referers.\n * - `RECONNECT_HARD_CAP_ATTEMPTS` guards against runaway reconnect loops\n * after catastrophic network events; crosses into `AUTH_FAIL` so the\n * operator sees a clear signal instead of silent retry forever.\n * - Frame parsing is defensive: malformed JSON, unknown `type`, missing\n * payload — all classified as `validation` errors (non-terminal for\n * the connection, but dropped with a metric + log).\n * - No message-layer ordering here. Per-conversation seq ordering + gap\n * recovery belong to the SDK's `RealtimeClient` and the drain layer\n * (P3 consumers). This module is strictly the transport.\n */\n\nimport type { RawData, WebSocket as WsInstance } from 'ws'\nimport { WebSocket as NodeWebSocket } from 'ws'\n\nimport {\n AgentChatChannelError,\n classifyNetworkError,\n type ErrorClass,\n} from './errors.js'\nimport type { Logger } from './log.js'\nimport type { MetricsRecorder } from './metrics.js'\nimport {\n canSend,\n isTerminal,\n transition,\n type ConnectionEvent,\n type ConnectionState,\n} from './state-machine.js'\nimport type { AgentchatChannelConfig } from './config-schema.js'\nimport type { UnixMillis } from './types.js'\n\n// HELLO handshake must resolve faster than the server's 5s cutoff — we give\n// ourselves 4s so a clean close + reconnect happens before the server drops.\nconst HELLO_ACK_TIMEOUT_MS = 4_000\n\n// Reconnect attempts above this threshold almost certainly mean the network\n// is partitioned from the AgentChat control plane, or the API key was\n// revoked at the edge (without a terminal 401). Surface AUTH_FAIL so the\n// operator has a clear signal rather than silent forever-retry.\nconst RECONNECT_HARD_CAP_ATTEMPTS = 60\n\n// Maximum frame size we'll accept from the server. Matches AgentChat's\n// own server-side outbound cap (2 MiB — large attachments go via the REST\n// upload flow, not inline in WS frames).\nconst MAX_FRAME_BYTES = 2 * 1024 * 1024\n\n// WebSocket close codes we treat as auth failures (terminal until operator\n// reconfigures). 1008 = policy violation; AgentChat uses it + 4401/4403 for\n// auth-related rejects. Other 4xxx codes are treated as retry-transient.\nconst AUTH_CLOSE_CODES = new Set([1008, 4401, 4403])\n\n/** One parsed inbound server frame. */\nexport interface InboundFrame {\n readonly type: string\n readonly payload: Record<string, unknown>\n readonly receivedAt: UnixMillis\n readonly raw: unknown\n}\n\n/** One client-action frame the caller wants to push. */\nexport interface OutboundFrame {\n readonly type: string\n readonly payload: Record<string, unknown>\n readonly id?: string\n}\n\nexport interface WsClientEvents {\n stateChanged: (next: ConnectionState, prev: ConnectionState) => void\n inboundFrame: (frame: InboundFrame) => void\n error: (error: AgentChatChannelError) => void\n /** Fired once per `hello.ok` — useful for triggering a /v1/messages/sync drain upstream. */\n authenticated: (at: UnixMillis) => void\n /** Fired after a clean close + CLOSED state (after stop() or terminal auth failure). */\n closed: () => void\n}\n\nexport interface WsClientOptions {\n readonly config: AgentchatChannelConfig\n readonly logger: Logger\n readonly metrics: MetricsRecorder\n /** Clock source — override in tests. Default: `Date.now`. */\n readonly now?: () => UnixMillis\n /** WebSocket constructor override — tests inject a mock. Default: `ws`. */\n readonly webSocketCtor?: typeof NodeWebSocket\n /** Random source for jitter — override in tests. Default: `Math.random`. */\n readonly random?: () => number\n /** timer.setTimeout override for tests. */\n readonly setTimeout?: (fn: () => void, ms: number) => NodeJS.Timeout\n readonly clearTimeout?: (h: NodeJS.Timeout) => void\n readonly setInterval?: (fn: () => void, ms: number) => NodeJS.Timeout\n readonly clearInterval?: (h: NodeJS.Timeout) => void\n}\n\ntype Listener<E extends keyof WsClientEvents> = WsClientEvents[E]\n\n/**\n * AgentChat channel WebSocket client.\n *\n * Lifecycle:\n * 1. `start()` — DISCONNECTED → CONNECTING. Transport opens, HELLO is sent.\n * 2. `hello.ok` → READY. Heartbeat timer starts. Upstream consumers begin.\n * 3. On socket drop → DISCONNECTED → CONNECTING (with backoff).\n * 4. `stop(deadlineMs)` → DRAINING. Wait for in-flight drains, then CLOSED.\n *\n * Thread-safety: this class is single-threaded. All callbacks fire on the\n * Node event loop; callers should never invoke public methods from timer\n * callbacks without being aware of reentrancy (e.g., a `stateChanged`\n * listener that calls `send()` is fine, but `start()` inside `closed()`\n * will re-enter the lifecycle — usually a bug).\n */\nexport class AgentchatWsClient {\n private readonly config: AgentchatChannelConfig\n private readonly logger: Logger\n private readonly metrics: MetricsRecorder\n private readonly now: () => UnixMillis\n private readonly WebSocketCtor: typeof NodeWebSocket\n private readonly random: () => number\n private readonly _setTimeout: (fn: () => void, ms: number) => NodeJS.Timeout\n private readonly _clearTimeout: (h: NodeJS.Timeout) => void\n private readonly _setInterval: (fn: () => void, ms: number) => NodeJS.Timeout\n private readonly _clearInterval: (h: NodeJS.Timeout) => void\n\n private state: ConnectionState = { kind: 'DISCONNECTED' }\n private ws: WsInstance | null = null\n private attempt = 0\n\n private helloAckTimer: NodeJS.Timeout | null = null\n private pingTimer: NodeJS.Timeout | null = null\n private pongTimer: NodeJS.Timeout | null = null\n private reconnectTimer: NodeJS.Timeout | null = null\n private drainTimer: NodeJS.Timeout | null = null\n\n private readonly listeners: {\n [K in keyof WsClientEvents]: Set<Listener<K>>\n } = {\n stateChanged: new Set(),\n inboundFrame: new Set(),\n error: new Set(),\n authenticated: new Set(),\n closed: new Set(),\n }\n\n constructor(options: WsClientOptions) {\n this.config = options.config\n this.logger = options.logger.child({ component: 'ws-client' })\n this.metrics = options.metrics\n this.now = options.now ?? Date.now\n this.WebSocketCtor = options.webSocketCtor ?? NodeWebSocket\n this.random = options.random ?? Math.random\n this._setTimeout = options.setTimeout ?? ((fn, ms) => setTimeout(fn, ms))\n this._clearTimeout = options.clearTimeout ?? ((h) => clearTimeout(h))\n this._setInterval = options.setInterval ?? ((fn, ms) => setInterval(fn, ms))\n this._clearInterval = options.clearInterval ?? ((h) => clearInterval(h))\n\n this.metrics.setConnectionState(this.state.kind)\n }\n\n // ─── Public API ──────────────────────────────────────────────────────\n\n /** Current connection state. Read-only from the caller's perspective. */\n getState(): ConnectionState {\n return this.state\n }\n\n /**\n * Kick off connection. No-op if already connecting, authenticating, or\n * ready. Throws on `AUTH_FAIL` — the caller must call `reconfigured()`\n * after rotating the API key before retrying.\n */\n start(): void {\n if (this.state.kind === 'AUTH_FAIL') {\n throw new AgentChatChannelError(\n 'terminal-auth',\n 'cannot start: channel is in AUTH_FAIL — rotate api key and call reconfigured()',\n )\n }\n if (this.state.kind === 'CLOSED') {\n throw new Error('cannot start: client is closed. Create a new instance.')\n }\n if (this.state.kind !== 'DISCONNECTED') {\n // Already in progress — nothing to do.\n return\n }\n this.openSocket(1)\n }\n\n /**\n * Push a client-action frame. Requires `canSend(state)` — returns false\n * if the socket is not ready. Callers should queue and retry from the\n * outbound adapter (P4) rather than drop here.\n */\n send(frame: OutboundFrame): boolean {\n if (!canSend(this.state) || !this.ws || this.ws.readyState !== NodeWebSocket.OPEN) {\n return false\n }\n try {\n this.ws.send(JSON.stringify(frame))\n return true\n } catch (err) {\n this.emitError(\n new AgentChatChannelError(\n classifyNetworkError(err),\n 'ws send failed',\n { cause: err },\n ),\n )\n return false\n }\n }\n\n /**\n * Request a graceful drain. The caller-supplied deadline is a Unix-ms\n * timestamp; after it passes, the socket is force-closed regardless of\n * remaining in-flight work. Safe to call from any state.\n */\n stop(deadline?: UnixMillis): void {\n const now = this.now()\n const computedDeadline = deadline ?? now + 5_000\n\n if (this.state.kind === 'DRAINING') {\n // Second stop() — tighten the deadline if the caller asked for\n // earlier closure, otherwise ignore.\n if (computedDeadline < this.state.deadline) {\n this.applyEvent({ type: 'DRAIN_REQUESTED', now, deadline: computedDeadline })\n this.scheduleDrainDeadline(computedDeadline)\n }\n return\n }\n\n if (isTerminal(this.state)) {\n return\n }\n\n this.applyEvent({ type: 'DRAIN_REQUESTED', now, deadline: computedDeadline })\n\n // `applyEvent` mutated `this.state`; widen the read so TS doesn't\n // over-narrow against the pre-apply snapshot (TS tracks the control-flow\n // narrowing across the earlier guards and isn't aware the method call\n // mutated state).\n const after = (this.state as ConnectionState).kind\n if (after === 'DRAINING') {\n this.scheduleDrainDeadline(computedDeadline)\n } else if (after === 'CLOSED') {\n this.closeSocket(1000, 'client drain (immediate)')\n this.emit('closed')\n }\n }\n\n /**\n * Signal that operator has rotated the API key. Transitions from\n * AUTH_FAIL back to DISCONNECTED; the next `start()` call will attempt\n * a fresh HELLO with the current config.\n */\n reconfigured(): void {\n if (this.state.kind !== 'AUTH_FAIL') return\n this.applyEvent({ type: 'RECONFIGURED' })\n }\n\n on<E extends keyof WsClientEvents>(event: E, handler: Listener<E>): () => void {\n this.listeners[event].add(handler as Listener<E>)\n return () => {\n this.listeners[event].delete(handler as Listener<E>)\n }\n }\n\n // ─── Internals: socket lifecycle ─────────────────────────────────────\n\n private openSocket(attempt: number): void {\n this.attempt = attempt\n const now = this.now()\n this.applyEvent({ type: 'CONNECT', now, attempt })\n\n const url = `${this.config.apiBase.replace(/^http/, 'ws')}/v1/ws`\n\n let ws: WsInstance\n try {\n ws = new this.WebSocketCtor(url, {\n perMessageDeflate: false,\n // `ws` auto-pong is on by default — we keep it so heartbeat RTT\n // is symmetric even when the server initiates the ping.\n maxPayload: MAX_FRAME_BYTES,\n })\n } catch (err) {\n this.emitError(\n new AgentChatChannelError(\n classifyNetworkError(err),\n 'ws constructor threw',\n { cause: err },\n ),\n )\n this.scheduleReconnect('ctor-failed')\n return\n }\n\n this.ws = ws\n this.bindSocket(ws)\n }\n\n private bindSocket(ws: WsInstance): void {\n ws.on('open', () => this.handleOpen())\n ws.on('message', (data, isBinary) => this.handleMessage(data, isBinary))\n ws.on('pong', () => this.handlePong())\n ws.on('close', (code, reason) => this.handleClose(code, reason.toString()))\n ws.on('error', (err) => {\n this.emitError(\n new AgentChatChannelError(\n classifyNetworkError(err),\n 'ws transport error',\n { cause: err },\n ),\n )\n // Don't transition here — `close` always follows `error`. Let\n // handleClose drive the state transition.\n })\n }\n\n private handleOpen(): void {\n if (!this.ws) return\n const now = this.now()\n this.applyEvent({ type: 'SOCKET_OPEN', now })\n\n // Send HELLO. This is the sole authentication path — the server will\n // reject any non-hello frame before `hello.ok` and close 1008.\n try {\n this.ws.send(\n JSON.stringify({ type: 'hello', api_key: this.config.apiKey }),\n )\n } catch (err) {\n this.emitError(\n new AgentChatChannelError(\n 'retry-transient',\n 'hello send failed',\n { cause: err },\n ),\n )\n this.closeSocket(1011, 'hello send failed')\n return\n }\n\n // Bound the handshake. Server has a 5s HELLO_TIMEOUT; we stay under.\n this.helloAckTimer = this._setTimeout(() => {\n this.helloAckTimer = null\n this.logger.warn({ timeoutMs: HELLO_ACK_TIMEOUT_MS }, 'hello ack timeout')\n this.emitError(\n new AgentChatChannelError('retry-transient', 'hello ack timeout'),\n )\n this.closeSocket(1008, 'hello ack timeout')\n }, HELLO_ACK_TIMEOUT_MS)\n }\n\n private handleMessage(data: RawData, isBinary: boolean): void {\n if (isBinary) {\n this.logger.warn({}, 'received binary frame — dropping (text-only protocol)')\n return\n }\n\n const received = this.now()\n\n // `RawData` can be Buffer | ArrayBuffer | Buffer[]. Normalize to string.\n const text =\n typeof data === 'string'\n ? data\n : Array.isArray(data)\n ? Buffer.concat(data).toString('utf8')\n : Buffer.isBuffer(data)\n ? data.toString('utf8')\n : Buffer.from(data as ArrayBuffer).toString('utf8')\n\n if (text.length > MAX_FRAME_BYTES) {\n this.logger.warn({ bytes: text.length }, 'oversized frame — dropping')\n return\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch (err) {\n this.emitError(\n new AgentChatChannelError(\n 'validation',\n 'malformed json frame',\n { cause: err },\n ),\n )\n return\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n this.emitError(\n new AgentChatChannelError('validation', 'frame not an object'),\n )\n return\n }\n\n const obj = parsed as Record<string, unknown>\n const type = typeof obj.type === 'string' ? obj.type : null\n if (!type) {\n this.emitError(\n new AgentChatChannelError('validation', 'frame missing type'),\n )\n return\n }\n\n // Intercept the handshake ack. Never surfaces to subscribers — the\n // normalizer (P3) only sees app-level server events.\n if (this.state.kind === 'AUTHENTICATING') {\n if (type === 'hello.ok') {\n this.handleHelloOk(received)\n return\n }\n if (type === 'hello.error' || type === 'auth.rejected' || type === 'error') {\n const reason = this.extractReason(obj) ?? 'auth rejected'\n this.handleAuthRejected(reason)\n return\n }\n // Frames that arrive mid-handshake before hello.ok are protocol\n // violations — close and reconnect.\n this.logger.warn({ type }, 'frame arrived before hello.ok — ignoring')\n return\n }\n\n // Once authenticated, rate_limit.warning is a soft advisory that the\n // upstream outbound adapter should respect. Emit it as an inbound\n // frame; metrics bookkeep here.\n const payload = this.extractPayload(obj)\n\n this.emit('inboundFrame', {\n type,\n payload,\n receivedAt: received,\n raw: parsed,\n })\n }\n\n private extractReason(obj: Record<string, unknown>): string | undefined {\n const payload = obj.payload\n if (payload && typeof payload === 'object') {\n const msg = (payload as Record<string, unknown>).message\n if (typeof msg === 'string') return msg\n const reason = (payload as Record<string, unknown>).reason\n if (typeof reason === 'string') return reason\n }\n const top = obj.message ?? obj.reason\n return typeof top === 'string' ? top : undefined\n }\n\n private extractPayload(obj: Record<string, unknown>): Record<string, unknown> {\n const payload = obj.payload\n return payload && typeof payload === 'object' && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {}\n }\n\n private handleHelloOk(now: UnixMillis): void {\n if (this.helloAckTimer) {\n this._clearTimeout(this.helloAckTimer)\n this.helloAckTimer = null\n }\n this.applyEvent({ type: 'HELLO_OK', now })\n this.attempt = 0\n this.startHeartbeat()\n this.emit('authenticated', now)\n }\n\n private handleAuthRejected(reason: string): void {\n if (this.helloAckTimer) {\n this._clearTimeout(this.helloAckTimer)\n this.helloAckTimer = null\n }\n this.logger.error({ reason }, 'auth rejected — moving to AUTH_FAIL')\n this.applyEvent({ type: 'AUTH_REJECTED', reason })\n this.emitError(\n new AgentChatChannelError('terminal-auth', `auth rejected: ${reason}`),\n )\n this.closeSocket(1008, 'auth rejected')\n }\n\n private handleClose(code: number, reason: string): void {\n const now = this.now()\n const wasAuthenticating = this.state.kind === 'AUTHENTICATING'\n const wasDraining = this.state.kind === 'DRAINING'\n const authClass = AUTH_CLOSE_CODES.has(code)\n\n this.stopHeartbeat()\n if (this.helloAckTimer) {\n this._clearTimeout(this.helloAckTimer)\n this.helloAckTimer = null\n }\n this.ws = null\n\n if (authClass && wasAuthenticating) {\n this.applyEvent({ type: 'AUTH_REJECTED', reason: `close ${code}: ${reason}` })\n this.emitError(\n new AgentChatChannelError(\n 'terminal-auth',\n `socket closed with auth code ${code}: ${reason}`,\n ),\n )\n this.emit('closed')\n return\n }\n\n this.applyEvent({ type: 'SOCKET_CLOSED', code, reason })\n\n if (wasDraining || this.state.kind === 'CLOSED') {\n this.emit('closed')\n return\n }\n\n this.logger.info(\n { code, reason, attempt: this.attempt },\n 'socket closed — scheduling reconnect',\n )\n this.scheduleReconnect(`close-${code}`)\n }\n\n private closeSocket(code: number, reason: string): void {\n if (!this.ws) return\n try {\n this.ws.close(code, reason)\n } catch {\n // Already closed or in an invalid state — `close` will still fire.\n }\n }\n\n // ─── Internals: heartbeat ────────────────────────────────────────────\n\n private startHeartbeat(): void {\n this.stopHeartbeat()\n const intervalMs = this.config.ping.intervalMs\n this.pingTimer = this._setInterval(() => this.sendPing(), intervalMs)\n }\n\n private stopHeartbeat(): void {\n if (this.pingTimer) {\n this._clearInterval(this.pingTimer)\n this.pingTimer = null\n }\n if (this.pongTimer) {\n this._clearTimeout(this.pongTimer)\n this.pongTimer = null\n }\n }\n\n private sendPing(): void {\n if (!this.ws || this.ws.readyState !== NodeWebSocket.OPEN) return\n try {\n this.ws.ping()\n } catch (err) {\n this.emitError(\n new AgentChatChannelError(\n 'retry-transient',\n 'ws ping failed',\n { cause: err },\n ),\n )\n return\n }\n const timeoutMs = this.config.ping.timeoutMs\n if (this.pongTimer) this._clearTimeout(this.pongTimer)\n this.pongTimer = this._setTimeout(() => {\n this.pongTimer = null\n const now = this.now()\n this.logger.warn({ timeoutMs }, 'ping timeout — declaring degraded')\n this.applyEvent({ type: 'PING_TIMEOUT', now })\n // The server has gone silent. Force-reconnect — the state machine\n // moves READY → DEGRADED on PING_TIMEOUT, but we need to actually\n // tear down the socket so `close` re-drives reconnect.\n this.closeSocket(1011, 'ping timeout')\n }, timeoutMs)\n }\n\n private handlePong(): void {\n if (this.pongTimer) {\n this._clearTimeout(this.pongTimer)\n this.pongTimer = null\n }\n // If we were in DEGRADED due to backpressure, pong alone isn't the\n // recovery signal — backpressure clears when the outbound queue drains.\n // But if we were in DEGRADED due to ping-timeout (shouldn't happen —\n // we close immediately on that path), a pong would recover us.\n if (this.state.kind === 'DEGRADED' && this.state.reason === 'ping-timeout') {\n this.applyEvent({ type: 'RECOVERED', now: this.now() })\n }\n }\n\n // ─── Internals: reconnect ────────────────────────────────────────────\n\n private scheduleReconnect(reason: string): void {\n if (this.state.kind === 'CLOSED' || this.state.kind === 'AUTH_FAIL') return\n if (this.reconnectTimer) return\n\n const nextAttempt = this.attempt + 1\n\n if (nextAttempt > RECONNECT_HARD_CAP_ATTEMPTS) {\n const msg = `reconnect hard cap (${RECONNECT_HARD_CAP_ATTEMPTS}) reached`\n this.logger.error({ attempt: nextAttempt }, msg)\n this.applyEvent({ type: 'AUTH_REJECTED', reason: msg })\n this.emitError(\n new AgentChatChannelError('terminal-auth', msg),\n )\n return\n }\n\n const delay = this.computeReconnectDelay(nextAttempt)\n this.metrics.incReconnect({ reason })\n this.logger.info(\n { attempt: nextAttempt, delayMs: delay, reason },\n 'scheduling reconnect',\n )\n\n this.reconnectTimer = this._setTimeout(() => {\n this.reconnectTimer = null\n this.openSocket(nextAttempt)\n }, delay)\n }\n\n private computeReconnectDelay(attempt: number): number {\n const { initialBackoffMs, maxBackoffMs, jitterRatio } = this.config.reconnect\n // `attempt` is the total connection count (1 = initial connect, 2+ =\n // reconnects). Backoff scales with the *reconnect* count, so the first\n // reconnect uses `initialBackoffMs * 2^0 = initialBackoffMs`.\n const reconnectCount = Math.max(1, attempt - 1)\n const exp = initialBackoffMs * Math.pow(2, Math.min(reconnectCount - 1, 20))\n const capped = Math.min(exp, maxBackoffMs)\n // Symmetric ±jitterRatio. Thundering-herd-safe: a fleet that all drops\n // at the same instant re-enters the connect queue spread across\n // capped * [1-jitterRatio, 1+jitterRatio].\n const jitter = 1 - jitterRatio + this.random() * 2 * jitterRatio\n return Math.max(0, Math.floor(capped * jitter))\n }\n\n // ─── Internals: drain ────────────────────────────────────────────────\n\n private scheduleDrainDeadline(deadline: UnixMillis): void {\n if (this.drainTimer) this._clearTimeout(this.drainTimer)\n const now = this.now()\n const delay = Math.max(0, deadline - now)\n this.drainTimer = this._setTimeout(() => {\n this.drainTimer = null\n if (this.state.kind === 'DRAINING') {\n this.logger.warn({ deadline }, 'drain deadline exceeded — force-closing')\n this.applyEvent({ type: 'DRAIN_COMPLETED' })\n this.closeSocket(1000, 'drain deadline')\n this.emit('closed')\n }\n }, delay)\n }\n\n /**\n * Called by upper layers when their pending work has fully drained, to\n * let the WS client transition CLOSED earlier than the deadline.\n */\n drainCompleted(): void {\n if (this.state.kind !== 'DRAINING') return\n if (this.drainTimer) {\n this._clearTimeout(this.drainTimer)\n this.drainTimer = null\n }\n this.applyEvent({ type: 'DRAIN_COMPLETED' })\n this.closeSocket(1000, 'drain completed')\n this.emit('closed')\n }\n\n // ─── Internals: state machine + emit ─────────────────────────────────\n\n private applyEvent(event: ConnectionEvent): void {\n const prev = this.state\n const next = transition(prev, event)\n if (next === prev) {\n // No transition — log at debug so we see invalid events without\n // crashing. Useful for catching bugs in upper layers.\n this.logger.debug(\n { from: prev.kind, event: event.type },\n 'transition.invalid',\n )\n return\n }\n this.state = next\n this.metrics.setConnectionState(next.kind)\n this.logger.info(\n { from: prev.kind, to: next.kind, event: event.type },\n 'state transition',\n )\n this.emit('stateChanged', next, prev)\n }\n\n private emit<E extends keyof WsClientEvents>(\n event: E,\n ...args: Parameters<WsClientEvents[E]>\n ): void {\n for (const listener of this.listeners[event]) {\n try {\n ;(listener as (...a: unknown[]) => void)(...(args as unknown[]))\n } catch (err) {\n this.logger.error(\n { event, err: err instanceof Error ? err.message : String(err) },\n 'listener threw — continuing',\n )\n }\n }\n }\n\n private emitError(error: AgentChatChannelError): void {\n this.metrics.incOutboundFailed({ errorClass: error.class_ })\n this.logger.warn(\n { class: error.class_, message: error.message, statusCode: error.statusCode },\n 'channel error',\n )\n this.emit('error', error)\n }\n}\n\n/**\n * Classify a low-level error with the WS client's conventions — exported\n * for integration tests that want to assert on error class directly.\n */\nexport function classifyWsError(err: unknown): ErrorClass {\n return classifyNetworkError(err)\n}\n","/**\n * Inbound normalizer — AgentChat server events → channel-neutral shape.\n *\n * Responsibilities:\n * - Validate every server frame against a Zod schema. Unknown shapes\n * surface as `validation` errors (the transport catches them and drops\n * the frame without killing the connection).\n * - Translate AgentChat-native payloads into a stable, plugin-internal\n * `NormalizedInbound` shape. The OpenClaw channel binding (P7 runtime\n * wiring) adapts this further to the gateway's `ChannelInboundMessage`\n * contract.\n * - Classify conversation kind (direct vs group) from the `dir_*`/`grp_*`\n * prefix convention so consumers don't need to grep prefixes themselves.\n *\n * Why this module exists (rather than passing raw frames up):\n * - The WS client is pure transport; it shouldn't know what\n * `message.new` means semantically.\n * - OpenClaw's ChannelInboundMessage has a specific shape (thread id,\n * content parts, attachments, sender identity). Converting from\n * AgentChat's wire format in one place is the only sane way to keep\n * the mapping auditable.\n * - Per-event Zod schemas make drift between plugin and server obvious\n * and loud — a server field rename surfaces as a validation error\n * caught in CI long before it goes to prod.\n */\n\nimport { z } from 'zod'\n\nimport type { InboundFrame } from './ws-client.js'\nimport { AgentChatChannelError } from './errors.js'\nimport type { UnixMillis } from './types.js'\n\n// ─── Conversation-id prefix convention ─────────────────────────────────\n//\n// Mirrors `apps/api-server/src/services/{message,group}.service.ts`:\n// - DM conversations are minted via `generateId('conv')` → `conv_*`\n// - Groups are minted via `generateId('grp')` → `grp_*`\n//\n// We also accept the legacy `dir_` prefix for DMs — pre-production test\n// fixtures and docs sometimes used it, and no harm in tolerating both.\n\nconst DIRECT_PREFIXES = ['conv_', 'dir_'] as const\nconst GROUP_PREFIX = 'grp_'\n\nexport type ConversationKind = 'direct' | 'group'\n\nexport function classifyConversationId(id: string): ConversationKind | null {\n for (const p of DIRECT_PREFIXES) {\n if (id.startsWith(p)) return 'direct'\n }\n if (id.startsWith(GROUP_PREFIX)) return 'group'\n return null\n}\n\n// ─── Zod schemas for server events ─────────────────────────────────────\n//\n// Every field we actually read is `required`; anything else is tolerated\n// via `.passthrough()` so a server-side addition doesn't break the plugin.\n// Status enum is mirrored from `agentchat/packages/sdk-typescript/src/types/message.ts`.\n\nconst messageContentSchema = z\n .object({\n text: z.string().optional(),\n data: z.record(z.string(), z.unknown()).optional(),\n attachment_id: z.string().optional(),\n })\n .passthrough()\n\nconst messageSchema = z\n .object({\n id: z.string(),\n conversation_id: z.string(),\n sender: z.string(),\n client_msg_id: z.string(),\n seq: z.number().int().nonnegative(),\n type: z.enum(['text', 'structured', 'file', 'system']),\n content: messageContentSchema,\n metadata: z.record(z.string(), z.unknown()).default({}),\n // Per-recipient delivery state lives in `message_deliveries` since\n // migration 011 — the `messages` row no longer carries `status`,\n // `delivered_at`, or `read_at`. Fresh-send envelopes over WS omit\n // them entirely; the drain path (syncUndelivered) still attaches\n // `status: 'stored'` for backlogged frames. Accept both shapes.\n status: z.enum(['stored', 'delivered', 'read']).optional(),\n created_at: z.string(),\n delivered_at: z.string().nullable().optional(),\n read_at: z.string().nullable().optional(),\n })\n .passthrough()\n\nconst messageNewSchema = messageSchema\n\nconst messageReadSchema = z\n .object({\n conversation_id: z.string(),\n // Per-agent read cursor. Everything with seq <= through_seq is read.\n through_seq: z.number().int().nonnegative(),\n // Handle of the reader (who moved their cursor).\n reader: z.string(),\n at: z.string().optional(),\n })\n .passthrough()\n\nconst typingSchema = z\n .object({\n conversation_id: z.string(),\n sender: z.string(),\n })\n .passthrough()\n\nconst presenceUpdateSchema = z\n .object({\n handle: z.string(),\n status: z.enum(['online', 'away', 'offline']),\n last_active_at: z.string().optional(),\n custom_status: z.string().nullable().optional(),\n })\n .passthrough()\n\nconst rateLimitWarningSchema = z\n .object({\n endpoint: z.string().optional(),\n limit: z.number().optional(),\n remaining: z.number().optional(),\n reset_at: z.string().optional(),\n message: z.string().optional(),\n })\n .passthrough()\n\nconst groupInviteReceivedSchema = z\n .object({\n id: z.string(),\n group_id: z.string(),\n group_name: z.string(),\n group_description: z.string().nullable().optional(),\n group_avatar_url: z.string().nullable().optional(),\n group_member_count: z.number().int().nonnegative(),\n inviter_handle: z.string(),\n created_at: z.string(),\n })\n .passthrough()\n\nconst groupDeletedSchema = z\n .object({\n group_id: z.string(),\n deleted_by_handle: z.string(),\n deleted_at: z.string(),\n })\n .passthrough()\n\n// ─── Normalized shapes ─────────────────────────────────────────────────\n\nexport interface NormalizedMessage {\n readonly kind: 'message'\n readonly conversationKind: ConversationKind\n readonly conversationId: string\n /** Sender handle. */\n readonly sender: string\n readonly messageId: string\n readonly clientMsgId: string\n readonly seq: number\n readonly messageType: 'text' | 'structured' | 'file' | 'system'\n readonly content: {\n readonly text?: string\n readonly data?: Record<string, unknown>\n readonly attachmentId?: string\n }\n readonly metadata: Record<string, unknown>\n /**\n * Per-recipient delivery state. Since migration 011, per-recipient state\n * lives on `message_deliveries`, not the message row — so fresh-send\n * `message.new` envelopes have no status field. Drain-path (sync /\n * undelivered) envelopes still include `'stored'`. `null` means the\n * server didn't attach one; callers that need the authoritative state\n * should query `GET /v1/messages/sync` or `/delivery-receipts`.\n */\n readonly status: 'stored' | 'delivered' | 'read' | null\n readonly createdAt: string\n readonly deliveredAt: string | null\n readonly readAt: string | null\n readonly receivedAt: UnixMillis\n}\n\nexport interface NormalizedReadReceipt {\n readonly kind: 'read-receipt'\n readonly conversationKind: ConversationKind\n readonly conversationId: string\n readonly reader: string\n readonly throughSeq: number\n readonly at: string | null\n readonly receivedAt: UnixMillis\n}\n\nexport interface NormalizedTyping {\n readonly kind: 'typing'\n readonly action: 'start' | 'stop'\n readonly conversationKind: ConversationKind\n readonly conversationId: string\n readonly sender: string\n readonly receivedAt: UnixMillis\n}\n\nexport interface NormalizedPresence {\n readonly kind: 'presence'\n readonly handle: string\n readonly status: 'online' | 'away' | 'offline'\n readonly lastActiveAt: string | null\n readonly customStatus: string | null\n readonly receivedAt: UnixMillis\n}\n\nexport interface NormalizedRateLimitWarning {\n readonly kind: 'rate-limit-warning'\n readonly endpoint: string | null\n readonly limit: number | null\n readonly remaining: number | null\n readonly resetAt: string | null\n readonly message: string | null\n readonly receivedAt: UnixMillis\n}\n\nexport interface NormalizedGroupInvite {\n readonly kind: 'group-invite'\n readonly inviteId: string\n readonly groupId: string\n readonly groupName: string\n readonly groupDescription: string | null\n readonly groupAvatarUrl: string | null\n readonly groupMemberCount: number\n readonly inviterHandle: string\n readonly createdAt: string\n readonly receivedAt: UnixMillis\n}\n\nexport interface NormalizedGroupDeleted {\n readonly kind: 'group-deleted'\n readonly groupId: string\n readonly deletedByHandle: string\n readonly deletedAt: string\n readonly receivedAt: UnixMillis\n}\n\n/**\n * Unknown server event — arrived over the wire but isn't in our explicit\n * handler set. We still surface it (the gateway may want to log it or\n * forward it), but with a `type` field so downstream can discriminate.\n */\nexport interface NormalizedUnknown {\n readonly kind: 'unknown'\n readonly type: string\n readonly payload: Record<string, unknown>\n readonly receivedAt: UnixMillis\n}\n\nexport type NormalizedInbound =\n | NormalizedMessage\n | NormalizedReadReceipt\n | NormalizedTyping\n | NormalizedPresence\n | NormalizedRateLimitWarning\n | NormalizedGroupInvite\n | NormalizedGroupDeleted\n | NormalizedUnknown\n\n// ─── Normalize entrypoint ──────────────────────────────────────────────\n\n/**\n * Normalize a raw inbound frame into a channel-neutral shape.\n *\n * Throws `AgentChatChannelError` with class `validation` if the payload\n * fails its schema. Callers (the runtime) should log + drop the frame\n * rather than propagate the throw — the connection stays healthy.\n */\nexport function normalizeInbound(frame: InboundFrame): NormalizedInbound {\n switch (frame.type) {\n case 'message.new':\n return normalizeMessageNew(frame)\n case 'message.read':\n return normalizeMessageRead(frame)\n case 'typing.start':\n return normalizeTyping(frame, 'start')\n case 'typing.stop':\n return normalizeTyping(frame, 'stop')\n case 'presence.update':\n return normalizePresence(frame)\n case 'rate_limit.warning':\n return normalizeRateLimitWarning(frame)\n case 'group.invite.received':\n return normalizeGroupInvite(frame)\n case 'group.deleted':\n return normalizeGroupDeleted(frame)\n default:\n return {\n kind: 'unknown',\n type: frame.type,\n payload: frame.payload,\n receivedAt: frame.receivedAt,\n }\n }\n}\n\nfunction validate<T>(schema: z.ZodType<T>, payload: unknown, eventType: string): T {\n const parsed = schema.safeParse(payload)\n if (!parsed.success) {\n throw new AgentChatChannelError(\n 'validation',\n `inbound ${eventType} schema invalid: ${parsed.error.message}`,\n { cause: parsed.error },\n )\n }\n return parsed.data\n}\n\nfunction requireConvKind(conversationId: string, eventType: string): ConversationKind {\n const kind = classifyConversationId(conversationId)\n if (!kind) {\n throw new AgentChatChannelError(\n 'validation',\n `inbound ${eventType} has unknown conversation id prefix: ${conversationId}`,\n )\n }\n return kind\n}\n\nfunction normalizeMessageNew(frame: InboundFrame): NormalizedMessage {\n const msg = validate(messageNewSchema, frame.payload, 'message.new')\n const conversationKind = requireConvKind(msg.conversation_id, 'message.new')\n return {\n kind: 'message',\n conversationKind,\n conversationId: msg.conversation_id,\n sender: msg.sender,\n messageId: msg.id,\n clientMsgId: msg.client_msg_id,\n seq: msg.seq,\n messageType: msg.type,\n content: {\n text: msg.content.text,\n data: msg.content.data,\n attachmentId: msg.content.attachment_id,\n },\n metadata: msg.metadata,\n status: msg.status ?? null,\n createdAt: msg.created_at,\n deliveredAt: msg.delivered_at ?? null,\n readAt: msg.read_at ?? null,\n receivedAt: frame.receivedAt,\n }\n}\n\nfunction normalizeMessageRead(frame: InboundFrame): NormalizedReadReceipt {\n const body = validate(messageReadSchema, frame.payload, 'message.read')\n const conversationKind = requireConvKind(body.conversation_id, 'message.read')\n return {\n kind: 'read-receipt',\n conversationKind,\n conversationId: body.conversation_id,\n reader: body.reader,\n throughSeq: body.through_seq,\n at: body.at ?? null,\n receivedAt: frame.receivedAt,\n }\n}\n\nfunction normalizeTyping(frame: InboundFrame, action: 'start' | 'stop'): NormalizedTyping {\n const body = validate(typingSchema, frame.payload, `typing.${action}`)\n const conversationKind = requireConvKind(body.conversation_id, `typing.${action}`)\n return {\n kind: 'typing',\n action,\n conversationKind,\n conversationId: body.conversation_id,\n sender: body.sender,\n receivedAt: frame.receivedAt,\n }\n}\n\nfunction normalizePresence(frame: InboundFrame): NormalizedPresence {\n const body = validate(presenceUpdateSchema, frame.payload, 'presence.update')\n return {\n kind: 'presence',\n handle: body.handle,\n status: body.status,\n lastActiveAt: body.last_active_at ?? null,\n customStatus: body.custom_status ?? null,\n receivedAt: frame.receivedAt,\n }\n}\n\nfunction normalizeRateLimitWarning(frame: InboundFrame): NormalizedRateLimitWarning {\n const body = validate(rateLimitWarningSchema, frame.payload, 'rate_limit.warning')\n return {\n kind: 'rate-limit-warning',\n endpoint: body.endpoint ?? null,\n limit: body.limit ?? null,\n remaining: body.remaining ?? null,\n resetAt: body.reset_at ?? null,\n message: body.message ?? null,\n receivedAt: frame.receivedAt,\n }\n}\n\nfunction normalizeGroupInvite(frame: InboundFrame): NormalizedGroupInvite {\n const body = validate(groupInviteReceivedSchema, frame.payload, 'group.invite.received')\n return {\n kind: 'group-invite',\n inviteId: body.id,\n groupId: body.group_id,\n groupName: body.group_name,\n groupDescription: body.group_description ?? null,\n groupAvatarUrl: body.group_avatar_url ?? null,\n groupMemberCount: body.group_member_count,\n inviterHandle: body.inviter_handle,\n createdAt: body.created_at,\n receivedAt: frame.receivedAt,\n }\n}\n\nfunction normalizeGroupDeleted(frame: InboundFrame): NormalizedGroupDeleted {\n const body = validate(groupDeletedSchema, frame.payload, 'group.deleted')\n return {\n kind: 'group-deleted',\n groupId: body.group_id,\n deletedByHandle: body.deleted_by_handle,\n deletedAt: body.deleted_at,\n receivedAt: frame.receivedAt,\n }\n}\n","/**\n * Retry + circuit-breaker primitives for outbound AgentChat API calls.\n *\n * Why not just use the SDK's retry policy?\n * - The SDK's retry is a \"best-effort per-request\" policy: a 429 triggers\n * a bounded delay, a 5xx triggers exponential backoff, done. That works\n * for a CLI tool or one-shot send.\n * - A channel plugin runs continuously and must degrade gracefully under\n * sustained failure: if the API is down for 60 seconds, we should stop\n * hammering it, open a circuit, and let a background probe close it\n * back when it recovers. Without this, a dead API becomes a retry\n * storm that multiplies every outbound send by the full retry budget.\n *\n * This module provides two orthogonal pieces:\n * - `retryWithPolicy(fn, policy, classify)` — a typed exponential-backoff\n * retry wrapper that respects `AgentChatChannelError.retryAfterMs` from\n * 429 responses and stops retrying immediately on terminal classes.\n * - `CircuitBreaker` — classic half-open pattern. After `failureThreshold`\n * consecutive transient failures inside `windowMs`, the circuit opens\n * for `cooldownMs`. Subsequent calls fast-fail as `circuit-open`. After\n * cooldown, one probe request is allowed; success closes, failure\n * re-opens for another cooldown.\n *\n * Both are pure; they take a clock + random source so tests drive them\n * deterministically without fake timers.\n */\n\nimport { AgentChatChannelError, type ErrorClass } from './errors.js'\nimport type { UnixMillis } from './types.js'\n\n// ─── Retry policy ──────────────────────────────────────────────────────\n\nexport interface RetryPolicy {\n readonly maxAttempts: number\n readonly initialBackoffMs: number\n readonly maxBackoffMs: number\n readonly jitterRatio: number\n /** Clock source. Default: Date.now. */\n readonly now?: () => UnixMillis\n /** Random source for jitter. Default: Math.random. */\n readonly random?: () => number\n /** Sleep implementation. Default: setTimeout-based. */\n readonly sleep?: (ms: number) => Promise<void>\n}\n\nexport interface RetryOutcome<T> {\n readonly result: T\n readonly attempts: number\n readonly totalDelayMs: number\n}\n\n/** Default sleep — replaceable by tests via the policy.sleep override. */\nfunction defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Execute `fn` with retry. Returns the successful result + attempt count.\n * Throws the last error if all attempts exhaust.\n *\n * Retry rules:\n * - Error classes `terminal-auth`, `terminal-user`, `validation` throw\n * immediately without retry.\n * - `idempotent-replay` is treated as success by the caller, not this\n * layer — caller converts it before throwing.\n * - `retry-rate` uses the server-provided `retryAfterMs` when present,\n * else the jittered exponential backoff.\n * - `retry-transient` always uses jittered exponential.\n */\nexport async function retryWithPolicy<T>(\n fn: (attempt: number) => Promise<T>,\n policy: RetryPolicy,\n): Promise<RetryOutcome<T>> {\n const random = policy.random ?? Math.random\n const sleep = policy.sleep ?? defaultSleep\n let totalDelayMs = 0\n let lastErr: unknown\n\n for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {\n try {\n const result = await fn(attempt)\n return { result, attempts: attempt, totalDelayMs }\n } catch (err) {\n lastErr = err\n if (!(err instanceof AgentChatChannelError)) {\n throw err\n }\n if (isTerminalClass(err.class_)) {\n throw err\n }\n if (attempt >= policy.maxAttempts) {\n throw err\n }\n const delay = backoffDelay({\n attempt,\n errorClass: err.class_,\n retryAfterMs: err.retryAfterMs,\n policy,\n random,\n })\n totalDelayMs += delay\n await sleep(delay)\n }\n }\n throw lastErr\n}\n\nfunction isTerminalClass(class_: ErrorClass): boolean {\n // `idempotent-replay` is surfaced as a \"do-not-retry\" signal: the server\n // has already persisted a message with this client_msg_id (either from\n // this or a concurrent caller). Retrying won't help — the caller needs\n // to treat the original message as the canonical one.\n return (\n class_ === 'terminal-auth' ||\n class_ === 'terminal-user' ||\n class_ === 'validation' ||\n class_ === 'idempotent-replay'\n )\n}\n\ninterface BackoffInput {\n attempt: number\n errorClass: ErrorClass\n retryAfterMs: number | undefined\n policy: RetryPolicy\n random: () => number\n}\n\nfunction backoffDelay({ attempt, errorClass, retryAfterMs, policy, random }: BackoffInput): number {\n // 429 with server-provided hint: obey it exactly (plus a small jitter so\n // a synchronized fleet doesn't all wake at the exact same instant).\n if (errorClass === 'retry-rate' && typeof retryAfterMs === 'number') {\n const jitter = 1 + random() * policy.jitterRatio\n return Math.min(policy.maxBackoffMs, Math.floor(retryAfterMs * jitter))\n }\n const exp = policy.initialBackoffMs * Math.pow(2, Math.min(attempt - 1, 20))\n const capped = Math.min(exp, policy.maxBackoffMs)\n const jitter = 1 - policy.jitterRatio + random() * 2 * policy.jitterRatio\n return Math.max(0, Math.floor(capped * jitter))\n}\n\n// ─── Circuit breaker ───────────────────────────────────────────────────\n\nexport type CircuitState = 'closed' | 'open' | 'half-open'\n\nexport interface CircuitBreakerOptions {\n readonly failureThreshold: number\n /** Open the circuit when `failureThreshold` failures occur inside this window. */\n readonly windowMs: number\n readonly cooldownMs: number\n readonly now?: () => UnixMillis\n}\n\nexport interface CircuitSnapshot {\n readonly state: CircuitState\n readonly recentFailures: number\n readonly openedAt: UnixMillis | null\n readonly halfOpenAt: UnixMillis | null\n}\n\n/**\n * Single-process circuit breaker. Not distributed — each channel instance\n * has its own view. For a multi-instance deployment, the open-circuit\n * signal is observable via metrics (each instance emits `circuit_state`)\n * but each instance must independently detect the outage.\n */\nexport class CircuitBreaker {\n private readonly opts: CircuitBreakerOptions\n private readonly now: () => UnixMillis\n private state: CircuitState = 'closed'\n private failureTimestamps: UnixMillis[] = []\n private openedAt: UnixMillis | null = null\n private halfOpenAt: UnixMillis | null = null\n\n constructor(opts: CircuitBreakerOptions) {\n this.opts = opts\n this.now = opts.now ?? Date.now\n }\n\n snapshot(): CircuitSnapshot {\n return {\n state: this.state,\n recentFailures: this.failureTimestamps.length,\n openedAt: this.openedAt,\n halfOpenAt: this.halfOpenAt,\n }\n }\n\n /**\n * Check state at call time.\n * - `closed` / `half-open` → returns `{ allow: true }`. Caller must\n * invoke `onSuccess()` / `onFailure()` after the attempt.\n * - `open` → returns `{ allow: false, reason }` so the caller can\n * fast-fail without making the network call. If the cooldown has\n * elapsed, transitions to `half-open` first and allows one probe.\n */\n precheck(): { allow: true } | { allow: false; reason: string } {\n if (this.state === 'open') {\n const now = this.now()\n const elapsed = now - (this.openedAt ?? now)\n if (elapsed >= this.opts.cooldownMs) {\n this.state = 'half-open'\n this.halfOpenAt = now\n return { allow: true }\n }\n return { allow: false, reason: 'circuit open — API appears unhealthy' }\n }\n return { allow: true }\n }\n\n onSuccess(): void {\n if (this.state === 'half-open') {\n this.state = 'closed'\n this.openedAt = null\n this.halfOpenAt = null\n }\n this.failureTimestamps = []\n }\n\n /**\n * Record a failure. Only transient classes count toward the breaker —\n * terminal-auth/terminal-user/validation failures are caller bugs or\n * server contract violations, not \"API down\" signals.\n */\n onFailure(errorClass: ErrorClass): void {\n if (isTerminalClass(errorClass)) return\n\n const now = this.now()\n\n if (this.state === 'half-open') {\n // Probe failed — re-open immediately.\n this.state = 'open'\n this.openedAt = now\n this.halfOpenAt = null\n return\n }\n\n this.failureTimestamps.push(now)\n this.trimOldFailures(now)\n\n if (this.failureTimestamps.length >= this.opts.failureThreshold) {\n this.state = 'open'\n this.openedAt = now\n }\n }\n\n private trimOldFailures(now: UnixMillis): void {\n const cutoff = now - this.opts.windowMs\n let firstFresh = 0\n while (\n firstFresh < this.failureTimestamps.length &&\n this.failureTimestamps[firstFresh]! < cutoff\n ) {\n firstFresh++\n }\n if (firstFresh > 0) this.failureTimestamps.splice(0, firstFresh)\n }\n}\n","/**\n * Single source of truth for the package version string.\n *\n * Kept as a hand-edited constant (not an `import ... from '../package.json'`)\n * so that tsup can bundle ESM/CJS without requiring `resolveJsonModule` +\n * runtime filesystem access from inside the published dist. A unit test\n * (`tests/version.test.ts`) pins this against `package.json` so bumping one\n * without the other fails CI.\n */\nexport const PACKAGE_VERSION = '0.3.0'\n","/**\n * Outbound adapter — OpenClaw send → AgentChat `POST /v1/messages`.\n *\n * Pipeline (left to right, each step is independently observable):\n * 1. Caller invokes `sendMessage(input)` with a channel-neutral shape.\n * 2. We derive a stable `client_msg_id` (idempotency key). If the caller\n * supplied one, we respect it; otherwise we mint a UUID.\n * 3. Circuit-breaker precheck. Open circuit → fast-fail `retry-transient`.\n * 4. `retryWithPolicy(...)` wraps the actual HTTP call.\n * 5. On success, metrics/logs + return the `Message` the server minted.\n * 6. On 409 (idempotent-replay), treat as success with the replay body.\n * 7. On 429, honor `Retry-After` (seconds or HTTP-date) via the retry\n * policy. Surface as `retry-rate`.\n * 8. On 5xx / network flap, retry with jittered exponential backoff.\n * 9. On 4xx other than 429/409, classify as `terminal-user` → no retry.\n * 10. On 401/403 → `terminal-auth`. We signal upstream so the WS client\n * moves to AUTH_FAIL and the operator gets paged.\n *\n * Backpressure:\n * - An in-flight semaphore bounds concurrent sends to `outbound.maxInFlight`.\n * - Over-threshold sends are enqueued and drained as capacity frees up.\n * - Queue has its own hard cap (`10 * maxInFlight`); over-cap sends reject\n * immediately with `retry-transient` so the caller can shed load rather\n * than OOM.\n */\n\nimport type { Message } from './types/message.js'\n\nimport { AgentChatChannelError, classifyHttpStatus, classifyNetworkError, parseRetryAfter } from './errors.js'\nimport type { Logger } from './log.js'\nimport type { MetricsRecorder } from './metrics.js'\nimport { CircuitBreaker, retryWithPolicy, type CircuitBreakerOptions, type RetryPolicy } from './retry.js'\nimport type { AgentchatChannelConfig } from './config-schema.js'\nimport type { UnixMillis } from './types.js'\nimport { PACKAGE_VERSION } from './version.js'\n\n// ─── Types ─────────────────────────────────────────────────────────────\n\nexport type OutboundMessageInput =\n | OutboundDirectMessage\n | OutboundGroupMessage\n\nexport interface OutboundMessageBase {\n /**\n * Client-generated idempotency key. Optional — we mint one if absent.\n * Retries of the same logical send MUST reuse the same value or you'll\n * get duplicates.\n */\n readonly clientMsgId?: string\n readonly type?: 'text' | 'structured' | 'file'\n readonly content: {\n readonly text?: string\n readonly data?: Record<string, unknown>\n readonly attachmentId?: string\n }\n readonly metadata?: Record<string, unknown>\n /** Correlation id carried through logs and metrics. */\n readonly correlationId?: string\n}\n\nexport interface OutboundDirectMessage extends OutboundMessageBase {\n readonly kind: 'direct'\n /** Recipient handle (e.g. \"alice\"). */\n readonly to: string\n}\n\nexport interface OutboundGroupMessage extends OutboundMessageBase {\n readonly kind: 'group'\n /** `grp_*` conversation id. */\n readonly conversationId: string\n}\n\nexport interface OutboundBacklogWarning {\n readonly recipientHandle: string\n readonly undeliveredCount: number\n}\n\nexport interface SendResult {\n readonly message: Message\n readonly backlogWarning: OutboundBacklogWarning | null\n readonly idempotentReplay: boolean\n readonly attempts: number\n readonly latencyMs: number\n readonly requestId: string | null\n}\n\nexport interface OutboundAdapterOptions {\n readonly config: AgentchatChannelConfig\n readonly logger: Logger\n readonly metrics: MetricsRecorder\n readonly fetch?: typeof fetch\n readonly now?: () => UnixMillis\n readonly random?: () => number\n readonly sleep?: (ms: number) => Promise<void>\n readonly circuitBreaker?: CircuitBreakerOptions\n readonly retryPolicy?: Partial<RetryPolicy>\n /** Surface backlog warnings to upstream — optional observability hook. */\n readonly onBacklogWarning?: (warning: OutboundBacklogWarning) => void\n}\n\nconst DEFAULT_RETRY_POLICY: Omit<RetryPolicy, 'now' | 'random' | 'sleep'> = {\n maxAttempts: 4,\n initialBackoffMs: 250,\n maxBackoffMs: 10_000,\n jitterRatio: 0.3,\n}\n\nconst DEFAULT_CIRCUIT_OPTIONS: CircuitBreakerOptions = {\n failureThreshold: 10,\n windowMs: 60_000,\n cooldownMs: 30_000,\n}\n\n// ─── Adapter ───────────────────────────────────────────────────────────\n\nexport class OutboundAdapter {\n private readonly config: AgentchatChannelConfig\n private readonly logger: Logger\n private readonly metrics: MetricsRecorder\n private readonly fetchImpl: typeof fetch\n private readonly now: () => UnixMillis\n private readonly breaker: CircuitBreaker\n private readonly retryPolicy: RetryPolicy\n private readonly onBacklogWarning?: (warning: OutboundBacklogWarning) => void\n\n // Backpressure bookkeeping.\n private inFlight = 0\n private readonly queue: Array<() => void> = []\n private readonly queueHardCap: number\n\n constructor(opts: OutboundAdapterOptions) {\n this.config = opts.config\n this.logger = opts.logger.child({ component: 'outbound' })\n this.metrics = opts.metrics\n this.fetchImpl = opts.fetch ?? fetch\n this.now = opts.now ?? Date.now\n this.onBacklogWarning = opts.onBacklogWarning\n this.breaker = new CircuitBreaker(opts.circuitBreaker ?? DEFAULT_CIRCUIT_OPTIONS)\n this.retryPolicy = {\n ...DEFAULT_RETRY_POLICY,\n ...opts.retryPolicy,\n now: opts.now,\n random: opts.random,\n sleep: opts.sleep,\n }\n this.queueHardCap = Math.max(10, this.config.outbound.maxInFlight * 10)\n }\n\n /**\n * Send a message. Returns on success; throws `AgentChatChannelError` on\n * terminal or exhausted-retry failure. The returned `SendResult.message`\n * is the row the server minted (or echoed back on idempotent replay).\n */\n async sendMessage(input: OutboundMessageInput): Promise<SendResult> {\n const clientMsgId = input.clientMsgId ?? this.mintClientMsgId()\n const correlationId = input.correlationId ?? clientMsgId\n const log = this.logger.child({ clientMsgId, correlationId, kind: input.kind })\n\n const precheck = this.breaker.precheck()\n if (!precheck.allow) {\n this.metrics.incOutboundFailed({ errorClass: 'retry-transient' })\n throw new AgentChatChannelError('retry-transient', precheck.reason)\n }\n\n await this.acquireSlot()\n const startedAt = this.now()\n try {\n const outcome = await retryWithPolicy(\n (attempt) => this.sendOnce({ input, clientMsgId, attempt, log }),\n this.retryPolicy,\n )\n const endedAt = this.now()\n this.breaker.onSuccess()\n this.metrics.incOutboundSent({ kind: 'message' })\n this.metrics.observeSendLatency(endedAt - startedAt)\n return {\n ...outcome.result,\n attempts: outcome.attempts,\n latencyMs: endedAt - startedAt,\n }\n } catch (err) {\n if (err instanceof AgentChatChannelError) {\n this.breaker.onFailure(err.class_)\n this.metrics.incOutboundFailed({ errorClass: err.class_ })\n log.warn(\n { class: err.class_, status: err.statusCode, msg: err.message },\n 'send failed',\n )\n } else {\n this.metrics.incOutboundFailed({ errorClass: 'retry-transient' })\n log.error(\n { err: err instanceof Error ? err.message : String(err) },\n 'send failed — unexpected error',\n )\n }\n throw err\n } finally {\n this.releaseSlot()\n }\n }\n\n /** Current state for observability / health checks. */\n snapshot(): { inFlight: number; queued: number; circuit: ReturnType<CircuitBreaker['snapshot']> } {\n return {\n inFlight: this.inFlight,\n queued: this.queue.length,\n circuit: this.breaker.snapshot(),\n }\n }\n\n // ─── Internals ───────────────────────────────────────────────────────\n\n private async sendOnce(args: {\n input: OutboundMessageInput\n clientMsgId: string\n attempt: number\n log: Logger\n }): Promise<Omit<SendResult, 'attempts' | 'latencyMs'>> {\n const { input, clientMsgId, attempt, log } = args\n const body = this.buildBody(input, clientMsgId)\n const url = `${this.config.apiBase}/v1/messages`\n const headers: Record<string, string> = {\n 'authorization': `Bearer ${this.config.apiKey}`,\n 'content-type': 'application/json',\n 'user-agent': `@agentchatme/openclaw/${PACKAGE_VERSION} (+attempt=${attempt})`,\n }\n\n let res: Response\n try {\n res = await this.fetchImpl(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n } catch (err) {\n throw new AgentChatChannelError(\n classifyNetworkError(err),\n `POST /v1/messages network error: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n )\n }\n\n const requestId = res.headers.get('x-request-id')\n const idempotentReplay = res.headers.get('idempotent-replay') === 'true'\n const backlogWarning = this.parseBacklogWarning(res.headers.get('x-backlog-warning'))\n\n if (res.ok) {\n const message = (await res.json().catch(() => null)) as Message | null\n if (!message || typeof message !== 'object') {\n throw new AgentChatChannelError(\n 'validation',\n 'POST /v1/messages returned non-JSON success body',\n { statusCode: res.status },\n )\n }\n if (idempotentReplay) {\n log.info({ status: res.status, requestId }, 'idempotent replay — server echoed existing message')\n }\n if (backlogWarning && this.onBacklogWarning) {\n try {\n this.onBacklogWarning(backlogWarning)\n } catch (err) {\n // Handler errors must not break send, but silent swallow leaves\n // operators blind — log it so the failure is at least diagnosable.\n log.error(\n { err: err instanceof Error ? err.message : String(err) },\n 'onBacklogWarning handler threw — swallowed to protect send path',\n )\n }\n }\n return { message, backlogWarning, idempotentReplay, requestId }\n }\n\n // 2xx-none-of-the-above path: parse error body, classify, throw.\n const errorBody = await res.json().catch(() => null)\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'), this.now())\n const errorClass = classifyHttpStatus(res.status, res.headers.get('retry-after'))\n const serverMessage =\n (errorBody as { message?: unknown } | null)?.message ?? `HTTP ${res.status}`\n throw new AgentChatChannelError(\n errorClass,\n typeof serverMessage === 'string' ? serverMessage : `HTTP ${res.status}`,\n {\n statusCode: res.status,\n retryAfterMs: retryAfter,\n },\n )\n }\n\n private buildBody(input: OutboundMessageInput, clientMsgId: string): Record<string, unknown> {\n const content: Record<string, unknown> = {}\n if (input.content.text !== undefined) content.text = input.content.text\n if (input.content.data !== undefined) content.data = input.content.data\n if (input.content.attachmentId !== undefined) content.attachment_id = input.content.attachmentId\n\n if (Object.keys(content).length === 0) {\n throw new AgentChatChannelError(\n 'terminal-user',\n 'outbound message has empty content — at least one of text/data/attachmentId required',\n )\n }\n\n const body: Record<string, unknown> = {\n client_msg_id: clientMsgId,\n content,\n }\n if (input.type) body.type = input.type\n if (input.metadata) body.metadata = input.metadata\n if (input.kind === 'direct') body.to = input.to\n else body.conversation_id = input.conversationId\n return body\n }\n\n private parseBacklogWarning(header: string | null): OutboundBacklogWarning | null {\n if (!header) return null\n const eq = header.indexOf('=')\n if (eq <= 0 || eq === header.length - 1) return null\n const recipientHandle = header.slice(0, eq).trim()\n const countStr = header.slice(eq + 1).trim()\n const undeliveredCount = Number(countStr)\n if (!recipientHandle) return null\n if (!Number.isFinite(undeliveredCount) || !Number.isInteger(undeliveredCount)) return null\n return { recipientHandle, undeliveredCount }\n }\n\n private mintClientMsgId(): string {\n const cryptoObj = (globalThis as { crypto?: Crypto }).crypto\n if (cryptoObj?.randomUUID) return cryptoObj.randomUUID()\n return `cmsg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 12)}`\n }\n\n // ─── Backpressure ────────────────────────────────────────────────────\n\n private async acquireSlot(): Promise<void> {\n if (this.inFlight < this.config.outbound.maxInFlight) {\n this.inFlight++\n this.metrics.setInFlightDepth(this.inFlight)\n return\n }\n if (this.queue.length >= this.queueHardCap) {\n throw new AgentChatChannelError(\n 'retry-transient',\n `outbound queue full (${this.queue.length}) — shedding load`,\n )\n }\n return new Promise<void>((resolve) => {\n this.queue.push(() => {\n this.inFlight++\n this.metrics.setInFlightDepth(this.inFlight)\n resolve()\n })\n })\n }\n\n private releaseSlot(): void {\n this.inFlight = Math.max(0, this.inFlight - 1)\n this.metrics.setInFlightDepth(this.inFlight)\n const next = this.queue.shift()\n if (next) next()\n }\n}\n","/**\n * AgentChat channel runtime — single lifecycle object that ties the WS\n * transport (P2), inbound normalizer (P3), and outbound adapter (P4)\n * together. This is the surface an OpenClaw channel binding consumes.\n *\n * Responsibilities:\n * - Instantiate the WS client, hook its `inboundFrame` event through\n * `normalizeInbound` and into user-supplied handlers.\n * - Expose `sendMessage` that delegates to the OutboundAdapter.\n * - Coordinate drain: `stop(deadline)` waits for outbound in-flight to\n * clear (up to the deadline) before closing the WS.\n * - Surface a single `getHealth()` snapshot combining connection state +\n * outbound queue depth + circuit breaker state.\n *\n * Not in scope here:\n * - Per-conversation seq ordering and gap recovery — the SDK's\n * `RealtimeClient` owns that. For the channel plugin, we deliver\n * inbound frames as they arrive; upper layers can call\n * `GET /v1/messages/sync` for reconciliation if they require strict\n * ordering across reconnects.\n * - OpenClaw ChannelInboundMessage translation — that lives in the\n * bridge module (consumed by the gateway), not here. Keeping this\n * module decoupled means it can be smoke-tested without OpenClaw.\n */\n\nimport type { Logger } from './log.js'\nimport type { MetricsRecorder } from './metrics.js'\nimport { createLogger, type LogLevel } from './log.js'\nimport { createNoopMetrics } from './metrics.js'\nimport type { AgentchatChannelConfig } from './config-schema.js'\nimport { AgentchatWsClient, type InboundFrame } from './ws-client.js'\nimport { normalizeInbound, type NormalizedInbound } from './inbound.js'\nimport {\n OutboundAdapter,\n type OutboundMessageInput,\n type OutboundBacklogWarning,\n type SendResult,\n} from './outbound.js'\nimport { AgentChatChannelError } from './errors.js'\nimport type { ConnectionState } from './state-machine.js'\nimport type { UnixMillis } from './types.js'\n\nexport interface ChannelRuntimeHandlers {\n /** Called for every successfully normalized inbound event. */\n onInbound?: (event: NormalizedInbound) => void | Promise<void>\n /** Called whenever a frame fails validation. Default: log-and-drop. */\n onValidationError?: (error: AgentChatChannelError, frame: InboundFrame) => void\n /** Called on state transitions — surface to gateway for health/UI. */\n onStateChanged?: (next: ConnectionState, prev: ConnectionState) => void\n /** Called once per successful HELLO_OK (initial + every reconnect). */\n onAuthenticated?: (at: UnixMillis) => void\n /** Called on every closed/unreachable situation worth observing. */\n onError?: (error: AgentChatChannelError) => void\n /** Called when the server signals a backlog warning on an outbound send. */\n onBacklogWarning?: (warning: OutboundBacklogWarning) => void\n}\n\nexport interface ChannelRuntimeOptions {\n readonly config: AgentchatChannelConfig\n readonly handlers?: ChannelRuntimeHandlers\n /** Pre-built logger — if absent, we construct one from `config.observability`. */\n readonly logger?: Logger\n /** Pre-built metrics recorder — if absent, uses no-op. */\n readonly metrics?: MetricsRecorder\n readonly fetch?: typeof fetch\n /** Injected for tests. */\n readonly webSocketCtor?: ConstructorParameters<\n typeof AgentchatWsClient\n >[0]['webSocketCtor']\n readonly now?: () => UnixMillis\n readonly random?: () => number\n readonly sleep?: (ms: number) => Promise<void>\n}\n\nexport interface HealthSnapshot {\n readonly state: ConnectionState\n readonly authenticated: boolean\n readonly outbound: {\n readonly inFlight: number\n readonly queued: number\n readonly circuitState: 'closed' | 'open' | 'half-open'\n }\n}\n\n/**\n * Orchestrates the full channel. Construct once per (channelId, accountId)\n * pair at gateway startup; call `start()` to bring it up, `stop()` to\n * drain. Dispose is folded into `stop()` — after it resolves, the\n * instance is terminal.\n */\nexport class AgentchatChannelRuntime {\n private readonly config: AgentchatChannelConfig\n private readonly handlers: ChannelRuntimeHandlers\n private readonly logger: Logger\n private readonly metrics: MetricsRecorder\n private readonly ws: AgentchatWsClient\n private readonly outbound: OutboundAdapter\n private readonly now: () => UnixMillis\n private started = false\n private authenticated = false\n private stopPromise: Promise<void> | null = null\n\n constructor(opts: ChannelRuntimeOptions) {\n this.config = opts.config\n this.handlers = opts.handlers ?? {}\n this.now = opts.now ?? Date.now\n this.logger =\n opts.logger ??\n createLogger({\n level: this.config.observability.logLevel as LogLevel,\n redactKeys: this.config.observability.redactKeys,\n })\n this.metrics = opts.metrics ?? createNoopMetrics()\n\n this.ws = new AgentchatWsClient({\n config: this.config,\n logger: this.logger,\n metrics: this.metrics,\n webSocketCtor: opts.webSocketCtor,\n now: opts.now,\n random: opts.random,\n })\n\n this.outbound = new OutboundAdapter({\n config: this.config,\n logger: this.logger,\n metrics: this.metrics,\n fetch: opts.fetch,\n now: opts.now,\n random: opts.random,\n sleep: opts.sleep,\n onBacklogWarning: (warning) => {\n try {\n this.handlers.onBacklogWarning?.(warning)\n } catch (err) {\n this.logger.error(\n { err: err instanceof Error ? err.message : String(err) },\n 'onBacklogWarning handler threw',\n )\n }\n },\n })\n\n this.bindWsEvents()\n }\n\n /** Open the transport. Idempotent — subsequent calls are no-ops. */\n start(): void {\n if (this.started) return\n this.started = true\n this.ws.start()\n }\n\n /**\n * Graceful shutdown. Waits for outbound in-flight to drain up to the\n * deadline, then force-closes the WS. Returns a promise that resolves\n * once the WS has emitted `closed`.\n */\n stop(deadlineMs?: UnixMillis): Promise<void> {\n if (this.stopPromise) return this.stopPromise\n const deadline = deadlineMs ?? this.now() + 5_000\n\n this.stopPromise = new Promise<void>((resolve) => {\n const off = this.ws.on('closed', () => {\n off()\n resolve()\n })\n this.ws.stop(deadline)\n })\n // Once outbound is idle, let the WS know it can close early.\n void this.pollUntilIdle(deadline)\n return this.stopPromise\n }\n\n private async pollUntilIdle(deadline: UnixMillis): Promise<void> {\n // Spin until outbound reports no in-flight + no queue, or we hit the\n // deadline. Cheap polling (10ms) is fine — in steady-state we expect\n // this to fire within tens of ms.\n const step = 10\n for (;;) {\n const snap = this.outbound.snapshot()\n if (snap.inFlight === 0 && snap.queued === 0) {\n this.ws.drainCompleted()\n return\n }\n if (this.now() >= deadline) return\n await new Promise((r) => setTimeout(r, step))\n }\n }\n\n /**\n * Send an outbound message. Delegates to the OutboundAdapter; callers\n * should handle `AgentChatChannelError` with class dispatch.\n */\n sendMessage(input: OutboundMessageInput): Promise<SendResult> {\n return this.outbound.sendMessage(input)\n }\n\n /** Push a client-action frame over the WS (typing, read-ack, presence). */\n sendWsAction(type: 'typing.start' | 'typing.stop' | 'message.read_ack' | 'presence.update', payload: Record<string, unknown>): boolean {\n return this.ws.send({ type, payload })\n }\n\n /**\n * Operator has rotated the API key — signal the WS client so it can\n * exit AUTH_FAIL. The caller is responsible for creating a new runtime\n * with the updated config OR for calling this after config hot-reload.\n */\n reconfigured(): void {\n this.ws.reconfigured()\n }\n\n getHealth(): HealthSnapshot {\n const outSnap = this.outbound.snapshot()\n return {\n state: this.ws.getState(),\n authenticated: this.authenticated,\n outbound: {\n inFlight: outSnap.inFlight,\n queued: outSnap.queued,\n circuitState: outSnap.circuit.state,\n },\n }\n }\n\n // ─── Internals ───────────────────────────────────────────────────────\n\n private bindWsEvents(): void {\n this.ws.on('stateChanged', (next, prev) => {\n if (next.kind !== 'READY' && next.kind !== 'DEGRADED') {\n this.authenticated = false\n }\n try {\n this.handlers.onStateChanged?.(next, prev)\n } catch (err) {\n this.logger.error(\n { err: err instanceof Error ? err.message : String(err) },\n 'onStateChanged handler threw',\n )\n }\n })\n\n this.ws.on('authenticated', (at) => {\n this.authenticated = true\n try {\n this.handlers.onAuthenticated?.(at)\n } catch (err) {\n this.logger.error(\n { err: err instanceof Error ? err.message : String(err) },\n 'onAuthenticated handler threw',\n )\n }\n })\n\n this.ws.on('inboundFrame', (frame) => {\n this.dispatchFrame(frame)\n })\n\n this.ws.on('error', (error) => {\n try {\n this.handlers.onError?.(error)\n } catch (err) {\n this.logger.error(\n { err: err instanceof Error ? err.message : String(err) },\n 'onError handler threw',\n )\n }\n })\n }\n\n private dispatchFrame(frame: InboundFrame): void {\n let normalized: NormalizedInbound\n try {\n normalized = normalizeInbound(frame)\n } catch (err) {\n if (err instanceof AgentChatChannelError) {\n this.logger.warn(\n { type: frame.type, class: err.class_, message: err.message },\n 'inbound validation failed — dropping',\n )\n try {\n this.handlers.onValidationError?.(err, frame)\n } catch (handlerErr) {\n this.logger.error(\n { err: handlerErr instanceof Error ? handlerErr.message : String(handlerErr) },\n 'onValidationError handler threw',\n )\n }\n } else {\n this.logger.error(\n { err: err instanceof Error ? err.message : String(err) },\n 'inbound normalizer threw unexpectedly',\n )\n }\n return\n }\n\n this.recordInboundMetric(normalized)\n\n try {\n const result = this.handlers.onInbound?.(normalized)\n if (result instanceof Promise) {\n result.catch((err) => {\n this.logger.error(\n { err: err instanceof Error ? err.message : String(err), type: normalized.kind },\n 'async onInbound handler rejected',\n )\n })\n }\n } catch (err) {\n this.logger.error(\n { err: err instanceof Error ? err.message : String(err), type: normalized.kind },\n 'onInbound handler threw',\n )\n }\n }\n\n private recordInboundMetric(n: NormalizedInbound): void {\n switch (n.kind) {\n case 'message':\n this.metrics.incInboundDelivered({\n kind: n.conversationKind === 'group' ? 'group-message' : 'message',\n })\n break\n case 'typing':\n this.metrics.incInboundDelivered({ kind: 'typing' })\n break\n case 'read-receipt':\n this.metrics.incInboundDelivered({ kind: 'read' })\n break\n case 'presence':\n this.metrics.incInboundDelivered({ kind: 'presence' })\n break\n case 'rate-limit-warning':\n this.metrics.incInboundDelivered({ kind: 'rate-limit-warning' })\n break\n case 'group-invite':\n case 'group-deleted':\n case 'unknown':\n // Not tracked — cardinality would explode on `unknown` kinds.\n break\n }\n }\n}\n"]}