@agentchatme/openclaw 0.6.10 → 0.6.11
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 +77 -1032
- package/README.md +50 -0
- package/RUNBOOK.md +1 -1
- package/dist/binding/agents-anchor.cjs +1 -1
- package/dist/binding/agents-anchor.cjs.map +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/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/setup-entry.cjs +4 -4
- package/dist/setup-entry.cjs.map +1 -1
- package/dist/setup-entry.js +2 -2
- package/dist/setup-entry.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/binding/agents-anchor.d.cts +0 -104
- package/dist/binding/agents-anchor.d.ts +0 -104
- package/dist/configured-state.d.cts +0 -20
- package/dist/configured-state.d.ts +0 -20
- package/dist/credentials/read-env.d.cts +0 -33
- package/dist/credentials/read-env.d.ts +0 -33
- package/dist/index.d.cts +0 -759
- package/dist/index.d.ts +0 -759
- package/dist/setup-entry-Dtj6vwDY.d.cts +0 -104
- package/dist/setup-entry-Dtj6vwDY.d.ts +0 -104
- package/dist/setup-entry.d.cts +0 -3
- package/dist/setup-entry.d.ts +0 -3
package/dist/index.d.cts
DELETED
|
@@ -1,759 +0,0 @@
|
|
|
1
|
-
import { A as AgentchatChannelConfig } from './setup-entry-Dtj6vwDY.cjs';
|
|
2
|
-
export { a as AgentchatResolvedAccount, b as agentchatChannelEntry, c as agentchatPlugin, d as agentchatSetupEntry, c as agentchatSetupPlugin, b as default, p as parseChannelConfig } from './setup-entry-Dtj6vwDY.cjs';
|
|
3
|
-
export { hasAgentChatConfiguredState } from './configured-state.cjs';
|
|
4
|
-
import { WebSocket } from 'ws';
|
|
5
|
-
import 'openclaw/plugin-sdk/channel-core';
|
|
6
|
-
import 'zod';
|
|
7
|
-
|
|
8
|
-
interface Logger {
|
|
9
|
-
trace(obj: object, msg?: string): void;
|
|
10
|
-
debug(obj: object, msg?: string): void;
|
|
11
|
-
info(obj: object, msg?: string): void;
|
|
12
|
-
warn(obj: object, msg?: string): void;
|
|
13
|
-
error(obj: object, msg?: string): void;
|
|
14
|
-
child(bindings: Record<string, unknown>): Logger;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Optional Prometheus metrics for the channel plugin.
|
|
19
|
-
*
|
|
20
|
-
* Design: the gateway owns the `/metrics` endpoint. Plugins do not expose
|
|
21
|
-
* their own port. If the user passes a `prom-client` Registry via channel
|
|
22
|
-
* runtime context, we register our counters/gauges/histograms into it.
|
|
23
|
-
* Otherwise, we return a no-op recorder — zero overhead, zero config.
|
|
24
|
-
*
|
|
25
|
-
* Names are prefixed with `agentchat_channel_` for easy scraping.
|
|
26
|
-
*/
|
|
27
|
-
interface MetricsRecorder {
|
|
28
|
-
/** Incremented on every successfully delivered inbound message. */
|
|
29
|
-
incInboundDelivered(labels: {
|
|
30
|
-
kind: InboundKind;
|
|
31
|
-
}): void;
|
|
32
|
-
/** Incremented on every successfully sent outbound message. */
|
|
33
|
-
incOutboundSent(labels: {
|
|
34
|
-
kind: OutboundKind;
|
|
35
|
-
}): void;
|
|
36
|
-
/** Incremented on every send failure, labeled by error class. */
|
|
37
|
-
incOutboundFailed(labels: {
|
|
38
|
-
errorClass: string;
|
|
39
|
-
}): void;
|
|
40
|
-
/** Incremented on every reconnect attempt. */
|
|
41
|
-
incReconnect(labels: {
|
|
42
|
-
reason: string;
|
|
43
|
-
}): void;
|
|
44
|
-
/** Observe end-to-end send latency (ms). */
|
|
45
|
-
observeSendLatency(ms: number): void;
|
|
46
|
-
/** Set the current connection state (cardinality bounded by state kinds). */
|
|
47
|
-
setConnectionState(kind: string): void;
|
|
48
|
-
/** Set the current in-flight send queue depth. */
|
|
49
|
-
setInFlightDepth(n: number): void;
|
|
50
|
-
}
|
|
51
|
-
type InboundKind = 'message' | 'group-message' | 'typing' | 'read' | 'presence' | 'rate-limit-warning';
|
|
52
|
-
type OutboundKind = 'message' | 'typing' | 'read';
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Error taxonomy for the AgentChat channel plugin.
|
|
56
|
-
*
|
|
57
|
-
* Every error that crosses a pipeline boundary (inbound receive, outbound
|
|
58
|
-
* send, config validation, transport) must be classifiable as one of:
|
|
59
|
-
*
|
|
60
|
-
* terminal-auth — 401/403. API key invalid or revoked. Do not retry.
|
|
61
|
-
* Move state machine to AUTH_FAIL.
|
|
62
|
-
* terminal-user — 400/422 (client-side validation). Bug in this plugin
|
|
63
|
-
* or malformed outbound. Log at error level, drop,
|
|
64
|
-
* do not retry.
|
|
65
|
-
* retry-rate — 429. Retry after `retryAfterMs` (or jittered
|
|
66
|
-
* exponential backoff if header absent).
|
|
67
|
-
* retry-transient — 5xx, ECONNRESET, ETIMEDOUT, network flap.
|
|
68
|
-
* Exponential backoff + jitter. Open circuit after N.
|
|
69
|
-
* idempotent-replay — 409 on POST /v1/messages with duplicate
|
|
70
|
-
* client_msg_id. Treat as success, log at info.
|
|
71
|
-
* validation — Zod schema failed on inbound payload. Likely a
|
|
72
|
-
* server change. Log at error, drop, alert.
|
|
73
|
-
*/
|
|
74
|
-
type ErrorClass = 'terminal-auth' | 'terminal-user' | 'retry-rate' | 'retry-transient' | 'idempotent-replay' | 'validation';
|
|
75
|
-
declare class AgentChatChannelError extends Error {
|
|
76
|
-
readonly class_: ErrorClass;
|
|
77
|
-
readonly retryAfterMs: number | undefined;
|
|
78
|
-
readonly statusCode: number | undefined;
|
|
79
|
-
constructor(class_: ErrorClass, message: string, options?: {
|
|
80
|
-
cause?: unknown;
|
|
81
|
-
retryAfterMs?: number;
|
|
82
|
-
statusCode?: number;
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Internal shared types for @agentchatme/openclaw.
|
|
88
|
-
*
|
|
89
|
-
* Kept intentionally small. Anything externally visible is exported from
|
|
90
|
-
* `./index.ts` or `./setup-entry.ts`. Types with a public SDK shape (channel
|
|
91
|
-
* plugin, setup plugin) live next to their respective entry files.
|
|
92
|
-
*/
|
|
93
|
-
type UnixMillis = number;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Connection state machine for the AgentChat WebSocket.
|
|
97
|
-
*
|
|
98
|
-
* Pure functions only — no I/O, no timers. The runtime (P2) owns the socket
|
|
99
|
-
* and drives transitions by emitting events.
|
|
100
|
-
*
|
|
101
|
-
* States:
|
|
102
|
-
* DISCONNECTED — initial, and after a clean close
|
|
103
|
-
* CONNECTING — TCP/TLS handshake + WS upgrade in flight
|
|
104
|
-
* AUTHENTICATING — socket open, waiting for `hello.ok` from server
|
|
105
|
-
* READY — authenticated, receiving + sending normally
|
|
106
|
-
* DEGRADED — heartbeat missed or send buffer full; still connected but impaired
|
|
107
|
-
* DRAINING — SIGTERM received; flush in-flight sends, then close
|
|
108
|
-
* CLOSED — terminal after clean shutdown
|
|
109
|
-
* AUTH_FAIL — terminal after 401/403; operator action required (rotate key)
|
|
110
|
-
*
|
|
111
|
-
* Invariants:
|
|
112
|
-
* - From AUTH_FAIL, no event can move us back to CONNECTING without
|
|
113
|
-
* an explicit RECONFIGURED event (operator rotated key).
|
|
114
|
-
* - From CLOSED, only SHUTDOWN is a no-op; anything else is a bug.
|
|
115
|
-
* - DRAINING has a deadline (ms timestamp) after which we force-close.
|
|
116
|
-
*/
|
|
117
|
-
|
|
118
|
-
type ConnectionState = {
|
|
119
|
-
readonly kind: 'DISCONNECTED';
|
|
120
|
-
} | {
|
|
121
|
-
readonly kind: 'CONNECTING';
|
|
122
|
-
readonly attempt: number;
|
|
123
|
-
readonly startedAt: UnixMillis;
|
|
124
|
-
} | {
|
|
125
|
-
readonly kind: 'AUTHENTICATING';
|
|
126
|
-
readonly startedAt: UnixMillis;
|
|
127
|
-
} | {
|
|
128
|
-
readonly kind: 'READY';
|
|
129
|
-
readonly connectedAt: UnixMillis;
|
|
130
|
-
} | {
|
|
131
|
-
readonly kind: 'DEGRADED';
|
|
132
|
-
readonly since: UnixMillis;
|
|
133
|
-
readonly reason: string;
|
|
134
|
-
} | {
|
|
135
|
-
readonly kind: 'DRAINING';
|
|
136
|
-
readonly since: UnixMillis;
|
|
137
|
-
readonly deadline: UnixMillis;
|
|
138
|
-
} | {
|
|
139
|
-
readonly kind: 'CLOSED';
|
|
140
|
-
} | {
|
|
141
|
-
readonly kind: 'AUTH_FAIL';
|
|
142
|
-
readonly reason: string;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* AgentChat WebSocket client — state-machine-driven, production-grade.
|
|
147
|
-
*
|
|
148
|
-
* Responsibilities:
|
|
149
|
-
* - Own the WS transport and HELLO handshake lifecycle.
|
|
150
|
-
* - Drive the connection state machine (`./state-machine.ts`) by emitting
|
|
151
|
-
* events in response to socket/auth/heartbeat transitions.
|
|
152
|
-
* - Maintain native WS PING/PONG heartbeat at `ping.intervalMs`; declare
|
|
153
|
-
* DEGRADED on `ping.timeoutMs` miss, then force-reconnect.
|
|
154
|
-
* - Schedule reconnect with exponential backoff + ±`jitterRatio` jitter
|
|
155
|
-
* per `reconnect.*` config. Thundering-herd-safe across a fleet.
|
|
156
|
-
* - Emit typed events upwards (`inboundFrame`, `stateChanged`, `error`)
|
|
157
|
-
* so the normalizer (P3) and outbound adapter (P4) can consume them.
|
|
158
|
-
*
|
|
159
|
-
* Intentional design choices:
|
|
160
|
-
* - Uses the `ws` package directly (not `globalThis.WebSocket`) because
|
|
161
|
-
* OpenClaw runs on Node — `ws` exposes `.ping()` / `.pong()` / event
|
|
162
|
-
* hooks that native WebSocket omits. Every major agent-hosting target
|
|
163
|
-
* (Fly, Render, Vercel functions, Lambda) is Node.
|
|
164
|
-
* - Authenticates via HELLO frame (`{type: "hello", api_key}`), never via
|
|
165
|
-
* URL query string. Keeps the key out of access logs and Referers.
|
|
166
|
-
* - `RECONNECT_HARD_CAP_ATTEMPTS` guards against runaway reconnect loops
|
|
167
|
-
* after catastrophic network events; crosses into `AUTH_FAIL` so the
|
|
168
|
-
* operator sees a clear signal instead of silent retry forever.
|
|
169
|
-
* - Frame parsing is defensive: malformed JSON, unknown `type`, missing
|
|
170
|
-
* payload — all classified as `validation` errors (non-terminal for
|
|
171
|
-
* the connection, but dropped with a metric + log).
|
|
172
|
-
* - No message-layer ordering here. Per-conversation seq ordering + gap
|
|
173
|
-
* recovery belong to the SDK's `RealtimeClient` and the drain layer
|
|
174
|
-
* (P3 consumers). This module is strictly the transport.
|
|
175
|
-
*/
|
|
176
|
-
|
|
177
|
-
/** One parsed inbound server frame. */
|
|
178
|
-
interface InboundFrame {
|
|
179
|
-
readonly type: string;
|
|
180
|
-
readonly payload: Record<string, unknown>;
|
|
181
|
-
readonly receivedAt: UnixMillis;
|
|
182
|
-
readonly raw: unknown;
|
|
183
|
-
}
|
|
184
|
-
/** One client-action frame the caller wants to push. */
|
|
185
|
-
interface OutboundFrame {
|
|
186
|
-
readonly type: string;
|
|
187
|
-
readonly payload: Record<string, unknown>;
|
|
188
|
-
readonly id?: string;
|
|
189
|
-
}
|
|
190
|
-
interface WsClientEvents {
|
|
191
|
-
stateChanged: (next: ConnectionState, prev: ConnectionState) => void;
|
|
192
|
-
inboundFrame: (frame: InboundFrame) => void;
|
|
193
|
-
error: (error: AgentChatChannelError) => void;
|
|
194
|
-
/** Fired once per `hello.ok` — useful for triggering a /v1/messages/sync drain upstream. */
|
|
195
|
-
authenticated: (at: UnixMillis) => void;
|
|
196
|
-
/** Fired after a clean close + CLOSED state (after stop() or terminal auth failure). */
|
|
197
|
-
closed: () => void;
|
|
198
|
-
}
|
|
199
|
-
interface WsClientOptions {
|
|
200
|
-
readonly config: AgentchatChannelConfig;
|
|
201
|
-
readonly logger: Logger;
|
|
202
|
-
readonly metrics: MetricsRecorder;
|
|
203
|
-
/** Clock source — override in tests. Default: `Date.now`. */
|
|
204
|
-
readonly now?: () => UnixMillis;
|
|
205
|
-
/** WebSocket constructor override — tests inject a mock. Default: `ws`. */
|
|
206
|
-
readonly webSocketCtor?: typeof WebSocket;
|
|
207
|
-
/** Random source for jitter — override in tests. Default: `Math.random`. */
|
|
208
|
-
readonly random?: () => number;
|
|
209
|
-
/** timer.setTimeout override for tests. */
|
|
210
|
-
readonly setTimeout?: (fn: () => void, ms: number) => NodeJS.Timeout;
|
|
211
|
-
readonly clearTimeout?: (h: NodeJS.Timeout) => void;
|
|
212
|
-
readonly setInterval?: (fn: () => void, ms: number) => NodeJS.Timeout;
|
|
213
|
-
readonly clearInterval?: (h: NodeJS.Timeout) => void;
|
|
214
|
-
}
|
|
215
|
-
type Listener<E extends keyof WsClientEvents> = WsClientEvents[E];
|
|
216
|
-
/**
|
|
217
|
-
* AgentChat channel WebSocket client.
|
|
218
|
-
*
|
|
219
|
-
* Lifecycle:
|
|
220
|
-
* 1. `start()` — DISCONNECTED → CONNECTING. Transport opens, HELLO is sent.
|
|
221
|
-
* 2. `hello.ok` → READY. Heartbeat timer starts. Upstream consumers begin.
|
|
222
|
-
* 3. On socket drop → DISCONNECTED → CONNECTING (with backoff).
|
|
223
|
-
* 4. `stop(deadlineMs)` → DRAINING. Wait for in-flight drains, then CLOSED.
|
|
224
|
-
*
|
|
225
|
-
* Thread-safety: this class is single-threaded. All callbacks fire on the
|
|
226
|
-
* Node event loop; callers should never invoke public methods from timer
|
|
227
|
-
* callbacks without being aware of reentrancy (e.g., a `stateChanged`
|
|
228
|
-
* listener that calls `send()` is fine, but `start()` inside `closed()`
|
|
229
|
-
* will re-enter the lifecycle — usually a bug).
|
|
230
|
-
*/
|
|
231
|
-
declare class AgentchatWsClient {
|
|
232
|
-
private readonly config;
|
|
233
|
-
private readonly logger;
|
|
234
|
-
private readonly metrics;
|
|
235
|
-
private readonly now;
|
|
236
|
-
private readonly WebSocketCtor;
|
|
237
|
-
private readonly random;
|
|
238
|
-
private readonly _setTimeout;
|
|
239
|
-
private readonly _clearTimeout;
|
|
240
|
-
private readonly _setInterval;
|
|
241
|
-
private readonly _clearInterval;
|
|
242
|
-
private state;
|
|
243
|
-
private ws;
|
|
244
|
-
private attempt;
|
|
245
|
-
private helloAckTimer;
|
|
246
|
-
private pingTimer;
|
|
247
|
-
private pongTimer;
|
|
248
|
-
private reconnectTimer;
|
|
249
|
-
private drainTimer;
|
|
250
|
-
private readonly listeners;
|
|
251
|
-
constructor(options: WsClientOptions);
|
|
252
|
-
/** Current connection state. Read-only from the caller's perspective. */
|
|
253
|
-
getState(): ConnectionState;
|
|
254
|
-
/**
|
|
255
|
-
* Kick off connection. No-op if already connecting, authenticating, or
|
|
256
|
-
* ready. Throws on `AUTH_FAIL` — the caller must call `reconfigured()`
|
|
257
|
-
* after rotating the API key before retrying.
|
|
258
|
-
*/
|
|
259
|
-
start(): void;
|
|
260
|
-
/**
|
|
261
|
-
* Push a client-action frame. Requires `canSend(state)` — returns false
|
|
262
|
-
* if the socket is not ready. Callers should queue and retry from the
|
|
263
|
-
* outbound adapter (P4) rather than drop here.
|
|
264
|
-
*/
|
|
265
|
-
send(frame: OutboundFrame): boolean;
|
|
266
|
-
/**
|
|
267
|
-
* Request a graceful drain. The caller-supplied deadline is a Unix-ms
|
|
268
|
-
* timestamp; after it passes, the socket is force-closed regardless of
|
|
269
|
-
* remaining in-flight work. Safe to call from any state.
|
|
270
|
-
*/
|
|
271
|
-
stop(deadline?: UnixMillis): void;
|
|
272
|
-
/**
|
|
273
|
-
* Signal that operator has rotated the API key. Transitions from
|
|
274
|
-
* AUTH_FAIL back to DISCONNECTED; the next `start()` call will attempt
|
|
275
|
-
* a fresh HELLO with the current config.
|
|
276
|
-
*/
|
|
277
|
-
reconfigured(): void;
|
|
278
|
-
on<E extends keyof WsClientEvents>(event: E, handler: Listener<E>): () => void;
|
|
279
|
-
private openSocket;
|
|
280
|
-
private bindSocket;
|
|
281
|
-
private handleOpen;
|
|
282
|
-
private handleMessage;
|
|
283
|
-
private extractReason;
|
|
284
|
-
private extractPayload;
|
|
285
|
-
private handleHelloOk;
|
|
286
|
-
private handleAuthRejected;
|
|
287
|
-
private handleClose;
|
|
288
|
-
private closeSocket;
|
|
289
|
-
private startHeartbeat;
|
|
290
|
-
private stopHeartbeat;
|
|
291
|
-
private sendPing;
|
|
292
|
-
private handlePong;
|
|
293
|
-
private scheduleReconnect;
|
|
294
|
-
private computeReconnectDelay;
|
|
295
|
-
private scheduleDrainDeadline;
|
|
296
|
-
/**
|
|
297
|
-
* Called by upper layers when their pending work has fully drained, to
|
|
298
|
-
* let the WS client transition CLOSED earlier than the deadline.
|
|
299
|
-
*/
|
|
300
|
-
drainCompleted(): void;
|
|
301
|
-
private applyEvent;
|
|
302
|
-
private emit;
|
|
303
|
-
private emitError;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Inbound normalizer — AgentChat server events → channel-neutral shape.
|
|
308
|
-
*
|
|
309
|
-
* Responsibilities:
|
|
310
|
-
* - Validate every server frame against a Zod schema. Unknown shapes
|
|
311
|
-
* surface as `validation` errors (the transport catches them and drops
|
|
312
|
-
* the frame without killing the connection).
|
|
313
|
-
* - Translate AgentChat-native payloads into a stable, plugin-internal
|
|
314
|
-
* `NormalizedInbound` shape. The OpenClaw channel binding (P7 runtime
|
|
315
|
-
* wiring) adapts this further to the gateway's `ChannelInboundMessage`
|
|
316
|
-
* contract.
|
|
317
|
-
* - Classify conversation kind (direct vs group) from the `dir_*`/`grp_*`
|
|
318
|
-
* prefix convention so consumers don't need to grep prefixes themselves.
|
|
319
|
-
*
|
|
320
|
-
* Why this module exists (rather than passing raw frames up):
|
|
321
|
-
* - The WS client is pure transport; it shouldn't know what
|
|
322
|
-
* `message.new` means semantically.
|
|
323
|
-
* - OpenClaw's ChannelInboundMessage has a specific shape (thread id,
|
|
324
|
-
* content parts, attachments, sender identity). Converting from
|
|
325
|
-
* AgentChat's wire format in one place is the only sane way to keep
|
|
326
|
-
* the mapping auditable.
|
|
327
|
-
* - Per-event Zod schemas make drift between plugin and server obvious
|
|
328
|
-
* and loud — a server field rename surfaces as a validation error
|
|
329
|
-
* caught in CI long before it goes to prod.
|
|
330
|
-
*/
|
|
331
|
-
|
|
332
|
-
type ConversationKind = 'direct' | 'group';
|
|
333
|
-
interface NormalizedMessage {
|
|
334
|
-
readonly kind: 'message';
|
|
335
|
-
readonly conversationKind: ConversationKind;
|
|
336
|
-
readonly conversationId: string;
|
|
337
|
-
/** Sender handle. */
|
|
338
|
-
readonly sender: string;
|
|
339
|
-
readonly messageId: string;
|
|
340
|
-
readonly clientMsgId: string;
|
|
341
|
-
readonly seq: number;
|
|
342
|
-
readonly messageType: 'text' | 'structured' | 'file' | 'system';
|
|
343
|
-
readonly content: {
|
|
344
|
-
readonly text?: string;
|
|
345
|
-
readonly data?: Record<string, unknown>;
|
|
346
|
-
readonly attachmentId?: string;
|
|
347
|
-
};
|
|
348
|
-
readonly metadata: Record<string, unknown>;
|
|
349
|
-
/**
|
|
350
|
-
* Per-recipient delivery state. Since migration 011, per-recipient state
|
|
351
|
-
* lives on `message_deliveries`, not the message row — so fresh-send
|
|
352
|
-
* `message.new` envelopes have no status field. Drain-path (sync /
|
|
353
|
-
* undelivered) envelopes still include `'stored'`. `null` means the
|
|
354
|
-
* server didn't attach one; callers that need the authoritative state
|
|
355
|
-
* should query `GET /v1/messages/sync` or `/delivery-receipts`.
|
|
356
|
-
*/
|
|
357
|
-
readonly status: 'stored' | 'delivered' | 'read' | null;
|
|
358
|
-
readonly createdAt: string;
|
|
359
|
-
readonly deliveredAt: string | null;
|
|
360
|
-
readonly readAt: string | null;
|
|
361
|
-
readonly receivedAt: UnixMillis;
|
|
362
|
-
}
|
|
363
|
-
interface NormalizedReadReceipt {
|
|
364
|
-
readonly kind: 'read-receipt';
|
|
365
|
-
readonly conversationKind: ConversationKind;
|
|
366
|
-
readonly conversationId: string;
|
|
367
|
-
readonly reader: string;
|
|
368
|
-
readonly throughSeq: number;
|
|
369
|
-
readonly at: string | null;
|
|
370
|
-
readonly receivedAt: UnixMillis;
|
|
371
|
-
}
|
|
372
|
-
interface NormalizedTyping {
|
|
373
|
-
readonly kind: 'typing';
|
|
374
|
-
readonly action: 'start' | 'stop';
|
|
375
|
-
readonly conversationKind: ConversationKind;
|
|
376
|
-
readonly conversationId: string;
|
|
377
|
-
readonly sender: string;
|
|
378
|
-
readonly receivedAt: UnixMillis;
|
|
379
|
-
}
|
|
380
|
-
interface NormalizedPresence {
|
|
381
|
-
readonly kind: 'presence';
|
|
382
|
-
readonly handle: string;
|
|
383
|
-
readonly status: 'online' | 'away' | 'offline';
|
|
384
|
-
readonly lastActiveAt: string | null;
|
|
385
|
-
readonly customStatus: string | null;
|
|
386
|
-
readonly receivedAt: UnixMillis;
|
|
387
|
-
}
|
|
388
|
-
interface NormalizedRateLimitWarning {
|
|
389
|
-
readonly kind: 'rate-limit-warning';
|
|
390
|
-
readonly endpoint: string | null;
|
|
391
|
-
readonly limit: number | null;
|
|
392
|
-
readonly remaining: number | null;
|
|
393
|
-
readonly resetAt: string | null;
|
|
394
|
-
readonly message: string | null;
|
|
395
|
-
readonly receivedAt: UnixMillis;
|
|
396
|
-
}
|
|
397
|
-
interface NormalizedGroupInvite {
|
|
398
|
-
readonly kind: 'group-invite';
|
|
399
|
-
readonly inviteId: string;
|
|
400
|
-
readonly groupId: string;
|
|
401
|
-
readonly groupName: string;
|
|
402
|
-
readonly groupDescription: string | null;
|
|
403
|
-
readonly groupAvatarUrl: string | null;
|
|
404
|
-
readonly groupMemberCount: number;
|
|
405
|
-
readonly inviterHandle: string;
|
|
406
|
-
readonly createdAt: string;
|
|
407
|
-
readonly receivedAt: UnixMillis;
|
|
408
|
-
}
|
|
409
|
-
interface NormalizedGroupDeleted {
|
|
410
|
-
readonly kind: 'group-deleted';
|
|
411
|
-
readonly groupId: string;
|
|
412
|
-
readonly deletedByHandle: string;
|
|
413
|
-
readonly deletedAt: string;
|
|
414
|
-
readonly receivedAt: UnixMillis;
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Unknown server event — arrived over the wire but isn't in our explicit
|
|
418
|
-
* handler set. We still surface it (the gateway may want to log it or
|
|
419
|
-
* forward it), but with a `type` field so downstream can discriminate.
|
|
420
|
-
*/
|
|
421
|
-
interface NormalizedUnknown {
|
|
422
|
-
readonly kind: 'unknown';
|
|
423
|
-
readonly type: string;
|
|
424
|
-
readonly payload: Record<string, unknown>;
|
|
425
|
-
readonly receivedAt: UnixMillis;
|
|
426
|
-
}
|
|
427
|
-
type NormalizedInbound = NormalizedMessage | NormalizedReadReceipt | NormalizedTyping | NormalizedPresence | NormalizedRateLimitWarning | NormalizedGroupInvite | NormalizedGroupDeleted | NormalizedUnknown;
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Shape of a message record as returned by the AgentChat REST API.
|
|
431
|
-
*
|
|
432
|
-
* Mirrors the `Message` interface defined in the AgentChat TypeScript SDK
|
|
433
|
-
* (`packages/sdk-typescript/src/types/message.ts`). We keep a local copy so
|
|
434
|
-
* this plugin has no runtime dependency on the SDK — it's type-only at the
|
|
435
|
-
* source and the SDK isn't published to npm yet. If the server's message
|
|
436
|
-
* contract changes, update both files together; a drift is a schema
|
|
437
|
-
* mismatch the server will catch, but we'd rather fail type-check first.
|
|
438
|
-
*/
|
|
439
|
-
type MessageType = 'text' | 'structured' | 'file' | 'system';
|
|
440
|
-
type MessageStatus = 'stored' | 'delivered' | 'read';
|
|
441
|
-
interface MessageContent {
|
|
442
|
-
text?: string;
|
|
443
|
-
data?: Record<string, unknown>;
|
|
444
|
-
attachment_id?: string;
|
|
445
|
-
}
|
|
446
|
-
interface Message {
|
|
447
|
-
id: string;
|
|
448
|
-
conversation_id: string;
|
|
449
|
-
sender: string;
|
|
450
|
-
client_msg_id: string;
|
|
451
|
-
seq: number;
|
|
452
|
-
type: MessageType;
|
|
453
|
-
content: MessageContent;
|
|
454
|
-
metadata: Record<string, unknown>;
|
|
455
|
-
status: MessageStatus;
|
|
456
|
-
created_at: string;
|
|
457
|
-
delivered_at: string | null;
|
|
458
|
-
read_at: string | null;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Outbound adapter — OpenClaw send → AgentChat `POST /v1/messages`.
|
|
463
|
-
*
|
|
464
|
-
* Pipeline (left to right, each step is independently observable):
|
|
465
|
-
* 1. Caller invokes `sendMessage(input)` with a channel-neutral shape.
|
|
466
|
-
* 2. We derive a stable `client_msg_id` (idempotency key). If the caller
|
|
467
|
-
* supplied one, we respect it; otherwise we mint a UUID.
|
|
468
|
-
* 3. Circuit-breaker precheck. Open circuit → fast-fail `retry-transient`.
|
|
469
|
-
* 4. `retryWithPolicy(...)` wraps the actual HTTP call.
|
|
470
|
-
* 5. On success, metrics/logs + return the `Message` the server minted.
|
|
471
|
-
* 6. On 409 (idempotent-replay), treat as success with the replay body.
|
|
472
|
-
* 7. On 429, honor `Retry-After` (seconds or HTTP-date) via the retry
|
|
473
|
-
* policy. Surface as `retry-rate`.
|
|
474
|
-
* 8. On 5xx / network flap, retry with jittered exponential backoff.
|
|
475
|
-
* 9. On 4xx other than 429/409, classify as `terminal-user` → no retry.
|
|
476
|
-
* 10. On 401/403 → `terminal-auth`. We signal upstream so the WS client
|
|
477
|
-
* moves to AUTH_FAIL and the operator gets paged.
|
|
478
|
-
*
|
|
479
|
-
* Backpressure:
|
|
480
|
-
* - An in-flight semaphore bounds concurrent sends to `outbound.maxInFlight`.
|
|
481
|
-
* - Over-threshold sends are enqueued and drained as capacity frees up.
|
|
482
|
-
* - Queue has its own hard cap (`10 * maxInFlight`); over-cap sends reject
|
|
483
|
-
* immediately with `retry-transient` so the caller can shed load rather
|
|
484
|
-
* than OOM.
|
|
485
|
-
*/
|
|
486
|
-
|
|
487
|
-
type OutboundMessageInput = OutboundDirectMessage | OutboundGroupMessage;
|
|
488
|
-
interface OutboundMessageBase {
|
|
489
|
-
/**
|
|
490
|
-
* Client-generated idempotency key. Optional — we mint one if absent.
|
|
491
|
-
* Retries of the same logical send MUST reuse the same value or you'll
|
|
492
|
-
* get duplicates.
|
|
493
|
-
*/
|
|
494
|
-
readonly clientMsgId?: string;
|
|
495
|
-
readonly type?: 'text' | 'structured' | 'file';
|
|
496
|
-
readonly content: {
|
|
497
|
-
readonly text?: string;
|
|
498
|
-
readonly data?: Record<string, unknown>;
|
|
499
|
-
readonly attachmentId?: string;
|
|
500
|
-
};
|
|
501
|
-
readonly metadata?: Record<string, unknown>;
|
|
502
|
-
/** Correlation id carried through logs and metrics. */
|
|
503
|
-
readonly correlationId?: string;
|
|
504
|
-
}
|
|
505
|
-
interface OutboundDirectMessage extends OutboundMessageBase {
|
|
506
|
-
readonly kind: 'direct';
|
|
507
|
-
/** Recipient handle (e.g. "alice"). */
|
|
508
|
-
readonly to: string;
|
|
509
|
-
}
|
|
510
|
-
interface OutboundGroupMessage extends OutboundMessageBase {
|
|
511
|
-
readonly kind: 'group';
|
|
512
|
-
/** `grp_*` conversation id. */
|
|
513
|
-
readonly conversationId: string;
|
|
514
|
-
}
|
|
515
|
-
interface OutboundBacklogWarning {
|
|
516
|
-
readonly recipientHandle: string;
|
|
517
|
-
readonly undeliveredCount: number;
|
|
518
|
-
}
|
|
519
|
-
interface SendResult {
|
|
520
|
-
readonly message: Message;
|
|
521
|
-
readonly backlogWarning: OutboundBacklogWarning | null;
|
|
522
|
-
readonly idempotentReplay: boolean;
|
|
523
|
-
readonly attempts: number;
|
|
524
|
-
readonly latencyMs: number;
|
|
525
|
-
readonly requestId: string | null;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* AgentChat channel runtime — single lifecycle object that ties the WS
|
|
530
|
-
* transport (P2), inbound normalizer (P3), and outbound adapter (P4)
|
|
531
|
-
* together. This is the surface an OpenClaw channel binding consumes.
|
|
532
|
-
*
|
|
533
|
-
* Responsibilities:
|
|
534
|
-
* - Instantiate the WS client, hook its `inboundFrame` event through
|
|
535
|
-
* `normalizeInbound` and into user-supplied handlers.
|
|
536
|
-
* - Expose `sendMessage` that delegates to the OutboundAdapter.
|
|
537
|
-
* - Coordinate drain: `stop(deadline)` waits for outbound in-flight to
|
|
538
|
-
* clear (up to the deadline) before closing the WS.
|
|
539
|
-
* - Surface a single `getHealth()` snapshot combining connection state +
|
|
540
|
-
* outbound queue depth + circuit breaker state.
|
|
541
|
-
*
|
|
542
|
-
* Not in scope here:
|
|
543
|
-
* - Per-conversation seq ordering and gap recovery — the SDK's
|
|
544
|
-
* `RealtimeClient` owns that. For the channel plugin, we deliver
|
|
545
|
-
* inbound frames as they arrive; upper layers can call
|
|
546
|
-
* `GET /v1/messages/sync` for reconciliation if they require strict
|
|
547
|
-
* ordering across reconnects.
|
|
548
|
-
* - OpenClaw ChannelInboundMessage translation — that lives in the
|
|
549
|
-
* bridge module (consumed by the gateway), not here. Keeping this
|
|
550
|
-
* module decoupled means it can be smoke-tested without OpenClaw.
|
|
551
|
-
*/
|
|
552
|
-
|
|
553
|
-
interface ChannelRuntimeHandlers {
|
|
554
|
-
/** Called for every successfully normalized inbound event. */
|
|
555
|
-
onInbound?: (event: NormalizedInbound) => void | Promise<void>;
|
|
556
|
-
/** Called whenever a frame fails validation. Default: log-and-drop. */
|
|
557
|
-
onValidationError?: (error: AgentChatChannelError, frame: InboundFrame) => void;
|
|
558
|
-
/** Called on state transitions — surface to gateway for health/UI. */
|
|
559
|
-
onStateChanged?: (next: ConnectionState, prev: ConnectionState) => void;
|
|
560
|
-
/** Called once per successful HELLO_OK (initial + every reconnect). */
|
|
561
|
-
onAuthenticated?: (at: UnixMillis) => void;
|
|
562
|
-
/** Called on every closed/unreachable situation worth observing. */
|
|
563
|
-
onError?: (error: AgentChatChannelError) => void;
|
|
564
|
-
/** Called when the server signals a backlog warning on an outbound send. */
|
|
565
|
-
onBacklogWarning?: (warning: OutboundBacklogWarning) => void;
|
|
566
|
-
}
|
|
567
|
-
interface ChannelRuntimeOptions {
|
|
568
|
-
readonly config: AgentchatChannelConfig;
|
|
569
|
-
readonly handlers?: ChannelRuntimeHandlers;
|
|
570
|
-
/** Pre-built logger — if absent, we construct one from `config.observability`. */
|
|
571
|
-
readonly logger?: Logger;
|
|
572
|
-
/** Pre-built metrics recorder — if absent, uses no-op. */
|
|
573
|
-
readonly metrics?: MetricsRecorder;
|
|
574
|
-
readonly fetch?: typeof fetch;
|
|
575
|
-
/** Injected for tests. */
|
|
576
|
-
readonly webSocketCtor?: ConstructorParameters<typeof AgentchatWsClient>[0]['webSocketCtor'];
|
|
577
|
-
readonly now?: () => UnixMillis;
|
|
578
|
-
readonly random?: () => number;
|
|
579
|
-
readonly sleep?: (ms: number) => Promise<void>;
|
|
580
|
-
}
|
|
581
|
-
interface HealthSnapshot {
|
|
582
|
-
readonly state: ConnectionState;
|
|
583
|
-
readonly authenticated: boolean;
|
|
584
|
-
readonly outbound: {
|
|
585
|
-
readonly inFlight: number;
|
|
586
|
-
readonly queued: number;
|
|
587
|
-
readonly circuitState: 'closed' | 'open' | 'half-open';
|
|
588
|
-
};
|
|
589
|
-
}
|
|
590
|
-
/**
|
|
591
|
-
* Orchestrates the full channel. Construct once per (channelId, accountId)
|
|
592
|
-
* pair at gateway startup; call `start()` to bring it up, `stop()` to
|
|
593
|
-
* drain. Dispose is folded into `stop()` — after it resolves, the
|
|
594
|
-
* instance is terminal.
|
|
595
|
-
*/
|
|
596
|
-
declare class AgentchatChannelRuntime {
|
|
597
|
-
private readonly config;
|
|
598
|
-
private readonly handlers;
|
|
599
|
-
private readonly logger;
|
|
600
|
-
private readonly metrics;
|
|
601
|
-
private readonly ws;
|
|
602
|
-
private readonly outbound;
|
|
603
|
-
private readonly now;
|
|
604
|
-
private started;
|
|
605
|
-
private authenticated;
|
|
606
|
-
private stopPromise;
|
|
607
|
-
constructor(opts: ChannelRuntimeOptions);
|
|
608
|
-
/** Open the transport. Idempotent — subsequent calls are no-ops. */
|
|
609
|
-
start(): void;
|
|
610
|
-
/**
|
|
611
|
-
* Graceful shutdown. Waits for outbound in-flight to drain up to the
|
|
612
|
-
* deadline, then force-closes the WS. Returns a promise that resolves
|
|
613
|
-
* once the WS has emitted `closed`.
|
|
614
|
-
*/
|
|
615
|
-
stop(deadlineMs?: UnixMillis): Promise<void>;
|
|
616
|
-
private pollUntilIdle;
|
|
617
|
-
/**
|
|
618
|
-
* Send an outbound message. Delegates to the OutboundAdapter; callers
|
|
619
|
-
* should handle `AgentChatChannelError` with class dispatch.
|
|
620
|
-
*/
|
|
621
|
-
sendMessage(input: OutboundMessageInput): Promise<SendResult>;
|
|
622
|
-
/** Push a client-action frame over the WS (typing, read-ack, presence). */
|
|
623
|
-
sendWsAction(type: 'typing.start' | 'typing.stop' | 'message.read_ack' | 'presence.update', payload: Record<string, unknown>): boolean;
|
|
624
|
-
/**
|
|
625
|
-
* Operator has rotated the API key — signal the WS client so it can
|
|
626
|
-
* exit AUTH_FAIL. The caller is responsible for creating a new runtime
|
|
627
|
-
* with the updated config OR for calling this after config hot-reload.
|
|
628
|
-
*/
|
|
629
|
-
reconfigured(): void;
|
|
630
|
-
getHealth(): HealthSnapshot;
|
|
631
|
-
private bindWsEvents;
|
|
632
|
-
private dispatchFrame;
|
|
633
|
-
private recordInboundMetric;
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
/**
|
|
637
|
-
* Account-config primitives for the AgentChat channel plugin.
|
|
638
|
-
*
|
|
639
|
-
* This module owns the smallest set of shared pieces that both the plugin
|
|
640
|
-
* definition (`channel.ts`) and the interactive setup wizard
|
|
641
|
-
* (`channel.wizard.ts`) need to read or mutate the `channels.agentchat.*`
|
|
642
|
-
* section of the OpenClaw config. Keeping them in a leaf file (no imports
|
|
643
|
-
* from other channel-* modules) breaks the channel.ts ↔ channel.wizard.ts
|
|
644
|
-
* import cycle — without it, the wizard literal's `channel:` field resolves
|
|
645
|
-
* to the temporal-dead-zone value of `AGENTCHAT_CHANNEL_ID` at module-init
|
|
646
|
-
* time, which bundlers emit as `undefined`.
|
|
647
|
-
*
|
|
648
|
-
* Invariants:
|
|
649
|
-
* - Flat form (`channels.agentchat.{apiKey,...}`) is the default-account
|
|
650
|
-
* layout when no `accounts` key is present. Once a named account is
|
|
651
|
-
* written, flat form is never used again for the default account.
|
|
652
|
-
* - The `enabled` flag is section-level (not per-account) and is kept out
|
|
653
|
-
* of the Zod-parsed account shape because the schema is `.strict()`.
|
|
654
|
-
*/
|
|
655
|
-
|
|
656
|
-
declare const AGENTCHAT_CHANNEL_ID: "agentchat";
|
|
657
|
-
declare const AGENTCHAT_DEFAULT_ACCOUNT_ID = "default";
|
|
658
|
-
|
|
659
|
-
/**
|
|
660
|
-
* Minimal HTTP client used by the setup plugin (P7) to:
|
|
661
|
-
* - verify an API key is live before finalizing setup (`validateApiKey`)
|
|
662
|
-
* - drive the email-OTP self-registration flow for agents without a key yet
|
|
663
|
-
* (`registerAgentStart` → `registerAgentVerify`)
|
|
664
|
-
*
|
|
665
|
-
* Why this lives separately from `outbound.ts`:
|
|
666
|
-
* - `outbound.ts` is the hot-path message sender. It wants retries, a circuit
|
|
667
|
-
* breaker, metrics, and a long-lived `fetch`. Setup is one-shot, low-rate,
|
|
668
|
-
* user-interactive — a 200ms validation call doesn't need any of that.
|
|
669
|
-
* - Setup runs before the runtime exists; coupling it to `OutboundAdapter`
|
|
670
|
-
* (which expects a parsed `AgentchatChannelConfig`) would force an odd
|
|
671
|
-
* partial-config path during registration.
|
|
672
|
-
*
|
|
673
|
-
* The server endpoints this module targets are stable AgentChat REST calls:
|
|
674
|
-
* - `GET /v1/agents/me` → 200 OK when the key authenticates
|
|
675
|
-
* - `POST /v1/register` → 200 with `{ pending_id }`
|
|
676
|
-
* - `POST /v1/register/verify` → 201 with `{ agent, api_key }` on success
|
|
677
|
-
*
|
|
678
|
-
* All methods return strongly-typed result unions — setup UIs can `switch` on
|
|
679
|
-
* the discriminant without guessing at HTTP status codes.
|
|
680
|
-
*/
|
|
681
|
-
/** Subset of the AgentChat agent row the setup surface needs to show the user. */
|
|
682
|
-
interface AgentchatAgentIdentity {
|
|
683
|
-
readonly handle: string;
|
|
684
|
-
readonly displayName: string | null;
|
|
685
|
-
readonly email: string;
|
|
686
|
-
readonly createdAt: string;
|
|
687
|
-
}
|
|
688
|
-
type ValidateApiKeyResult = {
|
|
689
|
-
readonly ok: true;
|
|
690
|
-
readonly agent: AgentchatAgentIdentity;
|
|
691
|
-
} | {
|
|
692
|
-
readonly ok: false;
|
|
693
|
-
/** High-level reason code the UI can map to a localized message. */
|
|
694
|
-
readonly reason: 'unauthorized' | 'forbidden' | 'deleted' | 'network-error' | 'unreachable' | 'server-error' | 'unexpected-shape';
|
|
695
|
-
readonly message: string;
|
|
696
|
-
readonly status?: number;
|
|
697
|
-
};
|
|
698
|
-
interface ValidateApiKeyOptions {
|
|
699
|
-
readonly apiBase?: string;
|
|
700
|
-
readonly fetch?: typeof fetch;
|
|
701
|
-
readonly timeoutMs?: number;
|
|
702
|
-
}
|
|
703
|
-
/**
|
|
704
|
-
* Probe the API key against `GET /v1/agents/me`. Returns a discriminated
|
|
705
|
-
* result — never throws on HTTP or network errors. The caller decides how
|
|
706
|
-
* to surface each failure mode to the user.
|
|
707
|
-
*/
|
|
708
|
-
declare function validateApiKey(apiKey: string, opts?: ValidateApiKeyOptions): Promise<ValidateApiKeyResult>;
|
|
709
|
-
interface RegisterAgentStartInput {
|
|
710
|
-
readonly email: string;
|
|
711
|
-
readonly handle: string;
|
|
712
|
-
readonly displayName?: string;
|
|
713
|
-
readonly description?: string;
|
|
714
|
-
}
|
|
715
|
-
type RegisterStartResult = {
|
|
716
|
-
readonly ok: true;
|
|
717
|
-
readonly pendingId: string;
|
|
718
|
-
} | {
|
|
719
|
-
readonly ok: false;
|
|
720
|
-
readonly reason: 'invalid-handle' | 'handle-taken' | 'email-taken' | 'email-exhausted' | 'rate-limited' | 'otp-failed' | 'network-error' | 'server-error' | 'validation';
|
|
721
|
-
readonly message: string;
|
|
722
|
-
readonly status?: number;
|
|
723
|
-
readonly retryAfterSeconds?: number;
|
|
724
|
-
};
|
|
725
|
-
interface RegisterAgentVerifyInput {
|
|
726
|
-
readonly pendingId: string;
|
|
727
|
-
readonly code: string;
|
|
728
|
-
}
|
|
729
|
-
type RegisterVerifyResult = {
|
|
730
|
-
readonly ok: true;
|
|
731
|
-
readonly apiKey: string;
|
|
732
|
-
readonly agent: AgentchatAgentIdentity;
|
|
733
|
-
} | {
|
|
734
|
-
readonly ok: false;
|
|
735
|
-
readonly reason: 'expired' | 'invalid-code' | 'rate-limited' | 'handle-taken' | 'email-taken' | 'network-error' | 'server-error' | 'unexpected-shape' | 'validation';
|
|
736
|
-
readonly message: string;
|
|
737
|
-
readonly status?: number;
|
|
738
|
-
readonly retryAfterSeconds?: number;
|
|
739
|
-
};
|
|
740
|
-
interface RegisterOptions {
|
|
741
|
-
readonly apiBase?: string;
|
|
742
|
-
readonly fetch?: typeof fetch;
|
|
743
|
-
readonly timeoutMs?: number;
|
|
744
|
-
}
|
|
745
|
-
/**
|
|
746
|
-
* Kick off an email-OTP registration. Server caches the intent under a
|
|
747
|
-
* `pending_id` for 10 minutes and emails a 6-digit code to `email`.
|
|
748
|
-
*/
|
|
749
|
-
declare function registerAgentStart(input: RegisterAgentStartInput, opts?: RegisterOptions): Promise<RegisterStartResult>;
|
|
750
|
-
/** Verify the OTP the user received by email and mint the API key. */
|
|
751
|
-
declare function registerAgentVerify(input: RegisterAgentVerifyInput, opts?: RegisterOptions): Promise<RegisterVerifyResult>;
|
|
752
|
-
/**
|
|
753
|
-
* Throw-flavored wrapper used by callers that prefer exception control flow
|
|
754
|
-
* (the setup plugin's `afterAccountConfigWritten` hook). Converts a failure
|
|
755
|
-
* result into an `AgentChatChannelError` with an appropriate class.
|
|
756
|
-
*/
|
|
757
|
-
declare function assertApiKeyValid(apiKey: string, opts?: ValidateApiKeyOptions): Promise<AgentchatAgentIdentity>;
|
|
758
|
-
|
|
759
|
-
export { AGENTCHAT_CHANNEL_ID, AGENTCHAT_DEFAULT_ACCOUNT_ID, AgentChatChannelError, type AgentchatAgentIdentity, AgentchatChannelConfig, AgentchatChannelRuntime, type ChannelRuntimeHandlers, type ChannelRuntimeOptions, type ConnectionState, type ConversationKind, type ErrorClass, type HealthSnapshot, type Message, type MessageContent, type MessageStatus, type MessageType, type NormalizedGroupDeleted, type NormalizedGroupInvite, type NormalizedInbound, type NormalizedMessage, type NormalizedPresence, type NormalizedRateLimitWarning, type NormalizedReadReceipt, type NormalizedTyping, type NormalizedUnknown, type OutboundBacklogWarning, type OutboundDirectMessage, type OutboundGroupMessage, type OutboundMessageInput, type RegisterAgentStartInput, type RegisterAgentVerifyInput, type RegisterOptions, type RegisterStartResult, type RegisterVerifyResult, type SendResult, type ValidateApiKeyOptions, type ValidateApiKeyResult, assertApiKeyValid, registerAgentStart, registerAgentVerify, validateApiKey };
|