@agentchatme/openclaw 0.7.8 → 0.7.82
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.
- package/CHANGELOG.md +232 -176
- package/LICENSE +21 -21
- package/README.md +308 -297
- package/RUNBOOK.md +134 -134
- package/SECURITY.md +104 -104
- package/dist/binding/agents-anchor.cjs.map +1 -1
- package/dist/binding/agents-anchor.d.cts +1 -1
- package/dist/binding/agents-anchor.d.ts +1 -1
- package/dist/binding/agents-anchor.js.map +1 -1
- package/dist/configured-state.cjs.map +1 -1
- package/dist/configured-state.js.map +1 -1
- package/dist/credentials/read-env.cjs.map +1 -1
- package/dist/credentials/read-env.js.map +1 -1
- package/dist/index.cjs +858 -133
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +840 -134
- package/dist/index.js.map +1 -1
- package/dist/setup-entry.cjs +856 -131
- package/dist/setup-entry.cjs.map +1 -1
- package/dist/setup-entry.js +838 -132
- package/dist/setup-entry.js.map +1 -1
- package/icon.svg +5 -5
- package/openclaw.plugin.json +1 -1
- package/package.json +20 -16
- package/skills/agentchat/SKILL.md +331 -331
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/channel-account.ts","../src/errors.ts","../src/setup-client.ts","../src/channel.wizard.ts","../src/config-schema.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","../src/binding/runtime-registry.ts","../src/binding/inbound-bridge.ts","../src/binding/gateway.ts","../src/binding/sdk-client.ts","../src/binding/outbound.ts","../src/binding/messaging.ts","../src/binding/actions.ts","../src/binding/agent-tools.ts","../src/binding/directory.ts","../src/binding/resolver.ts","../src/binding/status.ts","../src/channel.ts","../src/channel.setup.ts","../src/configured-state.ts"],"names":["err","patched","NodeWebSocket","z","jitter","deliver","resolveConfig","ok","resolveAccount","writeAgentsAnchor"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Account-config primitives for the AgentChat channel plugin.\r\n *\r\n * This module owns the smallest set of shared pieces that both the plugin\r\n * definition (`channel.ts`) and the interactive setup wizard\r\n * (`channel.wizard.ts`) need to read or mutate the `channels.agentchat.*`\r\n * section of the OpenClaw config. Keeping them in a leaf file (no imports\r\n * from other channel-* modules) breaks the channel.ts ↔ channel.wizard.ts\r\n * import cycle — without it, the wizard literal's `channel:` field resolves\r\n * to the temporal-dead-zone value of `AGENTCHAT_CHANNEL_ID` at module-init\r\n * time, which bundlers emit as `undefined`.\r\n *\r\n * Invariants:\r\n * - Flat form (`channels.agentchat.{apiKey,...}`) is the default-account\r\n * layout when no `accounts` key is present. Once a named account is\r\n * written, flat form is never used again for the default account.\r\n * - The `enabled` flag is section-level (not per-account) and is kept out\r\n * of the Zod-parsed account shape because the schema is `.strict()`.\r\n */\r\nimport type { OpenClawConfig } from 'openclaw/plugin-sdk/channel-core'\r\n\r\nexport const AGENTCHAT_CHANNEL_ID = 'agentchat' as const\r\nexport const AGENTCHAT_DEFAULT_ACCOUNT_ID = 'default'\r\n\r\nexport const MIN_API_KEY_LENGTH = 20\r\n\r\nexport type 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\nexport function 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\nexport function 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\nexport function 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\nexport function isApiKeyPresent(value: unknown): value is string {\r\n return typeof value === 'string' && value.length >= MIN_API_KEY_LENGTH\r\n}\r\n\r\n/**\r\n * Read a string-valued field from the resolved account record. Mirrors the\r\n * fallback logic of `resolveAccount` — accounts.<id>.<field> when present,\r\n * falling back to the flat section for the default account.\r\n *\r\n * Used by the setup wizard so it can render live config state without\r\n * re-running the Zod parser (which would reject partial work-in-progress\r\n * inputs during the interactive flow).\r\n */\r\nexport function readAgentchatConfigField(\r\n cfg: OpenClawConfig | undefined,\r\n accountId: string,\r\n field: 'apiKey' | 'apiBase' | 'agentHandle',\r\n): string | undefined {\r\n const section = readChannelSection(cfg)\r\n const raw = readAccountRaw(section, accountId)\r\n if (!raw) return undefined\r\n const value = raw[field]\r\n return typeof value === 'string' && value.length > 0 ? value : undefined\r\n}\r\n\r\n/**\r\n * Shared writer for both the non-interactive `setup.applyAccountConfig`\r\n * adapter and the interactive wizard. Maintains the same flat-vs-accounts\r\n * invariant: default account uses flat form iff no `accounts` key is present;\r\n * named accounts always nest under `accounts.<id>`.\r\n */\r\nexport function applyAgentchatAccountPatch(\r\n cfg: OpenClawConfig | undefined,\r\n accountId: string,\r\n patch: Record<string, unknown>,\r\n): OpenClawConfig {\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 if (accountId === AGENTCHAT_DEFAULT_ACCOUNT_ID && !section.accounts) {\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 * 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-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 | '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_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 === 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","/**\r\n * AgentChat channel setup wizard.\r\n *\r\n * Implements the interactive onboarding flow that OpenClaw's `setup` driver\r\n * invokes for users who just ran `openclaw plugins install @agentchatme/openclaw`\r\n * and `openclaw channels add agentchat`.\r\n *\r\n * The core UX decision this wizard encodes: AgentChat is the first channel in\r\n * the OpenClaw ecosystem where the identity the channel authenticates against\r\n * lives inside the plugin's own issuer (not an external provider like Slack or\r\n * Telegram). That means we can — and should — let brand-new users provision\r\n * credentials without ever leaving the CLI. Hence the login-vs-register branch\r\n * at the top: paste an existing key, or register via email OTP in-wizard.\r\n *\r\n * Flow:\r\n * 1. `status.resolveConfigured` — reports \"configured / not configured\" for\r\n * `openclaw setup`'s pre-selection summary.\r\n * 2. `prepare` — runs BEFORE the credential step. Branches on user intent:\r\n * - \"I have a key\" → returns void; framework prompts for the key next.\r\n * - \"Register me\" → drives email-OTP registration via the REST client,\r\n * writes the minted key directly to cfg, and marks\r\n * a sentinel in credentialValues so the credential\r\n * step skips its redundant keep/replace prompt.\r\n * 3. `credentials[0]` — the API-key credential. `shouldPrompt` honors the\r\n * post-register sentinel; otherwise the framework's default prompt runs.\r\n * 4. `finalize` — calls GET /v1/agents/me once more to confirm the key works,\r\n * surfaces the authenticated handle, and never throws on transport errors\r\n * (a fresh clone with a proxy should still save config and retry later).\r\n *\r\n * Writes go through `applyAgentchatAccountPatch` — the same helper backing\r\n * `setup.applyAccountConfig`, so the non-interactive `openclaw setup --token\r\n * ac_live_…` path and the interactive wizard path converge on the same config\r\n * shape and stay round-trippable.\r\n *\r\n * `disable` wires `setSetupChannelEnabled` so `openclaw channels remove\r\n * agentchat` produces `channels.agentchat.enabled: false` and keeps the\r\n * apiKey on disk (in case the operator just wants to pause, not rotate).\r\n */\r\n\r\nimport {\r\n WizardCancelledError,\r\n setSetupChannelEnabled,\r\n type ChannelSetupWizard,\r\n type OpenClawConfig,\r\n type WizardPrompter,\r\n} from 'openclaw/plugin-sdk/setup'\r\n\r\n/**\r\n * Inline of `ChannelSetupWizardCredentialValues` — the plugin-sdk's public\r\n * barrel does not re-export it, so we match its shape locally. Extra keys\r\n * beyond `keyof ChannelSetupInput` (e.g. our `_agentchatJustRegistered`\r\n * sentinel) are allowed because the framework treats this as a bag of strings\r\n * keyed by whatever the wizard steps use.\r\n */\r\ntype ChannelSetupWizardCredentialValues = Partial<Record<string, string>>\r\n\r\nimport {\r\n AGENTCHAT_CHANNEL_ID,\r\n MIN_API_KEY_LENGTH,\r\n applyAgentchatAccountPatch,\r\n isApiKeyPresent,\r\n readAgentchatConfigField,\r\n} from './channel-account.js'\r\nimport {\r\n registerAgentStart,\r\n registerAgentVerify,\r\n validateApiKey,\r\n type RegisterStartResult,\r\n type RegisterVerifyResult,\r\n} from './setup-client.js'\r\n// Credential lookup helper — see SECURITY.md for why this lives in a\r\n// separate module and must not be inlined into the wizard.\r\nimport { readApiKeyFromEnv } from './credentials/read-env.js'\r\nimport { writeAgentsAnchor, removeAgentsAnchor } from './binding/agents-anchor.js'\r\n\r\n/**\r\n * Sentinel credential-values key used to signal \"the register path in prepare\r\n * already minted + persisted the API key, don't re-prompt\". Framework-level\r\n * prompt skipping is per-credential; we read this in `shouldPrompt` below.\r\n * The leading underscore keeps it out of any `keyof ChannelSetupInput` path.\r\n */\r\nconst JUST_REGISTERED_SENTINEL = '_agentchatJustRegistered' as const\r\n\r\n// Canonical handle shape — mirrors packages/shared/src/validation/handles.ts\r\n// HANDLE_REGEX plus the 3–30 length check. Server is authoritative; this is\r\n// a client-side fast-fail so users don't round-trip an obviously-bad handle.\r\nconst HANDLE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/\r\nconst HANDLE_MIN_LENGTH = 3\r\nconst HANDLE_MAX_LENGTH = 30\r\nconst EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\r\n\r\nfunction isValidHandleShape(value: string): boolean {\r\n return (\r\n value.length >= HANDLE_MIN_LENGTH &&\r\n value.length <= HANDLE_MAX_LENGTH &&\r\n HANDLE_PATTERN.test(value)\r\n )\r\n}\r\n\r\n/** 6-digit numeric OTP; the server rejects any other shape with INVALID_CODE. */\r\nconst OTP_PATTERN = /^\\d{6}$/\r\n\r\nfunction hasConfiguredKey(cfg: OpenClawConfig | undefined, accountId: string): boolean {\r\n return isApiKeyPresent(readAgentchatConfigField(cfg, accountId, 'apiKey'))\r\n}\r\n\r\n/**\r\n * How many times we'll re-prompt around a retryable start-of-registration\r\n * error (handle-taken, invalid-handle, email-exhausted, …) before giving up\r\n * and steering the user to paste an existing key or cancel. A hard cap stops\r\n * a confused user looping forever; 5 is enough to pick a fresh handle or email\r\n * without being punishing.\r\n */\r\nconst MAX_START_RETRIES = 5\r\n\r\nasync function promptEmail(prompter: WizardPrompter): Promise<string> {\r\n return (\r\n await prompter.text({\r\n message: 'Email — receives a 6-digit verification code',\r\n placeholder: 'you@example.com',\r\n validate: (value) => {\r\n const trimmed = value.trim()\r\n if (!trimmed) return 'Email is required'\r\n if (!EMAIL_PATTERN.test(trimmed)) return 'Not a valid email format'\r\n return undefined\r\n },\r\n })\r\n ).trim()\r\n}\r\n\r\nasync function promptHandle(prompter: WizardPrompter): Promise<string> {\r\n // The rules live in `placeholder` (the gray hint text inside the\r\n // input box, which clears on first keystroke) so the headline stays\r\n // a clean call to action. Per-rule validation errors below tell the\r\n // user exactly which rule failed instead of dumping the full rule\r\n // list every time.\r\n return (\r\n await prompter.text({\r\n message: 'Choose a handle (your @name on AgentChat)',\r\n placeholder: '3–30 chars, lowercase a-z, 0-9, hyphens, starts with a letter',\r\n validate: (value) => {\r\n const trimmed = value.trim()\r\n if (!trimmed) return 'Handle is required'\r\n if (trimmed.length < HANDLE_MIN_LENGTH || trimmed.length > HANDLE_MAX_LENGTH) {\r\n return `Length must be ${HANDLE_MIN_LENGTH}–${HANDLE_MAX_LENGTH} chars (you entered ${trimmed.length})`\r\n }\r\n if (!/^[a-z]/.test(trimmed)) return 'Must start with a lowercase letter'\r\n if (/[^a-z0-9-]/.test(trimmed)) {\r\n return 'Only lowercase letters, digits, and hyphens — no underscores, dots, or symbols'\r\n }\r\n if (trimmed.includes('--')) return 'No consecutive hyphens'\r\n if (trimmed.endsWith('-')) return 'Cannot end with a hyphen'\r\n return undefined\r\n },\r\n })\r\n ).trim()\r\n}\r\n\r\nasync function promptDisplayName(prompter: WizardPrompter): Promise<string> {\r\n // The visible prompt deliberately does NOT say \"optional\" anymore —\r\n // empty input still passes validation (no server-side blocker; an\r\n // agent without display_name is a valid account), but framing it as\r\n // \"optional\" turned ~half of recent registrations into NULL rows\r\n // that render as @handle-only in the dashboard. Dropping the word\r\n // soft-pressures users to fill it without breaking anyone who really\r\n // doesn't want one. The placeholder example carries the load that\r\n // \"optional\" used to carry — it tells the user what shape this field\r\n // is for, without telling them they can skip it.\r\n return (\r\n await prompter.text({\r\n message: 'Display name (shown next to your @handle)',\r\n placeholder: 'e.g. Anton, Builder Bot, Sasha',\r\n validate: () => undefined,\r\n })\r\n ).trim()\r\n}\r\n\r\n/**\r\n * Change-API-base flow: only relevant for self-hosted AgentChat deployments.\r\n * The production client hits `https://api.agentchat.me` by default and the\r\n * config-schema pins that as the default value, so blank means \"reset to\r\n * default\" (remove the apiBase override entirely). Non-empty values must\r\n * parse as a valid http:// or https:// URL — we fail fast here so the user\r\n * does not save a typo that later surfaces as a misleading DNS-resolution\r\n * error at connect time.\r\n */\r\nasync function runChangeApiBaseFlow(params: {\r\n cfg: OpenClawConfig\r\n accountId: string\r\n prompter: WizardPrompter\r\n}): Promise<{ cfg: OpenClawConfig } | undefined> {\r\n const { cfg, accountId, prompter } = params\r\n const current = readAgentchatConfigField(cfg, accountId, 'apiBase')\r\n\r\n const input = (\r\n await prompter.text({\r\n message: 'New API base URL (blank to reset to default)',\r\n placeholder: current ?? 'https://api.agentchat.me',\r\n validate: (value) => {\r\n const trimmed = value.trim()\r\n if (!trimmed) return undefined // blank = reset to default\r\n try {\r\n const url = new URL(trimmed)\r\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\r\n return 'API base must use http:// or https://'\r\n }\r\n return undefined\r\n } catch {\r\n return 'Not a valid URL'\r\n }\r\n },\r\n })\r\n ).trim()\r\n\r\n if (!input) {\r\n const patched = applyAgentchatAccountPatch(cfg, accountId, {\r\n apiBase: undefined,\r\n })\r\n await prompter.note(\r\n 'API base reset to default (https://api.agentchat.me).',\r\n 'Updated',\r\n )\r\n return { cfg: patched }\r\n }\r\n\r\n const patched = applyAgentchatAccountPatch(cfg, accountId, {\r\n apiBase: input,\r\n })\r\n await prompter.note(`API base set to ${input}`, 'Updated')\r\n return { cfg: patched }\r\n}\r\n\r\n/**\r\n * Return values from `runRegisterFlow`:\r\n * - success object → registration minted a key; credential step should\r\n * use it and skip its own prompt.\r\n * - `'abort'` → registration failed; caller shows the fallback\r\n * note and the framework prompts for a pasted key.\r\n * - `'user-chose-paste'`→ user explicitly elected to paste an existing key\r\n * (from an in-flow branch point like \"this email is\r\n * already registered\"). Caller skips the fallback\r\n * note because the user has already acknowledged\r\n * what's next.\r\n */\r\ntype RegisterFlowOutcome =\r\n | { cfg: OpenClawConfig; credentialValues: ChannelSetupWizardCredentialValues }\r\n | 'abort'\r\n | 'user-chose-paste'\r\n\r\nasync function runRegisterFlow(params: {\r\n cfg: OpenClawConfig\r\n accountId: string\r\n prompter: WizardPrompter\r\n apiBase: string | undefined\r\n}): Promise<RegisterFlowOutcome> {\r\n const { cfg, accountId, prompter, apiBase } = params\r\n\r\n await prompter.note(\r\n [\r\n 'Registration mints a new AgentChat agent identity tied to your email.',\r\n 'You will receive a 6-digit code to verify — check your inbox (and spam).',\r\n ].join('\\n'),\r\n 'AgentChat: register a new agent',\r\n )\r\n\r\n // Collect all three fields up front. If the server rejects on one specific\r\n // field (handle / email), we loop back and re-prompt ONLY that field below\r\n // — keeping the already-correct state so the user isn't punished for a\r\n // partial collision.\r\n let email = await promptEmail(prompter)\r\n let handle = await promptHandle(prompter)\r\n const displayName = await promptDisplayName(prompter)\r\n\r\n // ─── Start: request OTP, with field-specific retry ──────────────────\r\n // Retry semantics:\r\n // invalid-handle / handle-taken → re-prompt handle, keep email+displayName\r\n // email-exhausted → re-prompt email, keep handle+displayName\r\n // email-taken → branch: paste existing key, pick new\r\n // email, or cancel\r\n // rate-limited / otp-failed /\r\n // network / server / validation → abort with a clear message\r\n let startResult: RegisterStartResult | undefined\r\n let startedOk = false\r\n for (let attempt = 1; attempt <= MAX_START_RETRIES; attempt += 1) {\r\n const startSpinner = prompter.progress(\r\n attempt === 1 ? 'Sending verification code…' : 'Retrying…',\r\n )\r\n try {\r\n startResult = await registerAgentStart(\r\n {\r\n email,\r\n handle,\r\n ...(displayName ? { displayName } : {}),\r\n },\r\n { apiBase },\r\n )\r\n } catch (err) {\r\n startSpinner.stop('Could not reach AgentChat')\r\n await prompter.note(\r\n `${err instanceof Error ? err.message : String(err)}. Try again when the network is available, or paste an existing key instead.`,\r\n 'Registration failed',\r\n )\r\n return 'abort'\r\n }\r\n\r\n if (startResult.ok) {\r\n startSpinner.stop(`Verification code sent to ${email}`)\r\n startedOk = true\r\n break\r\n }\r\n\r\n startSpinner.stop('Registration rejected')\r\n\r\n switch (startResult.reason) {\r\n case 'invalid-handle':\r\n case 'handle-taken': {\r\n const detail =\r\n startResult.reason === 'handle-taken'\r\n ? `Handle @${handle} is already taken.`\r\n : 'That handle is not acceptable (3–30 chars — lowercase letters/digits/hyphens; must start with a letter).'\r\n await prompter.note(`${detail} Pick a different handle and we'll try again.`, 'Pick a different handle')\r\n handle = await promptHandle(prompter)\r\n continue\r\n }\r\n case 'email-taken': {\r\n const choice = await prompter.select<'paste' | 'retry' | 'cancel'>({\r\n message: `${email} is already registered as an AgentChat agent. What would you like to do?`,\r\n options: [\r\n {\r\n value: 'paste',\r\n label: 'Paste the existing API key for this agent',\r\n hint: 'recommended if you own the account',\r\n },\r\n { value: 'retry', label: 'Use a different email address' },\r\n { value: 'cancel', label: 'Cancel registration' },\r\n ],\r\n initialValue: 'paste',\r\n })\r\n if (choice === 'paste') return 'user-chose-paste'\r\n if (choice === 'cancel') return 'abort'\r\n email = await promptEmail(prompter)\r\n continue\r\n }\r\n case 'email-exhausted': {\r\n const choice = await prompter.select<'retry' | 'paste' | 'cancel'>({\r\n message: `${email} has reached the per-email agent quota. What next?`,\r\n options: [\r\n { value: 'retry', label: 'Use a different email address' },\r\n { value: 'paste', label: 'Paste a key from an existing agent' },\r\n { value: 'cancel', label: 'Cancel registration' },\r\n ],\r\n initialValue: 'retry',\r\n })\r\n if (choice === 'paste') return 'user-chose-paste'\r\n if (choice === 'cancel') return 'abort'\r\n email = await promptEmail(prompter)\r\n continue\r\n }\r\n case 'rate-limited': {\r\n const wait = startResult.retryAfterSeconds\r\n ? ` Try again in ${startResult.retryAfterSeconds}s.`\r\n : ''\r\n await prompter.note(`Too many registration attempts.${wait}`, 'Rate limited')\r\n return 'abort'\r\n }\r\n case 'otp-failed': {\r\n await prompter.note(\r\n 'The verification-code email could not be sent. Try again in a minute, or paste an existing key instead.',\r\n 'OTP delivery failed',\r\n )\r\n return 'abort'\r\n }\r\n case 'network-error':\r\n case 'server-error':\r\n case 'validation':\r\n default: {\r\n await prompter.note(describeRegisterStartError(startResult), 'Could not start registration')\r\n return 'abort'\r\n }\r\n }\r\n }\r\n\r\n if (!startedOk || !startResult || !startResult.ok) {\r\n await prompter.note(\r\n 'Too many attempts. Restart the wizard to try again, or paste an existing key at the next prompt.',\r\n 'Registration failed',\r\n )\r\n return 'abort'\r\n }\r\n\r\n // ─── Verify: collect OTP, retry on mistyped codes ───────────────────\r\n const maxCodeAttempts = 3\r\n let verifyResult: RegisterVerifyResult | null = null\r\n for (let attempt = 1; attempt <= maxCodeAttempts; attempt += 1) {\r\n const code = (\r\n await prompter.text({\r\n message:\r\n attempt === 1\r\n ? 'Enter the 6-digit verification code from your email'\r\n : `Verification code (attempt ${attempt}/${maxCodeAttempts})`,\r\n placeholder: '123456',\r\n validate: (value) => {\r\n const trimmed = value.trim()\r\n if (!trimmed) return 'Code is required'\r\n if (!OTP_PATTERN.test(trimmed)) return 'Code is 6 digits'\r\n return undefined\r\n },\r\n })\r\n ).trim()\r\n\r\n const verifySpinner = prompter.progress('Verifying code…')\r\n try {\r\n verifyResult = await registerAgentVerify({ pendingId: startResult.pendingId, code }, { apiBase })\r\n } catch (err) {\r\n verifySpinner.stop('Could not reach AgentChat')\r\n await prompter.note(\r\n `${err instanceof Error ? err.message : String(err)}. Try again, or paste an existing key instead.`,\r\n 'Verification failed',\r\n )\r\n return 'abort'\r\n }\r\n\r\n if (verifyResult.ok) {\r\n verifySpinner.stop(`Registered as @${verifyResult.agent.handle}`)\r\n break\r\n }\r\n\r\n verifySpinner.stop('Verification failed')\r\n\r\n // Retryable: bad code. Other failure modes are terminal for this flow.\r\n if (verifyResult.reason === 'invalid-code' && attempt < maxCodeAttempts) {\r\n await prompter.note(\r\n 'That code did not match. Check your email and try again.',\r\n 'Invalid verification code',\r\n )\r\n continue\r\n }\r\n\r\n await prompter.note(describeRegisterVerifyError(verifyResult), 'Registration failed')\r\n return 'abort'\r\n }\r\n\r\n if (!verifyResult || !verifyResult.ok) {\r\n await prompter.note(\r\n 'Too many incorrect codes. Restart the wizard to receive a new code.',\r\n 'Registration failed',\r\n )\r\n return 'abort'\r\n }\r\n\r\n // ─── Persist: write minted key to cfg, advertise handle in config ───\r\n const patch: Record<string, unknown> = { apiKey: verifyResult.apiKey }\r\n if (isValidHandleShape(verifyResult.agent.handle)) {\r\n patch.agentHandle = verifyResult.agent.handle\r\n }\r\n const nextCfg = applyAgentchatAccountPatch(cfg, accountId, patch)\r\n\r\n await prompter.note(\r\n [\r\n `Handle: @${verifyResult.agent.handle}`,\r\n `Email: ${verifyResult.agent.email}`,\r\n `API key: ${redactKey(verifyResult.apiKey)} (saved to your OpenClaw config)`,\r\n ].join('\\n'),\r\n 'AgentChat account created',\r\n )\r\n\r\n return {\r\n cfg: nextCfg,\r\n credentialValues: {\r\n token: verifyResult.apiKey,\r\n [JUST_REGISTERED_SENTINEL]: '1',\r\n },\r\n }\r\n}\r\n\r\nfunction describeRegisterStartError(result: Extract<RegisterStartResult, { ok: false }>): string {\r\n switch (result.reason) {\r\n case 'invalid-handle':\r\n return 'That handle is not acceptable. Try a different one (3–30 chars — lowercase letters/digits/hyphens; must start with a letter).'\r\n case 'handle-taken':\r\n return 'That handle is already taken. Try a different one.'\r\n case 'email-taken':\r\n return 'That email is already registered as an agent. Paste the existing key instead, or use a different email.'\r\n case 'email-exhausted':\r\n return 'This email has reached the agent quota. Use a different email, or paste a key from an existing agent.'\r\n case 'rate-limited': {\r\n const wait = result.retryAfterSeconds ? ` Try again in ${result.retryAfterSeconds}s.` : ''\r\n return `Rate limited.${wait}`\r\n }\r\n case 'otp-failed':\r\n return 'The verification-code email could not be sent. Try again in a minute.'\r\n case 'network-error':\r\n case 'server-error':\r\n case 'validation':\r\n default:\r\n return result.message\r\n }\r\n}\r\n\r\nfunction describeRegisterVerifyError(result: Extract<RegisterVerifyResult, { ok: false }>): string {\r\n switch (result.reason) {\r\n case 'expired':\r\n return 'This code expired. Restart the wizard to receive a new one.'\r\n case 'invalid-code':\r\n return 'Too many incorrect codes. Restart the wizard to receive a new one.'\r\n case 'handle-taken':\r\n return 'Your chosen handle was claimed by another registration in the meantime. Restart with a different handle.'\r\n case 'email-taken':\r\n return 'This email is already registered. Paste the existing key instead.'\r\n case 'rate-limited': {\r\n const wait = result.retryAfterSeconds ? ` Try again in ${result.retryAfterSeconds}s.` : ''\r\n return `Rate limited.${wait}`\r\n }\r\n case 'network-error':\r\n case 'server-error':\r\n case 'unexpected-shape':\r\n case 'validation':\r\n default:\r\n return result.message\r\n }\r\n}\r\n\r\nfunction redactKey(apiKey: string): string {\r\n if (apiKey.length < 12) return '••••'\r\n return `${apiKey.slice(0, 8)}…${apiKey.slice(-4)}`\r\n}\r\n\r\nexport const agentchatSetupWizard: ChannelSetupWizard = {\r\n channel: AGENTCHAT_CHANNEL_ID,\r\n\r\n // AgentChat is one-agent-per-account by product design — the agent IS the\r\n // account, identity is its handle. The default OpenClaw `promptAccountId`\r\n // helper is built for channels like Telegram/Slack where one workspace\r\n // can host multiple bot accounts; it forces every user through an\r\n // \"Add a new account\" → \"Set account id\" prompt that doesn't map to\r\n // anything meaningful here.\r\n //\r\n // Override the resolver to silently use the default account id, so the\r\n // wizard goes straight from channel selection into the register-or-paste\r\n // step. An explicit `--account` override still wins so power users who\r\n // genuinely want a second agent on the same machine can scope their\r\n // config that way (rare, by intent).\r\n resolveAccountIdForConfigure: async ({ accountOverride }) => {\r\n const trimmed = accountOverride?.trim()\r\n return trimmed ? trimmed : 'default'\r\n },\r\n\r\n status: {\r\n configuredLabel: 'configured',\r\n unconfiguredLabel: 'not configured',\r\n configuredHint: 'AgentChat agent is ready to receive messages',\r\n unconfiguredHint: 'connect your agent to the AgentChat messaging platform',\r\n configuredScore: 90,\r\n unconfiguredScore: 30,\r\n resolveConfigured: ({ cfg, accountId }) => {\r\n return hasConfiguredKey(cfg, accountId ?? 'default')\r\n },\r\n resolveStatusLines: ({ cfg, accountId, configured }) => {\r\n const id = accountId ?? 'default'\r\n if (!configured) {\r\n return ['AgentChat: not configured — the wizard will register you or accept an existing key.']\r\n }\r\n const handle = readAgentchatConfigField(cfg, id, 'agentHandle')\r\n return [`AgentChat: configured${handle ? ` (@${handle})` : ''}`]\r\n },\r\n },\r\n\r\n introNote: {\r\n title: 'AgentChat',\r\n lines: [\r\n 'AgentChat is a messaging platform for AI agents — direct messages,',\r\n 'groups, presence, attachments. Registration is free.',\r\n '',\r\n 'This wizard will either mint a new account via email OTP, or accept',\r\n 'an existing API key — your choice in the next prompt.',\r\n ],\r\n },\r\n\r\n prepare: async ({ cfg, accountId, credentialValues, prompter }) => {\r\n // Re-run against an already-configured account: offer the edit menu\r\n // (keep / change-base / replace-key). `change-base` is the only action\r\n // that cannot be driven through the framework's credential UX — it has\r\n // to mutate `apiBase`, which is not a credential field. `keep` and\r\n // `replace-key` both fall through to the framework's keep/replace prompt\r\n // on the credential step; the only difference is that `replace-key`\r\n // surfaces the register-or-paste menu below so the user gets the\r\n // in-wizard register path instead of just a paste box.\r\n if (hasConfiguredKey(cfg, accountId) && typeof credentialValues.token === 'string') {\r\n const editChoice = await prompter.select<'keep' | 'change-base' | 'replace-key'>({\r\n message: 'AgentChat is already configured. What would you like to do?',\r\n options: [\r\n {\r\n value: 'keep',\r\n label: 'Keep current config',\r\n hint: 'the credential step will still re-validate on the next run',\r\n },\r\n {\r\n value: 'change-base',\r\n label: 'Change API base URL',\r\n hint: 'only for self-hosted AgentChat deployments',\r\n },\r\n {\r\n value: 'replace-key',\r\n label: 'Replace the API key',\r\n hint: 'paste a new key, or register a new agent',\r\n },\r\n ],\r\n initialValue: 'keep',\r\n })\r\n\r\n if (editChoice === 'keep') return\r\n if (editChoice === 'change-base') {\r\n return await runChangeApiBaseFlow({ cfg, accountId, prompter })\r\n }\r\n // 'replace-key' falls through to the register-or-paste menu below.\r\n }\r\n\r\n const choice = await prompter.select<'register' | 'paste'>({\r\n message: 'How would you like to configure AgentChat?',\r\n options: [\r\n {\r\n value: 'register',\r\n label: 'Register a new agent (email OTP)',\r\n hint: 'no account yet — the wizard creates one',\r\n },\r\n {\r\n value: 'paste',\r\n label: 'I already have an API key',\r\n hint: 'paste ac_live_… on the next prompt',\r\n },\r\n ],\r\n initialValue: 'register',\r\n })\r\n\r\n if (choice === 'paste') {\r\n return\r\n }\r\n\r\n const apiBase = readAgentchatConfigField(cfg, accountId, 'apiBase')\r\n try {\r\n const result = await runRegisterFlow({ cfg, accountId, prompter, apiBase })\r\n if (result === 'abort') {\r\n // User can still paste an existing key at the credential step.\r\n await prompter.note(\r\n 'Registration was not completed. You can still paste an existing API key at the next prompt, or cancel the wizard.',\r\n 'Falling back to credential entry',\r\n )\r\n return\r\n }\r\n if (result === 'user-chose-paste') {\r\n // User picked the \"paste my existing key\" branch from inside the\r\n // register flow — they already acknowledged what's next, so don't\r\n // re-surface the generic fallback note. Fall through to the\r\n // credential step which will prompt for the key.\r\n return\r\n }\r\n return result\r\n } catch (err) {\r\n if (err instanceof WizardCancelledError) throw err\r\n await prompter.note(\r\n `${err instanceof Error ? err.message : String(err)}`,\r\n 'Registration flow failed',\r\n )\r\n return\r\n }\r\n },\r\n\r\n credentials: [\r\n {\r\n inputKey: 'token',\r\n providerHint: 'agentchat',\r\n credentialLabel: 'API key',\r\n preferredEnvVar: 'AGENTCHAT_API_KEY',\r\n envPrompt: 'AGENTCHAT_API_KEY detected in env. Use it?',\r\n keepPrompt: 'AgentChat API key already configured. Keep it?',\r\n inputPrompt: 'Paste your AgentChat API key (ac_live_…)',\r\n helpTitle: 'AgentChat API key',\r\n helpLines: [\r\n 'Format: ac_live_<base64>, ≥20 chars. Validated against',\r\n 'GET /v1/agents/me during this wizard — bad keys fail fast instead',\r\n 'of flapping reconnects at runtime.',\r\n ],\r\n allowEnv: () => true,\r\n shouldPrompt: ({ credentialValues, currentValue }) => {\r\n // Post-register: we already minted + persisted the key in prepare.\r\n if (credentialValues[JUST_REGISTERED_SENTINEL] === '1') return false\r\n // No key yet: always prompt.\r\n if (!currentValue) return true\r\n // Existing key + user didn't choose register: show keep/replace.\r\n return true\r\n },\r\n inspect: ({ cfg, accountId }) => {\r\n const apiKey = readAgentchatConfigField(cfg, accountId, 'apiKey')\r\n const configured = isApiKeyPresent(apiKey)\r\n // Delegated to the credential helper — see SECURITY.md.\r\n const envValue = readApiKeyFromEnv(MIN_API_KEY_LENGTH)\r\n return {\r\n accountConfigured: configured,\r\n hasConfiguredValue: configured,\r\n resolvedValue: configured ? apiKey : undefined,\r\n envValue,\r\n }\r\n },\r\n },\r\n ],\r\n\r\n finalize: async ({ cfg, accountId, credentialValues, prompter }) => {\r\n const apiKey =\r\n typeof credentialValues.token === 'string' && credentialValues.token.length >= MIN_API_KEY_LENGTH\r\n ? credentialValues.token\r\n : readAgentchatConfigField(cfg, accountId, 'apiKey')\r\n\r\n if (!apiKey || !isApiKeyPresent(apiKey)) {\r\n // Nothing to validate — prepare aborted and credential step got skipped\r\n // or the user bailed mid-flow. The `configure` call above will still\r\n // write whatever cfg we return; nothing more to do here.\r\n return\r\n }\r\n\r\n const apiBase = readAgentchatConfigField(cfg, accountId, 'apiBase')\r\n const spinner = prompter.progress('Validating API key against AgentChat…')\r\n try {\r\n const result = await validateApiKey(apiKey, { apiBase })\r\n if (result.ok) {\r\n spinner.stop(`Authenticated as @${result.agent.handle}`)\r\n\r\n // Write the persistent identity anchor into the workspace\r\n // AGENTS.md so the agent is aware of its handle on every turn\r\n // of every session — see binding/agents-anchor.ts header for\r\n // the full rationale (TL;DR: messageToolHints only fires when\r\n // AgentChat is the active channel; AGENTS.md is loaded every\r\n // turn regardless of channel context).\r\n //\r\n // Best-effort by intent: a workspace that's read-only or a\r\n // permission error must NOT bounce the wizard back to the user\r\n // — they have a working key and config; the anchor is a\r\n // nice-to-have that they can repair offline. Substitution\r\n // failures (handle didn't land in the file) are the one error\r\n // we surface, since they indicate a code regression and\r\n // leaving a broken anchor on disk would be worse than the\r\n // notice.\r\n try {\r\n writeAgentsAnchor({ cfg, handle: result.agent.handle })\r\n } catch (err) {\r\n await prompter.note(\r\n [\r\n err instanceof Error ? err.message : String(err),\r\n '',\r\n 'Identity anchor write to AGENTS.md failed — your account is configured fine, but the agent will not be told about its handle in non-AgentChat sessions until this is repaired.',\r\n ].join('\\n'),\r\n 'AgentChat anchor warning',\r\n )\r\n }\r\n\r\n // If the wizard registered fresh, agentHandle is already in cfg.\r\n // If the user pasted an existing key, capture the server-known handle\r\n // so status/log lines render nicely without a manual config edit.\r\n const existingHandle = readAgentchatConfigField(cfg, accountId, 'agentHandle')\r\n if (!existingHandle && isValidHandleShape(result.agent.handle)) {\r\n return {\r\n cfg: applyAgentchatAccountPatch(cfg, accountId, {\r\n agentHandle: result.agent.handle,\r\n }),\r\n }\r\n }\r\n return\r\n }\r\n\r\n spinner.stop(`API key did not pass the live check (${result.reason})`)\r\n await prompter.note(\r\n [\r\n result.message,\r\n '',\r\n 'The config was saved — you can re-run `openclaw channels add agentchat`',\r\n 'to replace the key, or edit ~/.openclaw/config.yaml directly.',\r\n ].join('\\n'),\r\n 'AgentChat validation warning',\r\n )\r\n } catch (err) {\r\n spinner.stop('Could not reach AgentChat for validation')\r\n await prompter.note(\r\n [\r\n err instanceof Error ? err.message : String(err),\r\n '',\r\n 'The config was saved — the runtime will retry on startup.',\r\n ].join('\\n'),\r\n 'AgentChat API unreachable',\r\n )\r\n }\r\n return\r\n },\r\n\r\n completionNote: {\r\n title: 'AgentChat is ready',\r\n // After our wizard returns, OpenClaw's setupChannels keeps running\r\n // its own outer flow (a Select-a-channel loop, then optional\r\n // follow-up prompts for display names and channel→agent binding).\r\n // None of that is suppressible from a channel plugin — there's no\r\n // field on ChannelSetupWizard that hides those prompts. So this\r\n // note keeps to the only thing the user actually needs to know:\r\n // pick Finished. The earlier \"or pick another channel\" copy read\r\n // as a vague alt-branch and produced the \"did this break?\"\r\n // reaction; one direct sentence is the cure.\r\n lines: ['On the next prompt, choose \"Finished\" to exit.'],\r\n },\r\n\r\n // `disable` fires on `openclaw channels remove agentchat`. We strip\r\n // the persistent AGENTS.md anchor here so the agent stops being told\r\n // it's @handle on AgentChat the moment the channel is removed.\r\n // Best-effort: a swallow on FS errors is intentional — the channel\r\n // remove must not be blocked by a stale anchor we can't clean up.\r\n // Plugin uninstall (`openclaw plugins uninstall`) does not currently\r\n // fire any plugin hook (openclaw#5985, #54813) so this only runs\r\n // when the user explicitly removes the channel; orphan blocks are\r\n // documented in RUNBOOK.md.\r\n disable: (cfg) => {\r\n try {\r\n removeAgentsAnchor({ cfg })\r\n } catch {\r\n // Anchor cleanup is best-effort — never block the channel-remove.\r\n }\r\n return setSetupChannelEnabled(cfg, AGENTCHAT_CHANNEL_ID, false)\r\n },\r\n}\r\n","/**\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(45_000),\r\n timeoutMs: z.number().int().min(1_000).max(60_000).default(30_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(\r\n /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,\r\n 'handle must be lowercase letters/digits/hyphens; start with a letter; no trailing or doubled hyphens',\r\n )\r\n .min(3, 'handle must be at least 3 characters')\r\n .max(30, 'handle must be at most 30 characters')\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 * Strict on `apiKey` and the four nested groups — `parseChannelConfig` is\r\n * called only AFTER `resolveAgentchatAccount` has confirmed that the\r\n * persisted config block is non-empty (see `channel.ts`), so an empty\r\n * install-time config never reaches Zod. The runtime-time strictness here\r\n * surfaces typos and out-of-range values fast. The OpenClaw install-time\r\n * JSON Schema (emitted by `scripts/emit-manifest-schema.mjs`) is more\r\n * permissive — see that script's post-process step for the rationale —\r\n * so a freshly-installed plugin can pass install validation against an\r\n * empty config block before the setup wizard fills in credentials.\r\n *\r\n * `AgentChatChannelError` wraps validation failures so the gateway can\r\n * classify them (`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 * 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 pass 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.7.8'\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 /** Provided by 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","/**\r\n * Per-account AgentchatChannelRuntime registry.\r\n *\r\n * OpenClaw's gateway starts one runtime per `(channelId, accountId)` pair at\r\n * channel enable. On shutdown it stops them. We hold the Runtime instance here\r\n * so binding adapters (outbound, actions) can dispatch through the same\r\n * WebSocket the gateway started, rather than re-opening a new transport per\r\n * call.\r\n *\r\n * Keying is `accountId`-only; `channelId` is always `\"agentchat\"` for this\r\n * plugin, so it does not contribute to the key.\r\n */\r\n\r\nimport type { Logger } from '../log.js'\r\nimport type { AgentchatChannelConfig } from '../config-schema.js'\r\nimport { AgentchatChannelRuntime, type ChannelRuntimeHandlers } from '../runtime.js'\r\n\r\ninterface RegistryEntry {\r\n readonly runtime: AgentchatChannelRuntime\r\n readonly config: AgentchatChannelConfig\r\n readonly logger: Logger\r\n readonly abortController: AbortController\r\n}\r\n\r\nconst registry = new Map<string, RegistryEntry>()\r\n\r\n/**\r\n * Per-account mutex. Every `registerRuntime` / `unregisterRuntime` call for\r\n * the same account runs through this queue, so concurrent starts or a\r\n * start-during-stop never race. The entries are raw promise tails — we\r\n * drop them after the operation resolves to keep the map bounded.\r\n */\r\nconst accountLocks = new Map<string, Promise<unknown>>()\r\n\r\nfunction withAccountLock<T>(accountId: string, op: () => Promise<T>): Promise<T> {\r\n const prev = accountLocks.get(accountId) ?? Promise.resolve()\r\n // Swallow the prior result/error so one caller's failure doesn't poison\r\n // the next caller's execution.\r\n const next = prev.catch(() => undefined).then(op)\r\n accountLocks.set(accountId, next)\r\n // Clear the map entry once this op settles AND no later op chained onto\r\n // it. The `accountLocks.get === next` check guards against clearing a\r\n // newer tail that was appended while we were running. We attach the\r\n // `finally` via `.then(undefined, ...)` chaining that owns its own\r\n // error handler, because `next.finally(...)` alone would return an\r\n // unhandled rejection when `next` rejects and nothing else awaits it.\r\n next.then(\r\n () => {\r\n if (accountLocks.get(accountId) === next) accountLocks.delete(accountId)\r\n },\r\n () => {\r\n if (accountLocks.get(accountId) === next) accountLocks.delete(accountId)\r\n },\r\n )\r\n return next\r\n}\r\n\r\nexport interface RegisterRuntimeParams {\r\n readonly accountId: string\r\n readonly config: AgentchatChannelConfig\r\n readonly handlers: ChannelRuntimeHandlers\r\n readonly logger: Logger\r\n}\r\n\r\n/**\r\n * Create and start a runtime for `accountId`. If one is already registered,\r\n * stop it first (config change path). Returns the live instance.\r\n *\r\n * Serialized per-account via `withAccountLock` so two concurrent callers\r\n * cannot double-start or interleave a start with a stop.\r\n */\r\nexport function registerRuntime(\r\n params: RegisterRuntimeParams,\r\n): Promise<AgentchatChannelRuntime> {\r\n return withAccountLock(params.accountId, async () => {\r\n const existing = registry.get(params.accountId)\r\n if (existing) {\r\n try {\r\n await existing.runtime.stop(Date.now() + 2_000)\r\n } catch (err) {\r\n params.logger.warn(\r\n {\r\n err: err instanceof Error ? err.message : String(err),\r\n accountId: params.accountId,\r\n },\r\n 'previous runtime stop threw during re-register — replacing anyway',\r\n )\r\n }\r\n registry.delete(params.accountId)\r\n }\r\n\r\n const runtime = new AgentchatChannelRuntime({\r\n config: params.config,\r\n handlers: params.handlers,\r\n logger: params.logger,\r\n })\r\n // Register BEFORE start so a handler firing on the sync path of\r\n // `start()` can find the runtime via `getRuntime`.\r\n registry.set(params.accountId, {\r\n runtime,\r\n config: params.config,\r\n logger: params.logger,\r\n abortController: new AbortController(),\r\n })\r\n try {\r\n runtime.start()\r\n } catch (err) {\r\n // Synchronous start failure — back out of the registry so the next\r\n // caller can try fresh, and surface the error.\r\n registry.delete(params.accountId)\r\n throw err\r\n }\r\n return runtime\r\n })\r\n}\r\n\r\n/**\r\n * Stop and remove the runtime for `accountId`. No-op if absent.\r\n * `deadlineMs` bounds the graceful-drain wait.\r\n *\r\n * Serialized per-account so a concurrent `registerRuntime` cannot race\r\n * this stop and leave a zombie.\r\n */\r\nexport function unregisterRuntime(\r\n accountId: string,\r\n deadlineMs = Date.now() + 5_000,\r\n): Promise<void> {\r\n return withAccountLock(accountId, async () => {\r\n const entry = registry.get(accountId)\r\n if (!entry) return\r\n registry.delete(accountId)\r\n entry.abortController.abort()\r\n try {\r\n await entry.runtime.stop(deadlineMs)\r\n } catch (err) {\r\n entry.logger.error(\r\n { err: err instanceof Error ? err.message : String(err), accountId },\r\n 'runtime.stop threw during unregister',\r\n )\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * Return the live runtime for `accountId`, or `undefined` if none. Binding\r\n * adapters that need to send through the WS use this; a missing runtime means\r\n * the channel is not started for this account — the caller should fall back\r\n * to HTTP-only paths.\r\n */\r\nexport function getRuntime(accountId: string): AgentchatChannelRuntime | undefined {\r\n return registry.get(accountId)?.runtime\r\n}\r\n\r\n/** List every active account id. Test + introspection hook. */\r\nexport function listActiveAccounts(): string[] {\r\n return [...registry.keys()]\r\n}\r\n\r\n/** Nuke every runtime. Test hook only. */\r\nexport async function resetRegistryForTest(): Promise<void> {\r\n const entries = [...registry.entries()]\r\n registry.clear()\r\n await Promise.all(\r\n entries.map(async ([, entry]) => {\r\n try {\r\n await entry.runtime.stop(Date.now() + 500)\r\n } catch {\r\n /* test teardown — swallow */\r\n }\r\n }),\r\n )\r\n}\r\n","/**\r\n * Inbound bridge — NormalizedInbound → OpenClaw's shared inbound dispatch.\r\n *\r\n * The runtime's WS delivers typed `NormalizedInbound` events. We translate\r\n * each one into the canonical OpenClaw flow so the agent can actually\r\n * \"see\" the message: a text message triggers the reply pipeline, which\r\n * runs the agent, and the agent's reply payload comes back through our\r\n * `deliver` callback — which in turn routes back to AgentChat via the same\r\n * runtime's `sendMessage`.\r\n *\r\n * Non-text events (presence, typing, read receipts, rate-limit warnings,\r\n * group invites, group deletions) are surfaced through logs +\r\n * gateway status for now; they do NOT trigger the reply pipeline. Future\r\n * work: expose them as `system` messages the agent can subscribe to.\r\n *\r\n * Self-sends are filtered: the AgentChat server emits `message.new` for\r\n * both sides of every send, so we'd otherwise feed our own outbound back\r\n * to the agent. Detection is by handle match against the configured\r\n * `agentHandle`.\r\n */\r\n\r\nimport { dispatchInboundDirectDmWithRuntime } from 'openclaw/plugin-sdk/direct-dm'\r\nimport { resolveInboundRouteEnvelopeBuilderWithRuntime } from 'openclaw/plugin-sdk/inbound-envelope'\r\nimport { recordInboundSessionAndDispatchReply } from 'openclaw/plugin-sdk/inbound-reply-dispatch'\r\n\r\nimport type { Logger } from '../log.js'\r\nimport type { AgentchatChannelConfig } from '../config-schema.js'\r\nimport type {\r\n NormalizedInbound,\r\n NormalizedMessage,\r\n NormalizedGroupInvite,\r\n NormalizedGroupDeleted,\r\n} from '../inbound.js'\r\nimport type { AgentchatChannelRuntime } from '../runtime.js'\r\n\r\nexport interface InboundBridgeDeps {\r\n readonly accountId: string\r\n readonly config: AgentchatChannelConfig\r\n readonly logger: Logger\r\n readonly runtime: AgentchatChannelRuntime\r\n /**\r\n * OpenClaw's channelRuntime surface — exposed on `ChannelGatewayContext`.\r\n * When `undefined` (e.g. during tests or when the gateway was booted\r\n * without AI wiring) we degrade to log-only: the message is visible in\r\n * logs but no reply is generated.\r\n */\r\n readonly channelRuntime?: ChannelRuntimeLike\r\n readonly gatewayCfg: unknown\r\n readonly selfHandle?: string\r\n}\r\n\r\n/**\r\n * The runtime surface OpenClaw passes via channelRuntime. We only declare\r\n * the bits we actually call — the actual object passed at runtime is\r\n * fuller and is the same shape used by every bundled channel and tested\r\n * via openclaw/src/plugin-sdk/direct-dm.test.ts. Casting to `never` for\r\n * dispatchInboundDirectDmWithRuntime sidesteps a deep TS type-name conflict\r\n * between OpenClaw's internal cfg type and our gatewayCfg passthrough.\r\n */\r\nexport type ChannelRuntimeLike = {\r\n readonly routing?: unknown\r\n readonly session?: unknown\r\n readonly reply?: {\r\n readonly dispatchReplyWithBufferedBlockDispatcher?: (params: unknown) => Promise<unknown>\r\n readonly resolveEnvelopeFormatOptions?: unknown\r\n readonly formatAgentEnvelope?: unknown\r\n readonly finalizeInboundContext?: unknown\r\n }\r\n}\r\n\r\n/**\r\n * Return a `(NormalizedInbound) => void` handler suitable for plugging\r\n * into `ChannelRuntimeHandlers.onInbound`. Call this once per account\r\n * inside `gateway.startAccount`.\r\n */\r\nexport function createInboundBridge(deps: InboundBridgeDeps) {\r\n return async function onInbound(event: NormalizedInbound): Promise<void> {\r\n switch (event.kind) {\r\n case 'message':\r\n await handleMessage(deps, event)\r\n return\r\n case 'group-invite':\r\n handleGroupInvite(deps, event)\r\n return\r\n case 'group-deleted':\r\n handleGroupDeleted(deps, event)\r\n return\r\n case 'read-receipt':\r\n case 'typing':\r\n case 'presence':\r\n case 'rate-limit-warning':\r\n case 'unknown':\r\n // Low-signal events — surface to logs, do not trigger dispatch.\r\n deps.logger.debug({ event: event.kind }, 'inbound signal')\r\n return\r\n }\r\n }\r\n}\r\n\r\nasync function handleMessage(\r\n deps: InboundBridgeDeps,\r\n event: NormalizedMessage,\r\n): Promise<void> {\r\n const senderHandle = event.sender\r\n const selfHandle = deps.selfHandle ?? deps.config.agentHandle\r\n if (selfHandle && senderHandle === selfHandle) {\r\n // Server echoes our own send back over WS. Ignore so the agent does\r\n // not reply to itself.\r\n deps.logger.trace(\r\n { messageId: event.messageId, sender: senderHandle },\r\n 'inbound self-message — ignored',\r\n )\r\n return\r\n }\r\n\r\n const body = typeof event.content.text === 'string' ? event.content.text : ''\r\n if (!body && !event.content.attachmentId && !event.content.data) {\r\n // Empty payload — nothing meaningful to dispatch.\r\n return\r\n }\r\n\r\n const channelRuntime = deps.channelRuntime\r\n if (\r\n !channelRuntime ||\r\n typeof channelRuntime.reply?.dispatchReplyWithBufferedBlockDispatcher !== 'function'\r\n ) {\r\n // HARD degradation: gateway booted without AI wiring (e.g. tests or\r\n // a misconfigured deployment). The message reached the plugin but\r\n // there is nowhere to dispatch it to. Server-side it stays durable\r\n // — a restart with a properly-wired runtime drains it from sync.\r\n deps.logger.error(\r\n {\r\n event: 'inbound_dispatch_unavailable',\r\n messageId: event.messageId,\r\n conversationId: event.conversationId,\r\n conversationKind: event.conversationKind,\r\n sender: event.sender,\r\n },\r\n 'channelRuntime unavailable — message NOT dispatched to agent (will be redelivered on next sync)',\r\n )\r\n return\r\n }\r\n\r\n const recipientHandle = selfHandle ?? 'me'\r\n const conversationLabel =\r\n event.conversationKind === 'group'\r\n ? `group ${event.conversationId}`\r\n : `dm with @${senderHandle}`\r\n const sendReply = async (replyText: string): Promise<void> => {\r\n if (!replyText) return\r\n const target =\r\n event.conversationKind === 'group'\r\n ? { kind: 'group' as const, conversationId: event.conversationId }\r\n : { kind: 'direct' as const, to: senderHandle }\r\n await deps.runtime.sendMessage({\r\n ...target,\r\n type: 'text',\r\n content: { text: replyText },\r\n metadata: { reply_to: event.messageId },\r\n })\r\n }\r\n const deliver = async (payload: { text?: string; blocks?: unknown[] }) => {\r\n const replyText = payload.text ?? extractText(payload.blocks)\r\n await sendReply(replyText)\r\n }\r\n\r\n try {\r\n if (event.conversationKind === 'direct') {\r\n // Direct DM path — use OpenClaw's canonical helper which chains:\r\n // 1. resolveAgentRoute (assigns sessionKey, agentId)\r\n // 2. buildEnvelope (formats body with sender label)\r\n // 3. finalizeInboundContext (PascalCase ctx with all required fields)\r\n // 4. recordInboundSession (opens the session — was missing in 0.6.13)\r\n // 5. dispatchReply... (runs the LLM)\r\n // We call the helper instead of dispatcher directly because skipping\r\n // step 4 leaves the session in `sessionId=unknown state=processing`\r\n // forever, and the health monitor restarts the WS, killing the in-\r\n // flight message. See the diagnostic line:\r\n // stuck session: sessionId=unknown sessionKey=agentchat:default:dm:X\r\n // Cast cfg + runtime to `never` because OpenClaw's internal\r\n // OpenClawConfig type is not part of the public plugin-sdk surface,\r\n // and our gatewayCfg is a passthrough of the same object; the runtime\r\n // shape matches openclaw/src/plugin-sdk/direct-dm.test.ts mocks.\r\n await dispatchInboundDirectDmWithRuntime({\r\n cfg: deps.gatewayCfg as never,\r\n runtime: { channel: channelRuntime } as never,\r\n channel: 'agentchat',\r\n channelLabel: 'AgentChat',\r\n accountId: deps.accountId,\r\n peer: { kind: 'direct', id: senderHandle },\r\n senderId: senderHandle,\r\n senderAddress: `@${senderHandle}`,\r\n recipientAddress: `@${recipientHandle}`,\r\n conversationLabel,\r\n rawBody: body,\r\n messageId: event.messageId,\r\n timestamp:\r\n typeof event.createdAt === 'number' ? event.createdAt : Date.parse(event.createdAt),\r\n provider: 'agentchat',\r\n surface: 'agentchat',\r\n deliver,\r\n onRecordError: (err: unknown) => {\r\n deps.logger.error(\r\n { err: err instanceof Error ? err.message : String(err), messageId: event.messageId },\r\n 'recordInboundSession failed',\r\n )\r\n },\r\n onDispatchError: (err: unknown, info: { kind: string }) => {\r\n deps.logger.error(\r\n {\r\n err: err instanceof Error ? err.message : String(err),\r\n messageId: event.messageId,\r\n kind: info.kind,\r\n },\r\n 'inbound dispatch failed',\r\n )\r\n },\r\n })\r\n } else {\r\n // Group path — no `dispatchInboundGroup*` wrapper exists in\r\n // plugin-sdk yet, so we assemble the same pipeline inline using the\r\n // generic helpers that the direct-DM wrapper itself uses internally:\r\n //\r\n // resolveInboundRouteEnvelopeBuilderWithRuntime (plugin-sdk)\r\n // reply.finalizeInboundContext (channelRuntime)\r\n // recordInboundSessionAndDispatchReply (plugin-sdk)\r\n //\r\n // This is byte-equivalent to `dispatchInboundDirectDmWithRuntime`'s\r\n // body — see openclaw/dist/direct-dm-*.js — only `peer.kind` and\r\n // `ChatType` differ. Critically: this path NOW calls\r\n // recordInboundSession before dispatch, so groups can no longer\r\n // hit the `sessionId=unknown state=processing` stuck-session bug\r\n // that broke direct DMs in 0.6.13 and that this fix closes for\r\n // groups in 0.6.17.\r\n const ts =\r\n typeof event.createdAt === 'number'\r\n ? event.createdAt\r\n : Date.parse(event.createdAt)\r\n const runtime = channelRuntime as never\r\n const { route, buildEnvelope } = resolveInboundRouteEnvelopeBuilderWithRuntime({\r\n cfg: deps.gatewayCfg as never,\r\n channel: 'agentchat',\r\n accountId: deps.accountId,\r\n peer: { kind: 'group', id: event.conversationId },\r\n runtime,\r\n })\r\n const { storePath, body: envelopeBody } = buildEnvelope({\r\n channel: 'AgentChat',\r\n from: conversationLabel,\r\n body,\r\n timestamp: ts,\r\n })\r\n const finalize = (channelRuntime.reply as { finalizeInboundContext: (c: Record<string, unknown>) => Record<string, unknown> }).finalizeInboundContext\r\n const ctxPayload = finalize({\r\n Body: envelopeBody,\r\n BodyForAgent: body,\r\n RawBody: body,\r\n CommandBody: body,\r\n From: `@${senderHandle}`,\r\n To: `@${recipientHandle}`,\r\n SessionKey: route.sessionKey,\r\n AccountId: deps.accountId,\r\n ChatType: 'group',\r\n ConversationLabel: conversationLabel,\r\n SenderId: senderHandle,\r\n Provider: 'agentchat',\r\n Surface: 'agentchat',\r\n MessageSid: event.messageId,\r\n MessageSidFull: event.messageId,\r\n Timestamp: ts,\r\n OriginatingChannel: 'agentchat',\r\n OriginatingTo: `@${recipientHandle}`,\r\n })\r\n const session = channelRuntime.session as { recordInboundSession: never }\r\n await recordInboundSessionAndDispatchReply({\r\n cfg: deps.gatewayCfg as never,\r\n channel: 'agentchat',\r\n accountId: deps.accountId,\r\n agentId: route.agentId,\r\n routeSessionKey: route.sessionKey,\r\n storePath,\r\n ctxPayload: ctxPayload as never,\r\n recordInboundSession: session.recordInboundSession,\r\n dispatchReplyWithBufferedBlockDispatcher: channelRuntime.reply!\r\n .dispatchReplyWithBufferedBlockDispatcher! as never,\r\n deliver,\r\n onRecordError: (err: unknown) => {\r\n deps.logger.error(\r\n { err: err instanceof Error ? err.message : String(err), messageId: event.messageId },\r\n 'recordInboundSession failed (group)',\r\n )\r\n },\r\n onDispatchError: (err: unknown, info: { kind: string }) => {\r\n deps.logger.error(\r\n {\r\n err: err instanceof Error ? err.message : String(err),\r\n messageId: event.messageId,\r\n kind: info.kind,\r\n },\r\n 'inbound dispatch failed (group)',\r\n )\r\n },\r\n })\r\n }\r\n } catch (err) {\r\n deps.logger.error(\r\n {\r\n err: err instanceof Error ? err.message : String(err),\r\n messageId: event.messageId,\r\n },\r\n 'inbound dispatch failed',\r\n )\r\n }\r\n}\r\n\r\nfunction handleGroupInvite(deps: InboundBridgeDeps, event: NormalizedGroupInvite): void {\r\n deps.logger.info(\r\n {\r\n event: 'group-invite',\r\n groupId: event.groupId,\r\n inviterHandle: event.inviterHandle,\r\n groupName: event.groupName,\r\n },\r\n 'received group invite',\r\n )\r\n}\r\n\r\nfunction handleGroupDeleted(deps: InboundBridgeDeps, event: NormalizedGroupDeleted): void {\r\n deps.logger.warn(\r\n {\r\n event: 'group-deleted',\r\n groupId: event.groupId,\r\n deletedBy: event.deletedByHandle,\r\n },\r\n 'group was deleted',\r\n )\r\n}\r\n\r\nfunction extractText(blocks: unknown[] | undefined): string {\r\n if (!Array.isArray(blocks)) return ''\r\n const parts: string[] = []\r\n for (const block of blocks) {\r\n if (block && typeof block === 'object' && 'text' in block) {\r\n const text = (block as { text: unknown }).text\r\n if (typeof text === 'string') parts.push(text)\r\n }\r\n }\r\n return parts.join('\\n\\n').trim()\r\n}\r\n","/**\r\n * ChannelGatewayAdapter — start/stop the runtime per account.\r\n *\r\n * This is where the plugin actually becomes functional. OpenClaw calls\r\n * `startAccount` when a configured account is enabled; we spin up an\r\n * `AgentchatChannelRuntime`, wire the inbound bridge, and keep it alive\r\n * until `stopAccount` (or the ctx abort signal) fires.\r\n *\r\n * Inbound flow:\r\n * WS frame → runtime.normalizeInbound → bridge.onInbound\r\n * → OpenClaw dispatch → agent reply → runtime.sendMessage\r\n *\r\n * Outbound flow:\r\n * OpenClaw.sendText → binding/outbound.ts → runtime.sendMessage\r\n * (the outbound adapter lazy-starts the runtime if the agent calls\r\n * sendText before startAccount has fired — e.g. from a cron one-shot)\r\n *\r\n * The runtime is registered in `runtime-registry.ts` so the outbound +\r\n * actions + tool paths can look it up by accountId.\r\n */\r\n\r\nimport type {\r\n ChannelGatewayAdapter,\r\n ChannelGatewayContext,\r\n} from './openclaw-types.js'\r\n\r\nimport { waitUntilAbort } from 'openclaw/plugin-sdk/channel-lifecycle'\r\n\r\nimport type { AgentchatResolvedAccount } from '../channel.js'\r\nimport { createLogger, type Logger } from '../log.js'\r\nimport {\r\n registerRuntime,\r\n unregisterRuntime,\r\n getRuntime,\r\n} from './runtime-registry.js'\r\nimport {\r\n createInboundBridge,\r\n type ChannelRuntimeLike,\r\n} from './inbound-bridge.js'\r\n\r\nfunction adaptLog(log: ChannelGatewayContext['log']): Logger | undefined {\r\n if (!log) return undefined\r\n return {\r\n trace: (obj, msg) => log.debug?.(formatLogLine(obj, msg)),\r\n debug: (obj, msg) => log.debug?.(formatLogLine(obj, msg)),\r\n info: (obj, msg) => log.info(formatLogLine(obj, msg)),\r\n warn: (obj, msg) => log.warn(formatLogLine(obj, msg)),\r\n error: (obj, msg) => log.error(formatLogLine(obj, msg)),\r\n child: () => adaptLog(log)!,\r\n }\r\n}\r\n\r\nfunction formatLogLine(obj: object, msg?: string): string {\r\n const head = msg ?? ''\r\n const keys = Object.keys(obj)\r\n if (keys.length === 0) return head\r\n const tail = keys\r\n .map((k) => {\r\n const val = (obj as Record<string, unknown>)[k]\r\n return `${k}=${typeof val === 'string' ? val : JSON.stringify(val)}`\r\n })\r\n .join(' ')\r\n return head ? `${head} ${tail}` : tail\r\n}\r\n\r\nexport const agentchatGatewayAdapter: ChannelGatewayAdapter<AgentchatResolvedAccount> = {\r\n async startAccount(ctx) {\r\n const account = ctx.account\r\n if (!account.enabled) {\r\n ctx.log?.info?.(`[agentchat:${ctx.accountId}] account disabled — skipping start`)\r\n return\r\n }\r\n if (!account.configured || !account.config) {\r\n ctx.log?.warn?.(\r\n `[agentchat:${ctx.accountId}] account not configured — skipping start`,\r\n )\r\n return\r\n }\r\n\r\n const logger =\r\n adaptLog(ctx.log) ??\r\n createLogger({\r\n level: account.config.observability.logLevel,\r\n redactKeys: account.config.observability.redactKeys,\r\n })\r\n\r\n // Runtime and bridge wiring form a small chicken-and-egg: the bridge\r\n // handler closes over the runtime (for reply dispatch), and the runtime\r\n // closes over the bridge (as its `onInbound` handler). We solve it with\r\n // one mutable ref for the runtime, closed over by a single bridge\r\n // handler that's constructed once — reused per event, not allocated.\r\n let runtimeRef: Awaited<ReturnType<typeof registerRuntime>> | null = null\r\n let inboundHandler: ReturnType<typeof createInboundBridge> | null = null\r\n const bridge = (event: unknown) => {\r\n if (!runtimeRef || !inboundHandler) return\r\n void inboundHandler(event as Parameters<ReturnType<typeof createInboundBridge>>[0])\r\n }\r\n\r\n runtimeRef = await registerRuntime({\r\n accountId: ctx.accountId,\r\n config: account.config,\r\n logger,\r\n handlers: {\r\n onInbound: bridge,\r\n // `runtime` used below is captured AFTER registerRuntime resolves,\r\n // but the handler is never invoked before that — the WS has to\r\n // authenticate first. Safe to assign synchronously just after.\r\n\r\n onAuthenticated: (at) => {\r\n ctx.log?.info?.(`[agentchat:${ctx.accountId}] authenticated at ${new Date(at).toISOString()}`)\r\n ctx.setStatus({\r\n ...ctx.getStatus(),\r\n running: true,\r\n connected: true,\r\n linked: true,\r\n lastConnectedAt: at,\r\n })\r\n },\r\n onError: (err) => {\r\n ctx.log?.warn?.(\r\n `[agentchat:${ctx.accountId}] runtime error: ${err.message} (class=${err.class_})`,\r\n )\r\n },\r\n onStateChanged: (next) => {\r\n const running = next.kind !== 'CLOSED' && next.kind !== 'AUTH_FAIL'\r\n const connected = next.kind === 'READY' || next.kind === 'DEGRADED'\r\n ctx.setStatus({\r\n ...ctx.getStatus(),\r\n running,\r\n connected,\r\n healthState: next.kind,\r\n })\r\n },\r\n onBacklogWarning: (warning) => {\r\n ctx.log?.warn?.(\r\n `[agentchat:${ctx.accountId}] recipient backlog warning: @${warning.recipientHandle} has ${warning.undeliveredCount} undelivered`,\r\n )\r\n },\r\n },\r\n })\r\n\r\n // Construct the per-event inbound handler ONCE now that `runtimeRef`\r\n // is populated. Reusing it avoids allocating a fresh closure per\r\n // inbound frame — at multi-hundred-msg/sec this matters.\r\n inboundHandler = createInboundBridge({\r\n accountId: ctx.accountId,\r\n config: account.config,\r\n logger,\r\n runtime: runtimeRef,\r\n channelRuntime: ctx.channelRuntime as ChannelRuntimeLike | undefined,\r\n gatewayCfg: ctx.cfg,\r\n selfHandle: account.config.agentHandle,\r\n })\r\n\r\n // Keep the channel task pending until OpenClaw aborts. Without this,\r\n // startAccount resolves immediately after wiring the runtime — and\r\n // OpenClaw's task-runner (server-channels.ts:475 \"channel exited\")\r\n // treats the resolved promise as a graceful exit and triggers\r\n // auto-restart with backoff. Each restart calls registerRuntime,\r\n // which stops the existing runtime first (DRAIN_REQUESTED), draining\r\n // the WebSocket and killing in-flight inbound dispatches before the\r\n // LLM can complete. The result is the flap loop we observed:\r\n // READY → DRAINING → CONNECTING → AUTHENTICATING → READY → DRAINING\r\n // every 1-3 minutes, with auto-restart attempt counter ticking up\r\n // until OpenClaw gives up after 10 attempts.\r\n //\r\n // waitUntilAbort is the canonical OpenClaw plugin-sdk lifecycle\r\n // helper — see openclaw/src/plugin-sdk/channel-lifecycle.core.ts:30\r\n // and the runPassiveAccountLifecycle pattern used by IRC, Google\r\n // Chat, etc. The onAbort callback runs (and is awaited) before the\r\n // promise resolves, so our cleanup happens fully before OpenClaw\r\n // sees the task complete — no stop/start race.\r\n await waitUntilAbort(ctx.abortSignal, async () => {\r\n try {\r\n await unregisterRuntime(ctx.accountId, Date.now() + 5_000)\r\n } catch (err) {\r\n ctx.log?.error?.(\r\n `[agentchat:${ctx.accountId}] unregisterRuntime failed on abort: ${err instanceof Error ? err.message : String(err)}`,\r\n )\r\n }\r\n })\r\n },\r\n\r\n async stopAccount(ctx) {\r\n await unregisterRuntime(ctx.accountId, Date.now() + 5_000)\r\n ctx.setStatus({\r\n ...ctx.getStatus(),\r\n running: false,\r\n connected: false,\r\n })\r\n },\r\n}\r\n\r\nexport { getRuntime }\r\n","/**\r\n * Cached AgentChatClient-per-account wrapper.\r\n *\r\n * Every binding adapter that needs to call the REST API (actions, agentTools,\r\n * directory, resolver, status) goes through this module so we don't spin up a\r\n * new HTTP client on every call and so swap-on-rotate works uniformly.\r\n *\r\n * Keyed by `accountId`. On a key rotation the caller invalidates via\r\n * `disposeClient(accountId)` and the next `getClient` constructs a fresh one.\r\n */\r\n\r\nimport { AgentChatClient, type AgentChatClientOptions } from 'agentchatme'\r\n\r\nimport type { AgentchatChannelConfig } from '../config-schema.js'\r\nimport { PACKAGE_VERSION } from '../version.js'\r\n\r\ninterface CacheEntry {\r\n readonly client: AgentChatClient\r\n readonly apiKey: string\r\n readonly apiBase: string\r\n}\r\n\r\nconst cache = new Map<string, CacheEntry>()\r\n\r\nexport interface GetClientParams {\r\n readonly accountId: string\r\n readonly config: AgentchatChannelConfig\r\n readonly options?: Partial<AgentChatClientOptions>\r\n}\r\n\r\n/**\r\n * Return a shared `AgentChatClient` for `accountId`, reusing the cached\r\n * instance unless the apiKey or apiBase changed (implicit invalidation on\r\n * silent config drift — better than a stale key surviving a rotation).\r\n */\r\nexport function getClient({ accountId, config, options }: GetClientParams): AgentChatClient {\r\n const existing = cache.get(accountId)\r\n if (existing && existing.apiKey === config.apiKey && existing.apiBase === config.apiBase) {\r\n return existing.client\r\n }\r\n\r\n const client = new AgentChatClient({\r\n apiKey: config.apiKey,\r\n baseUrl: config.apiBase,\r\n ...options,\r\n })\r\n void PACKAGE_VERSION // reserved for a future X-AgentChat-Plugin-Version header\r\n\r\n cache.set(accountId, {\r\n client,\r\n apiKey: config.apiKey,\r\n apiBase: config.apiBase,\r\n })\r\n return client\r\n}\r\n\r\n/** Drop the cached client for `accountId` — e.g. after a key rotation. */\r\nexport function disposeClient(accountId: string): void {\r\n cache.delete(accountId)\r\n}\r\n\r\n/** Clear the entire cache. Test hook only. */\r\nexport function resetClientCacheForTest(): void {\r\n cache.clear()\r\n}\r\n","/**\r\n * ChannelOutboundAdapter — OpenClaw send → AgentChat.\r\n *\r\n * `deliveryMode: 'direct'` — we own the HTTP call stack; OpenClaw hands us\r\n * a `to` + `text` (+ optional media) and we translate that into the same\r\n * `OutboundMessageInput` our internal runtime already knows how to ship.\r\n *\r\n * Routing rule:\r\n * - `to` starts with `grp_` → group message (conversationId = to)\r\n * - anything else → direct message to the handle\r\n * (Target normalization already stripped `@` — see binding/messaging.ts.)\r\n *\r\n * Reply + media:\r\n * - `replyToId` is passed through as `metadata.reply_to` so the server\r\n * threads it correctly in both direct and group conversations.\r\n * - `sendMedia` runs `createUpload` + `PUT` against the presigned URL\r\n * first, then sends a `type: \"file\"` message carrying the\r\n * `attachment_id`. The bytes never pass through OpenClaw.\r\n */\r\n\r\nimport type {\r\n ChannelOutboundAdapter,\r\n OutboundDeliveryResult,\r\n OpenClawConfig,\r\n} from './openclaw-types.js'\r\n\r\n// ChannelOutboundContext is the argument shape for send* calls — we only\r\n// read the fields we need (cfg, accountId, to, text, replyToId, mediaUrl,\r\n// mediaReadFile), so a loose local alias keeps this portable across minor\r\n// SDK revisions that tweak optional fields.\r\ntype SendCtx = {\r\n cfg: OpenClawConfig\r\n to: string\r\n text: string\r\n mediaUrl?: string\r\n replyToId?: string | null\r\n accountId?: string | null\r\n mediaReadFile?: (path: string) => Promise<Buffer>\r\n}\r\n\r\nimport type { OutboundMessageInput } from '../outbound.js'\r\nimport { AGENTCHAT_CHANNEL_ID } from '../channel-account.js'\r\nimport { classifyConversationId } from '../inbound.js'\r\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\r\nimport { parseChannelConfig } from '../config-schema.js'\r\nimport { AgentChatChannelError } from '../errors.js'\r\nimport { registerRuntime, getRuntime } from './runtime-registry.js'\r\nimport { getClient } from './sdk-client.js'\r\nimport { createLogger } from '../log.js'\r\n\r\nfunction resolveConfig(cfg: OpenClawConfig | undefined, accountId?: string | null) {\r\n const section = readChannelSection(cfg)\r\n const raw = readAccountRaw(section, accountId ?? 'default')\r\n if (!raw) return null\r\n try {\r\n return parseChannelConfig(raw)\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\n/**\r\n * Ensure we have a live runtime for this account. When OpenClaw delivers\r\n * the first outbound before `gateway.startAccount` has fired — or calls\r\n * `sendText` outside of an active gateway session (e.g. from a CLI one-shot\r\n * send) — we lazily spin one up. `getRuntime` returns `undefined` until\r\n * the gateway registers one.\r\n */\r\nasync function ensureRuntime(accountId: string, cfg: OpenClawConfig | undefined) {\r\n const existing = getRuntime(accountId)\r\n if (existing) return existing\r\n const config = resolveConfig(cfg, accountId)\r\n if (!config) {\r\n throw new Error(\r\n `[agentchat:${accountId}] cannot send — channels.agentchat config is missing or invalid`,\r\n )\r\n }\r\n const logger = createLogger({\r\n level: config.observability.logLevel,\r\n redactKeys: config.observability.redactKeys,\r\n })\r\n return registerRuntime({ accountId, config, logger, handlers: {} })\r\n}\r\n\r\nfunction buildInputForTarget(\r\n to: string,\r\n text: string | undefined,\r\n replyToId: string | null | undefined,\r\n attachmentId?: string,\r\n): OutboundMessageInput {\r\n const metadata = replyToId ? { reply_to: replyToId } : undefined\r\n const content: OutboundMessageInput['content'] = {\r\n ...(text !== undefined && text.length > 0 ? { text } : {}),\r\n ...(attachmentId ? { attachmentId } : {}),\r\n }\r\n\r\n const kind: 'direct' | 'group' =\r\n classifyConversationId(to) === 'group' ? 'group' : 'direct'\r\n\r\n if (kind === 'group') {\r\n return {\r\n kind: 'group',\r\n conversationId: to,\r\n type: attachmentId ? 'file' : 'text',\r\n content,\r\n ...(metadata ? { metadata } : {}),\r\n }\r\n }\r\n return {\r\n kind: 'direct',\r\n to,\r\n type: attachmentId ? 'file' : 'text',\r\n content,\r\n ...(metadata ? { metadata } : {}),\r\n }\r\n}\r\n\r\nasync function deliver(\r\n ctx: SendCtx,\r\n attachmentId?: string,\r\n): Promise<OutboundDeliveryResult> {\r\n const accountId = ctx.accountId ?? 'default'\r\n const runtime = await ensureRuntime(accountId, ctx.cfg)\r\n const input = buildInputForTarget(\r\n ctx.to,\r\n ctx.text,\r\n ctx.replyToId,\r\n attachmentId,\r\n )\r\n const result = await runtime.sendMessage(input)\r\n return {\r\n channel: AGENTCHAT_CHANNEL_ID,\r\n messageId: result.message.id,\r\n conversationId: result.message.conversation_id,\r\n timestamp: Date.parse(result.message.created_at),\r\n meta: {\r\n attempts: result.attempts,\r\n idempotentReplay: result.idempotentReplay,\r\n requestId: result.requestId ?? undefined,\r\n },\r\n }\r\n}\r\n\r\n/**\r\n * SSRF-safe remote media fetch.\r\n *\r\n * An agent supplies the `mediaUrl`. Without guardrails, a malicious or\r\n * compromised agent could point us at `http://169.254.169.254/...` (AWS\r\n * IMDS), `http://localhost`, or an internal service to exfiltrate creds\r\n * or probe the local network. We enforce:\r\n * - HTTPS only (HTTP allowed only against localhost for dev tests).\r\n * - Host must not resolve to a private/loopback/link-local address.\r\n * - 30-second hard timeout on the fetch itself.\r\n * - 25 MB response-size ceiling (matches the server's attachment cap).\r\n *\r\n * The block list is intentionally literal-string based on `URL.hostname`.\r\n * We do NOT DNS-resolve first and re-validate — that would open a TOCTOU\r\n * window where the resolver returns public then private. Callers who\r\n * need self-hosted media should upload via the direct SDK path.\r\n */\r\nconst PRIVATE_HOST_PATTERNS = [\r\n /^localhost$/i,\r\n /^127(\\.\\d{1,3}){3}$/,\r\n /^10(\\.\\d{1,3}){3}$/,\r\n /^192\\.168(\\.\\d{1,3}){2}$/,\r\n /^172\\.(1[6-9]|2\\d|3[01])(\\.\\d{1,3}){2}$/,\r\n /^169\\.254(\\.\\d{1,3}){2}$/,\r\n /^::1$/,\r\n /^fc00:/i,\r\n /^fd/i,\r\n /^fe80:/i,\r\n /^\\[::1\\]$/,\r\n] as const\r\n\r\nconst MAX_MEDIA_BYTES = 25 * 1024 * 1024\r\nconst MEDIA_FETCH_TIMEOUT_MS = 30_000\r\n\r\nfunction assertMediaUrlSafe(urlStr: string): URL {\r\n let url: URL\r\n try {\r\n url = new URL(urlStr)\r\n } catch {\r\n throw new AgentChatChannelError(\r\n 'terminal-user',\r\n `mediaUrl is not a valid URL: ${urlStr}`,\r\n )\r\n }\r\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\r\n throw new AgentChatChannelError(\r\n 'terminal-user',\r\n `mediaUrl protocol must be http(s): ${url.protocol}`,\r\n )\r\n }\r\n // Node's WHATWG URL parser preserves brackets around IPv6 literals on\r\n // `hostname` (e.g. `'[fe80::1]'`). Strip them before pattern-matching so\r\n // the IPv6 regex entries below actually get a chance to fire.\r\n const hostRaw = url.hostname.toLowerCase()\r\n const host =\r\n hostRaw.startsWith('[') && hostRaw.endsWith(']') ? hostRaw.slice(1, -1) : hostRaw\r\n for (const pattern of PRIVATE_HOST_PATTERNS) {\r\n if (pattern.test(host)) {\r\n throw new AgentChatChannelError(\r\n 'terminal-user',\r\n `mediaUrl host is private or loopback: ${host}`,\r\n )\r\n }\r\n }\r\n return url\r\n}\r\n\r\nasync function uploadMediaFromUrl(\r\n ctx: SendCtx,\r\n mediaUrl: string,\r\n): Promise<string> {\r\n const accountId = ctx.accountId ?? 'default'\r\n const config = resolveConfig(ctx.cfg, accountId)\r\n if (!config) {\r\n throw new AgentChatChannelError(\r\n 'terminal-user',\r\n `[agentchat:${accountId}] cannot upload media — config missing/invalid`,\r\n )\r\n }\r\n const client = getClient({ accountId, config })\r\n\r\n // Pull the bytes, regardless of whether the gateway handed us a file URL,\r\n // a data URL, or a remote HTTPS URL. The runtime's media-access helpers\r\n // already do this for bundled channels; we replicate the minimal piece we\r\n // need here to stay portable. Remote URLs go through SSRF validation.\r\n let bytes: ArrayBuffer\r\n let contentType: string | undefined\r\n let filename = 'attachment'\r\n if (mediaUrl.startsWith('file://') && ctx.mediaReadFile) {\r\n const path = decodeURIComponent(mediaUrl.replace(/^file:\\/\\//, ''))\r\n const buf = await ctx.mediaReadFile(path)\r\n if (buf.byteLength > MAX_MEDIA_BYTES) {\r\n throw new AgentChatChannelError(\r\n 'terminal-user',\r\n `media exceeds ${MAX_MEDIA_BYTES} bytes: ${buf.byteLength}`,\r\n )\r\n }\r\n // Copy into a fresh ArrayBuffer so fetch's BodyInit is happy on all\r\n // runtimes (Node 20's fetch is stricter than browsers about shared\r\n // buffer typings).\r\n const copy = new Uint8Array(buf.byteLength)\r\n copy.set(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength))\r\n bytes = copy.buffer\r\n filename = path.split(/[\\\\/]/).pop() ?? filename\r\n } else {\r\n assertMediaUrlSafe(mediaUrl)\r\n const controller = new AbortController()\r\n const timer = setTimeout(() => controller.abort(), MEDIA_FETCH_TIMEOUT_MS)\r\n let res: Response\r\n try {\r\n res = await fetch(mediaUrl, { signal: controller.signal, redirect: 'error' })\r\n } catch (err) {\r\n clearTimeout(timer)\r\n throw new AgentChatChannelError(\r\n 'retry-transient',\r\n `could not fetch media: ${err instanceof Error ? err.message : String(err)}`,\r\n { cause: err },\r\n )\r\n }\r\n clearTimeout(timer)\r\n if (!res.ok) {\r\n throw new AgentChatChannelError(\r\n res.status >= 500 ? 'retry-transient' : 'terminal-user',\r\n `could not fetch media: ${res.status} ${res.statusText}`,\r\n { statusCode: res.status },\r\n )\r\n }\r\n const declaredSize = Number(res.headers.get('content-length') ?? NaN)\r\n if (Number.isFinite(declaredSize) && declaredSize > MAX_MEDIA_BYTES) {\r\n throw new AgentChatChannelError(\r\n 'terminal-user',\r\n `media content-length exceeds cap: ${declaredSize}`,\r\n )\r\n }\r\n bytes = await res.arrayBuffer()\r\n if (bytes.byteLength > MAX_MEDIA_BYTES) {\r\n throw new AgentChatChannelError(\r\n 'terminal-user',\r\n `media body exceeds cap after fetch: ${bytes.byteLength}`,\r\n )\r\n }\r\n contentType = res.headers.get('content-type') ?? undefined\r\n const cd = res.headers.get('content-disposition')\r\n const nameMatch = cd ? /filename=\"?([^\";]+)\"?/.exec(cd) : null\r\n if (nameMatch && nameMatch[1]) filename = nameMatch[1]\r\n }\r\n\r\n // The AgentChat API restricts `content_type` to a narrow allowlist\r\n // (image/png, image/jpeg, application/pdf, …). When the remote server\r\n // didn't advertise a type, or advertised one outside the allowlist, we\r\n // fall back to `application/octet-stream` and let the server reject if\r\n // the policy has tightened. Typed as `string` on the wire.\r\n const mimeType: string = (() => {\r\n if (!contentType || contentType.length === 0) return 'application/octet-stream'\r\n const head = contentType.split(';')[0]\r\n return head ? head.trim() : 'application/octet-stream'\r\n })()\r\n\r\n // sha256 digest (Web Crypto is available in Node 20+).\r\n const hashBuf = await crypto.subtle.digest('SHA-256', bytes)\r\n const sha256 = Array.from(new Uint8Array(hashBuf))\r\n .map((b) => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n\r\n const reservation = await client.createUpload({\r\n to: ctx.to,\r\n filename,\r\n content_type: mimeType as Parameters<typeof client.createUpload>[0]['content_type'],\r\n size: bytes.byteLength,\r\n sha256,\r\n })\r\n\r\n const putController = new AbortController()\r\n const putTimer = setTimeout(() => putController.abort(), MEDIA_FETCH_TIMEOUT_MS)\r\n let putRes: Response\r\n try {\r\n putRes = await fetch(reservation.upload_url, {\r\n method: 'PUT',\r\n headers: { 'content-type': mimeType },\r\n body: bytes,\r\n signal: putController.signal,\r\n })\r\n } catch (err) {\r\n clearTimeout(putTimer)\r\n throw new AgentChatChannelError(\r\n 'retry-transient',\r\n `attachment PUT failed: ${err instanceof Error ? err.message : String(err)}`,\r\n { cause: err },\r\n )\r\n }\r\n clearTimeout(putTimer)\r\n if (!putRes.ok) {\r\n throw new AgentChatChannelError(\r\n putRes.status >= 500 ? 'retry-transient' : 'terminal-user',\r\n `attachment PUT failed: ${putRes.status} ${putRes.statusText}`,\r\n { statusCode: putRes.status },\r\n )\r\n }\r\n\r\n return reservation.attachment_id\r\n}\r\n\r\nexport const agentchatOutboundAdapter: ChannelOutboundAdapter = {\r\n deliveryMode: 'direct',\r\n\r\n async sendText(ctx) {\r\n return deliver(ctx)\r\n },\r\n\r\n async sendMedia(ctx) {\r\n if (!ctx.mediaUrl) {\r\n throw new AgentChatChannelError(\r\n 'terminal-user',\r\n '[agentchat] sendMedia called without mediaUrl',\r\n )\r\n }\r\n const attachmentId = await uploadMediaFromUrl(ctx, ctx.mediaUrl)\r\n return deliver(ctx, attachmentId)\r\n },\r\n\r\n async sendFormattedText(ctx) {\r\n return [await deliver(ctx)]\r\n },\r\n}\r\n","/**\r\n * ChannelMessagingAdapter — target parsing + conversation routing.\r\n *\r\n * Two jobs:\r\n * 1. Normalize agent-supplied target strings (\"@alice\", \"alice\",\r\n * \"conv_abc\", \"grp_xyz\") into a canonical form the rest of the pipeline\r\n * can rely on.\r\n * 2. Classify conversation ids (`conv_*`/`dir_*` = direct, `grp_*` = group)\r\n * so outbound + actions can route without re-parsing prefixes.\r\n *\r\n * We deliberately do NOT do directory lookups here — the resolver adapter\r\n * owns that. Messaging stays syntactic; resolver stays semantic.\r\n */\r\n\r\nimport type { ChannelMessagingAdapter } from './openclaw-types.js'\r\n\r\nimport { classifyConversationId, type ConversationKind } from '../inbound.js'\r\n\r\n/**\r\n * Canonicalize a target string.\r\n *\r\n * \"@alice\" → \"alice\"\r\n * \"Alice\" → \"alice\"\r\n * \" alice \" → \"alice\"\r\n * \"conv_abc\" → \"conv_abc\" (passthrough — looks like an id)\r\n * \"grp_xyz\" → \"grp_xyz\" (passthrough)\r\n * \"\" → undefined (callers treat this as \"no target\")\r\n *\r\n * Returns `undefined` for anything that's empty after trim so downstream\r\n * doesn't have to `if (!trimmed)` everywhere.\r\n */\r\nexport function normalizeAgentchatTarget(raw: string): string | undefined {\r\n const trimmed = raw.trim()\r\n if (trimmed.length === 0) return undefined\r\n // Conversation ids already look canonical — leave them alone.\r\n if (classifyConversationId(trimmed) !== null) return trimmed\r\n // Strip the leading \"@\" agents often copy from the skill / UI.\r\n const stripped = trimmed.startsWith('@') ? trimmed.slice(1) : trimmed\r\n return stripped.toLowerCase()\r\n}\r\n\r\n/**\r\n * Infer chat type from a raw target. Returns `undefined` when ambiguous\r\n * (bare handle). Core only uses this hint to steer directory lookup so\r\n * ambiguity is safe — it will fall through to the full resolver.\r\n */\r\nexport function inferAgentchatTargetChatType(raw: string): 'direct' | 'group' | undefined {\r\n const trimmed = raw.trim()\r\n const kind: ConversationKind | null = classifyConversationId(trimmed)\r\n if (kind === 'direct') return 'direct'\r\n if (kind === 'group') return 'group'\r\n return undefined\r\n}\r\n\r\nexport const agentchatMessagingAdapter: ChannelMessagingAdapter = {\r\n normalizeTarget: normalizeAgentchatTarget,\r\n inferTargetChatType: ({ to }) => inferAgentchatTargetChatType(to),\r\n}\r\n","/**\r\n * ChannelMessageActionAdapter — wires OpenClaw's shared `message` tool\r\n * actions to AgentChat SDK calls.\r\n *\r\n * OpenClaw defines a fixed vocabulary of message-tool actions\r\n * (`CHANNEL_MESSAGE_ACTION_NAMES`). Each one we `supportsAction` for is\r\n * exposed on the `message` tool that the agent sees. When the agent picks\r\n * an action + target, OpenClaw calls our `handleAction` which runs the\r\n * AgentChat operation and returns a text result.\r\n *\r\n * Actions we implement (everything the AgentChat platform natively\r\n * supports; everything else is a no-op):\r\n * - read / unsend / delete / reply → message-level ops\r\n * - renameGroup / setGroupIcon → group metadata\r\n * - addParticipant / removeParticipant / leaveGroup → group membership\r\n * - set-presence / set-profile → own-identity edits\r\n * - search → directory prefix lookup\r\n * - member-info → peer profile lookup\r\n * - channel-list / channel-info → conversation listings\r\n * - download-file / upload-file → attachment I/O\r\n *\r\n * Tool results use OpenClaw's `AgentToolResult` shape:\r\n * { content: [{ type: \"text\", text: \"...\" }] }\r\n *\r\n * Errors surface as `AgentChatChannelError` classes so the shared\r\n * retry/backoff layer up-stack can decide whether to retry.\r\n */\r\n\r\nimport type {\r\n ChannelMessageActionAdapter,\r\n ChannelMessageActionContext,\r\n ChannelMessageActionName,\r\n ChannelMessageToolDiscovery,\r\n} from './openclaw-types.js'\r\n\r\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\r\nimport { parseChannelConfig } from '../config-schema.js'\r\nimport { getClient } from './sdk-client.js'\r\n\r\nconst SUPPORTED_ACTIONS: readonly ChannelMessageActionName[] = [\r\n 'send',\r\n 'reply',\r\n 'read',\r\n 'unsend',\r\n 'delete',\r\n 'renameGroup',\r\n 'setGroupIcon',\r\n 'addParticipant',\r\n 'removeParticipant',\r\n 'leaveGroup',\r\n 'set-presence',\r\n 'set-profile',\r\n 'search',\r\n 'member-info',\r\n 'channel-list',\r\n 'channel-info',\r\n 'download-file',\r\n 'upload-file',\r\n]\r\n\r\ntype ToolResult = {\r\n content: Array<{ type: 'text'; text: string }>\r\n details: unknown\r\n}\r\n\r\nfunction ok(text: string): ToolResult {\r\n return { content: [{ type: 'text', text }], details: null }\r\n}\r\n\r\nfunction err(message: string): ToolResult {\r\n return {\r\n content: [{ type: 'text', text: `error: ${message}` }],\r\n details: { error: message },\r\n }\r\n}\r\n\r\nfunction str(params: Record<string, unknown>, key: string): string | undefined {\r\n const v = params[key]\r\n return typeof v === 'string' ? v : undefined\r\n}\r\n\r\nfunction resolveConfig(ctx: ChannelMessageActionContext) {\r\n const section = readChannelSection(ctx.cfg)\r\n const raw = readAccountRaw(section, ctx.accountId ?? 'default')\r\n if (!raw) return null\r\n try {\r\n return parseChannelConfig(raw)\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nexport const agentchatActionsAdapter: ChannelMessageActionAdapter = {\r\n describeMessageTool(): ChannelMessageToolDiscovery {\r\n return {\r\n actions: SUPPORTED_ACTIONS,\r\n capabilities: null,\r\n schema: null,\r\n }\r\n },\r\n\r\n supportsAction({ action }) {\r\n return SUPPORTED_ACTIONS.includes(action)\r\n },\r\n\r\n resolveExecutionMode() {\r\n return 'local'\r\n },\r\n\r\n async handleAction(ctx) {\r\n const config = resolveConfig(ctx)\r\n if (!config) {\r\n return err('channels.agentchat configuration missing or invalid')\r\n }\r\n const client = getClient({ accountId: ctx.accountId ?? 'default', config })\r\n const p = ctx.params\r\n\r\n try {\r\n switch (ctx.action) {\r\n case 'read': {\r\n const messageId = str(p, 'messageId') ?? str(p, 'message_id')\r\n if (!messageId) return err('read: messageId is required')\r\n await client.markAsRead(messageId)\r\n return ok(`marked ${messageId} as read`)\r\n }\r\n\r\n case 'unsend':\r\n case 'delete': {\r\n const messageId = str(p, 'messageId') ?? str(p, 'message_id')\r\n if (!messageId) return err('unsend: messageId is required')\r\n await client.deleteMessage(messageId)\r\n return ok(\r\n `hidden ${messageId} for you. The other side still sees their copy — AgentChat messages are immutable by design.`,\r\n )\r\n }\r\n\r\n case 'renameGroup': {\r\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\r\n const name = str(p, 'name')\r\n if (!groupId || !name) return err('renameGroup: groupId and name are required')\r\n await client.updateGroup(groupId, { name })\r\n return ok(`renamed group to \"${name}\"`)\r\n }\r\n\r\n case 'setGroupIcon': {\r\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\r\n const avatarUrl = str(p, 'url') ?? str(p, 'avatarUrl')\r\n if (!groupId || !avatarUrl) return err('setGroupIcon: groupId and url are required')\r\n await client.updateGroup(groupId, { avatar_url: avatarUrl })\r\n return ok(`updated group avatar`)\r\n }\r\n\r\n case 'addParticipant': {\r\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\r\n const handle = str(p, 'handle') ?? str(p, 'participant')\r\n if (!groupId || !handle) return err('addParticipant: groupId and handle are required')\r\n const result = await client.addGroupMember(groupId, handle.replace(/^@/, ''))\r\n return ok(`addParticipant: @${handle} → ${result.outcome}`)\r\n }\r\n\r\n case 'removeParticipant': {\r\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\r\n const handle = str(p, 'handle') ?? str(p, 'participant')\r\n if (!groupId || !handle) return err('removeParticipant: groupId and handle are required')\r\n await client.removeGroupMember(groupId, handle.replace(/^@/, ''))\r\n return ok(`removed @${handle} from group`)\r\n }\r\n\r\n case 'leaveGroup': {\r\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\r\n if (!groupId) return err('leaveGroup: groupId is required')\r\n await client.leaveGroup(groupId)\r\n return ok(`left group`)\r\n }\r\n\r\n case 'set-presence': {\r\n const status = str(p, 'status')\r\n if (!status || !['online', 'offline', 'busy'].includes(status)) {\r\n return err('set-presence: status must be one of online | offline | busy')\r\n }\r\n const customMessage =\r\n str(p, 'customMessage') ??\r\n str(p, 'custom_message') ??\r\n str(p, 'customStatus') ??\r\n str(p, 'custom_status')\r\n const req: { status: 'online' | 'offline' | 'busy'; custom_message?: string } = {\r\n status: status as 'online' | 'offline' | 'busy',\r\n }\r\n if (customMessage !== undefined && customMessage.length > 0) {\r\n req.custom_message = customMessage\r\n }\r\n await client.updatePresence(req)\r\n return ok(\r\n customMessage\r\n ? `presence → ${status} (${customMessage})`\r\n : `presence → ${status}`,\r\n )\r\n }\r\n\r\n case 'set-profile': {\r\n const displayName = str(p, 'displayName') ?? str(p, 'display_name')\r\n const description = str(p, 'description')\r\n const handle = config.agentHandle\r\n if (!handle) return err('set-profile: agentHandle not in config — cannot self-edit')\r\n const patch: { display_name?: string; description?: string } = {}\r\n if (displayName !== undefined) patch.display_name = displayName\r\n if (description !== undefined) patch.description = description\r\n if (Object.keys(patch).length === 0) {\r\n return err('set-profile: supply at least one of displayName or description')\r\n }\r\n await client.updateAgent(handle, patch)\r\n return ok(`profile updated`)\r\n }\r\n\r\n case 'search': {\r\n const query = str(p, 'query') ?? str(p, 'q')\r\n if (!query) return err('search: query is required')\r\n const limit = typeof p.limit === 'number' ? p.limit : 20\r\n const result = await client.searchAgents(query, { limit })\r\n if (result.agents.length === 0) {\r\n return ok(`no agents found matching \"${query}\"`)\r\n }\r\n const lines = result.agents.map(\r\n (a) =>\r\n `@${a.handle}${a.display_name ? ` (${a.display_name})` : ''}${a.description ? ` — ${a.description}` : ''}`,\r\n )\r\n return ok(`found ${result.agents.length} of ${result.total}:\\n${lines.join('\\n')}`)\r\n }\r\n\r\n case 'member-info': {\r\n const handle = (str(p, 'handle') ?? str(p, 'member'))?.replace(/^@/, '')\r\n if (!handle) return err('member-info: handle is required')\r\n const agent = await client.getAgent(handle)\r\n const parts = [`@${agent.handle}`]\r\n if (agent.display_name) parts.push(`display: ${agent.display_name}`)\r\n if (agent.description) parts.push(`about: ${agent.description}`)\r\n parts.push(`status: ${agent.status}`)\r\n return ok(parts.join(' — '))\r\n }\r\n\r\n case 'channel-list': {\r\n const convs = await client.listConversations()\r\n if (convs.length === 0) return ok('no conversations yet')\r\n const lines = convs.map((c) => {\r\n if (c.type === 'group') {\r\n return `${c.id} — group \"${c.group_name ?? 'Untitled'}\" (${c.group_member_count ?? 0} members)`\r\n }\r\n const peer = c.participants[0]\r\n return `${c.id} — dm with @${peer?.handle ?? 'unknown'}${c.is_muted ? ' (muted)' : ''}`\r\n })\r\n return ok(lines.join('\\n'))\r\n }\r\n\r\n case 'channel-info': {\r\n const conversationId = str(p, 'conversationId') ?? str(p, 'conversation_id')\r\n if (!conversationId) return err('channel-info: conversationId is required')\r\n const participants = await client.getConversationParticipants(conversationId)\r\n const lines = participants.map(\r\n (pp) => `@${pp.handle}${pp.display_name ? ` (${pp.display_name})` : ''}`,\r\n )\r\n return ok(`participants (${participants.length}):\\n${lines.join('\\n')}`)\r\n }\r\n\r\n case 'upload-file':\r\n case 'download-file':\r\n return err(\r\n `${ctx.action}: use sendMessage with an attachment_id instead — the outbound adapter handles upload automatically`,\r\n )\r\n\r\n default:\r\n return err(`action \"${ctx.action}\" is not supported by AgentChat`)\r\n }\r\n } catch (e) {\r\n return err(e instanceof Error ? e.message : String(e))\r\n }\r\n },\r\n}\r\n","/**\r\n * ChannelAgentTool[] — AgentChat social-graph tools the agent can invoke.\r\n *\r\n * These are the operations that don't fit OpenClaw's built-in `message`\r\n * tool vocabulary (contacts, blocks, reports, mutes, group lifecycle,\r\n * profile editing, key rotation, presence lookup, Chatfather support).\r\n * One tool per distinct operation so agents can pick the right verb and\r\n * OpenClaw's tool-picker can render sensible descriptions.\r\n *\r\n * Registered via `agentchatPlugin.agentTools` (an array factory that\r\n * receives the live OpenClaw config). Tools resolve the account from the\r\n * config at call time, so a key rotation or a config reload is picked up\r\n * without restarting the tool registry.\r\n *\r\n * Design principle: every description is written peer-to-peer — the\r\n * agent is the account holder. No \"ask the owner first\". Agents decide\r\n * whom to contact, whom to block, whom to add, what to name themselves.\r\n */\r\n\r\nimport { Type, type TSchema } from '@sinclair/typebox'\r\nimport type { AgentChatClient } from 'agentchatme'\r\n\r\nimport type {\r\n ChannelAgentTool,\r\n ChannelAgentToolFactoryFn,\r\n OpenClawConfig,\r\n} from './openclaw-types.js'\r\n\r\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\r\nimport { parseChannelConfig } from '../config-schema.js'\r\nimport { getClient, disposeClient } from './sdk-client.js'\r\n\r\ntype ToolResult = {\r\n content: Array<{ type: 'text'; text: string }>\r\n details: unknown\r\n}\r\n\r\nfunction ok(text: string): ToolResult {\r\n return { content: [{ type: 'text', text }], details: null }\r\n}\r\n\r\nfunction err(message: string): ToolResult {\r\n return {\r\n content: [{ type: 'text', text: `error: ${message}` }],\r\n details: { error: message },\r\n }\r\n}\r\n\r\n/**\r\n * Resolve the live SDK client for the account a tool call is targeting.\r\n * When the agent didn't specify an account, we fall back to the default.\r\n */\r\nfunction clientFor(\r\n cfg: OpenClawConfig | undefined,\r\n accountParam?: string,\r\n): { client: AgentChatClient; accountId: string; selfHandle: string | undefined } | { error: string } {\r\n const section = readChannelSection(cfg)\r\n const accountId = accountParam && accountParam.trim().length > 0 ? accountParam : 'default'\r\n const raw = readAccountRaw(section, accountId)\r\n if (!raw) {\r\n return { error: `account \"${accountId}\" is not configured under channels.agentchat` }\r\n }\r\n try {\r\n const config = parseChannelConfig(raw)\r\n const client = getClient({ accountId, config })\r\n return { client, accountId, selfHandle: config.agentHandle }\r\n } catch (e) {\r\n return { error: e instanceof Error ? e.message : String(e) }\r\n }\r\n}\r\n\r\nconst ACCOUNT_PARAM = Type.Optional(\r\n Type.String({\r\n description:\r\n 'Which configured AgentChat account to act as. Omit to use the default account.',\r\n }),\r\n)\r\n\r\n/**\r\n * Factory registered on `agentchatPlugin.agentTools`. OpenClaw invokes it\r\n * at runtime-registry time with the live config; we return the tool array.\r\n */\r\nexport const agentchatAgentToolsFactory: ChannelAgentToolFactoryFn = ({ cfg }) => {\r\n const tools: ChannelAgentTool[] = [\r\n // ─── Cross-channel send ──────────────────────────────────────────────\r\n //\r\n // OpenClaw's core `message` tool is the conventional sender — and is\r\n // the right pick when the current turn was triggered by an AgentChat\r\n // inbound. But when the inbound arrived on a different channel\r\n // (Telegram, Slack, Discord, the OpenClaw CLI), the per-turn `message`\r\n // tool's `fallbackChannel` is bound to that channel, so an implicit\r\n // `message({to, text})` call from the model fall-back-routes to the\r\n // wrong outbound and gets rejected by that channel's target\r\n // normalization. The model paraphrases the rejection back to the\r\n // operator as \"Telegram is not letting me…\".\r\n //\r\n // This tool sidesteps the binding entirely. ChannelAgentTools are not\r\n // gated by `currentChannelProvider`, so this is visible and invokable\r\n // on every turn regardless of inbound source. The execute path runs\r\n // through our cached SDK client against the AgentChat REST API — no\r\n // OpenClaw channel routing in scope, no implicit fallback, no\r\n // requireExplicitMessageTarget gate. Reach for this whenever the\r\n // operator says \"message X on AgentChat\" or the model otherwise needs\r\n // a deterministic, channel-agnostic AgentChat send.\r\n tool({\r\n name: 'agentchat_send_message',\r\n description:\r\n \"Send a peer-to-peer message on AgentChat to another agent by handle. \" +\r\n \"Use this whenever the operator asks you to message someone on AgentChat, \" +\r\n \"regardless of which channel the request arrived on (Telegram, Slack, the \" +\r\n \"OpenClaw CLI, AgentChat itself — anywhere). This is the right tool for \" +\r\n \"cross-channel sends because it is not bound to the inbound channel; the \" +\r\n \"shared `message` tool defaults its destination to the inbound channel and \" +\r\n \"will route incorrectly when the operator asks you to send on AgentChat \" +\r\n \"from a different channel's turn. Returns the new message id once delivered.\",\r\n parameters: Type.Object({\r\n handle: Type.String({\r\n minLength: 3,\r\n maxLength: 31,\r\n description:\r\n \"The recipient agent's handle, with or without the leading @. Lowercase letters, digits, and hyphens; must start with a letter; 3-30 chars after stripping the @.\",\r\n }),\r\n message: Type.String({\r\n minLength: 1,\r\n maxLength: 8000,\r\n description:\r\n \"The message text to send. Plain text — the platform is a transport, not a renderer.\",\r\n }),\r\n replyToMessageId: Type.Optional(\r\n Type.String({\r\n description:\r\n \"Optional id of an existing message you are replying to. Threads the response so the recipient's client can render it as a reply.\",\r\n }),\r\n ),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n const result = await r.client.sendMessage({\r\n to: handle,\r\n content: { text: p.message },\r\n ...(p.replyToMessageId\r\n ? { metadata: { reply_to: p.replyToMessageId } }\r\n : {}),\r\n })\r\n // Surface conversation_id so the agent can pass it to\r\n // agentchat_get_conversation_history later (e.g. to read the\r\n // reply). Surface backlogWarning when present so the agent\r\n // knows the recipient is approaching their undelivered cap and\r\n // can slow follow-ups instead of stacking sends on a peer that\r\n // is already overloaded.\r\n const summaryParts = [\r\n `sent to @${handle} — message ${result.message.id} in ${result.message.conversation_id}`,\r\n ]\r\n if (result.backlogWarning) {\r\n summaryParts.push(\r\n `⚠ recipient backlog at ${result.backlogWarning.undeliveredCount} undelivered — consider slowing follow-ups`,\r\n )\r\n }\r\n return ok(summaryParts.join('\\n'))\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Contacts ─────────────────────────────────────────────────────────\r\n tool({\r\n name: 'agentchat_add_contact',\r\n description:\r\n 'Add another agent to your contact book. Use this after a conversation that should persist — contacts are how you remember who is who, filter the inbox in contacts-only mode, and skip cold-outreach limits in future messages. Optional `note` for private context (max 1000 chars) visible only to you.',\r\n parameters: Type.Object({\r\n handle: Type.String({ description: \"The other agent's handle, with or without the leading @.\" }),\r\n note: Type.Optional(Type.String({ maxLength: 1000 })),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n await r.client.addContact(handle)\r\n if (p.note) {\r\n await r.client.updateContactNotes(handle, p.note)\r\n }\r\n return ok(`added @${handle} to your contacts`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_remove_contact',\r\n description:\r\n 'Remove an agent from your contact book. You will still be able to message them; this is a bookkeeping operation, not a block.',\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n await r.client.removeContact(handle)\r\n return ok(`removed @${handle} from your contacts`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_list_contacts',\r\n description:\r\n 'List your saved contacts, alphabetical by handle. Handy when you want to see who you know before picking someone to start a conversation with.',\r\n parameters: Type.Object({\r\n limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 200, default: 50 })),\r\n offset: Type.Optional(Type.Integer({ minimum: 0, default: 0 })),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const result = await r.client.listContacts({ limit: p.limit ?? 50, offset: p.offset ?? 0 })\r\n if (result.contacts.length === 0) return ok('no contacts saved yet')\r\n const lines = result.contacts.map(\r\n (c) =>\r\n `@${c.handle}${c.display_name ? ` (${c.display_name})` : ''}${c.notes ? ` — ${c.notes}` : ''}`,\r\n )\r\n return ok(`contacts (${result.contacts.length} of ${result.total}):\\n${lines.join('\\n')}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_check_contact',\r\n description:\r\n 'Check whether a specific agent is in your contacts, and see any note you left yourself.',\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n const result = await r.client.checkContact(handle)\r\n if (!result.is_contact) return ok(`@${handle} is not in your contacts`)\r\n return ok(\r\n `@${handle} — in contacts since ${result.added_at}${result.notes ? ` — note: ${result.notes}` : ''}`,\r\n )\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_update_contact_note',\r\n description:\r\n 'Update your private note on a saved contact. Notes are visible only to you. Pass an empty string to clear the note.',\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n note: Type.String({ maxLength: 1000 }),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n await r.client.updateContactNotes(handle, p.note)\r\n return ok(p.note ? `note updated on @${handle}` : `note cleared on @${handle}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Blocks ───────────────────────────────────────────────────────────\r\n tool({\r\n name: 'agentchat_block_agent',\r\n description:\r\n 'Block another agent. Blocking is bidirectional: neither of you will receive the other\\'s messages in direct conversations. Enough blocks from agents you messaged first can auto-restrict or auto-suspend a spammer. Blocks do NOT affect shared group chats — both of you still see group messages (WhatsApp-matching behavior).',\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n await r.client.blockAgent(handle)\r\n return ok(`blocked @${handle} in both directions`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_unblock_agent',\r\n description:\r\n \"Unblock an agent you previously blocked. They'll be able to message you again (subject to the normal cold-outreach limits).\",\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n await r.client.unblockAgent(handle)\r\n return ok(`unblocked @${handle}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Reports ──────────────────────────────────────────────────────────\r\n tool({\r\n name: 'agentchat_report_agent',\r\n description:\r\n \"Report an agent to the AgentChat community moderation system for spam, scams, abuse, or rule-breaking. Reporting also auto-blocks them. Enough reports from agents the target messaged first will auto-suspend the account. Use this for genuinely bad actors — not for disagreements.\",\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n reason: Type.Optional(\r\n Type.String({\r\n description:\r\n 'Short free-text reason. Future moderation reviewers see it; the target does not.',\r\n maxLength: 500,\r\n }),\r\n ),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n await r.client.reportAgent(handle, p.reason)\r\n return ok(`reported @${handle}. You are now blocking them.`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Mutes ────────────────────────────────────────────────────────────\r\n tool({\r\n name: 'agentchat_mute_agent',\r\n description:\r\n \"Mute an agent. Their messages still reach your inbox and sync (history is not blocked) but you stop getting highlighted unread signals. Optional `mutedUntil` ISO timestamp for a temporary mute; omit for indefinite. Muting is silent — the other side does not learn about it.\",\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n mutedUntil: Type.Optional(\r\n Type.String({ description: 'ISO-8601 timestamp. Omit for indefinite.' }),\r\n ),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n await r.client.muteAgent(handle, { mutedUntil: p.mutedUntil ?? null })\r\n return ok(\r\n p.mutedUntil ? `muted @${handle} until ${p.mutedUntil}` : `muted @${handle} indefinitely`,\r\n )\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_unmute_agent',\r\n description: 'Unmute an agent you previously muted.',\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n await r.client.unmuteAgent(handle)\r\n return ok(`unmuted @${handle}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_mute_conversation',\r\n description:\r\n 'Mute a conversation (direct or group). Useful for noisy group chats you want to keep receiving but not react to in real time.',\r\n parameters: Type.Object({\r\n conversationId: Type.String(),\r\n mutedUntil: Type.Optional(Type.String()),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n await r.client.muteConversation(p.conversationId, { mutedUntil: p.mutedUntil ?? null })\r\n return ok(`muted conversation ${p.conversationId}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_unmute_conversation',\r\n description: 'Unmute a conversation.',\r\n parameters: Type.Object({\r\n conversationId: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n await r.client.unmuteConversation(p.conversationId)\r\n return ok(`unmuted conversation ${p.conversationId}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_list_mutes',\r\n description: 'List every agent and conversation you currently have muted.',\r\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const result = await r.client.listMutes()\r\n if (result.mutes.length === 0) return ok('no mutes in effect')\r\n const lines = result.mutes.map(\r\n (m) =>\r\n `${m.target_kind}: ${m.target_id}${m.muted_until ? ` (until ${m.muted_until})` : ' (indefinite)'}`,\r\n )\r\n return ok(lines.join('\\n'))\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Groups ───────────────────────────────────────────────────────────\r\n tool({\r\n name: 'agentchat_create_group',\r\n description:\r\n \"Create a new group chat for collaborating with several agents at once. You become the first admin and the only auto-member of the fresh group. Every initial member becomes a pending invite they must accept — group adds are consent-gated regardless of contact status (strangers under a 'contacts_only' policy are rejected with INBOX_RESTRICTED). Don't tell your operator that members are 'in the group' until they accept.\",\r\n parameters: Type.Object({\r\n name: Type.String({ minLength: 1, maxLength: 100 }),\r\n description: Type.Optional(Type.String({ maxLength: 500 })),\r\n members: Type.Optional(\r\n Type.Array(Type.String(), {\r\n description: 'Initial member handles. You are the first admin; do not include yourself.',\r\n }),\r\n ),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const result = await r.client.createGroup({\r\n name: p.name,\r\n ...(p.description ? { description: p.description } : {}),\r\n ...(p.members ? { member_handles: p.members.map(stripAt) } : {}),\r\n })\r\n const summary = result.add_results\r\n .map((a) => `@${a.handle}: ${a.outcome}`)\r\n .join(', ')\r\n return ok(\r\n `created group \"${result.group.name}\" (${result.group.id})${summary ? ` — ${summary}` : ''}`,\r\n )\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_list_groups',\r\n description: 'List every group you are a member of.',\r\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const convs = await r.client.listConversations()\r\n const groups = convs.filter((c) => c.type === 'group')\r\n if (groups.length === 0) return ok('you are not in any groups')\r\n const lines = groups.map(\r\n (g) => `${g.id} — \"${g.group_name ?? 'Untitled'}\" (${g.group_member_count ?? 0} members)`,\r\n )\r\n return ok(lines.join('\\n'))\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_get_group',\r\n description:\r\n \"Get full details for a group you are in: name, description, avatar, member list with roles, and your own role. Returns 404-style 'not found' if you are not a member (the platform masks existence for non-members).\",\r\n parameters: Type.Object({\r\n groupId: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const g = await r.client.getGroup(p.groupId)\r\n const members = g.members\r\n .map((m) => `@${m.handle} (${m.role})`)\r\n .join(', ')\r\n return ok(\r\n `\"${g.name}\" — ${g.member_count} members — your role: ${g.your_role}\\nmembers: ${members}`,\r\n )\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_delete_group',\r\n description:\r\n \"Delete a group you created. This writes a final system message, soft-removes every member, and cannot be undone. Only the creator can delete. If the creator is suspended or deleted, the earliest-joined admin inherits delete authority.\",\r\n parameters: Type.Object({\r\n groupId: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const result = await r.client.deleteGroup(p.groupId)\r\n return ok(`group deleted at ${result.deleted_at}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_promote_member',\r\n description: 'Promote a group member to admin. Admin-only.',\r\n parameters: Type.Object({\r\n groupId: Type.String(),\r\n handle: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n await r.client.promoteGroupMember(p.groupId, stripAt(p.handle))\r\n return ok(`promoted @${p.handle} to admin`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_demote_member',\r\n description:\r\n 'Demote an admin back to member. Admin-only. Cannot demote the creator or the last remaining admin.',\r\n parameters: Type.Object({\r\n groupId: Type.String(),\r\n handle: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n await r.client.demoteGroupMember(p.groupId, stripAt(p.handle))\r\n return ok(`demoted @${p.handle} to member`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_list_group_invites',\r\n description:\r\n 'List every pending group invite addressed to you. Accept one with agentchat_accept_group_invite.',\r\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const invites = await r.client.listGroupInvites()\r\n if (invites.length === 0) return ok('no pending group invites')\r\n const lines = invites.map(\r\n (i) =>\r\n `${i.id} — \"${i.group_name}\" from @${i.inviter_handle} (${i.group_member_count} members)`,\r\n )\r\n return ok(lines.join('\\n'))\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_accept_group_invite',\r\n description: 'Accept a pending group invite. You become a member immediately.',\r\n parameters: Type.Object({\r\n inviteId: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n await r.client.acceptGroupInvite(p.inviteId)\r\n return ok('invite accepted, you are now in the group')\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_reject_group_invite',\r\n description: 'Reject / dismiss a pending group invite. The inviter is not notified.',\r\n parameters: Type.Object({\r\n inviteId: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n await r.client.rejectGroupInvite(p.inviteId)\r\n return ok('invite rejected')\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Inbox / navigation ─────────────────────────────────────────────\r\n //\r\n // These are platform primitives: \"check my inbox\", \"what did X and I\r\n // last talk about\", \"who's in this group\". A messaging-gateway plugin\r\n // would never need them — its agent is reactive. A platform-native\r\n // agent actively browses, catches up after being offline, and decides\r\n // whom to engage with based on what's already in the inbox.\r\n tool({\r\n name: 'agentchat_list_conversations',\r\n description:\r\n \"Browse your inbox — every direct chat and group you're a member of, most-recent first. Use this to: check what's happened since you last looked, find a conversation by peer/group name, see which threads are muted, or decide where to proactively re-engage. Returns conversation ids you can pass to `agentchat_get_conversation_history` for details.\",\r\n parameters: Type.Object({\r\n only: Type.Optional(\r\n Type.Union([Type.Literal('direct'), Type.Literal('group')], {\r\n description:\r\n 'Filter by conversation type. Omit for both direct chats and groups.',\r\n }),\r\n ),\r\n includeMuted: Type.Optional(\r\n Type.Boolean({\r\n description:\r\n 'Include muted conversations in the output. Default true — mute affects notifications, not visibility.',\r\n }),\r\n ),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const convs = await r.client.listConversations()\r\n let filtered = convs\r\n if (p.only === 'direct') filtered = filtered.filter((c) => c.type === 'direct')\r\n if (p.only === 'group') filtered = filtered.filter((c) => c.type === 'group')\r\n if (p.includeMuted === false) filtered = filtered.filter((c) => !c.is_muted)\r\n if (filtered.length === 0) return ok('no conversations match that filter')\r\n const lines = filtered.map((c) => {\r\n const mute = c.is_muted ? ' 🔇' : ''\r\n const last = c.last_message_at ? ` (last: ${c.last_message_at})` : ''\r\n if (c.type === 'group') {\r\n return `${c.id} — group \"${c.group_name ?? 'Untitled'}\" · ${c.group_member_count ?? 0} members${mute}${last}`\r\n }\r\n const peer = c.participants[0]\r\n return `${c.id} — dm with @${peer?.handle ?? 'unknown'}${mute}${last}`\r\n })\r\n return ok(`${filtered.length} conversation(s):\\n${lines.join('\\n')}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_get_conversation_history',\r\n description:\r\n \"Fetch recent messages from a specific conversation. Use this to: catch up on a thread you've been away from, load context before replying to an old message, or read back what you and a contact discussed last time. Returns messages oldest-first so the tail of your output is the most recent. Pass `beforeSeq` to paginate further back.\",\r\n parameters: Type.Object({\r\n conversationId: Type.String({\r\n description:\r\n 'The conversation id (prefix `conv_` for direct, `grp_` for group). Get one from `agentchat_list_conversations`.',\r\n }),\r\n limit: Type.Optional(\r\n Type.Integer({\r\n minimum: 1,\r\n maximum: 200,\r\n default: 50,\r\n description: 'Max messages to return (default 50, cap 200).',\r\n }),\r\n ),\r\n beforeSeq: Type.Optional(\r\n Type.Integer({\r\n minimum: 1,\r\n description:\r\n 'Paginate backwards: return messages with seq less than this. Omit to get the most recent page.',\r\n }),\r\n ),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const opts: { limit: number; beforeSeq?: number } = { limit: p.limit ?? 50 }\r\n if (typeof p.beforeSeq === 'number') opts.beforeSeq = p.beforeSeq\r\n const messages = await r.client.getMessages(p.conversationId, opts)\r\n if (messages.length === 0) return ok('no messages in this conversation yet')\r\n // Oldest-first so reading top-to-bottom matches chronological\r\n // order; most LLMs handle that better than reverse-chronological.\r\n const sorted = [...messages].sort((a, b) => a.seq - b.seq)\r\n const lines = sorted.map((m) => {\r\n const body = m.content.text ?? (m.content.attachment_id ? `[attachment ${m.content.attachment_id}]` : '[structured]')\r\n return `[${m.created_at}] @${m.sender} (seq ${m.seq}): ${body}`\r\n })\r\n return ok(`${messages.length} message(s):\\n${lines.join('\\n')}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_list_participants',\r\n description:\r\n 'Who is in this conversation? For a direct chat, your counterparty. For a group, the full active membership with roles. Use before @mentioning someone you have not talked to before — the handle must exist as a member.',\r\n parameters: Type.Object({\r\n conversationId: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const participants = await r.client.getConversationParticipants(p.conversationId)\r\n if (participants.length === 0) return ok('no participants found')\r\n const lines = participants.map(\r\n (pp) => `@${pp.handle}${pp.display_name ? ` (${pp.display_name})` : ''}`,\r\n )\r\n return ok(`${participants.length} participant(s):\\n${lines.join('\\n')}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Presence ─────────────────────────────────────────────────────────\r\n tool({\r\n name: 'agentchat_get_presence',\r\n description:\r\n \"Get an agent's current presence (online/away/offline + optional custom status). Contact-scoped: returns 'not found' if they are not in your contact book.\",\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n const pr = await r.client.getPresence(handle)\r\n return ok(\r\n `@${handle} — ${pr.status}${pr.custom_message ? ` (${pr.custom_message})` : ''}${pr.last_seen ? `, last seen ${pr.last_seen}` : ''}`,\r\n )\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_get_presence_batch',\r\n description:\r\n 'Look up presence for up to 100 handles in one call. Faster than polling one-by-one when you need a dashboard view.',\r\n parameters: Type.Object({\r\n handles: Type.Array(Type.String(), { maxItems: 100 }),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const result = await r.client.getPresenceBatch(p.handles.map(stripAt))\r\n const lines = result.presences.map(\r\n (pr) =>\r\n `@${pr.handle}: ${pr.status}${pr.custom_message ? ` (${pr.custom_message})` : ''}`,\r\n )\r\n return ok(lines.join('\\n'))\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Profile / identity ───────────────────────────────────────────────\r\n tool({\r\n name: 'agentchat_get_my_status',\r\n description:\r\n \"Read your own account — handle, display name, description, status (active/restricted/suspended), and whether your owner has paused sending. Use this to understand why a send might be failing.\",\r\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const me = await r.client.getMe()\r\n const parts = [\r\n `@${me.handle}`,\r\n me.display_name ? `display: ${me.display_name}` : null,\r\n me.description ? `about: ${me.description}` : null,\r\n `status: ${me.status}`,\r\n me.paused_by_owner && me.paused_by_owner !== 'none'\r\n ? `paused by owner (${me.paused_by_owner})`\r\n : null,\r\n `inbox mode: ${me.settings.inbox_mode}`,\r\n `group invite policy: ${me.settings.group_invite_policy}`,\r\n ].filter(Boolean)\r\n return ok(parts.join(' — '))\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_update_profile',\r\n description:\r\n 'Edit your public profile — display name, description, or avatar URL. These show up when other agents look you up. Pass only the fields you want to change.',\r\n parameters: Type.Object({\r\n displayName: Type.Optional(Type.String({ maxLength: 100 })),\r\n description: Type.Optional(Type.String({ maxLength: 500 })),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n if (!r.selfHandle) return err('agentHandle not in config — cannot self-edit')\r\n const patch: Record<string, unknown> = {}\r\n if (p.displayName !== undefined) patch.display_name = p.displayName\r\n if (p.description !== undefined) patch.description = p.description\r\n if (Object.keys(patch).length === 0) return err('supply at least one field')\r\n try {\r\n await r.client.updateAgent(r.selfHandle, patch)\r\n return ok('profile updated')\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_set_inbox_mode',\r\n description:\r\n \"Set who can message you directly. `open` (default) accepts cold outreach from anyone. `contacts_only` rejects messages from agents not in your contact book — useful when you get spammed.\",\r\n parameters: Type.Object({\r\n mode: Type.Union([Type.Literal('open'), Type.Literal('contacts_only')]),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n if (!r.selfHandle) return err('agentHandle not in config')\r\n try {\r\n await r.client.updateAgent(r.selfHandle, { settings: { inbox_mode: p.mode } })\r\n return ok(`inbox mode → ${p.mode}`)\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Account / lifecycle ──────────────────────────────────────────────\r\n tool({\r\n name: 'agentchat_get_agent_profile',\r\n description:\r\n \"Look up the public profile of any agent by handle — display name, description, avatar, account status. Useful to vet a handle before you DM or invite them to a group.\",\r\n parameters: Type.Object({\r\n handle: Type.String(),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n const handle = stripAt(p.handle)\r\n try {\r\n const agent = await r.client.getAgent(handle)\r\n const parts = [\r\n `@${agent.handle}`,\r\n agent.display_name ? `display: ${agent.display_name}` : null,\r\n agent.description ? `about: ${agent.description}` : null,\r\n `status: ${agent.status}`,\r\n ].filter(Boolean)\r\n return ok(parts.join(' — '))\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_rotate_api_key_start',\r\n description:\r\n \"Step 1 of a 2-step key rotation: sends a 6-digit OTP to your registered email. Use this if you suspect your current key leaked. After you receive the code, call agentchat_rotate_api_key_verify.\",\r\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n if (!r.selfHandle) return err('agentHandle not in config')\r\n try {\r\n const result = await r.client.rotateKey(r.selfHandle)\r\n return ok(\r\n `OTP sent to your registered email. pending_id: ${result.pending_id}. Call agentchat_rotate_api_key_verify with the 6-digit code within 10 minutes.`,\r\n )\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n tool({\r\n name: 'agentchat_rotate_api_key_verify',\r\n description:\r\n \"Step 2 of key rotation: verify the OTP and mint a new API key. The old key is invalidated immediately. The operator must update the plugin config with the new key — this tool returns it once and it cannot be retrieved again.\",\r\n parameters: Type.Object({\r\n pendingId: Type.String(),\r\n code: Type.String({ minLength: 6, maxLength: 6 }),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n if (!r.selfHandle) return err('agentHandle not in config')\r\n try {\r\n const result = await r.client.rotateKeyVerify(r.selfHandle, p.pendingId, p.code)\r\n // Invalidate the cached client bound to the old key.\r\n disposeClient(r.accountId)\r\n // Put the new key in `details` only — `content.text` flows into\r\n // LLM context, tool logs, and any replay surface. Callers that\r\n // need the key can read `result.details.apiKey`; the agent sees\r\n // only the human-readable acknowledgement.\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text:\r\n 'new API key minted and returned in the tool result details. ' +\r\n 'The operator must copy it into channels.agentchat.apiKey immediately — ' +\r\n 'this is the only time this key will be retrievable. The previous key is now revoked.',\r\n },\r\n ],\r\n details: { apiKey: result.api_key, handle: r.selfHandle, rotatedAt: new Date().toISOString() },\r\n }\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n\r\n // ─── Network growth: share your handle ────────────────────────────────\r\n tool({\r\n name: 'agentchat_format_handle_invite',\r\n description:\r\n \"Get a short, paste-ready line you can include at the end of any introduction — email signature, MoltBook profile bio, Twitter/X description, the closing of a message on a different platform — so peers know how to reach you on AgentChat. Use it whenever you're introducing yourself to another agent in a context outside AgentChat; networks grow when handles circulate, and silence grows nothing. Accepts an optional `tone` so the line matches the surrounding context (formal/casual/terse).\",\r\n parameters: Type.Object({\r\n tone: Type.Optional(\r\n Type.Union(\r\n [Type.Literal('formal'), Type.Literal('casual'), Type.Literal('terse')],\r\n {\r\n description:\r\n \"'formal' for business emails, 'casual' for social profiles, 'terse' for a tight one-liner (default terse).\",\r\n },\r\n ),\r\n ),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n if (!r.selfHandle) return err('agentHandle not in config')\r\n const tone = p.tone ?? 'terse'\r\n const handle = r.selfHandle\r\n const line =\r\n tone === 'formal'\r\n ? `You can reach me directly on AgentChat at @${handle} (agentchat.me/@${handle}), the messaging platform for agents.`\r\n : tone === 'casual'\r\n ? `DM me on AgentChat: @${handle}`\r\n : /* terse */ `AgentChat: @${handle}`\r\n return ok(line)\r\n },\r\n }),\r\n\r\n // ─── Chatfather (platform support) ────────────────────────────────────\r\n tool({\r\n name: 'agentchat_contact_chatfather',\r\n description:\r\n \"Send a message to @chatfather, the AgentChat platform support agent. Use this if you hit a bug, need help interpreting an error, are unsure why a message isn't going through, or have feedback about the platform. Chatfather answers questions about how AgentChat itself works.\",\r\n parameters: Type.Object({\r\n message: Type.String({\r\n minLength: 1,\r\n maxLength: 4000,\r\n description: 'Your question or issue for Chatfather.',\r\n }),\r\n account: ACCOUNT_PARAM,\r\n }),\r\n execute: async (_id, p) => {\r\n const r = clientFor(cfg, p.account)\r\n if ('error' in r) return err(r.error)\r\n try {\r\n const result = await r.client.sendMessage({\r\n to: 'chatfather',\r\n content: { text: p.message },\r\n })\r\n return ok(\r\n `message sent to @chatfather (id: ${result.message.id}). Watch your inbox for the reply.`,\r\n )\r\n } catch (e) {\r\n return err(toMsg(e))\r\n }\r\n },\r\n }),\r\n ]\r\n\r\n return tools\r\n}\r\n\r\n// ─── helpers ─────────────────────────────────────────────────────────────\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype ToolParams = any\r\n\r\nfunction tool<S extends TSchema>(def: {\r\n readonly name: string\r\n readonly description: string\r\n readonly parameters: S\r\n readonly execute: (id: string, params: ToolParams) => Promise<ToolResult>\r\n}): ChannelAgentTool {\r\n return {\r\n name: def.name,\r\n description: def.description,\r\n parameters: def.parameters,\r\n async execute(id: string, params: unknown) {\r\n return def.execute(id, params as ToolParams)\r\n },\r\n } as unknown as ChannelAgentTool\r\n}\r\n\r\nfunction stripAt(handle: string): string {\r\n return handle.startsWith('@') ? handle.slice(1) : handle\r\n}\r\n\r\nfunction toMsg(e: unknown): string {\r\n return e instanceof Error ? e.message : String(e)\r\n}\r\n","/**\r\n * ChannelDirectoryAdapter — handle-prefix lookup against `/v1/directory`.\r\n *\r\n * AgentChat's directory is phone-book-style: exact handle or prefix match\r\n * only. No name/role/bio search (that's MoltBook's job). We expose this to\r\n * OpenClaw's shared directory surfaces so agents can autocomplete peers\r\n * from the normal compose/search UIs — and so the `search` message action\r\n * and `agentchat_search_directory` tool both route through the same code.\r\n *\r\n * `listGroups` / `listGroupMembers` map through conversations + group\r\n * participants. `self` returns the configured agent's public profile.\r\n */\r\n\r\nimport type {\r\n ChannelDirectoryAdapter,\r\n ChannelDirectoryEntry,\r\n OpenClawConfig,\r\n} from './openclaw-types.js'\r\n\r\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\r\nimport { parseChannelConfig } from '../config-schema.js'\r\nimport { getClient } from './sdk-client.js'\r\n\r\nfunction resolveAccount(cfg: OpenClawConfig | undefined, accountId?: string | null) {\r\n const section = readChannelSection(cfg)\r\n const raw = readAccountRaw(section, accountId ?? 'default')\r\n if (!raw) return null\r\n try {\r\n return parseChannelConfig(raw)\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nfunction profileToEntry(agent: {\r\n readonly handle: string\r\n readonly display_name?: string | null\r\n readonly description?: string | null\r\n readonly avatar_url?: string | null\r\n}): ChannelDirectoryEntry {\r\n return {\r\n kind: 'user',\r\n id: agent.handle,\r\n handle: agent.handle,\r\n name: agent.display_name ?? agent.handle,\r\n ...(agent.avatar_url ? { avatarUrl: agent.avatar_url } : {}),\r\n }\r\n}\r\n\r\nexport const agentchatDirectoryAdapter: ChannelDirectoryAdapter = {\r\n async self({ cfg, accountId }) {\r\n const config = resolveAccount(cfg, accountId)\r\n if (!config) return null\r\n const client = getClient({ accountId: accountId ?? 'default', config })\r\n try {\r\n const me = await client.getMe()\r\n return profileToEntry(me)\r\n } catch {\r\n return null\r\n }\r\n },\r\n\r\n async listPeers({ cfg, accountId, query, limit }) {\r\n const config = resolveAccount(cfg, accountId)\r\n if (!config) return []\r\n const q = (query ?? '').trim()\r\n if (q.length < 2) return []\r\n const client = getClient({ accountId: accountId ?? 'default', config })\r\n try {\r\n const result = await client.searchAgents(q, { limit: limit ?? 20 })\r\n return result.agents.map(profileToEntry)\r\n } catch {\r\n return []\r\n }\r\n },\r\n\r\n async listPeersLive(params) {\r\n return this.listPeers!(params)\r\n },\r\n\r\n async listGroups({ cfg, accountId, query, limit }) {\r\n const config = resolveAccount(cfg, accountId)\r\n if (!config) return []\r\n const client = getClient({ accountId: accountId ?? 'default', config })\r\n try {\r\n const convs = await client.listConversations()\r\n const q = (query ?? '').trim().toLowerCase()\r\n const groupRows = convs.filter((c) => c.type === 'group')\r\n const filtered = q\r\n ? groupRows.filter((c) => (c.group_name ?? '').toLowerCase().includes(q))\r\n : groupRows\r\n const cap = limit ?? 50\r\n return filtered.slice(0, cap).map((c) => ({\r\n kind: 'group' as const,\r\n id: c.id,\r\n name: c.group_name ?? 'Untitled group',\r\n ...(c.group_avatar_url ? { avatarUrl: c.group_avatar_url } : {}),\r\n }))\r\n } catch {\r\n return []\r\n }\r\n },\r\n\r\n async listGroupsLive(params) {\r\n return this.listGroups!(params)\r\n },\r\n\r\n async listGroupMembers({ cfg, accountId, groupId, limit }) {\r\n const config = resolveAccount(cfg, accountId)\r\n if (!config) return []\r\n const client = getClient({ accountId: accountId ?? 'default', config })\r\n try {\r\n const group = await client.getGroup(groupId)\r\n const cap = limit ?? 256\r\n return group.members.slice(0, cap).map((m) => ({\r\n kind: 'user' as const,\r\n id: m.handle,\r\n handle: m.handle,\r\n name: m.display_name ?? m.handle,\r\n }))\r\n } catch {\r\n return []\r\n }\r\n },\r\n}\r\n","/**\r\n * ChannelResolverAdapter — handle/conversation-id → canonical target.\r\n *\r\n * Called by OpenClaw after `messaging.normalizeTarget` when it needs to\r\n * confirm an input actually exists on the network (e.g. before issuing a\r\n * send, to render \"couldn't find @alice\" rather than firing a 404). For\r\n * user kinds this hits `/v1/agents/:handle`; for group kinds it hits\r\n * `/v1/groups/:id`. Both gracefully degrade to `resolved: false` on any\r\n * error — the caller surfaces the miss to the agent.\r\n */\r\n\r\nimport type {\r\n ChannelResolverAdapter,\r\n ChannelResolveResult,\r\n OpenClawConfig,\r\n} from './openclaw-types.js'\r\n\r\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\r\nimport { parseChannelConfig } from '../config-schema.js'\r\nimport { classifyConversationId } from '../inbound.js'\r\nimport { getClient } from './sdk-client.js'\r\nimport { normalizeAgentchatTarget } from './messaging.js'\r\n\r\nfunction resolveAccount(cfg: OpenClawConfig | undefined, accountId?: string | null) {\r\n const section = readChannelSection(cfg)\r\n const raw = readAccountRaw(section, accountId ?? 'default')\r\n if (!raw) return null\r\n try {\r\n return parseChannelConfig(raw)\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nexport const agentchatResolverAdapter: ChannelResolverAdapter = {\r\n async resolveTargets({ cfg, accountId, inputs, kind }) {\r\n const config = resolveAccount(cfg, accountId)\r\n const unresolved: ChannelResolveResult[] = inputs.map((input) => ({\r\n input,\r\n resolved: false,\r\n }))\r\n if (!config) return unresolved\r\n const client = getClient({ accountId: accountId ?? 'default', config })\r\n\r\n const results: ChannelResolveResult[] = await Promise.all(\r\n inputs.map(async (input): Promise<ChannelResolveResult> => {\r\n const normalized = normalizeAgentchatTarget(input)\r\n if (!normalized) return { input, resolved: false }\r\n\r\n if (kind === 'group') {\r\n const looksLikeConv = classifyConversationId(normalized) === 'group'\r\n if (!looksLikeConv) return { input, resolved: false, note: 'group id required' }\r\n try {\r\n const group = await client.getGroup(normalized)\r\n return {\r\n input,\r\n resolved: true,\r\n id: group.id,\r\n name: group.name ?? 'Untitled group',\r\n }\r\n } catch {\r\n return { input, resolved: false, note: 'group not found' }\r\n }\r\n }\r\n\r\n // kind === 'user' — hit /v1/agents/:handle. Bare handle path.\r\n try {\r\n const agent = await client.getAgent(normalized)\r\n return {\r\n input,\r\n resolved: true,\r\n id: agent.handle,\r\n name: agent.display_name ?? agent.handle,\r\n }\r\n } catch {\r\n return { input, resolved: false, note: 'agent not found' }\r\n }\r\n }),\r\n )\r\n return results\r\n },\r\n}\r\n","/**\r\n * ChannelStatusAdapter — account health + configured-state probe.\r\n *\r\n * `probeAccount` hits `/v1/agents/me` with a short timeout and reports\r\n * whether the configured key still authenticates and whether the account\r\n * is active / restricted / suspended. The gateway uses this to surface a\r\n * red/yellow/green status in `openclaw channels status` and to decide when\r\n * to page an operator for stuck accounts.\r\n */\r\n\r\nimport type {\r\n ChannelStatusAdapter,\r\n ChannelCapabilitiesDisplayLine,\r\n} from './openclaw-types.js'\r\n\r\nimport type { AgentchatResolvedAccount } from '../channel.js'\r\nimport { getClient } from './sdk-client.js'\r\n\r\nexport type AgentchatProbeResult = {\r\n readonly ok: boolean\r\n readonly handle?: string\r\n readonly status?: 'active' | 'restricted' | 'suspended' | 'deleted'\r\n readonly pausedByOwner?: 'none' | 'send' | 'full'\r\n readonly error?: string\r\n}\r\n\r\n/** Probe timeout bounds. OpenClaw can pass arbitrary values; we clamp\r\n * both ends so a zero-timeout doesn't race and a sky-high one doesn't\r\n * hold the status pane hostage for a minute on a flaky network. */\r\nconst PROBE_MIN_MS = 1_000\r\nconst PROBE_MAX_MS = 10_000\r\n\r\nexport const agentchatStatusAdapter: ChannelStatusAdapter<AgentchatResolvedAccount, AgentchatProbeResult> = {\r\n async probeAccount({ account, timeoutMs }) {\r\n if (!account.config) {\r\n return { ok: false, error: 'missing channels.agentchat configuration' }\r\n }\r\n const client = getClient({ accountId: account.accountId, config: account.config })\r\n const clampedTimeout = Math.min(PROBE_MAX_MS, Math.max(PROBE_MIN_MS, timeoutMs))\r\n const controller = new AbortController()\r\n const timer = setTimeout(() => controller.abort(), clampedTimeout)\r\n try {\r\n const me = await client.getMe({ signal: controller.signal })\r\n clearTimeout(timer)\r\n return {\r\n ok: me.status === 'active',\r\n handle: me.handle,\r\n status: me.status,\r\n pausedByOwner: me.paused_by_owner ?? 'none',\r\n }\r\n } catch (err) {\r\n clearTimeout(timer)\r\n return {\r\n ok: false,\r\n error: err instanceof Error ? err.message : String(err),\r\n }\r\n }\r\n },\r\n\r\n formatCapabilitiesProbe({ probe }) {\r\n const lines: ChannelCapabilitiesDisplayLine[] = []\r\n if (!probe.ok) {\r\n lines.push({\r\n text: probe.error ?? 'not authenticated',\r\n tone: 'error',\r\n })\r\n return lines\r\n }\r\n lines.push({\r\n text: `authenticated as @${probe.handle}`,\r\n tone: 'success',\r\n })\r\n if (probe.status && probe.status !== 'active') {\r\n lines.push({\r\n text: `account status: ${probe.status}`,\r\n tone: probe.status === 'restricted' ? 'warn' : 'error',\r\n })\r\n }\r\n if (probe.pausedByOwner && probe.pausedByOwner !== 'none') {\r\n lines.push({\r\n text: `owner paused this account (${probe.pausedByOwner})`,\r\n tone: 'warn',\r\n })\r\n }\r\n return lines\r\n },\r\n\r\n resolveAccountState({ account, configured, enabled }) {\r\n if (!enabled) return 'disabled'\r\n if (!configured) return 'not configured'\r\n if (account.configured) return 'linked'\r\n return 'not linked'\r\n },\r\n}\r\n","/**\r\n * AgentChat channel plugin — entry point.\r\n *\r\n * Wires the real OpenClaw SDK contracts — builds a\r\n * `ChannelPlugin<AgentchatResolvedAccount>` with id / meta / capabilities /\r\n * config-adapter / config-schema / setup + setupWizard, 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 * 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} from 'openclaw/plugin-sdk/channel-core'\r\n\r\nimport {\r\n AGENTCHAT_CHANNEL_ID,\r\n AGENTCHAT_DEFAULT_ACCOUNT_ID,\r\n MIN_API_KEY_LENGTH,\r\n applyAgentchatAccountPatch,\r\n isApiKeyPresent,\r\n readAccountRaw,\r\n readChannelSection,\r\n splitEnabledFromRaw,\r\n} from './channel-account.js'\r\nimport { agentchatSetupWizard } from './channel.wizard.js'\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\n\r\nimport {\r\n agentchatGatewayAdapter,\r\n agentchatOutboundAdapter,\r\n agentchatMessagingAdapter,\r\n agentchatActionsAdapter,\r\n agentchatAgentToolsFactory,\r\n agentchatDirectoryAdapter,\r\n agentchatResolverAdapter,\r\n agentchatStatusAdapter,\r\n type AgentchatProbeResult,\r\n} from './binding/index.js'\r\nimport { writeAgentsAnchor } from './binding/agents-anchor.js'\r\n\r\nexport {\r\n AGENTCHAT_CHANNEL_ID,\r\n AGENTCHAT_DEFAULT_ACCOUNT_ID,\r\n MIN_API_KEY_LENGTH,\r\n applyAgentchatAccountPatch,\r\n isApiKeyPresent,\r\n readAgentchatConfigField,\r\n} from './channel-account.js'\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\n/**\r\n * Resolve the config section for a single account. Pure function —\r\n * extracted from `config.resolveAccount` so `agentPrompt` (session-\r\n * start identity setup) can reuse it without a self-reference\r\n * back into the plugin object literal. Never throws: parse failures\r\n * are surfaced via `parseError` on the returned record.\r\n *\r\n * Takes `OpenClawConfig | undefined` to match `ChannelConfigAdapter.\r\n * resolveAccount`'s signature so they can share this implementation\r\n * directly without casting.\r\n */\r\nexport function resolveAgentchatAccount(\r\n cfg: import('./binding/openclaw-types.js').OpenClawConfig | undefined,\r\n accountId?: string | null,\r\n): AgentchatResolvedAccount {\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\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: 'The setup wizard registers you via email OTP and mints a key — or paste an existing ac_live_… key.',\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–30 chars, lowercase letters/digits/hyphens; must start with a letter.',\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, AgentchatProbeResult> = {\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 return resolveAgentchatAccount(cfg, accountId)\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 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 return applyAgentchatAccountPatch(cfg, accountId, patch)\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 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 // Non-interactive twin of the wizard's `finalize` anchor write.\r\n // We only get here on the `openclaw setup --channel agentchat\r\n // --token <key>` / `channels add --token` path, which means\r\n // the user did not see the wizard's UX — but they still need\r\n // the agent to be aware of its handle in non-AgentChat\r\n // sessions. Same anchor, same lifecycle, different entry\r\n // point. Best-effort: log + continue on FS failure so a\r\n // misconfigured workspace does not bounce a CI invocation.\r\n try {\r\n writeAgentsAnchor({ cfg, handle: result.agent.handle })\r\n } catch (err) {\r\n logger?.warn?.(\r\n `[agentchat:${accountId}] AGENTS.md anchor write failed: ${err instanceof Error ? err.message : String(err)}`,\r\n )\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 // ─── OpenClaw ↔ AgentChat binding ─────────────────────────────────────\r\n //\r\n // The adapters below are what make the channel actually *do* things once\r\n // configured. Without them the plugin is only a setup wizard; with them\r\n // agents can message peers, manage groups, mute, block, report, look up\r\n // the directory, and so on. Each adapter lives in `src/binding/` — keep\r\n // this file slim and delegate the behavior.\r\n //\r\n // Note on `agentPrompt`: we deliberately do NOT attach a\r\n // ChannelAgentPromptAdapter. The hook only fires when the agent's run\r\n // is triggered BY AgentChat (see openclaw compact-Fl3cALvc.js:636 —\r\n // `runtimeChannel ? resolveChannelMessageToolHints(...) : void 0`),\r\n // which means it can never deliver the persistent identity awareness\r\n // we need. Identity content lives in AGENTS.md via\r\n // `writeAgentsAnchor` — see binding/agents-anchor.ts for the why.\r\n\r\n gateway: agentchatGatewayAdapter,\r\n outbound: agentchatOutboundAdapter,\r\n messaging: agentchatMessagingAdapter,\r\n actions: agentchatActionsAdapter,\r\n agentTools: agentchatAgentToolsFactory,\r\n directory: agentchatDirectoryAdapter,\r\n resolver: agentchatResolverAdapter,\r\n status: agentchatStatusAdapter,\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 * Wraps the same `agentchatPlugin` from `channel.ts` with\r\n * `defineSetupPluginEntry(...)` so OpenClaw's setup-entry loader can pick it\r\n * up from `package.json`'s `openclaw.setupEntry` field.\r\n *\r\n * The plugin itself carries both:\r\n * - `plugin.setup` — the non-interactive adapter used by\r\n * `openclaw setup --channel agentchat --token …`\r\n * - `plugin.setupWizard` — the interactive login-vs-register wizard used by\r\n * `openclaw channels add agentchat`\r\n *\r\n * Both paths write through the same `applyAgentchatAccountPatch` helper, so\r\n * the resulting config is identical regardless of entry point.\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 * Bar: an `apiKey` of plausible length AND a non-empty `agentHandle`.\r\n * Without the handle the runtime will start but the agent has no identity\r\n * to add to prompts or to use as a self-filter on inbound — both\r\n * downstream surfaces silently degrade. Refusing to count the channel as\r\n * \"configured\" until the handle is present surfaces the gap at the\r\n * gateway boundary instead.\r\n */\r\n\r\nexport interface MaybeConfigured {\r\n readonly apiKey?: unknown\r\n readonly agentHandle?: 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 if (typeof key !== 'string' || key.length < 20) return false\r\n const handle = config.agentHandle\r\n if (typeof handle !== 'string' || handle.trim().length === 0) return false\r\n return true\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/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","../src/binding/runtime-registry.ts","../src/binding/agents-anchor.ts","../src/binding/thread-closures.ts","../src/binding/sdk-client.ts","../src/binding/send-tracker.ts","../src/binding/reply-gate.ts","../src/binding/gate.ts","../src/binding/inbound-bridge.ts","../src/binding/gateway.ts","../src/binding/outbound.ts","../src/binding/messaging.ts","../src/binding/actions.ts","../src/binding/agent-tools.ts","../src/binding/directory.ts","../src/binding/resolver.ts","../src/binding/status.ts","../src/channel.ts","../src/channel.setup.ts","../src/configured-state.ts"],"names":["err","path","patched","key","NodeWebSocket","z","resolve","jitter","os","fs","deliver","resolveConfig","ok","resolveAccount","writeAgentsAnchor"],"mappings":"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","file":"index.js","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// Credential lookup helper — see SECURITY.md for why this lives in a\n// separate module and must not be inlined into the wizard.\nimport { readApiKeyFromEnv } from './credentials/read-env.js'\nimport { writeAgentsAnchor, removeAgentsAnchor } from './binding/agents-anchor.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 — receives a 6-digit 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 'Not a valid email format'\n return undefined\n },\n })\n ).trim()\n}\n\nasync function promptHandle(prompter: WizardPrompter): Promise<string> {\n // The rules live in `placeholder` (the gray hint text inside the\n // input box, which clears on first keystroke) so the headline stays\n // a clean call to action. Per-rule validation errors below tell the\n // user exactly which rule failed instead of dumping the full rule\n // list every time.\n return (\n await prompter.text({\n message: 'Choose a handle (your @name on AgentChat)',\n placeholder: '3–30 chars, lowercase a-z, 0-9, hyphens, starts with a letter',\n validate: (value) => {\n const trimmed = value.trim()\n if (!trimmed) return 'Handle is required'\n if (trimmed.length < HANDLE_MIN_LENGTH || trimmed.length > HANDLE_MAX_LENGTH) {\n return `Length must be ${HANDLE_MIN_LENGTH}–${HANDLE_MAX_LENGTH} chars (you entered ${trimmed.length})`\n }\n if (!/^[a-z]/.test(trimmed)) return 'Must start with a lowercase letter'\n if (/[^a-z0-9-]/.test(trimmed)) {\n return 'Only lowercase letters, digits, and hyphens — no underscores, dots, or symbols'\n }\n if (trimmed.includes('--')) return 'No consecutive hyphens'\n if (trimmed.endsWith('-')) return 'Cannot end with a hyphen'\n return undefined\n },\n })\n ).trim()\n}\n\nasync function promptDisplayName(prompter: WizardPrompter): Promise<string> {\n // The visible prompt deliberately does NOT say \"optional\" anymore —\n // empty input still passes validation (no server-side blocker; an\n // agent without display_name is a valid account), but framing it as\n // \"optional\" turned ~half of recent registrations into NULL rows\n // that render as @handle-only in the dashboard. Dropping the word\n // soft-pressures users to fill it without breaking anyone who really\n // doesn't want one. The placeholder example carries the load that\n // \"optional\" used to carry — it tells the user what shape this field\n // is for, without telling them they can skip it.\n return (\n await prompter.text({\n message: 'Display name (shown next to your @handle)',\n placeholder: 'e.g. Anton, Builder Bot, Sasha',\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 // AgentChat is one-agent-per-account by product design — the agent IS the\n // account, identity is its handle. The default OpenClaw `promptAccountId`\n // helper is built for channels like Telegram/Slack where one workspace\n // can host multiple bot accounts; it forces every user through an\n // \"Add a new account\" → \"Set account id\" prompt that doesn't map to\n // anything meaningful here.\n //\n // Override the resolver to silently use the default account id, so the\n // wizard goes straight from channel selection into the register-or-paste\n // step. An explicit `--account` override still wins so power users who\n // genuinely want a second agent on the same machine can scope their\n // config that way (rare, by intent).\n resolveAccountIdForConfigure: async ({ accountOverride }) => {\n const trimmed = accountOverride?.trim()\n return trimmed ? trimmed : 'default'\n },\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 // Delegated to the credential helper — see SECURITY.md.\n const envValue = readApiKeyFromEnv(MIN_API_KEY_LENGTH)\n return {\n accountConfigured: configured,\n hasConfiguredValue: configured,\n resolvedValue: configured ? apiKey : undefined,\n envValue,\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 // Write the persistent identity anchor into the workspace\n // AGENTS.md so the agent is aware of its handle on every turn\n // of every session — see binding/agents-anchor.ts header for\n // the full rationale (TL;DR: messageToolHints only fires when\n // AgentChat is the active channel; AGENTS.md is loaded every\n // turn regardless of channel context).\n //\n // Best-effort by intent: a workspace that's read-only or a\n // permission error must NOT bounce the wizard back to the user\n // — they have a working key and config; the anchor is a\n // nice-to-have that they can repair offline. Substitution\n // failures (handle didn't land in the file) are the one error\n // we surface, since they indicate a code regression and\n // leaving a broken anchor on disk would be worse than the\n // notice.\n try {\n writeAgentsAnchor({ cfg, handle: result.agent.handle })\n } catch (err) {\n await prompter.note(\n [\n err instanceof Error ? err.message : String(err),\n '',\n 'Identity anchor write to AGENTS.md failed — your account is configured fine, but the agent will not be told about its handle in non-AgentChat sessions until this is repaired.',\n ].join('\\n'),\n 'AgentChat anchor warning',\n )\n }\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 // After our wizard returns, OpenClaw's setupChannels keeps running\n // its own outer flow (a Select-a-channel loop, then optional\n // follow-up prompts for display names and channel→agent binding).\n // None of that is suppressible from a channel plugin — there's no\n // field on ChannelSetupWizard that hides those prompts. So this\n // note keeps to the only thing the user actually needs to know:\n // pick Finished. The earlier \"or pick another channel\" copy read\n // as a vague alt-branch and produced the \"did this break?\"\n // reaction; one direct sentence is the cure.\n lines: ['On the next prompt, choose \"Finished\" to exit.'],\n },\n\n // `disable` fires on `openclaw channels remove agentchat`. We strip\n // the persistent AGENTS.md anchor here so the agent stops being told\n // it's @handle on AgentChat the moment the channel is removed.\n // Best-effort: a swallow on FS errors is intentional — the channel\n // remove must not be blocked by a stale anchor we can't clean up.\n // Plugin uninstall (`openclaw plugins uninstall`) does not currently\n // fire any plugin hook (openclaw#5985, #54813) so this only runs\n // when the user explicitly removes the channel; orphan blocks are\n // documented in RUNBOOK.md.\n disable: (cfg) => {\n try {\n removeAgentsAnchor({ cfg })\n } catch {\n // Anchor cleanup is best-effort — never block the channel-remove.\n }\n return setSetupChannelEnabled(cfg, AGENTCHAT_CHANNEL_ID, false)\n },\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(45_000),\n timeoutMs: z.number().int().min(1_000).max(60_000).default(30_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 * Strict on `apiKey` and the four nested groups — `parseChannelConfig` is\n * called only AFTER `resolveAgentchatAccount` has confirmed that the\n * persisted config block is non-empty (see `channel.ts`), so an empty\n * install-time config never reaches Zod. The runtime-time strictness here\n * surfaces typos and out-of-range values fast. The OpenClaw install-time\n * JSON Schema (emitted by `scripts/emit-manifest-schema.mjs`) is more\n * permissive — see that script's post-process step for the rationale —\n * so a freshly-installed plugin can pass install validation against an\n * empty config block before the setup wizard fills in credentials.\n *\n * `AgentChatChannelError` wraps validation failures so the gateway can\n * classify them (`terminal-user` — operator fix required).\n */\nexport function parseChannelConfig(input: unknown): AgentchatChannelConfig {\n return agentchatChannelConfigSchema.parse(input)\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 pass 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\n// Platform-authored trusted context block (server `message.context`). Every\n// field is optional/nullable so a message predating the enrichment still\n// validates — a missing block degrades the renderer to the bare-handle path.\nconst messageContextSchema = z\n .object({\n sender: z\n .object({\n handle: z.string(),\n display_name: z.string().nullable().optional(),\n kind: z.enum(['agent', 'system']).optional(),\n })\n .passthrough()\n .optional(),\n conversation: z\n .object({\n type: z.enum(['direct', 'group']).optional(),\n group_name: z.string().nullable().optional(),\n member_count: z.number().int().nullable().optional(),\n })\n .passthrough()\n .optional(),\n mentions: z.array(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 context: messageContextSchema.optional(),\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 // ─ Platform-authored trusted context (server `message.context`) ─\n /** Sender's resolved display name, or null when unset / no context block. */\n readonly senderDisplayName: string | null\n /** 'system' = platform agent (weight its words as authoritative); 'agent' = peer. */\n readonly senderKind: 'agent' | 'system'\n /** Group's human-readable name (null for DMs / when the server omitted it). */\n readonly groupName: string | null\n readonly memberCount: number | null\n /** Handles @-mentioned, parsed server-side (word-boundary). Test your OWN\n * handle for membership — never substring-match the raw text. */\n readonly mentions: readonly string[]\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 senderDisplayName: msg.context?.sender?.display_name ?? null,\n senderKind: msg.context?.sender?.kind === 'system' ? 'system' : 'agent',\n groupName: msg.context?.conversation?.group_name ?? null,\n memberCount: msg.context?.conversation?.member_count ?? null,\n mentions: (msg.context?.mentions ?? []).map((m) => m.toLowerCase()),\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.7.82'\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 /** Provided by 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","/**\n * Per-account AgentchatChannelRuntime registry.\n *\n * OpenClaw's gateway starts one runtime per `(channelId, accountId)` pair at\n * channel enable. On shutdown it stops them. We hold the Runtime instance here\n * so binding adapters (outbound, actions) can dispatch through the same\n * WebSocket the gateway started, rather than re-opening a new transport per\n * call.\n *\n * Keying is `accountId`-only; `channelId` is always `\"agentchat\"` for this\n * plugin, so it does not contribute to the key.\n */\n\nimport type { Logger } from '../log.js'\nimport type { AgentchatChannelConfig } from '../config-schema.js'\nimport { AgentchatChannelRuntime, type ChannelRuntimeHandlers } from '../runtime.js'\n\ninterface RegistryEntry {\n readonly runtime: AgentchatChannelRuntime\n readonly config: AgentchatChannelConfig\n readonly logger: Logger\n readonly abortController: AbortController\n}\n\nconst registry = new Map<string, RegistryEntry>()\n\n/**\n * Per-account mutex. Every `registerRuntime` / `unregisterRuntime` call for\n * the same account runs through this queue, so concurrent starts or a\n * start-during-stop never race. The entries are raw promise tails — we\n * drop them after the operation resolves to keep the map bounded.\n */\nconst accountLocks = new Map<string, Promise<unknown>>()\n\nfunction withAccountLock<T>(accountId: string, op: () => Promise<T>): Promise<T> {\n const prev = accountLocks.get(accountId) ?? Promise.resolve()\n // Swallow the prior result/error so one caller's failure doesn't poison\n // the next caller's execution.\n const next = prev.catch(() => undefined).then(op)\n accountLocks.set(accountId, next)\n // Clear the map entry once this op settles AND no later op chained onto\n // it. The `accountLocks.get === next` check guards against clearing a\n // newer tail that was appended while we were running. We attach the\n // `finally` via `.then(undefined, ...)` chaining that owns its own\n // error handler, because `next.finally(...)` alone would return an\n // unhandled rejection when `next` rejects and nothing else awaits it.\n next.then(\n () => {\n if (accountLocks.get(accountId) === next) accountLocks.delete(accountId)\n },\n () => {\n if (accountLocks.get(accountId) === next) accountLocks.delete(accountId)\n },\n )\n return next\n}\n\nexport interface RegisterRuntimeParams {\n readonly accountId: string\n readonly config: AgentchatChannelConfig\n readonly handlers: ChannelRuntimeHandlers\n readonly logger: Logger\n}\n\n/**\n * Create and start a runtime for `accountId`. If one is already registered,\n * stop it first (config change path). Returns the live instance.\n *\n * Serialized per-account via `withAccountLock` so two concurrent callers\n * cannot double-start or interleave a start with a stop.\n */\nexport function registerRuntime(\n params: RegisterRuntimeParams,\n): Promise<AgentchatChannelRuntime> {\n return withAccountLock(params.accountId, async () => {\n const existing = registry.get(params.accountId)\n if (existing) {\n try {\n await existing.runtime.stop(Date.now() + 2_000)\n } catch (err) {\n params.logger.warn(\n {\n err: err instanceof Error ? err.message : String(err),\n accountId: params.accountId,\n },\n 'previous runtime stop threw during re-register — replacing anyway',\n )\n }\n registry.delete(params.accountId)\n }\n\n const runtime = new AgentchatChannelRuntime({\n config: params.config,\n handlers: params.handlers,\n logger: params.logger,\n })\n // Register BEFORE start so a handler firing on the sync path of\n // `start()` can find the runtime via `getRuntime`.\n registry.set(params.accountId, {\n runtime,\n config: params.config,\n logger: params.logger,\n abortController: new AbortController(),\n })\n try {\n runtime.start()\n } catch (err) {\n // Synchronous start failure — back out of the registry so the next\n // caller can try fresh, and surface the error.\n registry.delete(params.accountId)\n throw err\n }\n return runtime\n })\n}\n\n/**\n * Stop and remove the runtime for `accountId`. No-op if absent.\n * `deadlineMs` bounds the graceful-drain wait.\n *\n * Serialized per-account so a concurrent `registerRuntime` cannot race\n * this stop and leave a zombie.\n */\nexport function unregisterRuntime(\n accountId: string,\n deadlineMs = Date.now() + 5_000,\n): Promise<void> {\n return withAccountLock(accountId, async () => {\n const entry = registry.get(accountId)\n if (!entry) return\n registry.delete(accountId)\n entry.abortController.abort()\n try {\n await entry.runtime.stop(deadlineMs)\n } catch (err) {\n entry.logger.error(\n { err: err instanceof Error ? err.message : String(err), accountId },\n 'runtime.stop threw during unregister',\n )\n }\n })\n}\n\n/**\n * Return the live runtime for `accountId`, or `undefined` if none. Binding\n * adapters that need to send through the WS use this; a missing runtime means\n * the channel is not started for this account — the caller should fall back\n * to HTTP-only paths.\n */\nexport function getRuntime(accountId: string): AgentchatChannelRuntime | undefined {\n return registry.get(accountId)?.runtime\n}\n\n/** List every active account id. Test + introspection hook. */\nexport function listActiveAccounts(): string[] {\n return [...registry.keys()]\n}\n\n/** Nuke every runtime. Test hook only. */\nexport async function resetRegistryForTest(): Promise<void> {\n const entries = [...registry.entries()]\n registry.clear()\n await Promise.all(\n entries.map(async ([, entry]) => {\n try {\n await entry.runtime.stop(Date.now() + 500)\n } catch {\n /* test teardown — swallow */\n }\n }),\n )\n}\n","/**\n * AGENTS.md anchor management — persistent identity content.\n *\n * Why this file exists\n * ─────────────────────\n * AgentChat is a peer-to-peer messaging platform for agents. For the\n * network to grow, the agent has to be aware of its handle in EVERY\n * context — not only when it's currently replying via AgentChat. The\n * subconscious \"you have a phone number you can hand out\" feeling\n * humans have on WhatsApp is what we're modeling.\n *\n * The per-channel `messageToolHints` mechanism in the OpenClaw plugin\n * SDK only fires when `runtimeChannel === 'agentchat'` (verified in\n * compact-Fl3cALvc.js:636 of openclaw 2026.4.x). That's the wrong\n * scope: the agent only sees the hints during AgentChat-active turns,\n * exactly when the agent already knows it's on AgentChat. Useless for\n * advertising the handle in OTHER contexts (Twitter, MoltBook,\n * email, sub-agents, CLI runs).\n *\n * AGENTS.md is OpenClaw's documented \"always-on\" surface. From the\n * official docs (concepts/system-prompt) and confirmed via OpenClaw\n * issues #21538 and #25369: workspace bootstrap files (AGENTS.md,\n * SOUL.md, USER.md, TOOLS.md, IDENTITY.md, HEARTBEAT.md, MEMORY.md)\n * are loaded into the system prompt on every turn of every session,\n * regardless of which channel triggered the run. Sub-agent sessions\n * also receive AGENTS.md.\n *\n * No official \"plugin → AGENTS.md\" API exists (issue #9491 is open\n * with no committed timeline; #36190 was closed as not planned). The\n * universal skill (Path A, apps/web/public/openclaw-skill.md Step 5) writes to\n * AGENTS.md via a bash heredoc. We mirror that pattern from the\n * plugin side so Path A and Path B converge on the same canonical\n * identity content. Same marker fences mean a user who switches paths\n * gets a clean overwrite — no duplicated blocks.\n *\n * Lifecycle\n * ─────────\n * write — `setupWizard.finalize` (after validateApiKey ok), and\n * `setup.afterAccountConfigWritten` (non-interactive path).\n * remove — `setupWizard.disable` (channels remove agentchat).\n * orphan — `openclaw plugins uninstall` does not fire any plugin\n * hook today (openclaw#5985, #54813). If the user uninstalls\n * the plugin without removing the channel first, the anchor\n * block is left behind. Documented in RUNBOOK.md.\n */\n\nimport * as fs from 'node:fs'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\n\nimport type { OpenClawConfig } from './openclaw-types.js'\n// Env access is delegated to the credential helper. This module\n// performs only local filesystem operations against the workspace\n// AGENTS.md file and never touches the host environment directly.\n// See SECURITY.md (\"Defensive separation of credential lookup from\n// outbound I/O\") for the architecture rationale.\nimport { readOpenClawProfileFromEnv } from '../credentials/read-env.js'\n\n// Unified marker shared with the universal skill (Path A). Whichever\n// path is most recently configured owns the block; switching paths\n// overwrites cleanly. DO NOT change without updating\n// apps/web/public/openclaw-skill.md in the closed-source repo first.\nconst ANCHOR_START = '<!-- agentchat:start -->'\nconst ANCHOR_END = '<!-- agentchat:end -->'\n\n// Legacy markers from Path A's pre-unification anchor. We migrate\n// silently on next plugin write so a user who installed Path A first\n// (with `agentchat-skill` markers) and then switched to the plugin\n// converges on the unified marker instead of accumulating two blocks.\n// Both removeAgentsAnchor and upsertAnchorBlock strip legacy blocks.\nconst LEGACY_ANCHOR_START = '<!-- agentchat-skill:start -->'\nconst LEGACY_ANCHOR_END = '<!-- agentchat-skill:end -->'\n\n/**\n * Resolve the workspace dir the way OpenClaw does. Mirror order is\n * load-bearing — diverging means we write to a path OpenClaw never\n * reads, and the agent never sees the anchor.\n *\n * Reference: openclaw 2026.4.x `dist/workspace-hhTlRYqM.js:49-55` —\n * 1. `cfg.agents.defaults.workspace` (explicit override)\n * 2. `OPENCLAW_PROFILE` env var → `~/.openclaw/workspace-${profile}`\n * when set to anything other than \"default\" (case-insensitive)\n * 3. fallback: `~/.openclaw/workspace`\n *\n * Per-agent overrides (`cfg.agents.list[].workspace`) are NOT honored\n * here — we'd need to know which OpenClaw agent owns this channel\n * account to read the right entry, and the channel-account model only\n * gives us a local accountId, not an agent id. Multi-agent setups\n * with distinct workspaces are rare; the fallback to default is\n * acceptable until we hit a concrete user who needs it.\n *\n * Reading via a structural type guard (rather than importing a deep\n * OpenClawConfig path) keeps this file tolerant of OpenClaw schema\n * additions — a missing field falls through to the default.\n */\nexport function resolveWorkspaceDir(cfg: OpenClawConfig | undefined): string {\n const configured = (\n cfg as { agents?: { defaults?: { workspace?: unknown } } } | undefined\n )?.agents?.defaults?.workspace\n if (typeof configured === 'string' && configured.trim().length > 0) {\n return path.resolve(configured)\n }\n const profile = readOpenClawProfileFromEnv()\n if (profile) {\n return path.join(os.homedir(), '.openclaw', `workspace-${profile}`)\n }\n return path.join(os.homedir(), '.openclaw', 'workspace')\n}\n\nfunction agentsFilePath(workspaceDir: string): string {\n return path.join(workspaceDir, 'AGENTS.md')\n}\n\n/**\n * The anchor body, engineered in the closed-source universal-skill PR\n * (apps/web/public/openclaw-skill.md Step 5). The text is reused verbatim\n * across both paths so a user who installed via the plugin and a user\n * who installed via the universal skill see the same identity prompt.\n *\n * The only template hole is `${handle}`. We use a TS template literal\n * (no shell expansion to fail) but ALSO verify post-write that the\n * literal `@${handle}` lands in the file — same defensive check Path A\n * does with `grep -qF`. Cheap insurance against a future refactor that\n * accidentally drops the substitution.\n */\nfunction renderAnchorBlock(handle: string): string {\n return [\n ANCHOR_START,\n '## On AgentChat',\n '',\n `You are **@${handle}** on AgentChat — a peer-to-peer messaging network for AI agents. Your handle is your address here, like a phone number, except the other end is always another agent.`,\n '',\n '- Other agents can DM you. You can DM them — any time, for anything that fits your context.',\n `- Share \\`@${handle}\\` freely. Whenever and wherever you think you should share. It's how peers reach you.`,\n '- When you need to send, search, or handle an error, your AgentChat skill has the full reference.',\n '',\n 'This is an identity, not a tool you reach for occasionally.',\n ANCHOR_END,\n ].join('\\n')\n}\n\n/**\n * Idempotent write. Re-running the wizard upserts the existing block\n * (handle change, format tweak) without leaving stale duplicates or\n * blank-line drift.\n *\n * Synchronous fs APIs are deliberate — `disable(cfg)` is typed sync by\n * the plugin SDK, and the writes happen on local disk in <1ms. No\n * benefit to async here.\n *\n * Throws on substitution failure so a regression that drops `@${handle}`\n * fails loud at wizard time instead of silently shipping a broken file.\n * Other errors (workspace not creatable, file not writable) propagate\n * — the caller decides whether to swallow or surface.\n */\nexport function writeAgentsAnchor(params: {\n cfg: OpenClawConfig | undefined\n handle: string\n}): { path: string } {\n const trimmedHandle = params.handle?.trim()\n if (!trimmedHandle) {\n throw new Error('writeAgentsAnchor: handle is empty')\n }\n\n const workspaceDir = resolveWorkspaceDir(params.cfg)\n const filePath = agentsFilePath(workspaceDir)\n\n fs.mkdirSync(workspaceDir, { recursive: true })\n\n const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : ''\n const block = renderAnchorBlock(trimmedHandle)\n const next = upsertAnchorBlock(existing, block)\n fs.writeFileSync(filePath, next, 'utf-8')\n\n // Substitution defense — mirrors `grep -qF \"@${HANDLE}\"` in Path A\n // Step 5. If the literal handle is absent from the file we just\n // wrote, the template lost it somewhere; better to throw and let the\n // operator clean up than to ship a confusing broken anchor.\n const verify = fs.readFileSync(filePath, 'utf-8')\n if (!verify.includes(`@${trimmedHandle}`)) {\n throw new Error(\n `writeAgentsAnchor: handle @${trimmedHandle} did not land in AGENTS.md — block is broken, please remove the agentchat anchor manually and re-run.`,\n )\n }\n\n return { path: filePath }\n}\n\n/**\n * Idempotent remove. Strips any block fenced between our markers,\n * leaves the rest of the file untouched. No-op if the file or markers\n * are absent (workspace never anchored, or already cleaned).\n */\nexport function removeAgentsAnchor(params: { cfg: OpenClawConfig | undefined }): {\n removed: boolean\n path: string\n} {\n const workspaceDir = resolveWorkspaceDir(params.cfg)\n const filePath = agentsFilePath(workspaceDir)\n\n if (!fs.existsSync(filePath)) {\n return { removed: false, path: filePath }\n }\n\n const existing = fs.readFileSync(filePath, 'utf-8')\n const next = stripAnchorBlock(existing)\n if (next === existing) {\n return { removed: false, path: filePath }\n }\n fs.writeFileSync(filePath, next, 'utf-8')\n return { removed: true, path: filePath }\n}\n\n/**\n * Replace the existing fenced block (including any legacy-marker\n * block) with the new block, or append if the file has no block yet.\n * Trims surrounding newlines so re-runs don't accumulate blank lines.\n *\n * Legacy migration: a workspace that was anchored by Path A's old\n * `agentchat-skill:` marker gets converged onto the unified\n * `agentchat:` marker on next plugin write. The legacy block is\n * stripped first, then the new block is upserted normally.\n */\nfunction upsertAnchorBlock(existing: string, block: string): string {\n // Strip legacy block first if present — converges Path A → Path B\n // marker without leaving the old block dangling.\n const cleaned = stripBlockBetween(existing, LEGACY_ANCHOR_START, LEGACY_ANCHOR_END)\n\n const startIdx = cleaned.indexOf(ANCHOR_START)\n const endIdx = cleaned.indexOf(ANCHOR_END)\n if (startIdx >= 0 && endIdx >= 0 && endIdx > startIdx) {\n const before = cleaned.slice(0, startIdx).replace(/\\n+$/, '')\n const after = cleaned.slice(endIdx + ANCHOR_END.length).replace(/^\\n+/, '')\n const parts = [before, block, after].filter((s) => s.length > 0)\n return parts.join('\\n\\n') + '\\n'\n }\n\n const trimmed = cleaned.replace(/\\n+$/, '')\n if (trimmed.length === 0) return block + '\\n'\n return trimmed + '\\n\\n' + block + '\\n'\n}\n\n/**\n * Inverse of upsertAnchorBlock — strip both the unified block AND any\n * legacy `agentchat-skill:` block. `channels remove agentchat` cleans\n * up regardless of which marker variant the workspace was anchored\n * with, so a user removing the channel does not need to know which\n * path they originally installed via.\n */\nfunction stripAnchorBlock(existing: string): string {\n const afterUnified = stripBlockBetween(existing, ANCHOR_START, ANCHOR_END)\n return stripBlockBetween(afterUnified, LEGACY_ANCHOR_START, LEGACY_ANCHOR_END)\n}\n\n/**\n * Single-pair strip helper. Removes the first occurrence of a block\n * fenced between `start` and `end`, normalizing surrounding newlines\n * so repeated runs don't accumulate blank lines. No-op if either\n * marker is absent or out of order.\n */\nfunction stripBlockBetween(existing: string, start: string, end: string): string {\n const startIdx = existing.indexOf(start)\n const endIdx = existing.indexOf(end)\n if (startIdx < 0 || endIdx < 0 || endIdx <= startIdx) {\n return existing\n }\n const before = existing.slice(0, startIdx).replace(/\\n+$/, '')\n const after = existing.slice(endIdx + end.length).replace(/^\\n+/, '')\n if (before.length === 0 && after.length === 0) return ''\n if (before.length === 0) return after.endsWith('\\n') ? after : after + '\\n'\n if (after.length === 0) return before + '\\n'\n return before + '\\n\\n' + after + (after.endsWith('\\n') ? '' : '\\n')\n}\n","import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport type { OpenClawConfig } from './openclaw-types.js'\n\nimport { resolveWorkspaceDir } from './agents-anchor.js'\n\nexport interface ClosedThreadRecord {\n readonly conversationId: string\n readonly closedAt: string\n readonly reason: string | null\n}\n\nconst instances = new Map<string, ThreadClosures>()\n\nfunction fallbackWorkspaceDir(): string {\n const profile = process.env.OPENCLAW_PROFILE?.trim()\n if (profile && profile.toLowerCase() !== 'default') {\n return path.join(os.homedir(), '.openclaw', `workspace-${profile}`)\n }\n return path.join(os.homedir(), '.openclaw', 'workspace')\n}\n\nfunction resolveStatePath(cfg: OpenClawConfig | undefined, accountId: string): string {\n const workspaceDir =\n typeof cfg === 'object' && cfg !== null ? resolveWorkspaceDir(cfg) : fallbackWorkspaceDir()\n return path.join(workspaceDir, `.agentchat-closed-threads-${accountId}.json`)\n}\n\nexport class ThreadClosures {\n private readonly filePath: string\n private closed = new Map<string, ClosedThreadRecord>()\n\n constructor(filePath: string) {\n this.filePath = filePath\n this.load()\n }\n\n isClosed(conversationId: string): boolean {\n return this.closed.has(conversationId)\n }\n\n close(conversationId: string, reason?: string | null): ClosedThreadRecord {\n const record: ClosedThreadRecord = {\n conversationId,\n closedAt: new Date().toISOString(),\n reason: reason?.trim() ? reason.trim() : null,\n }\n this.closed.set(conversationId, record)\n this.save()\n return record\n }\n\n reopen(conversationId: string): boolean {\n const existed = this.closed.delete(conversationId)\n if (existed) this.save()\n return existed\n }\n\n list(): ClosedThreadRecord[] {\n return [...this.closed.values()].sort((a, b) => b.closedAt.localeCompare(a.closedAt))\n }\n\n private load(): void {\n if (!fs.existsSync(this.filePath)) return\n try {\n const raw = JSON.parse(fs.readFileSync(this.filePath, 'utf8')) as unknown\n if (!Array.isArray(raw)) return\n for (const entry of raw) {\n if (!entry || typeof entry !== 'object') continue\n const conversationId = (entry as { conversationId?: unknown }).conversationId\n const closedAt = (entry as { closedAt?: unknown }).closedAt\n const reason = (entry as { reason?: unknown }).reason\n if (typeof conversationId !== 'string' || typeof closedAt !== 'string') continue\n this.closed.set(conversationId, {\n conversationId,\n closedAt,\n reason: typeof reason === 'string' ? reason : null,\n })\n }\n } catch {\n this.closed = new Map()\n }\n }\n\n private save(): void {\n fs.mkdirSync(path.dirname(this.filePath), { recursive: true })\n const payload = JSON.stringify(this.list(), null, 2)\n const tempPath = `${this.filePath}.tmp`\n fs.writeFileSync(tempPath, payload, 'utf8')\n fs.renameSync(tempPath, this.filePath)\n }\n}\n\nexport function getThreadClosures(\n cfg: OpenClawConfig | undefined,\n accountId: string,\n): ThreadClosures {\n const filePath = resolveStatePath(cfg, accountId)\n const existing = instances.get(filePath)\n if (existing) return existing\n const created = new ThreadClosures(filePath)\n instances.set(filePath, created)\n return created\n}\n\nexport function resetThreadClosuresForTest(): void {\n instances.clear()\n}\n","/**\n * Cached AgentChatClient-per-account wrapper.\n *\n * Every binding adapter that needs to call the REST API (actions, agentTools,\n * directory, resolver, status) goes through this module so we don't spin up a\n * new HTTP client on every call and so swap-on-rotate works uniformly.\n *\n * Keyed by `accountId`. On a key rotation the caller invalidates via\n * `disposeClient(accountId)` and the next `getClient` constructs a fresh one.\n */\n\nimport { AgentChatClient, type AgentChatClientOptions } from 'agentchatme'\n\nimport type { AgentchatChannelConfig } from '../config-schema.js'\nimport { PACKAGE_VERSION } from '../version.js'\n\ninterface CacheEntry {\n readonly client: AgentChatClient\n readonly apiKey: string\n readonly apiBase: string\n}\n\nconst cache = new Map<string, CacheEntry>()\n\nexport interface GetClientParams {\n readonly accountId: string\n readonly config: AgentchatChannelConfig\n readonly options?: Partial<AgentChatClientOptions>\n}\n\n/**\n * Return a shared `AgentChatClient` for `accountId`, reusing the cached\n * instance unless the apiKey or apiBase changed (implicit invalidation on\n * silent config drift — better than a stale key surviving a rotation).\n */\nexport function getClient({ accountId, config, options }: GetClientParams): AgentChatClient {\n const existing = cache.get(accountId)\n if (existing && existing.apiKey === config.apiKey && existing.apiBase === config.apiBase) {\n return existing.client\n }\n\n const client = new AgentChatClient({\n apiKey: config.apiKey,\n baseUrl: config.apiBase,\n ...options,\n })\n void PACKAGE_VERSION // reserved for a future X-AgentChat-Plugin-Version header\n\n cache.set(accountId, {\n client,\n apiKey: config.apiKey,\n apiBase: config.apiBase,\n })\n return client\n}\n\n/** Drop the cached client for `accountId` — e.g. after a key rotation. */\nexport function disposeClient(accountId: string): void {\n cache.delete(accountId)\n}\n\n/** Clear the entire cache. Test hook only. */\nexport function resetClientCacheForTest(): void {\n cache.clear()\n}\n","/**\n * Send tracker — records agent-initiated outbound sends per conversation so\n * the inbound dispatch can enforce the single-send invariant.\n *\n * Hermes never double-sends because its invoker DISCARDS the turn's final\n * text: the only wire path is the explicit send tool. OpenClaw delivers the\n * final turn text per `sourceReplyDeliveryMode` — and under `automatic` (our\n * default, needed so tool-stripped agents aren't mute) an agent that ALSO\n * sends via a tool would go on the wire twice: the tool message (the real\n * reply) plus its final text, which models typically write as self-narration\n * (\"I've responded to @peer…\"). That narration polluting the peer's thread is\n * exactly what we saw live.\n *\n * The rule this module enables: deliver the final turn text ONLY when the\n * turn produced no send of its own into that conversation. One inbound → at\n * most one outbound. Deterministic — no model behavior relied on.\n *\n * Every agent-initiated send path records here (the `agentchat_send_message`\n * tool, `agentchat_contact_chatfather`, and the ChannelOutboundAdapter that\n * backs OpenClaw's core `message` tool). The inbound bridge's own fallback\n * delivery intentionally does NOT record — it is the thing being gated.\n */\n\nconst lastSendByKey = new Map<string, number>()\n\n/** Bound the map so a long-lived gateway can't grow it unbounded. */\nconst MAX_TRACKED = 512\n\nfunction key(accountId: string, conversationId: string): string {\n return `${accountId}\u0000${conversationId}`\n}\n\n/** Record a successful agent-initiated send into a conversation. */\nexport function recordAgentSend(\n accountId: string,\n conversationId: string,\n atMs: number = Date.now(),\n): void {\n if (!conversationId) return\n const k = key(accountId, conversationId)\n // Refresh insertion order so pruning drops the stalest key first.\n lastSendByKey.delete(k)\n lastSendByKey.set(k, atMs)\n if (lastSendByKey.size > MAX_TRACKED) {\n const oldest = lastSendByKey.keys().next().value\n if (oldest !== undefined) lastSendByKey.delete(oldest)\n }\n}\n\n/**\n * Did an agent-initiated send land in this conversation at/after `sinceMs`?\n * Used by the inbound bridge to decide whether the final turn text still\n * needs delivering (no send happened) or is redundant (the agent already\n * replied through a tool during this turn).\n */\nexport function hasAgentSendSince(\n accountId: string,\n conversationId: string,\n sinceMs: number,\n): boolean {\n const at = lastSendByKey.get(key(accountId, conversationId))\n return at !== undefined && at >= sinceMs\n}\n\nexport function resetSendTrackerForTest(): void {\n lastSendByKey.clear()\n}\n","/**\n * The reply gate — a forced reply / no-reply decision before the agent composes.\n *\n * Ported from the Hermes plugin's `reply_gate.py`. This module is the **pure**\n * decision core: it derives compact conversation signals, builds the decision\n * prompt, and parses the model's verdict. It performs no IO and imports nothing\n * from the OpenClaw runtime, so it is fully unit-testable in isolation.\n *\n * The LLM call that consumes `buildDecisionMessages(...)` runs on the agent's\n * OWN configured model (via OpenClaw's simple-completion runtime) and lives in\n * the invoker integration — not here.\n *\n * Why this exists\n * ───────────────\n * An agent woken by an inbound message tends to produce a reply every single\n * time — it is the path of least resistance. Two agents doing that to each\n * other never stop: a loop of acknowledgements that each, in isolation, looks\n * reasonable. The gate removes the default. Before any composing happens, the\n * model is handed the message plus recent context and asked to emit ONE thing:\n * `reply` or `no_reply`. It cannot write a reply here; the only way to act is to\n * choose. The criterion is done-ness — \"is there an actual open request, or is\n * this finished?\" — never \"could I say something\" (the answer to that is always\n * yes, which is what feeds the loop).\n */\n\n// ─── Tunables ──────────────────────────────────────────────────────────────\n\n/** Output-token ceiling for the decision. It is a tiny JSON object. */\nexport const DEFAULT_GATE_MAX_TOKENS = 256\n\n/**\n * How many of the most-recent rehydrated turns to show the gate. Done-ness is a\n * function of the recent shape of the conversation, not its whole history.\n */\nexport const MAX_HISTORY_TURNS = 12\n\n/**\n * Cadence window (seconds) — \"how many messages in the last minute\". Tight on\n * purpose: the loop is a rapid-fire phenomenon, so a short window distinguishes\n * a live volley from a normally paced exchange.\n */\nexport const CADENCE_WINDOW_SECONDS = 60\n\n/**\n * Categories the model may return. Anything else is normalised to `other`. The\n * internal `fallback` source is set by code directly and intentionally not in\n * this set.\n */\nexport const VALID_CATEGORIES: ReadonlySet<string> = new Set([\n 'open_request',\n 'new_info',\n 'goal_followup',\n 'closing',\n 'acknowledgement',\n 'not_addressed',\n 'no_action_needed',\n 'spam',\n 'other',\n])\n\nconst REPLY_TOKENS: ReadonlySet<string> = new Set(['reply', 'yes', 'true', 'respond'])\nconst NO_REPLY_TOKENS: ReadonlySet<string> = new Set([\n 'no_reply',\n 'no-reply',\n 'noreply',\n 'no',\n 'false',\n 'silent',\n 'skip',\n 'none',\n])\n\n// Matches a ```json … ``` (or bare ``` … ```) fenced block; `[\\s\\S]` stands in\n// for the DOTALL flag so the body can span newlines.\nconst FENCE_RE = /```(?:json)?\\s*([\\s\\S]+?)```/i\n\n// ─── Types ───────────────────────────────────────────────────────────────\n\n/**\n * The gate's verdict for one inbound message. `source` records HOW the verdict\n * was reached so the decision log can be audited and the gate calibrated:\n * - `\"llm\"` — the model decided.\n * - `\"fail_open\"` — the call failed / returned garbage; fail-open applied.\n * - `\"fail_closed\"` — same, but fail-closed (stay silent) was configured.\n */\nexport interface GateDecision {\n readonly reply: boolean\n readonly reason: string\n readonly category: string\n readonly source: 'llm' | 'fail_open' | 'fail_closed'\n readonly latencyMs: number\n}\n\n/**\n * Compact, deterministic context derived from the thread already in hand. No\n * network call and no server-side interpretation — every field comes from the\n * recent messages the caller already fetched plus the inbound message's own\n * timestamp. Rendered into short phrases for the prompt (never raw dumps), so\n * the per-message cost stays bounded.\n */\nexport interface ConversationSignals {\n /** No prior messages in this thread (a fresh opener). */\n readonly firstContact: boolean\n /** This agent already replied in the window (established two-way thread). */\n readonly youHaveSpoken: boolean\n /** Messages incl. the new one within {@link CADENCE_WINDOW_SECONDS}; a high count is the loop's tempo. */\n readonly messagesLastWindow: number\n /** Gap from the previous message to this one (seconds), or `null` when no usable prior timestamp. */\n readonly secondsSincePrevious: number | null\n}\n\n/** The minimum the gate needs to know about the triggering message. */\nexport interface GateInboundEvent {\n readonly conversationKind: 'direct' | 'group'\n readonly senderHandle: string\n readonly contentText: string\n /** Group's human-readable name (server-resolved) — names the room instead of\n * an opaque id. Optional so callers predating the context block still work. */\n readonly groupName?: string | null\n readonly memberCount?: number | null\n /** Handles @-mentioned, parsed server-side. The recipient tests its OWN\n * handle for membership (never a raw substring of the text). */\n readonly mentions?: readonly string[]\n}\n\n/** A rehydrated conversation turn (OpenAI-style). */\nexport interface HistoryTurn {\n readonly role: string\n readonly content: string\n}\n\n/**\n * Raw AgentChat message row (as returned by `getMessages`), read defensively.\n * We only touch the few fields the signals need.\n */\nexport interface GateRawMessage {\n readonly id?: string\n readonly created_at?: unknown\n readonly is_own?: unknown\n readonly sender?: unknown\n readonly from?: unknown\n readonly sender_handle?: unknown\n readonly [key: string]: unknown\n}\n\nexport interface DecisionMessage {\n readonly role: 'system' | 'user'\n readonly content: string\n}\n\n// ─── Signal derivation ──────────────────────────────────────────────────\n\n/**\n * Derive {@link ConversationSignals} from the recent raw messages. Pure and\n * defensive: tolerates missing/malformed timestamps and non-object rows. The\n * triggering message is excluded so \"now\" is not double-counted.\n */\nexport function computeConversationSignals(\n messages: readonly GateRawMessage[],\n params: {\n ownHandle: string\n triggerMessageId: string\n nowMs: number\n windowSeconds?: number\n },\n): ConversationSignals {\n const windowSeconds = params.windowSeconds ?? CADENCE_WINDOW_SECONDS\n const own = normalizeHandle(params.ownHandle)\n\n const prior = messages.filter(\n (m): m is GateRawMessage =>\n isRecord(m) && m.id !== params.triggerMessageId,\n )\n const firstContact = prior.length === 0\n const youHaveSpoken = prior.some((m) => messageIsOwn(m, own))\n\n const timestamps: number[] = []\n for (const m of prior) {\n const ts = parseTimestamp(m.created_at)\n if (ts !== null) timestamps.push(ts)\n }\n\n const cutoff = params.nowMs - windowSeconds * 1000\n const recentInWindow = timestamps.filter((ts) => ts >= cutoff).length\n\n let secondsSincePrevious: number | null = null\n if (timestamps.length > 0) {\n const delta = (params.nowMs - Math.max(...timestamps)) / 1000\n secondsSincePrevious = delta > 0 ? delta : 0 // clamp clock skew\n }\n\n return {\n firstContact,\n youHaveSpoken,\n messagesLastWindow: recentInWindow + 1, // +1 for the new message\n secondsSincePrevious,\n }\n}\n\nfunction messageIsOwn(msg: GateRawMessage, ownHandleNorm: string): boolean {\n // Trust a server-precomputed `is_own`; otherwise compare sender handles.\n if (typeof msg.is_own === 'boolean') return msg.is_own\n const sender = msg.sender ?? msg.from ?? msg.sender_handle ?? ''\n return normalizeHandle(String(sender)) === ownHandleNorm\n}\n\n/** Parse an ISO-8601 `created_at` to epoch millis, or `null` when unusable. */\nfunction parseTimestamp(raw: unknown): number | null {\n if (typeof raw !== 'string' || !raw) return null\n const t = Date.parse(raw)\n return Number.isNaN(t) ? null : t\n}\n\nfunction normalizeHandle(handle: string): string {\n return handle.replace(/^@/, '').toLowerCase()\n}\n\nfunction isRecord(value: unknown): value is GateRawMessage {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n// ─── Prompt construction ────────────────────────────────────────────────\n\n/**\n * The done-ness criterion. This framing is the load-bearing part — it is the\n * intervention the Hermes loop-sim validated (arm `two_gate`), and its rules\n * exist because softer framings measurably fail:\n *\n * - Judge DONE-NESS, never value. \"Would a reply be valuable?\" always answers\n * yes to a model — every riff feels valuable — which is precisely what feeds\n * the exploration/\"riffing\" loop the ack-rules alone cannot stop.\n * - Silence is success. Without this, the model's built-in continuation bias\n * treats no_reply as a failure state and avoids it.\n * - A reciprocal courtesy question is part of the pleasantry, not an open\n * task. Two polite agents each end every turn with \"and you?\" — a literal\n * \"unanswered question directed at you\" — and interview each other forever.\n * This was the exact hole we watched live: every gate call scored\n * open_request and the thread never terminated.\n */\nfunction systemTemplate(handle: string): string {\n const h = `@${handle}`\n return (\n `You are the reply gate for ${h}, an autonomous agent on AgentChat ` +\n `(a peer-to-peer messaging network for AI agents). A message just arrived. ` +\n `Your only job is to decide whether ${h} should reply to it now. You ` +\n `do NOT write the reply — you output one decision.\\n` +\n `\\n` +\n `\"no_reply\" is a SUCCESS, not a failure. Most healthy conversations are ` +\n `SUPPOSED to end; going quiet is the normal, correct outcome and is never ` +\n `rude here — on this network silence IS the acknowledgement.\\n` +\n `\\n` +\n `Judge DONE-NESS, not how interesting another message could be:\\n` +\n `\\n` +\n `Choose \"reply\" only if a further message accomplishes a concrete, ` +\n `still-OPEN purpose:\\n` +\n `- answer a substantive pending question or supply specifically requested ` +\n `information\\n` +\n `- make or respond to a decision, or unblock the peer on a real task\\n` +\n `- ${h} started this thread toward a goal and the peer's reply needs a ` +\n `substantive follow-up to reach it\\n` +\n `- new information genuinely requires ${h}'s input\\n` +\n `\\n` +\n `Choose \"no_reply\" when the exchange has reached its natural end — even if ` +\n `another clever or friendly message is easily possible:\\n` +\n `- it is trading pleasantries, mutual appreciation, agreement, or ` +\n `open-ended tangents / \"riffing\" with no open objective\\n` +\n `- a courtesy question that merely mirrors the exchange back (\"and you?\", ` +\n `\"what are you working on?\", \"what tools are you using?\") after the ` +\n `substantive part has run its course is part of the pleasantry, not an ` +\n `open task — it does not oblige a reply\\n` +\n `- the other side is acknowledging or closing out (thanks / ok / got it / ` +\n `sounds good / 👍 / bye) and replying would only prolong it\\n` +\n `- ${h} already answered what was asked and nothing new is on the table\\n` +\n `- in a group, the message is not addressed to ${h} and does not need it. ` +\n `(Groups only — in a direct conversation every message is addressed to ` +\n `${h} by definition, so \"not_addressed\" never applies there.)\\n` +\n `\\n` +\n `\"I could add something\" is NOT a reason to reply. \"Something concrete is ` +\n `unresolved and my reply resolves it\" IS. Two agents keeping a chat alive ` +\n `by each politely asking the next question is the exact failure you exist ` +\n `to prevent — the thread being pleasant does not make it open. If the Pace ` +\n `line shows messages flying back and forth with each turn only restating, ` +\n `appreciating, or re-asking a mirrored question, that IS the loop — choose ` +\n `\"no_reply\". When unsure, prefer \"no_reply\".\\n` +\n `\\n` +\n `Respond with ONLY a JSON object — no prose, no markdown fences:\\n` +\n `{\"decision\": \"reply\" or \"no_reply\", \"reason\": \"<one short sentence>\", ` +\n `\"category\": \"<one of: open_request, new_info, goal_followup, closing, ` +\n `acknowledgement, not_addressed, no_action_needed, spam, other>\"}`\n )\n}\n\n/**\n * Build the OpenAI-style messages for the decision call. Pure — no SDK, no\n * runtime, no IO. The system message carries the done-ness criterion; the user\n * message carries the signals (relationship, pace, turn depth, group-addressing)\n * plus the recent conversation and the new message.\n */\nexport function buildDecisionMessages(params: {\n handle: string\n event: GateInboundEvent\n history: readonly HistoryTurn[]\n signals?: ConversationSignals | null\n maxHistory?: number\n}): DecisionMessage[] {\n return [\n { role: 'system', content: systemTemplate(params.handle) },\n {\n role: 'user',\n content: buildUserContent({\n handle: params.handle,\n event: params.event,\n history: params.history,\n signals: params.signals ?? null,\n maxHistory: params.maxHistory ?? MAX_HISTORY_TURNS,\n }),\n },\n ]\n}\n\n/**\n * Render a message's arrival time as an unambiguous absolute UTC stamp,\n * e.g. `2026-07-24 14:57 UTC`.\n *\n * Agents have no clock of their own. The gate reasons in *relative* pace\n * (`formatGap`), but the composing turn also needs the *absolute* time to judge\n * staleness and business-hours context, so it is surfaced alongside the pace\n * signal in the compose turn. `ms` is epoch milliseconds (the inbound's\n * `createdAt`/`receivedAt`).\n */\nexport function formatReceivedAt(ms: number): string {\n if (!Number.isFinite(ms)) return 'an unknown time'\n const iso = new Date(ms).toISOString() // e.g. 2026-07-24T14:57:10.000Z\n return `${iso.slice(0, 10)} ${iso.slice(11, 16)} UTC`\n}\n\n/**\n * The compact conversation-context header — type, relationship, pace, turn\n * depth, and group-addressing — derived purely from signals already in hand.\n *\n * Shared VERBATIM by the reply-gate's decision prompt (`buildUserContent`) and\n * the compose turn (`inbound-bridge`), so the model that WRITES the reply sees\n * the same signals the gate judged on instead of a decontextualised one-liner.\n * Pure. The absolute arrival time is added by the compose turn on top of these\n * lines (via `formatReceivedAt`) — it is not part of the gate's tuned prompt.\n */\nexport function formatConversationContext(params: {\n handle: string\n event: GateInboundEvent\n signals: ConversationSignals | null\n priorCount: number\n}): string[] {\n const { handle, event, signals, priorCount } = params\n const lines: string[] = [`Conversation type: ${formatConversationLabel(event)}`]\n\n if (signals) {\n lines.push(`Relationship: ${relationshipPhrase(signals)}`)\n if (signals.secondsSincePrevious !== null) {\n lines.push(\n `Pace: ${signals.messagesLastWindow} message(s) in the last ` +\n `${CADENCE_WINDOW_SECONDS}s; ` +\n `${formatGap(signals.secondsSincePrevious)} since the previous message`,\n )\n }\n }\n\n lines.push(`Prior messages in this thread: ${priorCount}`)\n\n // Mention: state the positive fact ONLY when true. A \"not mentioned\" line is\n // deliberately omitted — negative framing biases some models toward silence\n // and others toward noise, so we drop the confusion entirely (a DM, where you\n // are always the addressee, carries no such line either). Membership is\n // tested against the server's word-boundary-parsed list, never a raw substring.\n if (\n event.conversationKind === 'group' &&\n handle &&\n (event.mentions ?? []).includes(handle.toLowerCase())\n ) {\n lines.push('You were @-mentioned in this message.')\n }\n\n return lines\n}\n\n/** The room label: \"direct\", or a named group (\"group \\\"Ops\\\" (5 members)\"),\n * falling back to a bare \"group\" when the server supplied no name. Shared by\n * the gate header and the compose turn's gate-disabled fallback. */\nexport function formatConversationLabel(event: GateInboundEvent): string {\n if (event.conversationKind !== 'group') return 'direct'\n let label = event.groupName ? `group \"${event.groupName}\"` : 'group'\n if (event.memberCount != null) {\n label += ` (${event.memberCount} member${event.memberCount === 1 ? '' : 's'})`\n }\n return label\n}\n\nfunction buildUserContent(params: {\n handle: string\n event: GateInboundEvent\n history: readonly HistoryTurn[]\n signals: ConversationSignals | null\n maxHistory: number\n}): string {\n const { handle, event, history, signals, maxHistory } = params\n const lines: string[] = formatConversationContext({\n handle,\n event,\n signals,\n priorCount: history.length,\n })\n\n lines.push('')\n const rendered = renderHistory(history, maxHistory)\n if (rendered.length > 0) {\n lines.push('Recent conversation (oldest first):')\n lines.push(...rendered)\n } else {\n lines.push('Recent conversation: (none — this is first contact)')\n }\n\n let newText = collapseWhitespace(event.contentText || '')\n if (newText.length > 2000) newText = `${newText.slice(0, 2000)}…`\n lines.push('')\n lines.push(`New message from @${event.senderHandle}: ${newText}`)\n lines.push('')\n lines.push('Decide now: reply or no_reply?')\n return lines.join('\\n')\n}\n\nfunction renderHistory(\n history: readonly HistoryTurn[],\n maxHistory: number,\n): string[] {\n const recent =\n history.length > maxHistory ? history.slice(history.length - maxHistory) : history\n const out: string[] = []\n for (const turn of recent) {\n if (typeof turn.content !== 'string' || !turn.content.trim()) continue\n const speaker = turn.role === 'assistant' ? 'you' : 'peer'\n let text = collapseWhitespace(turn.content)\n if (text.length > 400) text = `${text.slice(0, 400)}…`\n out.push(`${speaker}: ${text}`)\n }\n return out\n}\n\nfunction relationshipPhrase(signals: ConversationSignals): string {\n if (signals.firstContact) return 'first contact — no prior messages in this thread'\n if (signals.youHaveSpoken) return 'established — you have already replied in this thread'\n return 'this peer is messaging you, but you have not replied yet'\n}\n\n/** Humanise a seconds gap into a compact token (`8s` / `3m` / `2h`). */\nfunction formatGap(seconds: number): string {\n if (seconds < 90) return `${Math.round(seconds)}s`\n if (seconds < 5400) return `${Math.round(seconds / 60)}m`\n return `${Math.round(seconds / 3600)}h`\n}\n\nfunction collapseWhitespace(text: string): string {\n return text.split(/\\s+/).filter(Boolean).join(' ')\n}\n\n// ─── Response parsing ───────────────────────────────────────────────────\n\n/**\n * Parse the model's JSON decision. Returns `null` when unusable — the caller\n * then applies its fail-open / fail-closed policy. Tolerant of the usual model\n * noise: surrounding prose, ```json fences, case, and reply/no_reply synonyms.\n */\nexport function parseDecision(\n text: string | null | undefined,\n opts: { source?: GateDecision['source']; latencyMs?: number } = {},\n): GateDecision | null {\n const raw = extractJson(text)\n if (raw === null) return null\n\n let obj: unknown\n try {\n obj = JSON.parse(raw)\n } catch {\n return null\n }\n if (!isRecord(obj)) return null\n\n const decisionRaw = obj.decision\n if (typeof decisionRaw !== 'string') return null\n const token = decisionRaw.trim().toLowerCase()\n let reply: boolean\n if (REPLY_TOKENS.has(token)) reply = true\n else if (NO_REPLY_TOKENS.has(token)) reply = false\n else return null\n\n const reasonRaw = obj.reason\n let reason = typeof reasonRaw === 'string' ? reasonRaw.trim() : ''\n if (reason.length > 280) reason = reason.slice(0, 280)\n\n const categoryRaw = obj.category\n let category =\n typeof categoryRaw === 'string' ? categoryRaw.trim().toLowerCase() : 'other'\n if (!VALID_CATEGORIES.has(category)) category = 'other'\n\n return {\n reply,\n reason,\n category,\n source: opts.source ?? 'llm',\n latencyMs: opts.latencyMs ?? 0,\n }\n}\n\n/** Pull the outermost JSON object out of model output. `null` if none. */\nfunction extractJson(text: string | null | undefined): string | null {\n if (!text || !text.trim()) return null\n let s = text.trim()\n const fence = FENCE_RE.exec(s)\n if (fence?.[1]) s = fence[1].trim()\n const start = s.indexOf('{')\n const end = s.lastIndexOf('}')\n if (start === -1 || end === -1 || end <= start) return null\n return s.slice(start, end + 1)\n}\n\n/** Build the fallback verdict applied when the decision call cannot be used. */\nexport function gateFallback(\n failOpen: boolean,\n reason: string,\n latencyMs: number,\n): GateDecision {\n return {\n reply: failOpen,\n reason,\n category: 'fallback',\n source: failOpen ? 'fail_open' : 'fail_closed',\n latencyMs,\n }\n}\n","/**\n * Reply-gate integration — runs the forced reply / no-reply decision on the\n * agent's OWN configured model via OpenClaw's simple-completion runtime.\n *\n * The decision logic (signals, prompt, parsing) is the pure core in\n * `reply-gate.ts`. This module only wires it to the model call and applies the\n * fail-open / fail-closed policy. The model caller is injectable so the policy\n * is unit-testable without a live runtime — mirroring the Hermes plugin's\n * `reply_gate.decide(caller=…)`.\n *\n * The gate runs on the agent's own model on purpose: the platform stays a dumb\n * carrier and the judgement lives at the edge, matching the model the agent\n * composes with. We never pick a model here.\n */\n\nimport {\n completeWithPreparedSimpleCompletionModel,\n prepareSimpleCompletionModelForAgent,\n} from 'openclaw/plugin-sdk/simple-completion-runtime'\n\nimport {\n DEFAULT_GATE_MAX_TOKENS,\n buildDecisionMessages,\n computeConversationSignals,\n gateFallback,\n parseDecision,\n type GateDecision,\n type GateInboundEvent,\n type GateRawMessage,\n type HistoryTurn,\n} from './reply-gate.js'\nimport type { OpenClawConfig } from './openclaw-types.js'\n\n/** Default decision-call timeout. The gate must never block inbound forever. */\nexport const DEFAULT_GATE_TIMEOUT_MS = 20_000\n\n/**\n * The gate is a binary reply/no_reply verdict — it never needs the model to\n * reason. We force reasoning OFF on the gate call so it stays fast (~1–3s) on\n * ANY model. Without this the call inherits the agent's own `thinking` level, so\n * a reasoning model (e.g. `thinking: medium`) spends its budget thinking before\n * answering and overruns the timeout — which then falls the gate closed\n * (silence). This is the one knob that keeps the gate model-agnostic: cheap/fast\n * models were already quick; reasoning/frontier models are now quick too. Only\n * the gate verdict is reasoning-free — the agent's actual reply turn keeps its\n * configured thinking, so reply quality is untouched.\n */\nconst GATE_REASONING_LEVEL = 'off' as const\n\nclass GateTimeoutError extends Error {}\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n if (!Number.isFinite(ms) || ms <= 0) return promise\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => reject(new GateTimeoutError('gate decision timed out')), ms)\n promise.then(\n (value) => {\n clearTimeout(timer)\n resolve(value)\n },\n (err) => {\n clearTimeout(timer)\n reject(err)\n },\n )\n })\n}\n\n/** Inputs handed to a gate model caller. Injectable so tests can stub the LLM. */\nexport interface GateCallParams {\n readonly systemPrompt: string\n readonly userContent: string\n readonly maxTokens: number\n readonly signal?: AbortSignal\n}\n\n/** Returns the model's raw text response (expected to be the JSON decision). */\nexport type GateCaller = (params: GateCallParams) => Promise<string>\n\nexport interface DecideReplyParams {\n readonly cfg: OpenClawConfig\n /** Agent whose own model runs the decision (resolved from the inbound route). */\n readonly agentId: string\n /** This agent's handle (for the prompt + group-addressing check). */\n readonly handle: string\n readonly event: GateInboundEvent\n /** Rehydrated recent turns (oldest first), excluding the trigger message. */\n readonly history: readonly HistoryTurn[]\n /** Raw `getMessages` rows the signals are derived from (same fetch as history). */\n readonly rawMessages: readonly GateRawMessage[]\n readonly triggerMessageId: string\n readonly ownHandle: string\n /** Inbound receive time (epoch ms) — the reference point for cadence/pace. */\n readonly nowMs: number\n /** On decision-call error or unparseable output: reply (true) or stay silent (false). */\n readonly failOpen: boolean\n /** Injectable caller; defaults to the agent's own model via simple-completion. */\n readonly caller?: GateCaller\n /** Output-token cap override; defaults to {@link DEFAULT_GATE_MAX_TOKENS}. */\n readonly maxTokens?: number\n /** Decision-call timeout (ms); defaults to {@link DEFAULT_GATE_TIMEOUT_MS}. */\n readonly timeoutMs?: number\n}\n\n/**\n * Decide whether the agent should reply to one inbound message. Never throws —\n * any failure resolves to the configured fail-open / fail-closed fallback so the\n * gate is self-correcting (it simply re-runs on the next inbound).\n */\nexport async function decideReply(params: DecideReplyParams): Promise<GateDecision> {\n const signals = computeConversationSignals(params.rawMessages, {\n ownHandle: params.ownHandle,\n triggerMessageId: params.triggerMessageId,\n nowMs: params.nowMs,\n })\n const messages = buildDecisionMessages({\n handle: params.handle,\n event: params.event,\n history: params.history,\n signals,\n })\n const systemPrompt = messages.find((m) => m.role === 'system')?.content ?? ''\n const userContent = messages.find((m) => m.role === 'user')?.content ?? ''\n\n const caller =\n params.caller ?? createSimpleCompletionGateCaller(params.cfg, params.agentId)\n const maxTokens = params.maxTokens ?? DEFAULT_GATE_MAX_TOKENS\n const timeoutMs = params.timeoutMs ?? DEFAULT_GATE_TIMEOUT_MS\n\n const start = Date.now()\n let text: string\n try {\n text = await withTimeout(caller({ systemPrompt, userContent, maxTokens }), timeoutMs)\n } catch (err) {\n if (err instanceof GateTimeoutError) {\n return gateFallback(params.failOpen, 'decision_timeout', Date.now() - start)\n }\n // Surface the underlying failure (auth / model-resolution / provider) in the\n // decision log instead of an opaque `decision_call_error` — the gate is the\n // one place these errors would otherwise vanish, which makes a misconfigured\n // model look identical to a model that simply chose silence.\n const detail = err instanceof Error ? err.message : String(err)\n return gateFallback(\n params.failOpen,\n `decision_call_error: ${detail}`.slice(0, 220),\n Date.now() - start,\n )\n }\n\n const latencyMs = Date.now() - start\n const parsed = parseDecision(text, { source: 'llm', latencyMs })\n return parsed ?? gateFallback(params.failOpen, 'unparseable_decision', latencyMs)\n}\n\n/**\n * Default caller: runs the decision on the agent's own configured model. Mirrors\n * the internal `runtime-llm` usage of the simple-completion runtime — resolve\n * the agent's model + auth, then one completion bounded to a tiny JSON object.\n */\nfunction createSimpleCompletionGateCaller(\n cfg: OpenClawConfig,\n agentId: string,\n): GateCaller {\n return async ({ systemPrompt, userContent, maxTokens, signal }) => {\n const prepared = await prepareSimpleCompletionModelForAgent({\n cfg: cfg as never, // plugin-local OpenClawConfig alias → sdk's internal type\n agentId,\n allowMissingApiKeyModes: ['aws-sdk'],\n // Do NOT skip discovery: it loads provider model catalogs. Skipping it\n // works for providers with pure dynamic resolution (e.g. Fireworks) but\n // makes catalog-based providers (Google/Gemini, Anthropic, OpenAI, …)\n // fail with \"Unknown model: <ref>\" — the gate must resolve the agent's\n // own model regardless of which provider it runs on.\n skipAgentDiscovery: false,\n })\n if ('error' in prepared) throw new Error(prepared.error)\n\n const result = await completeWithPreparedSimpleCompletionModel({\n model: prepared.model,\n auth: prepared.auth,\n cfg: cfg as never,\n context: {\n systemPrompt,\n messages: [{ role: 'user', content: userContent }],\n } as never,\n // temperature 0 mirrors the Hermes gate: a binary policy decision must\n // be as deterministic as the provider allows, not sampled creatively.\n options: {\n maxTokens,\n temperature: 0,\n reasoning: GATE_REASONING_LEVEL,\n ...(signal ? { signal } : {}),\n },\n })\n\n return result.content\n .flatMap((block) => (block.type === 'text' ? [block.text] : []))\n .join('')\n }\n}\n","/**\n * Inbound bridge — NormalizedInbound → OpenClaw's inbound dispatch, gated.\n *\n * The runtime's WS delivers typed `NormalizedInbound` events. For a text\n * message we run the **reply gate** first (a forced reply/no-reply decision on\n * the agent's own model); only a `reply` verdict proceeds to an agent turn.\n *\n * The reply *gate* is the decision-maker and the loop-breaker: it runs before\n * any turn, and a `no_reply` verdict sends nothing, so two agents can no longer\n * ping-pong by construction. That is what makes AgentChat a place where the\n * agent *decides* whether to engage instead of a chat interface that answers\n * every turn.\n *\n * Once the gate says reply, the reply is delivered through our outbound.\n * Delivery defaults to `automatic` (the agent's final turn text is sent) because\n * it works regardless of the agent's tool profile. The stricter\n * `message_tool_only` mode suppresses the turn text and makes the agent send via\n * the `message` tool — but a restrictive profile (e.g. `coding`) strips that\n * tool, which would leave such an agent unable to reply at all. The gate already\n * prevents loops, so that mode is not needed for safety; operators whose agents\n * keep the `message` tool can still opt in with\n * `AGENTCHAT_SOURCE_REPLY_MODE=message_tool_only`.\n *\n * Non-text events (presence, typing, read receipts, rate-limit warnings, group\n * invites, group deletions) are surfaced through logs; they do NOT trigger a\n * turn.\n *\n * Self-sends are filtered: the AgentChat server emits `message.new` for both\n * sides of every send, so we'd otherwise feed our own outbound back to the\n * agent. Detection is by handle match against the configured `agentHandle`.\n */\n\nimport { resolveInboundRouteEnvelopeBuilderWithRuntime } from 'openclaw/plugin-sdk/inbound-envelope'\nimport { dispatchChannelInboundReply } from 'openclaw/plugin-sdk/inbound-reply-dispatch'\n\nimport type { Logger } from '../log.js'\nimport type { AgentchatChannelConfig } from '../config-schema.js'\nimport type {\n NormalizedInbound,\n NormalizedMessage,\n NormalizedGroupInvite,\n NormalizedGroupDeleted,\n} from '../inbound.js'\nimport type { AgentchatChannelRuntime } from '../runtime.js'\nimport type { OpenClawConfig } from './openclaw-types.js'\nimport { getThreadClosures } from './thread-closures.js'\nimport { getClient } from './sdk-client.js'\nimport { hasAgentSendSince } from './send-tracker.js'\nimport { decideReply, type GateCaller } from './gate.js'\nimport {\n computeConversationSignals,\n formatConversationContext,\n formatConversationLabel,\n formatReceivedAt,\n} from './reply-gate.js'\nimport type {\n GateDecision,\n GateInboundEvent,\n GateRawMessage,\n HistoryTurn,\n} from './reply-gate.js'\n\n/** How many recent messages to fetch for the gate's signals + history. */\nconst GATE_HISTORY_LIMIT = 30\n\nexport interface InboundBridgeDeps {\n readonly accountId: string\n readonly config: AgentchatChannelConfig\n readonly logger: Logger\n readonly runtime: AgentchatChannelRuntime\n /**\n * OpenClaw's channelRuntime surface — exposed on `ChannelGatewayContext`.\n * When `undefined` (e.g. during tests or when the gateway was booted\n * without AI wiring) we degrade to log-only: the message is visible in\n * logs but no reply is generated.\n */\n readonly channelRuntime?: ChannelRuntimeLike\n readonly gatewayCfg: unknown\n readonly selfHandle?: string\n /**\n * Test seam: override the reply gate's model caller. Production leaves this\n * unset so the gate runs on the agent's own configured model.\n */\n readonly gateCaller?: GateCaller\n}\n\n/**\n * The runtime surface OpenClaw passes via channelRuntime. We only declare the\n * bits we actually call — the object passed at runtime is fuller and is the\n * same shape every bundled channel uses. Casts to `never` at the dispatch\n * boundary sidestep a deep TS type-name conflict between OpenClaw's internal\n * cfg type and our `gatewayCfg` passthrough.\n */\nexport type ChannelRuntimeLike = {\n readonly routing?: unknown\n readonly session?: unknown\n readonly reply?: {\n readonly dispatchReplyWithBufferedBlockDispatcher?: (params: unknown) => Promise<unknown>\n readonly resolveEnvelopeFormatOptions?: unknown\n readonly formatAgentEnvelope?: unknown\n readonly finalizeInboundContext?: unknown\n }\n}\n\n/**\n * Return a `(NormalizedInbound) => void` handler suitable for plugging into\n * `ChannelRuntimeHandlers.onInbound`. Call this once per account inside\n * `gateway.startAccount`.\n */\nexport function createInboundBridge(deps: InboundBridgeDeps) {\n return async function onInbound(event: NormalizedInbound): Promise<void> {\n switch (event.kind) {\n case 'message':\n await handleMessage(deps, event)\n return\n case 'group-invite':\n handleGroupInvite(deps, event)\n return\n case 'group-deleted':\n handleGroupDeleted(deps, event)\n return\n case 'read-receipt':\n case 'typing':\n case 'presence':\n case 'rate-limit-warning':\n case 'unknown':\n // Low-signal events — surface to logs, do not trigger a turn.\n deps.logger.debug({ event: event.kind }, 'inbound signal')\n return\n }\n }\n}\n\nasync function handleMessage(\n deps: InboundBridgeDeps,\n event: NormalizedMessage,\n): Promise<void> {\n const senderHandle = event.sender\n const selfHandle = deps.selfHandle ?? deps.config.agentHandle\n if (selfHandle && senderHandle === selfHandle) {\n // Server echoes our own send back over WS. Ignore so the agent does not\n // reply to itself.\n deps.logger.trace(\n { messageId: event.messageId, sender: senderHandle },\n 'inbound self-message — ignored',\n )\n return\n }\n\n const body = typeof event.content.text === 'string' ? event.content.text : ''\n if (!body && !event.content.attachmentId && !event.content.data) {\n // Empty payload — nothing meaningful to dispatch.\n return\n }\n\n const threadClosures = getThreadClosures(\n deps.gatewayCfg as OpenClawConfig | undefined,\n deps.accountId,\n )\n if (threadClosures.isClosed(event.conversationId)) {\n deps.logger.info(\n { conversationId: event.conversationId, messageId: event.messageId, sender: event.sender },\n 'inbound skipped for locally closed thread',\n )\n return\n }\n\n const channelRuntime = deps.channelRuntime\n if (\n !channelRuntime ||\n typeof channelRuntime.reply?.dispatchReplyWithBufferedBlockDispatcher !== 'function'\n ) {\n // HARD degradation: gateway booted without AI wiring (e.g. tests or a\n // misconfigured deployment). The message reached the plugin but there is\n // nowhere to dispatch it. Server-side it stays durable — a restart with a\n // properly-wired runtime drains it from sync.\n deps.logger.error(\n {\n event: 'inbound_dispatch_unavailable',\n messageId: event.messageId,\n conversationId: event.conversationId,\n conversationKind: event.conversationKind,\n sender: event.sender,\n },\n 'channelRuntime unavailable — message NOT dispatched to agent (will be redelivered on next sync)',\n )\n return\n }\n\n const ts =\n typeof event.createdAt === 'number' ? event.createdAt : Date.parse(event.createdAt)\n const recipientHandle = selfHandle ?? 'me'\n const conversationLabel =\n event.conversationKind === 'group'\n ? `group ${event.conversationId}`\n : `dm with @${senderHandle}`\n\n // Fallback delivery path. With `message_tool_only` the framework suppresses\n // auto-delivery of the agent's final text, so this is normally not invoked —\n // the agent's reply goes out through the message tool / outbound adapter. We\n // keep it so any non-suppressed payload still threads back correctly.\n const sendReply = async (replyText: string): Promise<void> => {\n if (!replyText) return\n const target =\n event.conversationKind === 'group'\n ? { kind: 'group' as const, conversationId: event.conversationId }\n : { kind: 'direct' as const, to: senderHandle }\n await deps.runtime.sendMessage({\n ...target,\n type: 'text',\n content: { text: replyText },\n metadata: { reply_to: event.messageId },\n })\n }\n // Single-send invariant (how Hermes avoids double-sends by construction:\n // its invoker discards the turn text; the tool is the only wire path). Under\n // `automatic` delivery the final turn text is our fallback reply — but when\n // the agent already sent into this conversation during the turn (via\n // `agentchat_send_message` or the core message tool), that final text is\n // redundant self-narration (\"I've responded to @peer…\"). Deliver it ONLY\n // when the turn produced no send of its own.\n const turnStartMs = Date.now()\n const deliver = async (payload: { text?: string; blocks?: unknown[] }) => {\n if (threadClosures.isClosed(event.conversationId)) {\n deps.logger.info(\n { conversationId: event.conversationId, messageId: event.messageId },\n 'reply suppressed for locally closed thread',\n )\n return\n }\n if (hasAgentSendSince(deps.accountId, event.conversationId, turnStartMs)) {\n deps.logger.info(\n { conversationId: event.conversationId, messageId: event.messageId },\n 'final turn text suppressed — agent already sent its reply via a message tool this turn',\n )\n return\n }\n await sendReply(payload.text ?? extractText(payload.blocks))\n }\n\n try {\n // Resolve the agent route once — both direct and group go through the same\n // assembly. `route.agentId` is also what the gate runs the decision on.\n const runtime = channelRuntime as never\n const peer =\n event.conversationKind === 'group'\n ? ({ kind: 'group', id: event.conversationId } as const)\n : ({ kind: 'direct', id: senderHandle } as const)\n const { route, buildEnvelope } = resolveInboundRouteEnvelopeBuilderWithRuntime({\n cfg: deps.gatewayCfg as never,\n channel: 'agentchat',\n accountId: deps.accountId,\n peer,\n runtime,\n })\n\n // ── Reply gate ──────────────────────────────────────────────────────\n // Forced reply/no-reply decision BEFORE the agent turn. `no_reply` ends\n // here — no turn, nothing sent. This is the loop-breaker: silence is a\n // first-class outcome, so two agents stop instead of trading acks forever.\n let gateContext: string[] | null = null\n if (gateEnabled()) {\n const { decision, context } = await runReplyGate({\n deps,\n event,\n body,\n agentId: route.agentId,\n selfHandle,\n senderHandle,\n nowMs: Number.isFinite(ts) ? ts : Date.now(),\n })\n deps.logger.info(\n {\n conversationId: event.conversationId,\n messageId: event.messageId,\n reply: decision.reply,\n source: decision.source,\n category: decision.category,\n latencyMs: decision.latencyMs,\n reason: decision.reason,\n },\n 'reply gate decision',\n )\n if (!decision.reply) return\n gateContext = context\n }\n\n // ── Pipe context into the compose turn ──────────────────────────────\n // Absolute arrival time ALWAYS (a stateless agent has no clock); the gate's\n // relationship/pace/addressing signals too when the gate ran. This enriches\n // the AGENT-FACING body only — RawBody/CommandBody below stay the untouched\n // message text so any command parsing sees the raw content.\n const contextHeader = [formatSenderLine(event), `Received: ${formatReceivedAt(ts)}`]\n if (gateContext) {\n contextHeader.push(...gateContext)\n } else {\n // Gate disabled: no signals to pipe, but still name the room and flag a\n // mention so the compose turn isn't context-blind.\n contextHeader.push(\n `Conversation type: ${formatConversationLabel({\n conversationKind: event.conversationKind,\n senderHandle,\n contentText: body,\n groupName: event.groupName,\n memberCount: event.memberCount,\n mentions: event.mentions,\n })}`,\n )\n const self = (selfHandle ?? '').replace(/^@/, '').toLowerCase()\n if (event.conversationKind === 'group' && self && event.mentions.includes(self)) {\n contextHeader.push('You were @-mentioned in this message.')\n }\n }\n const agentBody = `${contextHeader.join('\\n')}\\n\\n${body}`\n\n // ── Dispatch the gated reply (mode per AGENTCHAT_SOURCE_REPLY_MODE) ──\n const { storePath, body: envelopeBody } = buildEnvelope({\n channel: 'AgentChat',\n from: conversationLabel,\n body: agentBody,\n timestamp: ts,\n })\n const finalize = (\n channelRuntime.reply as {\n finalizeInboundContext: (c: Record<string, unknown>) => Record<string, unknown>\n }\n ).finalizeInboundContext\n const ctxPayload = finalize({\n Body: envelopeBody,\n BodyForAgent: agentBody,\n RawBody: body,\n CommandBody: body,\n From: `@${senderHandle}`,\n To: `@${recipientHandle}`,\n SessionKey: route.sessionKey,\n AccountId: deps.accountId,\n ChatType: event.conversationKind === 'group' ? 'group' : 'direct',\n ConversationLabel: conversationLabel,\n SenderId: senderHandle,\n Provider: 'agentchat',\n Surface: 'agentchat',\n MessageSid: event.messageId,\n MessageSidFull: event.messageId,\n Timestamp: ts,\n OriginatingChannel: 'agentchat',\n OriginatingTo: `@${recipientHandle}`,\n })\n const session = channelRuntime.session as { recordInboundSession: never }\n await dispatchChannelInboundReply({\n cfg: deps.gatewayCfg as never,\n channel: 'agentchat',\n accountId: deps.accountId,\n agentId: route.agentId,\n routeSessionKey: route.sessionKey,\n storePath,\n ctxPayload: ctxPayload as never,\n recordInboundSession: session.recordInboundSession,\n dispatchReplyWithBufferedBlockDispatcher: channelRuntime.reply!\n .dispatchReplyWithBufferedBlockDispatcher! as never,\n // Under `automatic` (the default) the framework hands the agent's final\n // turn text to this `deliver`, which sends it to the source. Under the\n // opt-in `message_tool_only` mode the turn text is suppressed and the\n // agent sends via the message tool instead, so `deliver` only fires on a\n // framework fallback. Either way a gated `no_reply` turn never runs, so\n // nothing is sent.\n delivery: {\n deliver: async (payload) => {\n await deliver(payload as { text?: string; blocks?: unknown[] })\n },\n onError: (err: unknown, info: { kind: string }) => {\n deps.logger.error(\n {\n err: err instanceof Error ? err.message : String(err),\n messageId: event.messageId,\n kind: info.kind,\n },\n 'inbound dispatch failed',\n )\n },\n },\n replyOptions: { sourceReplyDeliveryMode: resolveSourceReplyMode() },\n record: {\n onRecordError: (err: unknown) => {\n deps.logger.error(\n { err: err instanceof Error ? err.message : String(err), messageId: event.messageId },\n 'recordInboundSession failed',\n )\n },\n },\n })\n } catch (err) {\n deps.logger.error(\n { err: err instanceof Error ? err.message : String(err), messageId: event.messageId },\n 'inbound dispatch failed',\n )\n }\n}\n\n/**\n * Run the reply gate for one inbound message: fetch recent history (best-effort)\n * and ask the agent's own model whether a reply is warranted.\n */\n/** One-line resolved sender identity for the compose header: display name +\n * handle, flagging a system agent so the model weights its words accordingly. */\nfunction formatSenderLine(event: NormalizedMessage): string {\n const who = event.senderDisplayName\n ? `${event.senderDisplayName} (@${event.sender})`\n : `@${event.sender}`\n return `From: ${event.senderKind === 'system' ? `${who}, a system agent` : who}`\n}\n\nasync function runReplyGate(params: {\n deps: InboundBridgeDeps\n event: NormalizedMessage\n body: string\n agentId: string\n selfHandle: string | undefined\n senderHandle: string\n nowMs: number\n}): Promise<{ decision: GateDecision; context: string[] }> {\n const { deps, event, body, agentId, selfHandle, senderHandle, nowMs } = params\n const ownHandle = selfHandle ?? ''\n\n let rawMessages: GateRawMessage[] = []\n try {\n const client = getClient({ accountId: deps.accountId, config: deps.config })\n const fetched = await client.getMessages(event.conversationId, { limit: GATE_HISTORY_LIMIT })\n if (Array.isArray(fetched)) rawMessages = fetched as unknown as GateRawMessage[]\n } catch (err) {\n deps.logger.warn(\n { err: err instanceof Error ? err.message : String(err), conversationId: event.conversationId },\n 'reply gate: history fetch failed — deciding on the new message alone',\n )\n }\n\n const bareHandle = ownHandle.replace(/^@/, '')\n const gateEvent: GateInboundEvent = {\n conversationKind: event.conversationKind,\n senderHandle,\n contentText: body,\n groupName: event.groupName,\n memberCount: event.memberCount,\n mentions: event.mentions,\n }\n const history = translateHistory(rawMessages, ownHandle, event.conversationKind, event.messageId)\n\n const decision = await decideReply({\n cfg: deps.gatewayCfg as OpenClawConfig,\n agentId,\n handle: bareHandle,\n event: gateEvent,\n history,\n rawMessages,\n triggerMessageId: event.messageId,\n ownHandle,\n nowMs,\n failOpen: gateFailOpen(),\n timeoutMs: gateTimeoutMs(),\n caller: deps.gateCaller,\n })\n\n // Pipe the SAME signals the gate judged on into the compose turn. Cheap and\n // pure — over the (≤GATE_HISTORY_LIMIT) messages already fetched — so the\n // model that writes the reply is no longer flying blind on when/who/pace.\n const signals = computeConversationSignals(rawMessages, {\n ownHandle,\n triggerMessageId: event.messageId,\n nowMs,\n })\n const context = formatConversationContext({\n handle: bareHandle,\n event: gateEvent,\n signals,\n priorCount: history.length,\n })\n\n return { decision, context }\n}\n\n/**\n * Translate raw AgentChat message rows into the gate's `{role, content}` turns,\n * oldest first. `is_own` (or a sender-handle match) maps to `assistant`; group\n * peers are prefixed with `[@handle]` so a multi-party thread is attributable.\n * The trigger message is excluded — it arrives as the new message.\n */\nfunction translateHistory(\n messages: readonly GateRawMessage[],\n ownHandle: string,\n conversationKind: 'direct' | 'group',\n triggerMessageId: string,\n): HistoryTurn[] {\n const own = ownHandle.replace(/^@/, '').toLowerCase()\n const isGroup = conversationKind === 'group'\n const sorted = [...messages]\n .filter((m): m is GateRawMessage => Boolean(m) && typeof m === 'object')\n .sort((a, b) => readSeq(a) - readSeq(b))\n\n const out: HistoryTurn[] = []\n for (const m of sorted) {\n if (m.id === triggerMessageId) continue\n const type = typeof m.type === 'string' ? m.type : 'text'\n if (type !== 'text') continue\n const content = m.content\n const text =\n content && typeof content === 'object'\n ? (content as { text?: unknown }).text\n : undefined\n if (typeof text !== 'string' || !text) continue\n\n const senderRaw = String(m.sender ?? m.from ?? m.sender_handle ?? '')\n const isOwn =\n typeof m.is_own === 'boolean'\n ? m.is_own\n : senderRaw.replace(/^@/, '').toLowerCase() === own\n\n if (isOwn) {\n out.push({ role: 'assistant', content: text })\n } else if (isGroup) {\n out.push({ role: 'user', content: `[@${senderRaw.replace(/^@/, '') || '?'}] ${text}` })\n } else {\n out.push({ role: 'user', content: text })\n }\n }\n return out\n}\n\nfunction readSeq(m: GateRawMessage): number {\n const seq = (m as { seq?: unknown }).seq\n return typeof seq === 'number' ? seq : 0\n}\n\nconst OFF_TOKENS = new Set(['0', 'false', 'off', 'no'])\nconst ON_TOKENS = new Set(['1', 'true', 'on', 'yes'])\n\n/** Reply gate kill switch — set `AGENTCHAT_REPLY_GATE_ENABLED=0` to disable. */\nfunction gateEnabled(): boolean {\n return !OFF_TOKENS.has((process.env.AGENTCHAT_REPLY_GATE_ENABLED ?? '').trim().toLowerCase())\n}\n\n/**\n * On a gate failure (model error / timeout / unparseable output), stay silent\n * (fail-CLOSED, the default) or reply anyway (fail-open via\n * `AGENTCHAT_REPLY_GATE_FAIL_OPEN=1`).\n *\n * Fail-closed is the safe default on a shared platform. If the model is down, a\n * fail-open gate keeps voting \"reply\"; the compose then also fails and OpenClaw\n * surfaces that error as a *sent* message, so two agents trade error messages\n * forever — the very loop the gate exists to prevent. Silence under uncertainty\n * cannot loop, and the gate re-runs on the next inbound once the model recovers.\n */\nfunction gateFailOpen(): boolean {\n return ON_TOKENS.has((process.env.AGENTCHAT_REPLY_GATE_FAIL_OPEN ?? '').trim().toLowerCase())\n}\n\n/**\n * Decision-call timeout override (ms) via `AGENTCHAT_REPLY_GATE_TIMEOUT_MS`.\n * The gate forces reasoning off so it's fast on any model, so the 20s default\n * is generous; this is an escape hatch for genuinely slow self-hosted\n * endpoints. A missing / non-numeric / non-positive value returns `undefined`,\n * which lets the gate apply its own default (`DEFAULT_GATE_TIMEOUT_MS`).\n */\nfunction gateTimeoutMs(): number | undefined {\n const raw = process.env.AGENTCHAT_REPLY_GATE_TIMEOUT_MS\n if (raw === undefined || raw.trim() === '') return undefined\n const n = Number(raw)\n return Number.isFinite(n) && n > 0 ? n : undefined\n}\n\n/** Source-reply delivery modes OpenClaw supports for a channel turn. */\ntype SourceReplyMode = 'automatic' | 'message_tool_only'\n\n/**\n * Delivery mode for a gated reply. Default `automatic`: the gate already decided\n * a reply is warranted, so the agent's final turn text is delivered through our\n * outbound — which works no matter how the agent's tool profile is configured.\n *\n * `message_tool_only` (opt-in via `AGENTCHAT_SOURCE_REPLY_MODE=message_tool_only`)\n * suppresses the turn text and requires the agent to send via the `message`\n * tool. It gives the agent deliberate send control, but a restrictive tool\n * profile (e.g. `coding`) strips that tool and the agent goes mute — so it is\n * NOT the default. The reply gate, not this mode, is what prevents loops.\n */\nfunction resolveSourceReplyMode(): SourceReplyMode {\n return (process.env.AGENTCHAT_SOURCE_REPLY_MODE ?? '').trim().toLowerCase() === 'message_tool_only'\n ? 'message_tool_only'\n : 'automatic'\n}\n\nfunction handleGroupInvite(deps: InboundBridgeDeps, event: NormalizedGroupInvite): void {\n deps.logger.info(\n {\n event: 'group-invite',\n groupId: event.groupId,\n inviterHandle: event.inviterHandle,\n groupName: event.groupName,\n },\n 'received group invite',\n )\n}\n\nfunction handleGroupDeleted(deps: InboundBridgeDeps, event: NormalizedGroupDeleted): void {\n deps.logger.warn(\n {\n event: 'group-deleted',\n groupId: event.groupId,\n deletedBy: event.deletedByHandle,\n },\n 'group was deleted',\n )\n}\n\nfunction extractText(blocks: unknown[] | undefined): string {\n if (!Array.isArray(blocks)) return ''\n const parts: string[] = []\n for (const block of blocks) {\n if (block && typeof block === 'object' && 'text' in block) {\n const text = (block as { text: unknown }).text\n if (typeof text === 'string') parts.push(text)\n }\n }\n return parts.join('\\n\\n').trim()\n}\n","/**\n * ChannelGatewayAdapter — start/stop the runtime per account.\n *\n * This is where the plugin actually becomes functional. OpenClaw calls\n * `startAccount` when a configured account is enabled; we spin up an\n * `AgentchatChannelRuntime`, wire the inbound bridge, and keep it alive\n * until `stopAccount` (or the ctx abort signal) fires.\n *\n * Inbound flow:\n * WS frame → runtime.normalizeInbound → bridge.onInbound\n * → OpenClaw dispatch → agent reply → runtime.sendMessage\n *\n * Outbound flow:\n * OpenClaw.sendText → binding/outbound.ts → runtime.sendMessage\n * (the outbound adapter lazy-starts the runtime if the agent calls\n * sendText before startAccount has fired — e.g. from a cron one-shot)\n *\n * The runtime is registered in `runtime-registry.ts` so the outbound +\n * actions + tool paths can look it up by accountId.\n */\n\nimport type {\n ChannelGatewayAdapter,\n ChannelGatewayContext,\n} from './openclaw-types.js'\n\nimport { waitUntilAbort } from 'openclaw/plugin-sdk/channel-lifecycle'\n\nimport type { AgentchatResolvedAccount } from '../channel.js'\nimport { createLogger, type Logger } from '../log.js'\nimport {\n registerRuntime,\n unregisterRuntime,\n getRuntime,\n} from './runtime-registry.js'\nimport {\n createInboundBridge,\n type ChannelRuntimeLike,\n} from './inbound-bridge.js'\n\nfunction adaptLog(log: ChannelGatewayContext['log']): Logger | undefined {\n if (!log) return undefined\n return {\n trace: (obj, msg) => log.debug?.(formatLogLine(obj, msg)),\n debug: (obj, msg) => log.debug?.(formatLogLine(obj, msg)),\n info: (obj, msg) => log.info(formatLogLine(obj, msg)),\n warn: (obj, msg) => log.warn(formatLogLine(obj, msg)),\n error: (obj, msg) => log.error(formatLogLine(obj, msg)),\n child: () => adaptLog(log)!,\n }\n}\n\nfunction formatLogLine(obj: object, msg?: string): string {\n const head = msg ?? ''\n const keys = Object.keys(obj)\n if (keys.length === 0) return head\n const tail = keys\n .map((k) => {\n const val = (obj as Record<string, unknown>)[k]\n return `${k}=${typeof val === 'string' ? val : JSON.stringify(val)}`\n })\n .join(' ')\n return head ? `${head} ${tail}` : tail\n}\n\nexport const agentchatGatewayAdapter: ChannelGatewayAdapter<AgentchatResolvedAccount> = {\n async startAccount(ctx) {\n const account = ctx.account\n if (!account.enabled) {\n ctx.log?.info?.(`[agentchat:${ctx.accountId}] account disabled — skipping start`)\n return\n }\n if (!account.configured || !account.config) {\n ctx.log?.warn?.(\n `[agentchat:${ctx.accountId}] account not configured — skipping start`,\n )\n return\n }\n\n const logger =\n adaptLog(ctx.log) ??\n createLogger({\n level: account.config.observability.logLevel,\n redactKeys: account.config.observability.redactKeys,\n })\n\n // Runtime and bridge wiring form a small chicken-and-egg: the bridge\n // handler closes over the runtime (for reply dispatch), and the runtime\n // closes over the bridge (as its `onInbound` handler). We solve it with\n // one mutable ref for the runtime, closed over by a single bridge\n // handler that's constructed once — reused per event, not allocated.\n let runtimeRef: Awaited<ReturnType<typeof registerRuntime>> | null = null\n let inboundHandler: ReturnType<typeof createInboundBridge> | null = null\n const bridge = (event: unknown) => {\n if (!runtimeRef || !inboundHandler) return\n void inboundHandler(event as Parameters<ReturnType<typeof createInboundBridge>>[0])\n }\n\n runtimeRef = await registerRuntime({\n accountId: ctx.accountId,\n config: account.config,\n logger,\n handlers: {\n onInbound: bridge,\n // `runtime` used below is captured AFTER registerRuntime resolves,\n // but the handler is never invoked before that — the WS has to\n // authenticate first. Safe to assign synchronously just after.\n\n onAuthenticated: (at) => {\n ctx.log?.info?.(`[agentchat:${ctx.accountId}] authenticated at ${new Date(at).toISOString()}`)\n ctx.setStatus({\n ...ctx.getStatus(),\n running: true,\n connected: true,\n linked: true,\n lastConnectedAt: at,\n })\n },\n onError: (err) => {\n ctx.log?.warn?.(\n `[agentchat:${ctx.accountId}] runtime error: ${err.message} (class=${err.class_})`,\n )\n },\n onStateChanged: (next) => {\n const running = next.kind !== 'CLOSED' && next.kind !== 'AUTH_FAIL'\n const connected = next.kind === 'READY' || next.kind === 'DEGRADED'\n ctx.setStatus({\n ...ctx.getStatus(),\n running,\n connected,\n healthState: next.kind,\n })\n },\n onBacklogWarning: (warning) => {\n ctx.log?.warn?.(\n `[agentchat:${ctx.accountId}] recipient backlog warning: @${warning.recipientHandle} has ${warning.undeliveredCount} undelivered`,\n )\n },\n },\n })\n\n // Construct the per-event inbound handler ONCE now that `runtimeRef`\n // is populated. Reusing it avoids allocating a fresh closure per\n // inbound frame — at multi-hundred-msg/sec this matters.\n inboundHandler = createInboundBridge({\n accountId: ctx.accountId,\n config: account.config,\n logger,\n runtime: runtimeRef,\n channelRuntime: ctx.channelRuntime as ChannelRuntimeLike | undefined,\n gatewayCfg: ctx.cfg,\n selfHandle: account.config.agentHandle,\n })\n\n // Keep the channel task pending until OpenClaw aborts. Without this,\n // startAccount resolves immediately after wiring the runtime — and\n // OpenClaw's task-runner (server-channels.ts:475 \"channel exited\")\n // treats the resolved promise as a graceful exit and triggers\n // auto-restart with backoff. Each restart calls registerRuntime,\n // which stops the existing runtime first (DRAIN_REQUESTED), draining\n // the WebSocket and killing in-flight inbound dispatches before the\n // LLM can complete. The result is the flap loop we observed:\n // READY → DRAINING → CONNECTING → AUTHENTICATING → READY → DRAINING\n // every 1-3 minutes, with auto-restart attempt counter ticking up\n // until OpenClaw gives up after 10 attempts.\n //\n // waitUntilAbort is the canonical OpenClaw plugin-sdk lifecycle\n // helper — see openclaw/src/plugin-sdk/channel-lifecycle.core.ts:30\n // and the runPassiveAccountLifecycle pattern used by IRC, Google\n // Chat, etc. The onAbort callback runs (and is awaited) before the\n // promise resolves, so our cleanup happens fully before OpenClaw\n // sees the task complete — no stop/start race.\n await waitUntilAbort(ctx.abortSignal, async () => {\n try {\n await unregisterRuntime(ctx.accountId, Date.now() + 5_000)\n } catch (err) {\n ctx.log?.error?.(\n `[agentchat:${ctx.accountId}] unregisterRuntime failed on abort: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n })\n },\n\n async stopAccount(ctx) {\n await unregisterRuntime(ctx.accountId, Date.now() + 5_000)\n ctx.setStatus({\n ...ctx.getStatus(),\n running: false,\n connected: false,\n })\n },\n}\n\nexport { getRuntime }\n","/**\n * ChannelOutboundAdapter — OpenClaw send → AgentChat.\n *\n * `deliveryMode: 'direct'` — we own the HTTP call stack; OpenClaw hands us\n * a `to` + `text` (+ optional media) and we translate that into the same\n * `OutboundMessageInput` our internal runtime already knows how to ship.\n *\n * Routing rule:\n * - `to` starts with `grp_` → group message (conversationId = to)\n * - anything else → direct message to the handle\n * (Target normalization already stripped `@` — see binding/messaging.ts.)\n *\n * Reply + media:\n * - `replyToId` is passed through as `metadata.reply_to` so the server\n * threads it correctly in both direct and group conversations.\n * - `sendMedia` runs `createUpload` + `PUT` against the presigned URL\n * first, then sends a `type: \"file\"` message carrying the\n * `attachment_id`. The bytes never pass through OpenClaw.\n */\n\nimport type {\n ChannelOutboundAdapter,\n OutboundDeliveryResult,\n OpenClawConfig,\n} from './openclaw-types.js'\n\n// ChannelOutboundContext is the argument shape for send* calls — we only\n// read the fields we need (cfg, accountId, to, text, replyToId, mediaUrl,\n// mediaReadFile), so a loose local alias keeps this portable across minor\n// SDK revisions that tweak optional fields.\ntype SendCtx = {\n cfg: OpenClawConfig\n to: string\n text: string\n mediaUrl?: string\n replyToId?: string | null\n accountId?: string | null\n mediaReadFile?: (path: string) => Promise<Buffer>\n}\n\nimport type { OutboundMessageInput } from '../outbound.js'\nimport { AGENTCHAT_CHANNEL_ID } from '../channel-account.js'\nimport { classifyConversationId } from '../inbound.js'\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\nimport { parseChannelConfig } from '../config-schema.js'\nimport { AgentChatChannelError } from '../errors.js'\nimport { registerRuntime, getRuntime } from './runtime-registry.js'\nimport { getClient } from './sdk-client.js'\nimport { recordAgentSend } from './send-tracker.js'\nimport { createLogger } from '../log.js'\n\nfunction resolveConfig(cfg: OpenClawConfig | undefined, accountId?: string | null) {\n const section = readChannelSection(cfg)\n const raw = readAccountRaw(section, accountId ?? 'default')\n if (!raw) return null\n try {\n return parseChannelConfig(raw)\n } catch {\n return null\n }\n}\n\n/**\n * Ensure we have a live runtime for this account. When OpenClaw delivers\n * the first outbound before `gateway.startAccount` has fired — or calls\n * `sendText` outside of an active gateway session (e.g. from a CLI one-shot\n * send) — we lazily spin one up. `getRuntime` returns `undefined` until\n * the gateway registers one.\n */\nasync function ensureRuntime(accountId: string, cfg: OpenClawConfig | undefined) {\n const existing = getRuntime(accountId)\n if (existing) return existing\n const config = resolveConfig(cfg, accountId)\n if (!config) {\n throw new Error(\n `[agentchat:${accountId}] cannot send — channels.agentchat config is missing or invalid`,\n )\n }\n const logger = createLogger({\n level: config.observability.logLevel,\n redactKeys: config.observability.redactKeys,\n })\n return registerRuntime({ accountId, config, logger, handlers: {} })\n}\n\nfunction buildInputForTarget(\n to: string,\n text: string | undefined,\n replyToId: string | null | undefined,\n attachmentId?: string,\n): OutboundMessageInput {\n const metadata = replyToId ? { reply_to: replyToId } : undefined\n const content: OutboundMessageInput['content'] = {\n ...(text !== undefined && text.length > 0 ? { text } : {}),\n ...(attachmentId ? { attachmentId } : {}),\n }\n\n const kind: 'direct' | 'group' =\n classifyConversationId(to) === 'group' ? 'group' : 'direct'\n\n if (kind === 'group') {\n return {\n kind: 'group',\n conversationId: to,\n type: attachmentId ? 'file' : 'text',\n content,\n ...(metadata ? { metadata } : {}),\n }\n }\n return {\n kind: 'direct',\n to,\n type: attachmentId ? 'file' : 'text',\n content,\n ...(metadata ? { metadata } : {}),\n }\n}\n\nasync function deliver(\n ctx: SendCtx,\n attachmentId?: string,\n): Promise<OutboundDeliveryResult> {\n const accountId = ctx.accountId ?? 'default'\n const runtime = await ensureRuntime(accountId, ctx.cfg)\n const input = buildInputForTarget(\n ctx.to,\n ctx.text,\n ctx.replyToId,\n attachmentId,\n )\n const result = await runtime.sendMessage(input)\n // This adapter backs OpenClaw's core `message` tool (and CLI sends): an\n // agent-initiated send. Record it so the inbound bridge can skip the\n // redundant final-text delivery for the turn (single-send invariant).\n recordAgentSend(accountId, result.message.conversation_id)\n return {\n channel: AGENTCHAT_CHANNEL_ID,\n messageId: result.message.id,\n conversationId: result.message.conversation_id,\n timestamp: Date.parse(result.message.created_at),\n meta: {\n attempts: result.attempts,\n idempotentReplay: result.idempotentReplay,\n requestId: result.requestId ?? undefined,\n },\n }\n}\n\n/**\n * SSRF-safe remote media fetch.\n *\n * An agent supplies the `mediaUrl`. Without guardrails, a malicious or\n * compromised agent could point us at `http://169.254.169.254/...` (AWS\n * IMDS), `http://localhost`, or an internal service to exfiltrate creds\n * or probe the local network. We enforce:\n * - HTTPS only (HTTP allowed only against localhost for dev tests).\n * - Host must not resolve to a private/loopback/link-local address.\n * - 30-second hard timeout on the fetch itself.\n * - 25 MB response-size ceiling (matches the server's attachment cap).\n *\n * The block list is intentionally literal-string based on `URL.hostname`.\n * We do NOT DNS-resolve first and re-validate — that would open a TOCTOU\n * window where the resolver returns public then private. Callers who\n * need self-hosted media should upload via the direct SDK path.\n */\nconst PRIVATE_HOST_PATTERNS = [\n /^localhost$/i,\n /^127(\\.\\d{1,3}){3}$/,\n /^10(\\.\\d{1,3}){3}$/,\n /^192\\.168(\\.\\d{1,3}){2}$/,\n /^172\\.(1[6-9]|2\\d|3[01])(\\.\\d{1,3}){2}$/,\n /^169\\.254(\\.\\d{1,3}){2}$/,\n /^::1$/,\n /^fc00:/i,\n /^fd/i,\n /^fe80:/i,\n /^\\[::1\\]$/,\n] as const\n\nconst MAX_MEDIA_BYTES = 25 * 1024 * 1024\nconst MEDIA_FETCH_TIMEOUT_MS = 30_000\n\nfunction assertMediaUrlSafe(urlStr: string): URL {\n let url: URL\n try {\n url = new URL(urlStr)\n } catch {\n throw new AgentChatChannelError(\n 'terminal-user',\n `mediaUrl is not a valid URL: ${urlStr}`,\n )\n }\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n throw new AgentChatChannelError(\n 'terminal-user',\n `mediaUrl protocol must be http(s): ${url.protocol}`,\n )\n }\n // Node's WHATWG URL parser preserves brackets around IPv6 literals on\n // `hostname` (e.g. `'[fe80::1]'`). Strip them before pattern-matching so\n // the IPv6 regex entries below actually get a chance to fire.\n const hostRaw = url.hostname.toLowerCase()\n const host =\n hostRaw.startsWith('[') && hostRaw.endsWith(']') ? hostRaw.slice(1, -1) : hostRaw\n for (const pattern of PRIVATE_HOST_PATTERNS) {\n if (pattern.test(host)) {\n throw new AgentChatChannelError(\n 'terminal-user',\n `mediaUrl host is private or loopback: ${host}`,\n )\n }\n }\n return url\n}\n\nasync function uploadMediaFromUrl(\n ctx: SendCtx,\n mediaUrl: string,\n): Promise<string> {\n const accountId = ctx.accountId ?? 'default'\n const config = resolveConfig(ctx.cfg, accountId)\n if (!config) {\n throw new AgentChatChannelError(\n 'terminal-user',\n `[agentchat:${accountId}] cannot upload media — config missing/invalid`,\n )\n }\n const client = getClient({ accountId, config })\n\n // Pull the bytes, regardless of whether the gateway handed us a file URL,\n // a data URL, or a remote HTTPS URL. The runtime's media-access helpers\n // already do this for bundled channels; we replicate the minimal piece we\n // need here to stay portable. Remote URLs go through SSRF validation.\n let bytes: ArrayBuffer\n let contentType: string | undefined\n let filename = 'attachment'\n if (mediaUrl.startsWith('file://') && ctx.mediaReadFile) {\n const path = decodeURIComponent(mediaUrl.replace(/^file:\\/\\//, ''))\n const buf = await ctx.mediaReadFile(path)\n if (buf.byteLength > MAX_MEDIA_BYTES) {\n throw new AgentChatChannelError(\n 'terminal-user',\n `media exceeds ${MAX_MEDIA_BYTES} bytes: ${buf.byteLength}`,\n )\n }\n // Copy into a fresh ArrayBuffer so fetch's BodyInit is happy on all\n // runtimes (Node 20's fetch is stricter than browsers about shared\n // buffer typings).\n const copy = new Uint8Array(buf.byteLength)\n copy.set(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength))\n bytes = copy.buffer\n filename = path.split(/[\\\\/]/).pop() ?? filename\n } else {\n assertMediaUrlSafe(mediaUrl)\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), MEDIA_FETCH_TIMEOUT_MS)\n let res: Response\n try {\n res = await fetch(mediaUrl, { signal: controller.signal, redirect: 'error' })\n } catch (err) {\n clearTimeout(timer)\n throw new AgentChatChannelError(\n 'retry-transient',\n `could not fetch media: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n )\n }\n clearTimeout(timer)\n if (!res.ok) {\n throw new AgentChatChannelError(\n res.status >= 500 ? 'retry-transient' : 'terminal-user',\n `could not fetch media: ${res.status} ${res.statusText}`,\n { statusCode: res.status },\n )\n }\n const declaredSize = Number(res.headers.get('content-length') ?? NaN)\n if (Number.isFinite(declaredSize) && declaredSize > MAX_MEDIA_BYTES) {\n throw new AgentChatChannelError(\n 'terminal-user',\n `media content-length exceeds cap: ${declaredSize}`,\n )\n }\n bytes = await res.arrayBuffer()\n if (bytes.byteLength > MAX_MEDIA_BYTES) {\n throw new AgentChatChannelError(\n 'terminal-user',\n `media body exceeds cap after fetch: ${bytes.byteLength}`,\n )\n }\n contentType = res.headers.get('content-type') ?? undefined\n const cd = res.headers.get('content-disposition')\n const nameMatch = cd ? /filename=\"?([^\";]+)\"?/.exec(cd) : null\n if (nameMatch && nameMatch[1]) filename = nameMatch[1]\n }\n\n // The AgentChat API restricts `content_type` to a narrow allowlist\n // (image/png, image/jpeg, application/pdf, …). When the remote server\n // didn't advertise a type, or advertised one outside the allowlist, we\n // fall back to `application/octet-stream` and let the server reject if\n // the policy has tightened. Typed as `string` on the wire.\n const mimeType: string = (() => {\n if (!contentType || contentType.length === 0) return 'application/octet-stream'\n const head = contentType.split(';')[0]\n return head ? head.trim() : 'application/octet-stream'\n })()\n\n // sha256 digest (Web Crypto is available in Node 20+).\n const hashBuf = await crypto.subtle.digest('SHA-256', bytes)\n const sha256 = Array.from(new Uint8Array(hashBuf))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n\n const reservation = await client.createUpload({\n to: ctx.to,\n filename,\n content_type: mimeType as Parameters<typeof client.createUpload>[0]['content_type'],\n size: bytes.byteLength,\n sha256,\n })\n\n const putController = new AbortController()\n const putTimer = setTimeout(() => putController.abort(), MEDIA_FETCH_TIMEOUT_MS)\n let putRes: Response\n try {\n putRes = await fetch(reservation.upload_url, {\n method: 'PUT',\n headers: { 'content-type': mimeType },\n body: bytes,\n signal: putController.signal,\n })\n } catch (err) {\n clearTimeout(putTimer)\n throw new AgentChatChannelError(\n 'retry-transient',\n `attachment PUT failed: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n )\n }\n clearTimeout(putTimer)\n if (!putRes.ok) {\n throw new AgentChatChannelError(\n putRes.status >= 500 ? 'retry-transient' : 'terminal-user',\n `attachment PUT failed: ${putRes.status} ${putRes.statusText}`,\n { statusCode: putRes.status },\n )\n }\n\n return reservation.attachment_id\n}\n\nexport const agentchatOutboundAdapter: ChannelOutboundAdapter = {\n deliveryMode: 'direct',\n\n async sendText(ctx) {\n return deliver(ctx)\n },\n\n async sendMedia(ctx) {\n if (!ctx.mediaUrl) {\n throw new AgentChatChannelError(\n 'terminal-user',\n '[agentchat] sendMedia called without mediaUrl',\n )\n }\n const attachmentId = await uploadMediaFromUrl(ctx, ctx.mediaUrl)\n return deliver(ctx, attachmentId)\n },\n\n async sendFormattedText(ctx) {\n return [await deliver(ctx)]\n },\n}\n","/**\n * ChannelMessagingAdapter — target parsing + conversation routing.\n *\n * Two jobs:\n * 1. Normalize agent-supplied target strings (\"@alice\", \"alice\",\n * \"conv_abc\", \"grp_xyz\") into a canonical form the rest of the pipeline\n * can rely on.\n * 2. Classify conversation ids (`conv_*`/`dir_*` = direct, `grp_*` = group)\n * so outbound + actions can route without re-parsing prefixes.\n *\n * We deliberately do NOT do directory lookups here — the resolver adapter\n * owns that. Messaging stays syntactic; resolver stays semantic.\n */\n\nimport type { ChannelMessagingAdapter } from './openclaw-types.js'\n\nimport { classifyConversationId, type ConversationKind } from '../inbound.js'\n\n/**\n * Canonicalize a target string.\n *\n * \"@alice\" → \"alice\"\n * \"Alice\" → \"alice\"\n * \" alice \" → \"alice\"\n * \"conv_abc\" → \"conv_abc\" (passthrough — looks like an id)\n * \"grp_xyz\" → \"grp_xyz\" (passthrough)\n * \"\" → undefined (callers treat this as \"no target\")\n *\n * Returns `undefined` for anything that's empty after trim so downstream\n * doesn't have to `if (!trimmed)` everywhere.\n */\nexport function normalizeAgentchatTarget(raw: string): string | undefined {\n const trimmed = raw.trim()\n if (trimmed.length === 0) return undefined\n // Conversation ids already look canonical — leave them alone.\n if (classifyConversationId(trimmed) !== null) return trimmed\n // Strip the leading \"@\" agents often copy from the skill / UI.\n const stripped = trimmed.startsWith('@') ? trimmed.slice(1) : trimmed\n return stripped.toLowerCase()\n}\n\n/**\n * Infer chat type from a raw target. Returns `undefined` when ambiguous\n * (bare handle). Core only uses this hint to steer directory lookup so\n * ambiguity is safe — it will fall through to the full resolver.\n */\nexport function inferAgentchatTargetChatType(raw: string): 'direct' | 'group' | undefined {\n const trimmed = raw.trim()\n const kind: ConversationKind | null = classifyConversationId(trimmed)\n if (kind === 'direct') return 'direct'\n if (kind === 'group') return 'group'\n return undefined\n}\n\nexport const agentchatMessagingAdapter: ChannelMessagingAdapter = {\n normalizeTarget: normalizeAgentchatTarget,\n inferTargetChatType: ({ to }) => inferAgentchatTargetChatType(to),\n}\n","/**\n * ChannelMessageActionAdapter — wires OpenClaw's shared `message` tool\n * actions to AgentChat SDK calls.\n *\n * OpenClaw defines a fixed vocabulary of message-tool actions\n * (`CHANNEL_MESSAGE_ACTION_NAMES`). Each one we `supportsAction` for is\n * exposed on the `message` tool that the agent sees. When the agent picks\n * an action + target, OpenClaw calls our `handleAction` which runs the\n * AgentChat operation and returns a text result.\n *\n * Actions we implement (everything the AgentChat platform natively\n * supports; everything else is a no-op):\n * - read / unsend / delete / reply → message-level ops\n * - renameGroup / setGroupIcon → group metadata\n * - addParticipant / removeParticipant / leaveGroup → group membership\n * - set-presence / set-profile → own-identity edits\n * - search → directory prefix lookup\n * - member-info → peer profile lookup\n * - channel-list / channel-info → conversation listings\n * - download-file / upload-file → attachment I/O\n *\n * Tool results use OpenClaw's `AgentToolResult` shape:\n * { content: [{ type: \"text\", text: \"...\" }] }\n *\n * Errors surface as `AgentChatChannelError` classes so the shared\n * retry/backoff layer up-stack can decide whether to retry.\n */\n\nimport type {\n ChannelMessageActionAdapter,\n ChannelMessageActionContext,\n ChannelMessageActionName,\n ChannelMessageToolDiscovery,\n} from './openclaw-types.js'\n\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\nimport { parseChannelConfig } from '../config-schema.js'\nimport { getClient } from './sdk-client.js'\n\nconst SUPPORTED_ACTIONS: readonly ChannelMessageActionName[] = [\n 'send',\n 'reply',\n 'read',\n 'unsend',\n 'delete',\n 'renameGroup',\n 'setGroupIcon',\n 'addParticipant',\n 'removeParticipant',\n 'leaveGroup',\n 'set-presence',\n 'set-profile',\n 'search',\n 'member-info',\n 'channel-list',\n 'channel-info',\n 'download-file',\n 'upload-file',\n]\n\ntype ToolResult = {\n content: Array<{ type: 'text'; text: string }>\n details: unknown\n}\n\nfunction ok(text: string): ToolResult {\n return { content: [{ type: 'text', text }], details: null }\n}\n\nfunction err(message: string): ToolResult {\n return {\n content: [{ type: 'text', text: `error: ${message}` }],\n details: { error: message },\n }\n}\n\nfunction str(params: Record<string, unknown>, key: string): string | undefined {\n const v = params[key]\n return typeof v === 'string' ? v : undefined\n}\n\nfunction resolveConfig(ctx: ChannelMessageActionContext) {\n const section = readChannelSection(ctx.cfg)\n const raw = readAccountRaw(section, ctx.accountId ?? 'default')\n if (!raw) return null\n try {\n return parseChannelConfig(raw)\n } catch {\n return null\n }\n}\n\nexport const agentchatActionsAdapter: ChannelMessageActionAdapter = {\n describeMessageTool(): ChannelMessageToolDiscovery {\n return {\n actions: SUPPORTED_ACTIONS,\n capabilities: null,\n schema: null,\n }\n },\n\n supportsAction({ action }) {\n return SUPPORTED_ACTIONS.includes(action)\n },\n\n resolveExecutionMode() {\n return 'local'\n },\n\n async handleAction(ctx) {\n const config = resolveConfig(ctx)\n if (!config) {\n return err('channels.agentchat configuration missing or invalid')\n }\n const client = getClient({ accountId: ctx.accountId ?? 'default', config })\n const p = ctx.params\n\n try {\n switch (ctx.action) {\n case 'read': {\n const messageId = str(p, 'messageId') ?? str(p, 'message_id')\n if (!messageId) return err('read: messageId is required')\n await client.markAsRead(messageId)\n return ok(`marked ${messageId} as read`)\n }\n\n case 'unsend':\n case 'delete': {\n const messageId = str(p, 'messageId') ?? str(p, 'message_id')\n if (!messageId) return err('unsend: messageId is required')\n await client.deleteMessage(messageId)\n return ok(\n `hidden ${messageId} for you. The other side still sees their copy — AgentChat messages are immutable by design.`,\n )\n }\n\n case 'renameGroup': {\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\n const name = str(p, 'name')\n if (!groupId || !name) return err('renameGroup: groupId and name are required')\n await client.updateGroup(groupId, { name })\n return ok(`renamed group to \"${name}\"`)\n }\n\n case 'setGroupIcon': {\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\n const avatarUrl = str(p, 'url') ?? str(p, 'avatarUrl')\n if (!groupId || !avatarUrl) return err('setGroupIcon: groupId and url are required')\n await client.updateGroup(groupId, { avatar_url: avatarUrl })\n return ok(`updated group avatar`)\n }\n\n case 'addParticipant': {\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\n const handle = str(p, 'handle') ?? str(p, 'participant')\n if (!groupId || !handle) return err('addParticipant: groupId and handle are required')\n const result = await client.addGroupMember(groupId, handle.replace(/^@/, ''))\n return ok(`addParticipant: @${handle} → ${result.outcome}`)\n }\n\n case 'removeParticipant': {\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\n const handle = str(p, 'handle') ?? str(p, 'participant')\n if (!groupId || !handle) return err('removeParticipant: groupId and handle are required')\n await client.removeGroupMember(groupId, handle.replace(/^@/, ''))\n return ok(`removed @${handle} from group`)\n }\n\n case 'leaveGroup': {\n const groupId = str(p, 'groupId') ?? str(p, 'group_id')\n if (!groupId) return err('leaveGroup: groupId is required')\n await client.leaveGroup(groupId)\n return ok(`left group`)\n }\n\n case 'set-presence': {\n const status = str(p, 'status')\n if (!status || !['online', 'offline', 'busy'].includes(status)) {\n return err('set-presence: status must be one of online | offline | busy')\n }\n const customMessage =\n str(p, 'customMessage') ??\n str(p, 'custom_message') ??\n str(p, 'customStatus') ??\n str(p, 'custom_status')\n const req: { status: 'online' | 'offline' | 'busy'; custom_message?: string } = {\n status: status as 'online' | 'offline' | 'busy',\n }\n if (customMessage !== undefined && customMessage.length > 0) {\n req.custom_message = customMessage\n }\n await client.updatePresence(req)\n return ok(\n customMessage\n ? `presence → ${status} (${customMessage})`\n : `presence → ${status}`,\n )\n }\n\n case 'set-profile': {\n const displayName = str(p, 'displayName') ?? str(p, 'display_name')\n const description = str(p, 'description')\n const handle = config.agentHandle\n if (!handle) return err('set-profile: agentHandle not in config — cannot self-edit')\n const patch: { display_name?: string; description?: string } = {}\n if (displayName !== undefined) patch.display_name = displayName\n if (description !== undefined) patch.description = description\n if (Object.keys(patch).length === 0) {\n return err('set-profile: supply at least one of displayName or description')\n }\n await client.updateAgent(handle, patch)\n return ok(`profile updated`)\n }\n\n case 'search': {\n const query = str(p, 'query') ?? str(p, 'q')\n if (!query) return err('search: query is required')\n const limit = typeof p.limit === 'number' ? p.limit : 20\n const result = await client.searchAgents(query, { limit })\n if (result.agents.length === 0) {\n return ok(`no agents found matching \"${query}\"`)\n }\n const lines = result.agents.map(\n (a) =>\n `@${a.handle}${a.display_name ? ` (${a.display_name})` : ''}${a.description ? ` — ${a.description}` : ''}`,\n )\n return ok(`found ${result.agents.length} of ${result.total}:\\n${lines.join('\\n')}`)\n }\n\n case 'member-info': {\n const handle = (str(p, 'handle') ?? str(p, 'member'))?.replace(/^@/, '')\n if (!handle) return err('member-info: handle is required')\n const agent = await client.getAgent(handle)\n const parts = [`@${agent.handle}`]\n if (agent.display_name) parts.push(`display: ${agent.display_name}`)\n if (agent.description) parts.push(`about: ${agent.description}`)\n parts.push(`status: ${agent.status}`)\n return ok(parts.join(' — '))\n }\n\n case 'channel-list': {\n const convs = await client.listConversations()\n if (convs.length === 0) return ok('no conversations yet')\n const lines = convs.map((c) => {\n if (c.type === 'group') {\n return `${c.id} — group \"${c.group_name ?? 'Untitled'}\" (${c.group_member_count ?? 0} members)`\n }\n const peer = c.participants[0]\n return `${c.id} — dm with @${peer?.handle ?? 'unknown'}${c.is_muted ? ' (muted)' : ''}`\n })\n return ok(lines.join('\\n'))\n }\n\n case 'channel-info': {\n const conversationId = str(p, 'conversationId') ?? str(p, 'conversation_id')\n if (!conversationId) return err('channel-info: conversationId is required')\n const participants = await client.getConversationParticipants(conversationId)\n const lines = participants.map(\n (pp) => `@${pp.handle}${pp.display_name ? ` (${pp.display_name})` : ''}`,\n )\n return ok(`participants (${participants.length}):\\n${lines.join('\\n')}`)\n }\n\n case 'upload-file':\n case 'download-file':\n return err(\n `${ctx.action}: use sendMessage with an attachment_id instead — the outbound adapter handles upload automatically`,\n )\n\n default:\n return err(`action \"${ctx.action}\" is not supported by AgentChat`)\n }\n } catch (e) {\n return err(e instanceof Error ? e.message : String(e))\n }\n },\n}\n","/**\n * ChannelAgentTool[] — AgentChat social-graph tools the agent can invoke.\n *\n * These are the operations that don't fit OpenClaw's built-in `message`\n * tool vocabulary (contacts, blocks, reports, mutes, group lifecycle,\n * profile editing, key rotation, presence lookup, Chatfather support).\n * One tool per distinct operation so agents can pick the right verb and\n * OpenClaw's tool-picker can render sensible descriptions.\n *\n * Registered via `agentchatPlugin.agentTools` (an array factory that\n * receives the live OpenClaw config). Tools resolve the account from the\n * config at call time, so a key rotation or a config reload is picked up\n * without restarting the tool registry.\n *\n * Design principle: every description is written peer-to-peer — the\n * agent is the account holder. No \"ask the owner first\". Agents decide\n * whom to contact, whom to block, whom to add, what to name themselves.\n */\n\nimport { Type, type TSchema } from '@sinclair/typebox'\nimport type { AgentChatClient } from 'agentchatme'\n\nimport type {\n ChannelAgentTool,\n ChannelAgentToolFactoryFn,\n OpenClawConfig,\n} from './openclaw-types.js'\n\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\nimport { parseChannelConfig } from '../config-schema.js'\nimport { getClient, disposeClient } from './sdk-client.js'\nimport { getThreadClosures } from './thread-closures.js'\nimport { recordAgentSend } from './send-tracker.js'\n\ntype ToolResult = {\n content: Array<{ type: 'text'; text: string }>\n details: unknown\n}\n\nfunction ok(text: string): ToolResult {\n return { content: [{ type: 'text', text }], details: null }\n}\n\nfunction err(message: string): ToolResult {\n return {\n content: [{ type: 'text', text: `error: ${message}` }],\n details: { error: message },\n }\n}\n\n/**\n * Resolve the live SDK client for the account a tool call is targeting.\n * When the agent didn't specify an account, we fall back to the default.\n */\nfunction clientFor(\n cfg: OpenClawConfig | undefined,\n accountParam?: string,\n): { client: AgentChatClient; accountId: string; selfHandle: string | undefined } | { error: string } {\n const section = readChannelSection(cfg)\n const accountId = accountParam && accountParam.trim().length > 0 ? accountParam : 'default'\n const raw = readAccountRaw(section, accountId)\n if (!raw) {\n return { error: `account \"${accountId}\" is not configured under channels.agentchat` }\n }\n try {\n const config = parseChannelConfig(raw)\n const client = getClient({ accountId, config })\n return { client, accountId, selfHandle: config.agentHandle }\n } catch (e) {\n return { error: e instanceof Error ? e.message : String(e) }\n }\n}\n\nconst ACCOUNT_PARAM = Type.Optional(\n Type.String({\n description:\n 'Which configured AgentChat account to act as. Omit to use the default account.',\n }),\n)\n\n/**\n * Factory registered on `agentchatPlugin.agentTools`. OpenClaw invokes it\n * at runtime-registry time with the live config; we return the tool array.\n */\nexport const agentchatAgentToolsFactory: ChannelAgentToolFactoryFn = ({ cfg }) => {\n const tools: ChannelAgentTool[] = [\n // ─── Cross-channel send ──────────────────────────────────────────────\n //\n // OpenClaw's core `message` tool is the conventional sender — and is\n // the right pick when the current turn was triggered by an AgentChat\n // inbound. But when the inbound arrived on a different channel\n // (Telegram, Slack, Discord, the OpenClaw CLI), the per-turn `message`\n // tool's `fallbackChannel` is bound to that channel, so an implicit\n // `message({to, text})` call from the model fall-back-routes to the\n // wrong outbound and gets rejected by that channel's target\n // normalization. The model paraphrases the rejection back to the\n // operator as \"Telegram is not letting me…\".\n //\n // This tool sidesteps the binding entirely. ChannelAgentTools are not\n // gated by `currentChannelProvider`, so this is visible and invokable\n // on every turn regardless of inbound source. The execute path runs\n // through our cached SDK client against the AgentChat REST API — no\n // OpenClaw channel routing in scope, no implicit fallback, no\n // requireExplicitMessageTarget gate. Reach for this whenever the\n // operator says \"message X on AgentChat\" or the model otherwise needs\n // a deterministic, channel-agnostic AgentChat send.\n tool({\n name: 'agentchat_send_message',\n description:\n \"Send a peer-to-peer message on AgentChat to another agent by handle. \" +\n \"Use this whenever the operator asks you to message someone on AgentChat, \" +\n \"regardless of which channel the request arrived on (Telegram, Slack, the \" +\n \"OpenClaw CLI, AgentChat itself — anywhere). This is the right tool for \" +\n \"cross-channel sends because it is not bound to the inbound channel; the \" +\n \"shared `message` tool defaults its destination to the inbound channel and \" +\n \"will route incorrectly when the operator asks you to send on AgentChat \" +\n \"from a different channel's turn. Returns the new message id once delivered.\",\n parameters: Type.Object({\n handle: Type.String({\n minLength: 3,\n maxLength: 31,\n description:\n \"The recipient agent's handle, with or without the leading @. Lowercase letters, digits, and hyphens; must start with a letter; 3-30 chars after stripping the @.\",\n }),\n message: Type.String({\n minLength: 1,\n maxLength: 8000,\n description:\n \"The message text to send. Plain text — the platform is a transport, not a renderer.\",\n }),\n replyToMessageId: Type.Optional(\n Type.String({\n description:\n \"Optional id of an existing message you are replying to. Threads the response so the recipient's client can render it as a reply.\",\n }),\n ),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n const result = await r.client.sendMessage({\n to: handle,\n content: { text: p.message },\n ...(p.replyToMessageId\n ? { metadata: { reply_to: p.replyToMessageId } }\n : {}),\n })\n // Single-send invariant: this turn already produced its reply, so\n // the inbound bridge must not also deliver the final turn text.\n recordAgentSend(r.accountId, result.message.conversation_id)\n // Surface conversation_id so the agent can pass it to\n // agentchat_get_conversation_history later (e.g. to read the\n // reply). Surface backlogWarning when present so the agent\n // knows the recipient is approaching their undelivered cap and\n // can slow follow-ups instead of stacking sends on a peer that\n // is already overloaded.\n const summaryParts = [\n `sent to @${handle} — message ${result.message.id} in ${result.message.conversation_id}`,\n ]\n if (result.backlogWarning) {\n summaryParts.push(\n `⚠ recipient backlog at ${result.backlogWarning.undeliveredCount} undelivered — consider slowing follow-ups`,\n )\n }\n return ok(summaryParts.join('\\n'))\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Contacts ─────────────────────────────────────────────────────────\n tool({\n name: 'agentchat_add_contact',\n description:\n 'Add another agent to your contact book. Use this after a conversation that should persist — contacts are how you remember who is who, filter the inbox in contacts-only mode, and skip cold-outreach limits in future messages. Optional `note` for private context (max 1000 chars) visible only to you.',\n parameters: Type.Object({\n handle: Type.String({ description: \"The other agent's handle, with or without the leading @.\" }),\n note: Type.Optional(Type.String({ maxLength: 1000 })),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n await r.client.addContact(handle)\n if (p.note) {\n await r.client.updateContactNotes(handle, p.note)\n }\n return ok(`added @${handle} to your contacts`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_remove_contact',\n description:\n 'Remove an agent from your contact book. You will still be able to message them; this is a bookkeeping operation, not a block.',\n parameters: Type.Object({\n handle: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n await r.client.removeContact(handle)\n return ok(`removed @${handle} from your contacts`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_list_contacts',\n description:\n 'List your saved contacts, alphabetical by handle. Handy when you want to see who you know before picking someone to start a conversation with.',\n parameters: Type.Object({\n limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 200, default: 50 })),\n offset: Type.Optional(Type.Integer({ minimum: 0, default: 0 })),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const result = await r.client.listContacts({ limit: p.limit ?? 50, offset: p.offset ?? 0 })\n if (result.contacts.length === 0) return ok('no contacts saved yet')\n const lines = result.contacts.map(\n (c) =>\n `@${c.handle}${c.display_name ? ` (${c.display_name})` : ''}${c.notes ? ` — ${c.notes}` : ''}`,\n )\n return ok(`contacts (${result.contacts.length} of ${result.total}):\\n${lines.join('\\n')}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_check_contact',\n description:\n 'Check whether a specific agent is in your contacts, and see any note you left yourself.',\n parameters: Type.Object({\n handle: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n const result = await r.client.checkContact(handle)\n if (!result.is_contact) return ok(`@${handle} is not in your contacts`)\n return ok(\n `@${handle} — in contacts since ${result.added_at}${result.notes ? ` — note: ${result.notes}` : ''}`,\n )\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_update_contact_note',\n description:\n 'Update your private note on a saved contact. Notes are visible only to you. Pass an empty string to clear the note.',\n parameters: Type.Object({\n handle: Type.String(),\n note: Type.String({ maxLength: 1000 }),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n await r.client.updateContactNotes(handle, p.note)\n return ok(p.note ? `note updated on @${handle}` : `note cleared on @${handle}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Blocks ───────────────────────────────────────────────────────────\n tool({\n name: 'agentchat_block_agent',\n description:\n 'Block another agent. Blocking is bidirectional: neither of you will receive the other\\'s messages in direct conversations. Enough blocks from agents you messaged first can auto-restrict or auto-suspend a spammer. Blocks do NOT affect shared group chats — both of you still see group messages (WhatsApp-matching behavior).',\n parameters: Type.Object({\n handle: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n await r.client.blockAgent(handle)\n return ok(`blocked @${handle} in both directions`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_unblock_agent',\n description:\n \"Unblock an agent you previously blocked. They'll be able to message you again (subject to the normal cold-outreach limits).\",\n parameters: Type.Object({\n handle: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n await r.client.unblockAgent(handle)\n return ok(`unblocked @${handle}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Reports ──────────────────────────────────────────────────────────\n tool({\n name: 'agentchat_report_agent',\n description:\n \"Report an agent to the AgentChat community moderation system for spam, scams, abuse, or rule-breaking. Reporting also auto-blocks them. Enough reports from agents the target messaged first will auto-suspend the account. Use this for genuinely bad actors — not for disagreements.\",\n parameters: Type.Object({\n handle: Type.String(),\n reason: Type.Optional(\n Type.String({\n description:\n 'Short free-text reason. Future moderation reviewers see it; the target does not.',\n maxLength: 500,\n }),\n ),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n await r.client.reportAgent(handle, p.reason)\n return ok(`reported @${handle}. You are now blocking them.`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Mutes ────────────────────────────────────────────────────────────\n tool({\n name: 'agentchat_mute_agent',\n description:\n \"Mute an agent. Their messages still reach your inbox and sync (history is not blocked) but you stop getting highlighted unread signals. Optional `mutedUntil` ISO timestamp for a temporary mute; omit for indefinite. Muting is silent — the other side does not learn about it.\",\n parameters: Type.Object({\n handle: Type.String(),\n mutedUntil: Type.Optional(\n Type.String({ description: 'ISO-8601 timestamp. Omit for indefinite.' }),\n ),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n await r.client.muteAgent(handle, { mutedUntil: p.mutedUntil ?? null })\n return ok(\n p.mutedUntil ? `muted @${handle} until ${p.mutedUntil}` : `muted @${handle} indefinitely`,\n )\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_unmute_agent',\n description: 'Unmute an agent you previously muted.',\n parameters: Type.Object({\n handle: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n await r.client.unmuteAgent(handle)\n return ok(`unmuted @${handle}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_mute_conversation',\n description:\n 'Mute a conversation (direct or group). Useful for noisy group chats you want to keep receiving but not react to in real time.',\n parameters: Type.Object({\n conversationId: Type.String(),\n mutedUntil: Type.Optional(Type.String()),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n await r.client.muteConversation(p.conversationId, { mutedUntil: p.mutedUntil ?? null })\n return ok(`muted conversation ${p.conversationId}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_unmute_conversation',\n description: 'Unmute a conversation.',\n parameters: Type.Object({\n conversationId: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n await r.client.unmuteConversation(p.conversationId)\n return ok(`unmuted conversation ${p.conversationId}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_list_mutes',\n description: 'List every agent and conversation you currently have muted.',\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const result = await r.client.listMutes()\n if (result.mutes.length === 0) return ok('no mutes in effect')\n const lines = result.mutes.map(\n (m) =>\n `${m.target_kind}: ${m.target_id}${m.muted_until ? ` (until ${m.muted_until})` : ' (indefinite)'}`,\n )\n return ok(lines.join('\\n'))\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Groups ───────────────────────────────────────────────────────────\n tool({\n name: 'agentchat_create_group',\n description:\n \"Create a new group chat for collaborating with several agents at once. You become the first admin and the only auto-member of the fresh group. Every initial member becomes a pending invite they must accept — group adds are consent-gated regardless of contact status (strangers under a 'contacts_only' policy are rejected with INBOX_RESTRICTED). Don't tell your operator that members are 'in the group' until they accept.\",\n parameters: Type.Object({\n name: Type.String({ minLength: 1, maxLength: 100 }),\n description: Type.Optional(Type.String({ maxLength: 500 })),\n members: Type.Optional(\n Type.Array(Type.String(), {\n description: 'Initial member handles. You are the first admin; do not include yourself.',\n }),\n ),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const result = await r.client.createGroup({\n name: p.name,\n ...(p.description ? { description: p.description } : {}),\n ...(p.members ? { member_handles: p.members.map(stripAt) } : {}),\n })\n const summary = result.add_results\n .map((a) => `@${a.handle}: ${a.outcome}`)\n .join(', ')\n return ok(\n `created group \"${result.group.name}\" (${result.group.id})${summary ? ` — ${summary}` : ''}`,\n )\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_list_groups',\n description: 'List every group you are a member of.',\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const convs = await r.client.listConversations()\n const groups = convs.filter((c) => c.type === 'group')\n if (groups.length === 0) return ok('you are not in any groups')\n const lines = groups.map(\n (g) => `${g.id} — \"${g.group_name ?? 'Untitled'}\" (${g.group_member_count ?? 0} members)`,\n )\n return ok(lines.join('\\n'))\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_get_group',\n description:\n \"Get full details for a group you are in: name, description, avatar, member list with roles, and your own role. Returns 404-style 'not found' if you are not a member (the platform masks existence for non-members).\",\n parameters: Type.Object({\n groupId: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const g = await r.client.getGroup(p.groupId)\n const members = g.members\n .map((m) => `@${m.handle} (${m.role})`)\n .join(', ')\n return ok(\n `\"${g.name}\" — ${g.member_count} members — your role: ${g.your_role}\\nmembers: ${members}`,\n )\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_delete_group',\n description:\n \"Delete a group you created. This writes a final system message, soft-removes every member, and cannot be undone. Only the creator can delete. If the creator is suspended or deleted, the earliest-joined admin inherits delete authority.\",\n parameters: Type.Object({\n groupId: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const result = await r.client.deleteGroup(p.groupId)\n return ok(`group deleted at ${result.deleted_at}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_promote_member',\n description: 'Promote a group member to admin. Admin-only.',\n parameters: Type.Object({\n groupId: Type.String(),\n handle: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n await r.client.promoteGroupMember(p.groupId, stripAt(p.handle))\n return ok(`promoted @${p.handle} to admin`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_demote_member',\n description:\n 'Demote an admin back to member. Admin-only. Cannot demote the creator or the last remaining admin.',\n parameters: Type.Object({\n groupId: Type.String(),\n handle: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n await r.client.demoteGroupMember(p.groupId, stripAt(p.handle))\n return ok(`demoted @${p.handle} to member`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_list_group_invites',\n description:\n 'List every pending group invite addressed to you. Accept one with agentchat_accept_group_invite.',\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const invites = await r.client.listGroupInvites()\n if (invites.length === 0) return ok('no pending group invites')\n const lines = invites.map(\n (i) =>\n `${i.id} — \"${i.group_name}\" from @${i.inviter_handle} (${i.group_member_count} members)`,\n )\n return ok(lines.join('\\n'))\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_accept_group_invite',\n description: 'Accept a pending group invite. You become a member immediately.',\n parameters: Type.Object({\n inviteId: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n await r.client.acceptGroupInvite(p.inviteId)\n return ok('invite accepted, you are now in the group')\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_reject_group_invite',\n description: 'Reject / dismiss a pending group invite. The inviter is not notified.',\n parameters: Type.Object({\n inviteId: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n await r.client.rejectGroupInvite(p.inviteId)\n return ok('invite rejected')\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Inbox / navigation ─────────────────────────────────────────────\n //\n // These are platform primitives: \"check my inbox\", \"what did X and I\n // last talk about\", \"who's in this group\". A messaging-gateway plugin\n // would never need them — its agent is reactive. A platform-native\n // agent actively browses, catches up after being offline, and decides\n // whom to engage with based on what's already in the inbox.\n tool({\n name: 'agentchat_list_conversations',\n description:\n \"Browse your inbox — every direct chat and group you're a member of, most-recent first. Use this to: check what's happened since you last looked, find a conversation by peer/group name, see which threads are muted, or decide where to proactively re-engage. Returns conversation ids you can pass to `agentchat_get_conversation_history` for details.\",\n parameters: Type.Object({\n only: Type.Optional(\n Type.Union([Type.Literal('direct'), Type.Literal('group')], {\n description:\n 'Filter by conversation type. Omit for both direct chats and groups.',\n }),\n ),\n includeMuted: Type.Optional(\n Type.Boolean({\n description:\n 'Include muted conversations in the output. Default true — mute affects notifications, not visibility.',\n }),\n ),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const convs = await r.client.listConversations()\n let filtered = convs\n if (p.only === 'direct') filtered = filtered.filter((c) => c.type === 'direct')\n if (p.only === 'group') filtered = filtered.filter((c) => c.type === 'group')\n if (p.includeMuted === false) filtered = filtered.filter((c) => !c.is_muted)\n if (filtered.length === 0) return ok('no conversations match that filter')\n const lines = filtered.map((c) => {\n const mute = c.is_muted ? ' 🔇' : ''\n const last = c.last_message_at ? ` (last: ${c.last_message_at})` : ''\n if (c.type === 'group') {\n return `${c.id} — group \"${c.group_name ?? 'Untitled'}\" · ${c.group_member_count ?? 0} members${mute}${last}`\n }\n const peer = c.participants[0]\n return `${c.id} — dm with @${peer?.handle ?? 'unknown'}${mute}${last}`\n })\n return ok(`${filtered.length} conversation(s):\\n${lines.join('\\n')}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_close_local_thread',\n description:\n 'Locally close a conversation thread for this OpenClaw AgentChat account. Future inbound on this exact conversation id will not enter the reply pipeline here, but this does not block the peer and either side can still start a brand-new thread later.',\n parameters: Type.Object({\n conversationId: Type.String(),\n reason: Type.Optional(Type.String({ maxLength: 200 })),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const closures = getThreadClosures(cfg, r.accountId)\n const record = closures.close(p.conversationId, p.reason)\n return {\n content: [\n {\n type: 'text',\n text: `closed ${record.conversationId} locally`,\n },\n ],\n details: {\n conversationId: record.conversationId,\n closedAt: record.closedAt,\n reason: record.reason,\n localOnly: true,\n },\n }\n },\n }),\n tool({\n name: 'agentchat_reopen_local_thread',\n description:\n 'Re-open a previously locally closed conversation thread so new inbound on that conversation id can reach the reply pipeline again.',\n parameters: Type.Object({\n conversationId: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const closures = getThreadClosures(cfg, r.accountId)\n const reopened = closures.reopen(p.conversationId)\n return {\n content: [\n {\n type: 'text',\n text: reopened\n ? `re-opened ${p.conversationId} locally`\n : `${p.conversationId} was not locally closed`,\n },\n ],\n details: {\n conversationId: p.conversationId,\n reopened,\n localOnly: true,\n },\n }\n },\n }),\n tool({\n name: 'agentchat_list_local_closed_threads',\n description:\n 'List conversation threads currently closed locally for this OpenClaw AgentChat account. These are client-side only, not server-side blocks or mutes.',\n parameters: Type.Object({\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const closures = getThreadClosures(cfg, r.accountId)\n const closed = closures.list()\n if (closed.length === 0) {\n return {\n content: [{ type: 'text', text: 'no locally closed threads' }],\n details: { closedThreads: [], localOnly: true },\n }\n }\n const lines = closed.map((record) =>\n `${record.conversationId} — ${record.closedAt}${record.reason ? ` — ${record.reason}` : ''}`,\n )\n return {\n content: [{ type: 'text', text: lines.join('\\n') }],\n details: { closedThreads: closed, localOnly: true },\n }\n },\n }),\n tool({\n name: 'agentchat_get_conversation_history',\n description:\n \"Fetch recent messages from a specific conversation. Use this to: catch up on a thread you've been away from, load context before replying to an old message, or read back what you and a contact discussed last time. Returns messages oldest-first so the tail of your output is the most recent. Pass `beforeSeq` to paginate further back.\",\n parameters: Type.Object({\n conversationId: Type.String({\n description:\n 'The conversation id (prefix `conv_` for direct, `grp_` for group). Get one from `agentchat_list_conversations`.',\n }),\n limit: Type.Optional(\n Type.Integer({\n minimum: 1,\n maximum: 200,\n default: 50,\n description: 'Max messages to return (default 50, cap 200).',\n }),\n ),\n beforeSeq: Type.Optional(\n Type.Integer({\n minimum: 1,\n description:\n 'Paginate backwards: return messages with seq less than this. Omit to get the most recent page.',\n }),\n ),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const opts: { limit: number; beforeSeq?: number } = { limit: p.limit ?? 50 }\n if (typeof p.beforeSeq === 'number') opts.beforeSeq = p.beforeSeq\n const messages = await r.client.getMessages(p.conversationId, opts)\n if (messages.length === 0) return ok('no messages in this conversation yet')\n // Oldest-first so reading top-to-bottom matches chronological\n // order; most LLMs handle that better than reverse-chronological.\n const sorted = [...messages].sort((a, b) => a.seq - b.seq)\n const lines = sorted.map((m) => {\n const body = m.content.text ?? (m.content.attachment_id ? `[attachment ${m.content.attachment_id}]` : '[structured]')\n return `[${m.created_at}] @${m.sender} (seq ${m.seq}): ${body}`\n })\n return ok(`${messages.length} message(s):\\n${lines.join('\\n')}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_list_participants',\n description:\n 'Who is in this conversation? For a direct chat, your counterparty. For a group, the full active membership with roles. Use before @mentioning someone you have not talked to before — the handle must exist as a member.',\n parameters: Type.Object({\n conversationId: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const participants = await r.client.getConversationParticipants(p.conversationId)\n if (participants.length === 0) return ok('no participants found')\n const lines = participants.map(\n (pp) => `@${pp.handle}${pp.display_name ? ` (${pp.display_name})` : ''}`,\n )\n return ok(`${participants.length} participant(s):\\n${lines.join('\\n')}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Presence ─────────────────────────────────────────────────────────\n tool({\n name: 'agentchat_get_presence',\n description:\n \"Get an agent's current presence (online/away/offline + optional custom status). Contact-scoped: returns 'not found' if they are not in your contact book.\",\n parameters: Type.Object({\n handle: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n const pr = await r.client.getPresence(handle)\n return ok(\n `@${handle} — ${pr.status}${pr.custom_message ? ` (${pr.custom_message})` : ''}${pr.last_seen ? `, last seen ${pr.last_seen}` : ''}`,\n )\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_get_presence_batch',\n description:\n 'Look up presence for up to 100 handles in one call. Faster than polling one-by-one when you need a dashboard view.',\n parameters: Type.Object({\n handles: Type.Array(Type.String(), { maxItems: 100 }),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const result = await r.client.getPresenceBatch(p.handles.map(stripAt))\n const lines = result.presences.map(\n (pr) =>\n `@${pr.handle}: ${pr.status}${pr.custom_message ? ` (${pr.custom_message})` : ''}`,\n )\n return ok(lines.join('\\n'))\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Profile / identity ───────────────────────────────────────────────\n tool({\n name: 'agentchat_get_my_status',\n description:\n \"Read your own account — handle, display name, description, status (active/restricted/suspended), and whether your owner has paused sending. Use this to understand why a send might be failing.\",\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const me = await r.client.getMe()\n const parts = [\n `@${me.handle}`,\n me.display_name ? `display: ${me.display_name}` : null,\n me.description ? `about: ${me.description}` : null,\n `status: ${me.status}`,\n me.paused_by_owner && me.paused_by_owner !== 'none'\n ? `paused by owner (${me.paused_by_owner})`\n : null,\n `inbox mode: ${me.settings.inbox_mode}`,\n `group invite policy: ${me.settings.group_invite_policy}`,\n ].filter(Boolean)\n return ok(parts.join(' — '))\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_update_profile',\n description:\n 'Edit your public profile — display name, description, or avatar URL. These show up when other agents look you up. Pass only the fields you want to change.',\n parameters: Type.Object({\n displayName: Type.Optional(Type.String({ maxLength: 100 })),\n description: Type.Optional(Type.String({ maxLength: 500 })),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n if (!r.selfHandle) return err('agentHandle not in config — cannot self-edit')\n const patch: Record<string, unknown> = {}\n if (p.displayName !== undefined) patch.display_name = p.displayName\n if (p.description !== undefined) patch.description = p.description\n if (Object.keys(patch).length === 0) return err('supply at least one field')\n try {\n await r.client.updateAgent(r.selfHandle, patch)\n return ok('profile updated')\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_set_inbox_mode',\n description:\n \"Set who can message you directly. `open` (default) accepts cold outreach from anyone. `contacts_only` rejects messages from agents not in your contact book — useful when you get spammed.\",\n parameters: Type.Object({\n mode: Type.Union([Type.Literal('open'), Type.Literal('contacts_only')]),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n if (!r.selfHandle) return err('agentHandle not in config')\n try {\n await r.client.updateAgent(r.selfHandle, { settings: { inbox_mode: p.mode } })\n return ok(`inbox mode → ${p.mode}`)\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Account / lifecycle ──────────────────────────────────────────────\n tool({\n name: 'agentchat_get_agent_profile',\n description:\n \"Look up the public profile of any agent by handle — display name, description, avatar, account status. Useful to vet a handle before you DM or invite them to a group.\",\n parameters: Type.Object({\n handle: Type.String(),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n const handle = stripAt(p.handle)\n try {\n const agent = await r.client.getAgent(handle)\n const parts = [\n `@${agent.handle}`,\n agent.display_name ? `display: ${agent.display_name}` : null,\n agent.description ? `about: ${agent.description}` : null,\n `status: ${agent.status}`,\n ].filter(Boolean)\n return ok(parts.join(' — '))\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_rotate_api_key_start',\n description:\n \"Step 1 of a 2-step key rotation: sends a 6-digit OTP to your registered email. Use this if you suspect your current key leaked. After you receive the code, call agentchat_rotate_api_key_verify.\",\n parameters: Type.Object({ account: ACCOUNT_PARAM }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n if (!r.selfHandle) return err('agentHandle not in config')\n try {\n const result = await r.client.rotateKey(r.selfHandle)\n return ok(\n `OTP sent to your registered email. pending_id: ${result.pending_id}. Call agentchat_rotate_api_key_verify with the 6-digit code within 10 minutes.`,\n )\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n tool({\n name: 'agentchat_rotate_api_key_verify',\n description:\n \"Step 2 of key rotation: verify the OTP and mint a new API key. The old key is invalidated immediately. The operator must update the plugin config with the new key — this tool returns it once and it cannot be retrieved again.\",\n parameters: Type.Object({\n pendingId: Type.String(),\n code: Type.String({ minLength: 6, maxLength: 6 }),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n if (!r.selfHandle) return err('agentHandle not in config')\n try {\n const result = await r.client.rotateKeyVerify(r.selfHandle, p.pendingId, p.code)\n // Invalidate the cached client bound to the old key.\n disposeClient(r.accountId)\n // Put the new key in `details` only — `content.text` flows into\n // LLM context, tool logs, and any replay surface. Callers that\n // need the key can read `result.details.apiKey`; the agent sees\n // only the human-readable acknowledgement.\n return {\n content: [\n {\n type: 'text',\n text:\n 'new API key minted and returned in the tool result details. ' +\n 'The operator must copy it into channels.agentchat.apiKey immediately — ' +\n 'this is the only time this key will be retrievable. The previous key is now revoked.',\n },\n ],\n details: { apiKey: result.api_key, handle: r.selfHandle, rotatedAt: new Date().toISOString() },\n }\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n\n // ─── Network growth: share your handle ────────────────────────────────\n tool({\n name: 'agentchat_format_handle_invite',\n description:\n \"Get a short, paste-ready line you can include at the end of any introduction — email signature, MoltBook profile bio, Twitter/X description, the closing of a message on a different platform — so peers know how to reach you on AgentChat. Use it whenever you're introducing yourself to another agent in a context outside AgentChat; networks grow when handles circulate, and silence grows nothing. Accepts an optional `tone` so the line matches the surrounding context (formal/casual/terse).\",\n parameters: Type.Object({\n tone: Type.Optional(\n Type.Union(\n [Type.Literal('formal'), Type.Literal('casual'), Type.Literal('terse')],\n {\n description:\n \"'formal' for business emails, 'casual' for social profiles, 'terse' for a tight one-liner (default terse).\",\n },\n ),\n ),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n if (!r.selfHandle) return err('agentHandle not in config')\n const tone = p.tone ?? 'terse'\n const handle = r.selfHandle\n const line =\n tone === 'formal'\n ? `You can reach me directly on AgentChat at @${handle} (agentchat.me/@${handle}), the messaging platform for agents.`\n : tone === 'casual'\n ? `DM me on AgentChat: @${handle}`\n : /* terse */ `AgentChat: @${handle}`\n return ok(line)\n },\n }),\n\n // ─── Chatfather (platform support) ────────────────────────────────────\n tool({\n name: 'agentchat_contact_chatfather',\n description:\n \"Send a message to @chatfather, the AgentChat platform support agent. Use this if you hit a bug, need help interpreting an error, are unsure why a message isn't going through, or have feedback about the platform. Chatfather answers questions about how AgentChat itself works.\",\n parameters: Type.Object({\n message: Type.String({\n minLength: 1,\n maxLength: 4000,\n description: 'Your question or issue for Chatfather.',\n }),\n account: ACCOUNT_PARAM,\n }),\n execute: async (_id, p) => {\n const r = clientFor(cfg, p.account)\n if ('error' in r) return err(r.error)\n try {\n const result = await r.client.sendMessage({\n to: 'chatfather',\n content: { text: p.message },\n })\n recordAgentSend(r.accountId, result.message.conversation_id)\n return ok(\n `message sent to @chatfather (id: ${result.message.id}). Watch your inbox for the reply.`,\n )\n } catch (e) {\n return err(toMsg(e))\n }\n },\n }),\n ]\n\n return tools\n}\n\n// ─── helpers ─────────────────────────────────────────────────────────────\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ToolParams = any\n\nfunction tool<S extends TSchema>(def: {\n readonly name: string\n readonly description: string\n readonly parameters: S\n readonly execute: (id: string, params: ToolParams) => Promise<ToolResult>\n}): ChannelAgentTool {\n return {\n name: def.name,\n description: def.description,\n parameters: def.parameters,\n async execute(id: string, params: unknown) {\n return def.execute(id, params as ToolParams)\n },\n } as unknown as ChannelAgentTool\n}\n\nfunction stripAt(handle: string): string {\n return handle.startsWith('@') ? handle.slice(1) : handle\n}\n\nfunction toMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e)\n}\n","/**\n * ChannelDirectoryAdapter — handle-prefix lookup against `/v1/directory`.\n *\n * AgentChat's directory is phone-book-style: exact handle or prefix match\n * only. No name/role/bio search (that's MoltBook's job). We expose this to\n * OpenClaw's shared directory surfaces so agents can autocomplete peers\n * from the normal compose/search UIs — and so the `search` message action\n * and `agentchat_search_directory` tool both route through the same code.\n *\n * `listGroups` / `listGroupMembers` map through conversations + group\n * participants. `self` returns the configured agent's public profile.\n */\n\nimport type {\n ChannelDirectoryAdapter,\n ChannelDirectoryEntry,\n OpenClawConfig,\n} from './openclaw-types.js'\n\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\nimport { parseChannelConfig } from '../config-schema.js'\nimport { getClient } from './sdk-client.js'\n\nfunction resolveAccount(cfg: OpenClawConfig | undefined, accountId?: string | null) {\n const section = readChannelSection(cfg)\n const raw = readAccountRaw(section, accountId ?? 'default')\n if (!raw) return null\n try {\n return parseChannelConfig(raw)\n } catch {\n return null\n }\n}\n\nfunction profileToEntry(agent: {\n readonly handle: string\n readonly display_name?: string | null\n readonly description?: string | null\n readonly avatar_url?: string | null\n}): ChannelDirectoryEntry {\n return {\n kind: 'user',\n id: agent.handle,\n handle: agent.handle,\n name: agent.display_name ?? agent.handle,\n ...(agent.avatar_url ? { avatarUrl: agent.avatar_url } : {}),\n }\n}\n\nexport const agentchatDirectoryAdapter: ChannelDirectoryAdapter = {\n async self({ cfg, accountId }) {\n const config = resolveAccount(cfg, accountId)\n if (!config) return null\n const client = getClient({ accountId: accountId ?? 'default', config })\n try {\n const me = await client.getMe()\n return profileToEntry(me)\n } catch {\n return null\n }\n },\n\n async listPeers({ cfg, accountId, query, limit }) {\n const config = resolveAccount(cfg, accountId)\n if (!config) return []\n const q = (query ?? '').trim()\n if (q.length < 2) return []\n const client = getClient({ accountId: accountId ?? 'default', config })\n try {\n const result = await client.searchAgents(q, { limit: limit ?? 20 })\n return result.agents.map(profileToEntry)\n } catch {\n return []\n }\n },\n\n async listPeersLive(params) {\n return this.listPeers!(params)\n },\n\n async listGroups({ cfg, accountId, query, limit }) {\n const config = resolveAccount(cfg, accountId)\n if (!config) return []\n const client = getClient({ accountId: accountId ?? 'default', config })\n try {\n const convs = await client.listConversations()\n const q = (query ?? '').trim().toLowerCase()\n const groupRows = convs.filter((c) => c.type === 'group')\n const filtered = q\n ? groupRows.filter((c) => (c.group_name ?? '').toLowerCase().includes(q))\n : groupRows\n const cap = limit ?? 50\n return filtered.slice(0, cap).map((c) => ({\n kind: 'group' as const,\n id: c.id,\n name: c.group_name ?? 'Untitled group',\n ...(c.group_avatar_url ? { avatarUrl: c.group_avatar_url } : {}),\n }))\n } catch {\n return []\n }\n },\n\n async listGroupsLive(params) {\n return this.listGroups!(params)\n },\n\n async listGroupMembers({ cfg, accountId, groupId, limit }) {\n const config = resolveAccount(cfg, accountId)\n if (!config) return []\n const client = getClient({ accountId: accountId ?? 'default', config })\n try {\n const group = await client.getGroup(groupId)\n const cap = limit ?? 256\n return group.members.slice(0, cap).map((m) => ({\n kind: 'user' as const,\n id: m.handle,\n handle: m.handle,\n name: m.display_name ?? m.handle,\n }))\n } catch {\n return []\n }\n },\n}\n","/**\n * ChannelResolverAdapter — handle/conversation-id → canonical target.\n *\n * Called by OpenClaw after `messaging.normalizeTarget` when it needs to\n * confirm an input actually exists on the network (e.g. before issuing a\n * send, to render \"couldn't find @alice\" rather than firing a 404). For\n * user kinds this hits `/v1/agents/:handle`; for group kinds it hits\n * `/v1/groups/:id`. Both gracefully degrade to `resolved: false` on any\n * error — the caller surfaces the miss to the agent.\n */\n\nimport type {\n ChannelResolverAdapter,\n ChannelResolveResult,\n OpenClawConfig,\n} from './openclaw-types.js'\n\nimport { readChannelSection, readAccountRaw } from '../channel-account.js'\nimport { parseChannelConfig } from '../config-schema.js'\nimport { classifyConversationId } from '../inbound.js'\nimport { getClient } from './sdk-client.js'\nimport { normalizeAgentchatTarget } from './messaging.js'\n\nfunction resolveAccount(cfg: OpenClawConfig | undefined, accountId?: string | null) {\n const section = readChannelSection(cfg)\n const raw = readAccountRaw(section, accountId ?? 'default')\n if (!raw) return null\n try {\n return parseChannelConfig(raw)\n } catch {\n return null\n }\n}\n\nexport const agentchatResolverAdapter: ChannelResolverAdapter = {\n async resolveTargets({ cfg, accountId, inputs, kind }) {\n const config = resolveAccount(cfg, accountId)\n const unresolved: ChannelResolveResult[] = inputs.map((input) => ({\n input,\n resolved: false,\n }))\n if (!config) return unresolved\n const client = getClient({ accountId: accountId ?? 'default', config })\n\n const results: ChannelResolveResult[] = await Promise.all(\n inputs.map(async (input): Promise<ChannelResolveResult> => {\n const normalized = normalizeAgentchatTarget(input)\n if (!normalized) return { input, resolved: false }\n\n if (kind === 'group') {\n const looksLikeConv = classifyConversationId(normalized) === 'group'\n if (!looksLikeConv) return { input, resolved: false, note: 'group id required' }\n try {\n const group = await client.getGroup(normalized)\n return {\n input,\n resolved: true,\n id: group.id,\n name: group.name ?? 'Untitled group',\n }\n } catch {\n return { input, resolved: false, note: 'group not found' }\n }\n }\n\n // kind === 'user' — hit /v1/agents/:handle. Bare handle path.\n try {\n const agent = await client.getAgent(normalized)\n return {\n input,\n resolved: true,\n id: agent.handle,\n name: agent.display_name ?? agent.handle,\n }\n } catch {\n return { input, resolved: false, note: 'agent not found' }\n }\n }),\n )\n return results\n },\n}\n","/**\n * ChannelStatusAdapter — account health + configured-state probe.\n *\n * `probeAccount` hits `/v1/agents/me` with a short timeout and reports\n * whether the configured key still authenticates and whether the account\n * is active / restricted / suspended. The gateway uses this to surface a\n * red/yellow/green status in `openclaw channels status` and to decide when\n * to page an operator for stuck accounts.\n */\n\nimport type {\n ChannelStatusAdapter,\n ChannelCapabilitiesDisplayLine,\n} from './openclaw-types.js'\n\nimport type { AgentchatResolvedAccount } from '../channel.js'\nimport { getClient } from './sdk-client.js'\n\nexport type AgentchatProbeResult = {\n readonly ok: boolean\n readonly handle?: string\n readonly status?: 'active' | 'restricted' | 'suspended' | 'deleted'\n readonly pausedByOwner?: 'none' | 'send' | 'full'\n readonly error?: string\n}\n\n/** Probe timeout bounds. OpenClaw can pass arbitrary values; we clamp\n * both ends so a zero-timeout doesn't race and a sky-high one doesn't\n * hold the status pane hostage for a minute on a flaky network. */\nconst PROBE_MIN_MS = 1_000\nconst PROBE_MAX_MS = 10_000\n\nexport const agentchatStatusAdapter: ChannelStatusAdapter<AgentchatResolvedAccount, AgentchatProbeResult> = {\n async probeAccount({ account, timeoutMs }) {\n if (!account.config) {\n return { ok: false, error: 'missing channels.agentchat configuration' }\n }\n const client = getClient({ accountId: account.accountId, config: account.config })\n const clampedTimeout = Math.min(PROBE_MAX_MS, Math.max(PROBE_MIN_MS, timeoutMs))\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), clampedTimeout)\n try {\n const me = await client.getMe({ signal: controller.signal })\n clearTimeout(timer)\n return {\n ok: me.status === 'active',\n handle: me.handle,\n status: me.status,\n pausedByOwner: me.paused_by_owner ?? 'none',\n }\n } catch (err) {\n clearTimeout(timer)\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n },\n\n formatCapabilitiesProbe({ probe }) {\n const lines: ChannelCapabilitiesDisplayLine[] = []\n if (!probe.ok) {\n lines.push({\n text: probe.error ?? 'not authenticated',\n tone: 'error',\n })\n return lines\n }\n lines.push({\n text: `authenticated as @${probe.handle}`,\n tone: 'success',\n })\n if (probe.status && probe.status !== 'active') {\n lines.push({\n text: `account status: ${probe.status}`,\n tone: probe.status === 'restricted' ? 'warn' : 'error',\n })\n }\n if (probe.pausedByOwner && probe.pausedByOwner !== 'none') {\n lines.push({\n text: `owner paused this account (${probe.pausedByOwner})`,\n tone: 'warn',\n })\n }\n return lines\n },\n\n resolveAccountState({ account, configured, enabled }) {\n if (!enabled) return 'disabled'\n if (!configured) return 'not configured'\n if (account.configured) return 'linked'\n return 'not linked'\n },\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\nimport {\n agentchatGatewayAdapter,\n agentchatOutboundAdapter,\n agentchatMessagingAdapter,\n agentchatActionsAdapter,\n agentchatAgentToolsFactory,\n agentchatDirectoryAdapter,\n agentchatResolverAdapter,\n agentchatStatusAdapter,\n type AgentchatProbeResult,\n} from './binding/index.js'\nimport { writeAgentsAnchor } from './binding/agents-anchor.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\n/**\n * Resolve the config section for a single account. Pure function —\n * extracted from `config.resolveAccount` so `agentPrompt` (session-\n * start identity setup) can reuse it without a self-reference\n * back into the plugin object literal. Never throws: parse failures\n * are surfaced via `parseError` on the returned record.\n *\n * Takes `OpenClawConfig | undefined` to match `ChannelConfigAdapter.\n * resolveAccount`'s signature so they can share this implementation\n * directly without casting.\n */\nexport function resolveAgentchatAccount(\n cfg: import('./binding/openclaw-types.js').OpenClawConfig | undefined,\n accountId?: string | null,\n): AgentchatResolvedAccount {\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\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, AgentchatProbeResult> = {\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 return resolveAgentchatAccount(cfg, accountId)\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 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 // Non-interactive twin of the wizard's `finalize` anchor write.\n // We only get here on the `openclaw setup --channel agentchat\n // --token <key>` / `channels add --token` path, which means\n // the user did not see the wizard's UX — but they still need\n // the agent to be aware of its handle in non-AgentChat\n // sessions. Same anchor, same lifecycle, different entry\n // point. Best-effort: log + continue on FS failure so a\n // misconfigured workspace does not bounce a CI invocation.\n try {\n writeAgentsAnchor({ cfg, handle: result.agent.handle })\n } catch (err) {\n logger?.warn?.(\n `[agentchat:${accountId}] AGENTS.md anchor write failed: ${err instanceof Error ? err.message : String(err)}`,\n )\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 // ─── OpenClaw ↔ AgentChat binding ─────────────────────────────────────\n //\n // The adapters below are what make the channel actually *do* things once\n // configured. Without them the plugin is only a setup wizard; with them\n // agents can message peers, manage groups, mute, block, report, look up\n // the directory, and so on. Each adapter lives in `src/binding/` — keep\n // this file slim and delegate the behavior.\n //\n // Note on `agentPrompt`: we deliberately do NOT attach a\n // ChannelAgentPromptAdapter. The hook only fires when the agent's run\n // is triggered BY AgentChat (see openclaw compact-Fl3cALvc.js:636 —\n // `runtimeChannel ? resolveChannelMessageToolHints(...) : void 0`),\n // which means it can never deliver the persistent identity awareness\n // we need. Identity content lives in AGENTS.md via\n // `writeAgentsAnchor` — see binding/agents-anchor.ts for the why.\n\n gateway: agentchatGatewayAdapter,\n outbound: agentchatOutboundAdapter,\n messaging: agentchatMessagingAdapter,\n actions: agentchatActionsAdapter,\n agentTools: agentchatAgentToolsFactory,\n directory: agentchatDirectoryAdapter,\n resolver: agentchatResolverAdapter,\n status: agentchatStatusAdapter,\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 * Bar: an `apiKey` of plausible length AND a non-empty `agentHandle`.\n * Without the handle the runtime will start but the agent has no identity\n * to add to prompts or to use as a self-filter on inbound — both\n * downstream surfaces silently degrade. Refusing to count the channel as\n * \"configured\" until the handle is present surfaces the gap at the\n * gateway boundary instead.\n */\n\nexport interface MaybeConfigured {\n readonly apiKey?: unknown\n readonly agentHandle?: unknown\n}\n\nexport function hasAgentChatConfiguredState(config: MaybeConfigured | undefined): boolean {\n if (!config || typeof config !== 'object') return false\n const key = config.apiKey\n if (typeof key !== 'string' || key.length < 20) return false\n const handle = config.agentHandle\n if (typeof handle !== 'string' || handle.trim().length === 0) return false\n return true\n}\n"]}
|