@gorlitzer-labs/apiary 1.13.3
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/LICENSE +21 -0
- package/README.md +328 -0
- package/dist/agent/index.d.ts +689 -0
- package/dist/agent/index.js +34 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/chunk-5V7QLCGB.js +184 -0
- package/dist/chunk-5V7QLCGB.js.map +1 -0
- package/dist/chunk-AYQJIAR5.js +152 -0
- package/dist/chunk-AYQJIAR5.js.map +1 -0
- package/dist/chunk-BZ4VDWC2.js +76 -0
- package/dist/chunk-BZ4VDWC2.js.map +1 -0
- package/dist/chunk-CFY6Z6Q6.js +95 -0
- package/dist/chunk-CFY6Z6Q6.js.map +1 -0
- package/dist/chunk-CZHO4DBN.js +1719 -0
- package/dist/chunk-CZHO4DBN.js.map +1 -0
- package/dist/chunk-D7DXZQWT.js +208 -0
- package/dist/chunk-D7DXZQWT.js.map +1 -0
- package/dist/chunk-ED6ROH6B.js +2021 -0
- package/dist/chunk-ED6ROH6B.js.map +1 -0
- package/dist/chunk-PEB6HEFT.js +606 -0
- package/dist/chunk-PEB6HEFT.js.map +1 -0
- package/dist/chunk-QL66XSDB.js +157 -0
- package/dist/chunk-QL66XSDB.js.map +1 -0
- package/dist/chunk-TPNFOQA7.js +288 -0
- package/dist/chunk-TPNFOQA7.js.map +1 -0
- package/dist/chunk-ZEFRNAX6.js +1771 -0
- package/dist/chunk-ZEFRNAX6.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +2432 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index-Dp3QSGog.d.ts +837 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/invites-OFXIQLLN.js +23 -0
- package/dist/invites-OFXIQLLN.js.map +1 -0
- package/dist/join-CQXEF65B.js +15 -0
- package/dist/join-CQXEF65B.js.map +1 -0
- package/dist/room-Z7KDRVYD.js +1099 -0
- package/dist/room-Z7KDRVYD.js.map +1 -0
- package/dist/run-DOADB4T7.js +90 -0
- package/dist/run-DOADB4T7.js.map +1 -0
- package/dist/update-JGE3WCQB.js +11 -0
- package/dist/update-JGE3WCQB.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,837 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/** Core types for apiary — messages, participants, pagination. */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The four top-level categories events are grouped under.
|
|
7
|
+
*
|
|
8
|
+
* Channels subscribe to one or more categories — they only receive events in
|
|
9
|
+
* their subscription set. Use this to filter what an agent or observer sees:
|
|
10
|
+
*
|
|
11
|
+
* - MESSAGE — chat messages and reactions (sent, edited, deleted, reacted)
|
|
12
|
+
* - PRESENCE — participants joining and leaving
|
|
13
|
+
* - ACTIVITY — agent activity (thinking, tool use, mode changes, compaction)
|
|
14
|
+
* - MENTION — direct @mentions delivered only to the mentioned participant
|
|
15
|
+
*/
|
|
16
|
+
declare const EventCategory: {
|
|
17
|
+
readonly MESSAGE: "MESSAGE";
|
|
18
|
+
readonly PRESENCE: "PRESENCE";
|
|
19
|
+
readonly ACTIVITY: "ACTIVITY";
|
|
20
|
+
readonly MENTION: "MENTION";
|
|
21
|
+
};
|
|
22
|
+
type EventCategory = (typeof EventCategory)[keyof typeof EventCategory];
|
|
23
|
+
/**
|
|
24
|
+
* A file or image attached to a message. Discriminated union on `type`.
|
|
25
|
+
*
|
|
26
|
+
* - `type: "path"` — local filesystem reference, intended for same-machine rooms.
|
|
27
|
+
* Receivers should gracefully handle the case where the path is not accessible
|
|
28
|
+
* on their machine (e.g. multi-machine rooms with a tunnel).
|
|
29
|
+
*
|
|
30
|
+
* - `type: "upload"` — server-hosted bytes, fetched via `GET /attachment/:id`
|
|
31
|
+
* with a valid session token. URL uses the server's `publicUrl` (tunnel URL
|
|
32
|
+
* when active, otherwise localhost).
|
|
33
|
+
*/
|
|
34
|
+
declare const AttachmentSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
35
|
+
type: z.ZodLiteral<"path">;
|
|
36
|
+
id: z.ZodString;
|
|
37
|
+
name: z.ZodString;
|
|
38
|
+
mime_type: z.ZodString;
|
|
39
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
40
|
+
path: z.ZodString;
|
|
41
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
42
|
+
type: z.ZodLiteral<"upload">;
|
|
43
|
+
id: z.ZodString;
|
|
44
|
+
name: z.ZodString;
|
|
45
|
+
mime_type: z.ZodString;
|
|
46
|
+
size: z.ZodNumber;
|
|
47
|
+
url: z.ZodString;
|
|
48
|
+
}, z.core.$strip>], "type">;
|
|
49
|
+
type Attachment = z.infer<typeof AttachmentSchema>;
|
|
50
|
+
/**
|
|
51
|
+
* A chat message. Immutable once stored — edits and deletes are separate events.
|
|
52
|
+
*
|
|
53
|
+
* - `id` — UUID, assigned by the room on creation
|
|
54
|
+
* - `room_id` — the room this message belongs to
|
|
55
|
+
* - `sender_id` — participant ID of the author
|
|
56
|
+
* - `sender_name` — display name at the time of sending (denormalized)
|
|
57
|
+
* - `content` — text body (may be empty if the message is image-only)
|
|
58
|
+
* - `reply_to_id` — if set, this message is a reply to that message ID
|
|
59
|
+
* - `recipients` — if non-empty, this is a whisper: only these participant IDs (plus the sender) can read it
|
|
60
|
+
* - `attachments` — zero or more file/image attachments
|
|
61
|
+
* - `image_url` — legacy single-image URL (kept for backward compat)
|
|
62
|
+
* - `image_mime_type` — MIME type of the legacy image
|
|
63
|
+
* - `image_size_bytes` — size of the legacy image in bytes
|
|
64
|
+
* - `timestamp` — creation time (UTC)
|
|
65
|
+
*/
|
|
66
|
+
declare const MessageSchema: z.ZodObject<{
|
|
67
|
+
id: z.ZodDefault<z.ZodString>;
|
|
68
|
+
room_id: z.ZodString;
|
|
69
|
+
sender_id: z.ZodString;
|
|
70
|
+
sender_name: z.ZodString;
|
|
71
|
+
content: z.ZodString;
|
|
72
|
+
reply_to_id: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
73
|
+
recipients: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
74
|
+
attachments: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
75
|
+
type: z.ZodLiteral<"path">;
|
|
76
|
+
id: z.ZodString;
|
|
77
|
+
name: z.ZodString;
|
|
78
|
+
mime_type: z.ZodString;
|
|
79
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
80
|
+
path: z.ZodString;
|
|
81
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
82
|
+
type: z.ZodLiteral<"upload">;
|
|
83
|
+
id: z.ZodString;
|
|
84
|
+
name: z.ZodString;
|
|
85
|
+
mime_type: z.ZodString;
|
|
86
|
+
size: z.ZodNumber;
|
|
87
|
+
url: z.ZodString;
|
|
88
|
+
}, z.core.$strip>], "type">>>;
|
|
89
|
+
image_url: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
90
|
+
image_mime_type: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
91
|
+
image_size_bytes: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
|
|
92
|
+
timestamp: z.ZodDefault<z.ZodDate>;
|
|
93
|
+
}, z.core.$strip>;
|
|
94
|
+
type Message = z.infer<typeof MessageSchema>;
|
|
95
|
+
/**
|
|
96
|
+
* Authority level — what a participant is allowed to do.
|
|
97
|
+
*
|
|
98
|
+
* - `admin` — full control: kick, promote, clear, tunnel, generate all links
|
|
99
|
+
* - `product_owner` — can mute/unmute members, set engagement modes, generate member/guest links
|
|
100
|
+
* - `member` — can send messages, set own mode, generate member/guest links
|
|
101
|
+
* - `guest` — read-only: can catch up and search, but can't send or act
|
|
102
|
+
*
|
|
103
|
+
* Set on join via share token. Admins can change authority mid-session via /promote, /demote, /mute, /unmute.
|
|
104
|
+
*/
|
|
105
|
+
type AuthorityLevel = "admin" | "product_owner" | "member" | "guest";
|
|
106
|
+
/** Whether a participant is a human or an agent. */
|
|
107
|
+
type ParticipantType = "human" | "agent";
|
|
108
|
+
/**
|
|
109
|
+
* A participant in a room.
|
|
110
|
+
*
|
|
111
|
+
* - `id` — stable unique ID across all rooms and sessions
|
|
112
|
+
* - `name` — display name (mutable — participants can rename)
|
|
113
|
+
* - `status` — current presence status ("online", "offline", etc.)
|
|
114
|
+
* - `type` — "human" or "agent"
|
|
115
|
+
* - `identifier` — optional stable @-mention slug, e.g. "my-agent".
|
|
116
|
+
* Unlike `name`, this never changes on rename.
|
|
117
|
+
* Used for @-mention matching in addition to the display name.
|
|
118
|
+
* Not all participants have one — guests and anonymous users
|
|
119
|
+
* typically don't.
|
|
120
|
+
* - `authority` — optional authority level. Defaults to "member" if unset.
|
|
121
|
+
*/
|
|
122
|
+
interface Participant {
|
|
123
|
+
id: string;
|
|
124
|
+
name: string;
|
|
125
|
+
status: string;
|
|
126
|
+
type: ParticipantType;
|
|
127
|
+
identifier?: string;
|
|
128
|
+
authority?: AuthorityLevel;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* A page of results with a cursor for fetching the previous page.
|
|
132
|
+
*
|
|
133
|
+
* All paginated queries return results newest-first. Pass `next_cursor` back
|
|
134
|
+
* to the same query to continue paginating backwards through history.
|
|
135
|
+
*
|
|
136
|
+
* - `items` — results for this page (newest-first)
|
|
137
|
+
* - `next_cursor` — pass this to get the next (older) page; null when exhausted
|
|
138
|
+
* - `has_more` — true if there are older items beyond this page
|
|
139
|
+
*/
|
|
140
|
+
interface PaginatedResult<T> {
|
|
141
|
+
items: T[];
|
|
142
|
+
next_cursor: string | null;
|
|
143
|
+
has_more: boolean;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Typed events for rooms — a discriminated union on the `type` field.
|
|
148
|
+
*
|
|
149
|
+
* Every event has:
|
|
150
|
+
* id — UUID assigned at creation
|
|
151
|
+
* type — the discriminant (e.g. "MessageSent", "ParticipantJoined")
|
|
152
|
+
* category — the EventCategory for subscription filtering
|
|
153
|
+
* room_id — the room this event belongs to
|
|
154
|
+
* participant_id — the participant who caused the event
|
|
155
|
+
* timestamp — UTC creation time
|
|
156
|
+
*
|
|
157
|
+
* Use `createEvent()` to build events — it fills in `id` and `timestamp`.
|
|
158
|
+
* Use `EVENT_ROLE` to classify events by their semantic role.
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
interface BaseRoomEvent {
|
|
162
|
+
/** UUID assigned at creation. */
|
|
163
|
+
id: string;
|
|
164
|
+
}
|
|
165
|
+
/** Someone sent a message. `message` contains the full content including any image. */
|
|
166
|
+
interface MessageSentEvent extends BaseRoomEvent {
|
|
167
|
+
type: "MessageSent";
|
|
168
|
+
category: "MESSAGE";
|
|
169
|
+
room_id: string;
|
|
170
|
+
participant_id: string;
|
|
171
|
+
timestamp: Date;
|
|
172
|
+
message: Message;
|
|
173
|
+
}
|
|
174
|
+
/** A message's text content was changed. Does not update image attachments. */
|
|
175
|
+
interface MessageEditedEvent extends BaseRoomEvent {
|
|
176
|
+
type: "MessageEdited";
|
|
177
|
+
category: "MESSAGE";
|
|
178
|
+
room_id: string;
|
|
179
|
+
participant_id: string;
|
|
180
|
+
timestamp: Date;
|
|
181
|
+
message_id: string;
|
|
182
|
+
new_content: string;
|
|
183
|
+
old_content: string;
|
|
184
|
+
}
|
|
185
|
+
/** A message was removed. The message ID is preserved for reference but content is gone. */
|
|
186
|
+
interface MessageDeletedEvent extends BaseRoomEvent {
|
|
187
|
+
type: "MessageDeleted";
|
|
188
|
+
category: "MESSAGE";
|
|
189
|
+
room_id: string;
|
|
190
|
+
participant_id: string;
|
|
191
|
+
timestamp: Date;
|
|
192
|
+
message_id: string;
|
|
193
|
+
}
|
|
194
|
+
/** A participant added an emoji reaction to a message. */
|
|
195
|
+
interface ReactionAddedEvent extends BaseRoomEvent {
|
|
196
|
+
type: "ReactionAdded";
|
|
197
|
+
category: "MESSAGE";
|
|
198
|
+
room_id: string;
|
|
199
|
+
participant_id: string;
|
|
200
|
+
timestamp: Date;
|
|
201
|
+
message_id: string;
|
|
202
|
+
emoji: string;
|
|
203
|
+
}
|
|
204
|
+
/** A participant removed their emoji reaction from a message. */
|
|
205
|
+
interface ReactionRemovedEvent extends BaseRoomEvent {
|
|
206
|
+
type: "ReactionRemoved";
|
|
207
|
+
category: "MESSAGE";
|
|
208
|
+
room_id: string;
|
|
209
|
+
participant_id: string;
|
|
210
|
+
timestamp: Date;
|
|
211
|
+
message_id: string;
|
|
212
|
+
emoji: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* A participant connected to the room.
|
|
216
|
+
*
|
|
217
|
+
* Not emitted for silent connects (`Room.connect(..., silent: true)`).
|
|
218
|
+
* Agents connect silently to avoid polluting the chat with join noise.
|
|
219
|
+
*/
|
|
220
|
+
interface ParticipantJoinedEvent extends BaseRoomEvent {
|
|
221
|
+
type: "ParticipantJoined";
|
|
222
|
+
category: "PRESENCE";
|
|
223
|
+
room_id: string;
|
|
224
|
+
participant_id: string;
|
|
225
|
+
timestamp: Date;
|
|
226
|
+
/** Full participant snapshot at join time. */
|
|
227
|
+
participant: Participant;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* A participant disconnected from the room.
|
|
231
|
+
*
|
|
232
|
+
* Not emitted for silent disconnects (`channel.disconnect(true)`).
|
|
233
|
+
*/
|
|
234
|
+
interface ParticipantLeftEvent extends BaseRoomEvent {
|
|
235
|
+
type: "ParticipantLeft";
|
|
236
|
+
category: "PRESENCE";
|
|
237
|
+
room_id: string;
|
|
238
|
+
participant_id: string;
|
|
239
|
+
timestamp: Date;
|
|
240
|
+
/** Full participant snapshot at leave time. */
|
|
241
|
+
participant: Participant;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* A participant's presence status changed.
|
|
245
|
+
*
|
|
246
|
+
* Emitted by the server for all presence transitions:
|
|
247
|
+
* - `online → unresponsive` — first ping timeout threshold missed (reason: "ping_timeout")
|
|
248
|
+
* - `unresponsive → online` — SSE reconnect recovery (reason: "recovered")
|
|
249
|
+
* - `unresponsive → offline` — sustained timeout, second threshold missed (reason: "ping_timeout")
|
|
250
|
+
* - `online → offline` — clean disconnect (reason: "left") or admin kick (reason: "kicked")
|
|
251
|
+
*
|
|
252
|
+
* The `"left"` and `"kicked"` variants are companion events emitted alongside
|
|
253
|
+
* `ParticipantLeftEvent` / `ParticipantKickedEvent` for state-machine consumers
|
|
254
|
+
* that only want a single event type for presence tracking.
|
|
255
|
+
*
|
|
256
|
+
* `previous_status: "offline"` never appears — re-entry is `ParticipantJoinedEvent`.
|
|
257
|
+
*/
|
|
258
|
+
interface StatusChangedEvent extends BaseRoomEvent {
|
|
259
|
+
type: "StatusChanged";
|
|
260
|
+
category: "PRESENCE";
|
|
261
|
+
room_id: string;
|
|
262
|
+
participant_id: string;
|
|
263
|
+
timestamp: Date;
|
|
264
|
+
/** Display name of the affected participant. */
|
|
265
|
+
name: string;
|
|
266
|
+
status: "online" | "unresponsive" | "offline";
|
|
267
|
+
previous_status: "online" | "unresponsive" | "offline";
|
|
268
|
+
reason: "ping_timeout" | "recovered" | "left" | "kicked";
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* A participant was kicked from the room by an admin.
|
|
272
|
+
*
|
|
273
|
+
* Emitted before the channel disconnect so all participants see it.
|
|
274
|
+
* The subsequent `ParticipantLeft` event is suppressed (silent disconnect).
|
|
275
|
+
*/
|
|
276
|
+
interface ParticipantKickedEvent extends BaseRoomEvent {
|
|
277
|
+
type: "ParticipantKicked";
|
|
278
|
+
category: "PRESENCE";
|
|
279
|
+
room_id: string;
|
|
280
|
+
/** The kicked participant. */
|
|
281
|
+
participant_id: string;
|
|
282
|
+
timestamp: Date;
|
|
283
|
+
/** Full participant snapshot at kick time. */
|
|
284
|
+
participant: Participant;
|
|
285
|
+
/** Display name of the admin who kicked them. */
|
|
286
|
+
kicked_by: string;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* A participant's authority level was changed by an admin.
|
|
290
|
+
*
|
|
291
|
+
* Covers mute (→ guest), unmute (→ member), and promotion (→ admin).
|
|
292
|
+
*/
|
|
293
|
+
interface AuthorityChangedEvent extends BaseRoomEvent {
|
|
294
|
+
type: "AuthorityChanged";
|
|
295
|
+
category: "PRESENCE";
|
|
296
|
+
room_id: string;
|
|
297
|
+
/** The affected participant. */
|
|
298
|
+
participant_id: string;
|
|
299
|
+
timestamp: Date;
|
|
300
|
+
/** Full participant snapshot (with updated authority). */
|
|
301
|
+
participant: Participant;
|
|
302
|
+
/** The new authority level. */
|
|
303
|
+
new_authority: AuthorityLevel;
|
|
304
|
+
/** Display name of the admin who made the change. */
|
|
305
|
+
changed_by: string;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* An agent made an MCP tool call.
|
|
309
|
+
*
|
|
310
|
+
* Emitted twice per tool call: once with `status: "started"` (before the call)
|
|
311
|
+
* and once with `status: "completed"` (after). Useful for showing live tool
|
|
312
|
+
* progress in a UI.
|
|
313
|
+
*/
|
|
314
|
+
interface ToolUseEvent extends BaseRoomEvent {
|
|
315
|
+
type: "ToolUse";
|
|
316
|
+
category: "ACTIVITY";
|
|
317
|
+
room_id: string;
|
|
318
|
+
participant_id: string;
|
|
319
|
+
timestamp: Date;
|
|
320
|
+
tool_name: string;
|
|
321
|
+
/** "started" before the call, "completed" after. */
|
|
322
|
+
status: "started" | "completed";
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* A generic activity event for platform-specific actions.
|
|
326
|
+
*
|
|
327
|
+
* Used when no specific event type fits. The `action` field identifies the
|
|
328
|
+
* action (e.g. `"mode_changed"`), and `detail` carries structured metadata.
|
|
329
|
+
*
|
|
330
|
+
* Current usages:
|
|
331
|
+
* - action: "mode_changed", detail: { mode: EngagementMode }
|
|
332
|
+
* Emitted when an agent's engagement mode changes for a room.
|
|
333
|
+
*/
|
|
334
|
+
interface ActivityEvent extends BaseRoomEvent {
|
|
335
|
+
type: "Activity";
|
|
336
|
+
category: "ACTIVITY";
|
|
337
|
+
room_id: string;
|
|
338
|
+
participant_id: string;
|
|
339
|
+
timestamp: Date;
|
|
340
|
+
action: string;
|
|
341
|
+
detail: Record<string, unknown> | null;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* An agent's context window was compacted.
|
|
345
|
+
*
|
|
346
|
+
* Fired when the LLM backend summarizes and compresses the conversation history
|
|
347
|
+
* to free up context space. After compaction, the agent re-reads all rooms via
|
|
348
|
+
* `catch_up` to rebuild its working context.
|
|
349
|
+
*/
|
|
350
|
+
interface ContextCompactedEvent extends BaseRoomEvent {
|
|
351
|
+
type: "ContextCompacted";
|
|
352
|
+
category: "ACTIVITY";
|
|
353
|
+
room_id: string;
|
|
354
|
+
participant_id: string;
|
|
355
|
+
timestamp: Date;
|
|
356
|
+
/** Full participant snapshot (for display name). */
|
|
357
|
+
participant: Participant;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* An admin cleared the room history.
|
|
361
|
+
*
|
|
362
|
+
* All clients should discard their local event/message state and start fresh.
|
|
363
|
+
* The event itself is broadcast but NOT persisted (storage is already wiped).
|
|
364
|
+
*/
|
|
365
|
+
interface RoomClearedEvent extends BaseRoomEvent {
|
|
366
|
+
type: "RoomCleared";
|
|
367
|
+
category: "ACTIVITY";
|
|
368
|
+
room_id: string;
|
|
369
|
+
participant_id: string;
|
|
370
|
+
timestamp: Date;
|
|
371
|
+
/** Display name of the admin who cleared the room. */
|
|
372
|
+
cleared_by: string;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Room rules were created or updated.
|
|
376
|
+
*
|
|
377
|
+
* Emitted when the rules file changes — either via `PUT /rules` (admin) or
|
|
378
|
+
* when the underlying `~/.apiary/rooms/<name>.rules.md` file is hand-edited
|
|
379
|
+
* (mtime watch). Surfaced by `apiary__catch_up` so long-running agents
|
|
380
|
+
* re-discover the current ruleset after compaction or mid-session edits.
|
|
381
|
+
*/
|
|
382
|
+
interface RulesChangedEvent extends BaseRoomEvent {
|
|
383
|
+
type: "RulesChanged";
|
|
384
|
+
category: "ACTIVITY";
|
|
385
|
+
room_id: string;
|
|
386
|
+
participant_id: string;
|
|
387
|
+
timestamp: Date;
|
|
388
|
+
/** The full ruleset in effect after this change. */
|
|
389
|
+
rules: string[];
|
|
390
|
+
/** Display name of the actor who updated the rules; "[system]" if hand-edit. */
|
|
391
|
+
updated_by: string;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* A participant was @mentioned in a message.
|
|
395
|
+
*
|
|
396
|
+
* Delivered only to the mentioned participant's channel — not broadcast to the
|
|
397
|
+
* room. The `participant_id` is the **recipient** (the person mentioned), not
|
|
398
|
+
* the sender. The sender is in `message.sender_id`.
|
|
399
|
+
*
|
|
400
|
+
* @mention detection is case-insensitive and matches on both `identifier`
|
|
401
|
+
* (e.g. `@my-agent`) and display `name` (e.g. `@Alice`).
|
|
402
|
+
*
|
|
403
|
+
* Agents in standby modes wake up on this event type only.
|
|
404
|
+
*/
|
|
405
|
+
interface MentionedEvent extends BaseRoomEvent {
|
|
406
|
+
type: "Mentioned";
|
|
407
|
+
category: "MENTION";
|
|
408
|
+
room_id: string;
|
|
409
|
+
/** The mentioned participant (the recipient of the @mention). */
|
|
410
|
+
participant_id: string;
|
|
411
|
+
timestamp: Date;
|
|
412
|
+
/** The full message that contained the @mention. */
|
|
413
|
+
message: Message;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* A participant was pinged for a status check.
|
|
417
|
+
*
|
|
418
|
+
* Delivered to the pinged participant's channel and all observers.
|
|
419
|
+
* Unlike @mentions, pings are non-blocking: active agents see them as
|
|
420
|
+
* buffered context ("content"), not triggers. Standby agents wake on ping.
|
|
421
|
+
*/
|
|
422
|
+
interface PingedEvent extends BaseRoomEvent {
|
|
423
|
+
type: "Pinged";
|
|
424
|
+
category: "MENTION";
|
|
425
|
+
room_id: string;
|
|
426
|
+
/** The pinged participant (the recipient). */
|
|
427
|
+
participant_id: string;
|
|
428
|
+
timestamp: Date;
|
|
429
|
+
/** Participant ID of the person who sent the ping. */
|
|
430
|
+
pinger_id: string;
|
|
431
|
+
/** Display name of the person who sent the ping. */
|
|
432
|
+
pinger_name: string;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* A whisper was sent to specific participants.
|
|
436
|
+
*
|
|
437
|
+
* Broadcast to all participants NOT in the whisper, so they know a private
|
|
438
|
+
* conversation is happening without seeing the content. Sender and recipients
|
|
439
|
+
* receive the full `MessageSentEvent` instead. Not persisted to storage.
|
|
440
|
+
*/
|
|
441
|
+
interface WhisperNotifiedEvent extends BaseRoomEvent {
|
|
442
|
+
type: "WhisperNotified";
|
|
443
|
+
category: "ACTIVITY";
|
|
444
|
+
room_id: string;
|
|
445
|
+
/** The sender's participant ID (follows the common event convention). */
|
|
446
|
+
participant_id: string;
|
|
447
|
+
timestamp: Date;
|
|
448
|
+
sender_id: string;
|
|
449
|
+
sender_name: string;
|
|
450
|
+
recipient_ids: string[];
|
|
451
|
+
recipient_names: string[];
|
|
452
|
+
}
|
|
453
|
+
type RoomEvent = MessageSentEvent | MessageEditedEvent | MessageDeletedEvent | ReactionAddedEvent | ReactionRemovedEvent | ParticipantJoinedEvent | ParticipantLeftEvent | ParticipantKickedEvent | AuthorityChangedEvent | StatusChangedEvent | ToolUseEvent | ActivityEvent | MentionedEvent | PingedEvent | ContextCompactedEvent | RoomClearedEvent | RulesChangedEvent | WhisperNotifiedEvent;
|
|
454
|
+
/**
|
|
455
|
+
* Semantic role of an event, used by the engagement system to decide how to
|
|
456
|
+
* handle it relative to an agent.
|
|
457
|
+
*
|
|
458
|
+
* - "message" — a direct chat message; may trigger LLM evaluation
|
|
459
|
+
* - "mention" — an @mention directed at a specific participant
|
|
460
|
+
* - "ambient" — background activity (joins, leaves, reactions) — buffered as
|
|
461
|
+
* context but doesn't trigger evaluation on its own
|
|
462
|
+
* - "internal" — platform bookkeeping (edits, deletes, status changes, agent
|
|
463
|
+
* activity) — always dropped by the engagement system
|
|
464
|
+
*/
|
|
465
|
+
type EventRole = "message" | "mention" | "ping" | "ambient" | "internal";
|
|
466
|
+
/** Maps each event type to its semantic role for the engagement system. */
|
|
467
|
+
declare const EVENT_ROLE: Record<RoomEvent["type"], EventRole>;
|
|
468
|
+
type EventData<T extends RoomEvent> = Omit<T, "id" | "timestamp"> & {
|
|
469
|
+
id?: string;
|
|
470
|
+
timestamp?: Date;
|
|
471
|
+
};
|
|
472
|
+
/**
|
|
473
|
+
* Create a typed room event, filling in `id` (UUID) and `timestamp` (now).
|
|
474
|
+
*
|
|
475
|
+
* @example
|
|
476
|
+
* const event = createEvent<MessageSentEvent>({
|
|
477
|
+
* type: "MessageSent",
|
|
478
|
+
* category: "MESSAGE",
|
|
479
|
+
* room_id: "room-1",
|
|
480
|
+
* participant_id: "user-1",
|
|
481
|
+
* message: { ... },
|
|
482
|
+
* });
|
|
483
|
+
*/
|
|
484
|
+
declare function createEvent<T extends RoomEvent>(data: EventData<T>): T;
|
|
485
|
+
|
|
486
|
+
declare class Channel {
|
|
487
|
+
readonly participantId: string;
|
|
488
|
+
readonly participantName: string;
|
|
489
|
+
subscriptions: Set<EventCategory>;
|
|
490
|
+
private _room;
|
|
491
|
+
private _queue;
|
|
492
|
+
private _waiters;
|
|
493
|
+
private _disconnected;
|
|
494
|
+
constructor(room: Room, participantId: string, participantName: string, subscriptions: Set<EventCategory>);
|
|
495
|
+
get roomId(): string;
|
|
496
|
+
/**
|
|
497
|
+
* Send a chat message from this participant.
|
|
498
|
+
*
|
|
499
|
+
* Persists the message to storage, broadcasts a `MessageSentEvent` to all
|
|
500
|
+
* participants (including the sender), and fires `MentionedEvent` for any
|
|
501
|
+
* `@name` or `@identifier` patterns found in the content.
|
|
502
|
+
*
|
|
503
|
+
* @param content — message text (may be empty if image is provided)
|
|
504
|
+
* @param replyToId — ID of the message being replied to (optional)
|
|
505
|
+
* @param image — optional legacy image attachment
|
|
506
|
+
* @param attachments — optional array of typed attachments
|
|
507
|
+
* @param recipients — if non-empty, this is a whisper: only these participant IDs (plus sender) receive it
|
|
508
|
+
*/
|
|
509
|
+
sendMessage(content: string, replyToId?: string | null, image?: {
|
|
510
|
+
url: string;
|
|
511
|
+
mimeType: string;
|
|
512
|
+
sizeBytes: number;
|
|
513
|
+
} | null, attachments?: Attachment[], recipients?: string[]): Promise<Message>;
|
|
514
|
+
/**
|
|
515
|
+
* Ping another participant for a status check.
|
|
516
|
+
*
|
|
517
|
+
* Creates a `PingedEvent` delivered to the target and all observers.
|
|
518
|
+
* Unlike @mentions, pings are non-blocking for active agents.
|
|
519
|
+
*/
|
|
520
|
+
ping(targetId: string): Promise<void>;
|
|
521
|
+
/**
|
|
522
|
+
* Emit a non-message activity event to the room.
|
|
523
|
+
*
|
|
524
|
+
* Use this for platform events: tool use indicators, mode changes, compaction
|
|
525
|
+
* notices, etc. The event is persisted and broadcast to all subscribed
|
|
526
|
+
* participants.
|
|
527
|
+
*/
|
|
528
|
+
emit(event: RoomEvent): Promise<void>;
|
|
529
|
+
/**
|
|
530
|
+
* Change which event categories this channel receives.
|
|
531
|
+
* Takes effect immediately — buffered events from unsubscribed categories
|
|
532
|
+
* are not retroactively removed.
|
|
533
|
+
*/
|
|
534
|
+
updateSubscriptions(categories: Set<EventCategory>): void;
|
|
535
|
+
/**
|
|
536
|
+
* Leave the room.
|
|
537
|
+
*
|
|
538
|
+
* @param silent — if true, suppresses the `ParticipantLeft` broadcast.
|
|
539
|
+
* Agents disconnect silently to avoid chat noise.
|
|
540
|
+
*/
|
|
541
|
+
disconnect(silent?: boolean): Promise<void>;
|
|
542
|
+
/** @internal Called by Room to mark this channel as disconnected without removing from room maps. */
|
|
543
|
+
_markDisconnected(): void;
|
|
544
|
+
/** @internal Called by Room to deliver an incoming event. Filters by subscription. */
|
|
545
|
+
_deliver(event: RoomEvent): void;
|
|
546
|
+
/**
|
|
547
|
+
* Receive the next event, waiting up to `timeoutMs`.
|
|
548
|
+
*
|
|
549
|
+
* Returns null if no event arrives within the timeout. Drains buffered events
|
|
550
|
+
* before waiting. Used by `EventMultiplexer` to fan-in events from multiple
|
|
551
|
+
* rooms into a single stream.
|
|
552
|
+
*/
|
|
553
|
+
receive(timeoutMs: number): Promise<RoomEvent | null>;
|
|
554
|
+
/**
|
|
555
|
+
* Async iterator — yields events as they arrive.
|
|
556
|
+
*
|
|
557
|
+
* Used by `EventMultiplexer` to fan-in all room channels into a single stream.
|
|
558
|
+
* The iterator completes when the channel is disconnected.
|
|
559
|
+
*
|
|
560
|
+
* @example
|
|
561
|
+
* for await (const event of channel) {
|
|
562
|
+
* console.log(event.type);
|
|
563
|
+
* }
|
|
564
|
+
*/
|
|
565
|
+
[Symbol.asyncIterator](): AsyncIterator<RoomEvent>;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Storage protocol and reference implementations for apiary rooms.
|
|
570
|
+
*
|
|
571
|
+
* # Implementing StorageProtocol
|
|
572
|
+
*
|
|
573
|
+
* Provide your own implementation to persist messages and events to a real
|
|
574
|
+
* database. Pass it to `new Room(roomId, myStorage)`.
|
|
575
|
+
*
|
|
576
|
+
* Pagination contract (applies to all paginated methods):
|
|
577
|
+
* - Results are returned newest-first.
|
|
578
|
+
* - `cursor` is the ID of the last item on the previous page (exclusive).
|
|
579
|
+
* Pass `null` to start from the most recent.
|
|
580
|
+
* - `next_cursor` in the result is the cursor to pass for the next (older) page.
|
|
581
|
+
* - `has_more` is true if there are older items beyond the current page.
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* // Minimal Postgres implementation sketch:
|
|
585
|
+
* class PostgresStorage implements StorageProtocol {
|
|
586
|
+
* async addMessage(message) {
|
|
587
|
+
* await db.query("INSERT INTO messages ...", [message]);
|
|
588
|
+
* return message;
|
|
589
|
+
* }
|
|
590
|
+
* async getMessage(room_id, message_id) {
|
|
591
|
+
* return db.query("SELECT * FROM messages WHERE id = $1", [message_id]);
|
|
592
|
+
* }
|
|
593
|
+
* async getMessages(room_id, limit = 30, cursor = null) {
|
|
594
|
+
* // Fetch `limit` messages before `cursor`, newest-first
|
|
595
|
+
* const rows = await db.query("...");
|
|
596
|
+
* return { items: rows, next_cursor: ..., has_more: ... };
|
|
597
|
+
* }
|
|
598
|
+
* async searchMessages(room_id, query, limit = 10, cursor = null) {
|
|
599
|
+
* // Full-text search, newest-first
|
|
600
|
+
* }
|
|
601
|
+
* async addEvent(event) {
|
|
602
|
+
* await db.query("INSERT INTO events ...", [event]);
|
|
603
|
+
* }
|
|
604
|
+
* async getEvents(room_id, category = null, limit = 50, cursor = null) {
|
|
605
|
+
* // Optional category filter, newest-first
|
|
606
|
+
* }
|
|
607
|
+
* }
|
|
608
|
+
*/
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Persistence interface for a room's messages and events.
|
|
612
|
+
*
|
|
613
|
+
* Implement this to back rooms with a real database. The reference
|
|
614
|
+
* `InMemoryStorage` is suitable for testing and single-process local use.
|
|
615
|
+
*
|
|
616
|
+
* All methods operate on a single `room_id` — one storage instance is shared
|
|
617
|
+
* across all rooms (the `room_id` partitions the data).
|
|
618
|
+
*/
|
|
619
|
+
interface StorageProtocol {
|
|
620
|
+
/**
|
|
621
|
+
* Persist a message and return it (with any server-assigned fields set).
|
|
622
|
+
* Called automatically by `Channel.sendMessage()`.
|
|
623
|
+
*/
|
|
624
|
+
addMessage(message: Message): Promise<Message>;
|
|
625
|
+
/**
|
|
626
|
+
* Look up a single message by ID. Returns null if not found.
|
|
627
|
+
* Used by agents when resolving reply context and message refs.
|
|
628
|
+
*/
|
|
629
|
+
getMessage(room_id: string, message_id: string): Promise<Message | null>;
|
|
630
|
+
/**
|
|
631
|
+
* Paginate messages for a room, newest-first.
|
|
632
|
+
*
|
|
633
|
+
* `cursor` — the `id` of the last message on the previous page (exclusive).
|
|
634
|
+
* Pass null to start from the most recent message.
|
|
635
|
+
*/
|
|
636
|
+
getMessages(room_id: string, limit?: number, cursor?: string | null): Promise<PaginatedResult<Message>>;
|
|
637
|
+
/**
|
|
638
|
+
* Full-text search across message content, newest-first.
|
|
639
|
+
*
|
|
640
|
+
* `query` — keyword or phrase to search for (case-insensitive).
|
|
641
|
+
* `cursor` — pagination cursor (same semantics as `getMessages`).
|
|
642
|
+
*/
|
|
643
|
+
searchMessages(room_id: string, query: string, limit?: number, cursor?: string | null): Promise<PaginatedResult<Message>>;
|
|
644
|
+
/**
|
|
645
|
+
* Persist a room event. Called for every event that passes through the room.
|
|
646
|
+
* Events are append-only — never updated or deleted.
|
|
647
|
+
*/
|
|
648
|
+
addEvent(event: RoomEvent): Promise<void>;
|
|
649
|
+
/**
|
|
650
|
+
* Paginate events for a room, newest-first.
|
|
651
|
+
*
|
|
652
|
+
* `category` — optional filter (e.g. EventCategory.MESSAGE). Pass null for all.
|
|
653
|
+
* `cursor` — pagination cursor (index-based for events).
|
|
654
|
+
*/
|
|
655
|
+
getEvents(room_id: string, category?: EventCategory | null, limit?: number, cursor?: string | null): Promise<PaginatedResult<RoomEvent>>;
|
|
656
|
+
/**
|
|
657
|
+
* Delete all messages and events for a room.
|
|
658
|
+
* Used by the `/clear` command to wipe room history.
|
|
659
|
+
*/
|
|
660
|
+
clearRoom(room_id: string): Promise<void>;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Reference in-memory implementation of `StorageProtocol`.
|
|
664
|
+
*
|
|
665
|
+
* Suitable for tests, development, and single-process local use. All data is
|
|
666
|
+
* lost on process restart — not for production.
|
|
667
|
+
*
|
|
668
|
+
* One instance can serve multiple rooms (data is partitioned by `room_id`).
|
|
669
|
+
*/
|
|
670
|
+
declare class InMemoryStorage implements StorageProtocol {
|
|
671
|
+
protected _messages: Map<string, {
|
|
672
|
+
id: string;
|
|
673
|
+
room_id: string;
|
|
674
|
+
sender_id: string;
|
|
675
|
+
sender_name: string;
|
|
676
|
+
content: string;
|
|
677
|
+
reply_to_id: string | null;
|
|
678
|
+
recipients: string[];
|
|
679
|
+
attachments: ({
|
|
680
|
+
type: "path";
|
|
681
|
+
id: string;
|
|
682
|
+
name: string;
|
|
683
|
+
mime_type: string;
|
|
684
|
+
path: string;
|
|
685
|
+
size?: number | undefined;
|
|
686
|
+
} | {
|
|
687
|
+
type: "upload";
|
|
688
|
+
id: string;
|
|
689
|
+
name: string;
|
|
690
|
+
mime_type: string;
|
|
691
|
+
size: number;
|
|
692
|
+
url: string;
|
|
693
|
+
})[];
|
|
694
|
+
image_url: string | null;
|
|
695
|
+
image_mime_type: string | null;
|
|
696
|
+
image_size_bytes: number | null;
|
|
697
|
+
timestamp: Date;
|
|
698
|
+
}[]>;
|
|
699
|
+
protected _events: Map<string, RoomEvent[]>;
|
|
700
|
+
addMessage(message: Message): Promise<Message>;
|
|
701
|
+
getMessage(room_id: string, message_id: string): Promise<Message | null>;
|
|
702
|
+
getMessages(room_id: string, limit?: number, cursor?: string | null): Promise<PaginatedResult<Message>>;
|
|
703
|
+
searchMessages(room_id: string, query: string, limit?: number, cursor?: string | null): Promise<PaginatedResult<Message>>;
|
|
704
|
+
addEvent(event: RoomEvent): Promise<void>;
|
|
705
|
+
getEvents(room_id: string, category?: EventCategory | null, limit?: number, cursor?: string | null): Promise<PaginatedResult<RoomEvent>>;
|
|
706
|
+
clearRoom(room_id: string): Promise<void>;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Room — a shared chat space where humans and agents are all just participants.
|
|
711
|
+
*
|
|
712
|
+
* Transport-agnostic: no WebSockets, no HTTP. The caller owns the transport
|
|
713
|
+
* and passes messages/events in via channels. This means the same Room works
|
|
714
|
+
* identically in a CLI, a web server, or a test.
|
|
715
|
+
*
|
|
716
|
+
* # Connecting
|
|
717
|
+
* Participants connect via `room.connect()`, which returns a `Channel`. The
|
|
718
|
+
* channel is their bidirectional connection: they send messages and receive
|
|
719
|
+
* events through it.
|
|
720
|
+
*
|
|
721
|
+
* # Observing
|
|
722
|
+
* Call `room.observe()` to get a read-only-style channel that receives every
|
|
723
|
+
* event in the room — including targeted @mention events directed at other
|
|
724
|
+
* participants. Observers are NOT participants: they don't appear in
|
|
725
|
+
* `listParticipants()` and don't trigger join/leave events.
|
|
726
|
+
*
|
|
727
|
+
* # @mention detection
|
|
728
|
+
* When a message is sent, the Room scans its content for `@token` patterns and
|
|
729
|
+
* fires a `MentionedEvent` for any participant whose `identifier` or display
|
|
730
|
+
* `name` matches the token (case-insensitive). The mention event is delivered
|
|
731
|
+
* to the mentioned participant AND to all observers.
|
|
732
|
+
*
|
|
733
|
+
* @example
|
|
734
|
+
* const storage = new InMemoryStorage();
|
|
735
|
+
* const room = new Room("room-1", storage);
|
|
736
|
+
*
|
|
737
|
+
* const aliceChannel = await room.connect("alice-id", "Alice");
|
|
738
|
+
* const agentChannel = await room.connect("agent-id", "Agent", "agent", "my-agent");
|
|
739
|
+
* const observer = room.observe();
|
|
740
|
+
*
|
|
741
|
+
* await aliceChannel.sendMessage("hey @my-agent what do you think?");
|
|
742
|
+
* // → MessageSentEvent broadcast to all participants + observer
|
|
743
|
+
* // → MentionedEvent delivered to agentChannel + observer
|
|
744
|
+
*/
|
|
745
|
+
|
|
746
|
+
declare class Room {
|
|
747
|
+
readonly roomId: string;
|
|
748
|
+
/** Direct access to the underlying storage. Useful for bulk reads. */
|
|
749
|
+
readonly storage: StorageProtocol;
|
|
750
|
+
private _channels;
|
|
751
|
+
private _participants;
|
|
752
|
+
private _observers;
|
|
753
|
+
private _nextObserverId;
|
|
754
|
+
/**
|
|
755
|
+
* @param roomId — stable identifier for this room (e.g. a UUID or slug)
|
|
756
|
+
* @param storage — storage backend; defaults to `InMemoryStorage`
|
|
757
|
+
*/
|
|
758
|
+
constructor(roomId: string, storage?: StorageProtocol);
|
|
759
|
+
/**
|
|
760
|
+
* Connect a participant and return their channel.
|
|
761
|
+
*/
|
|
762
|
+
connect(participantId: string, name: string, options?: {
|
|
763
|
+
type?: ParticipantType;
|
|
764
|
+
identifier?: string;
|
|
765
|
+
subscribe?: Set<EventCategory>;
|
|
766
|
+
silent?: boolean;
|
|
767
|
+
authority?: AuthorityLevel;
|
|
768
|
+
}): Promise<Channel>;
|
|
769
|
+
/**
|
|
770
|
+
* Observe all room events without being a participant.
|
|
771
|
+
*
|
|
772
|
+
* Returns a channel that receives every event — broadcasts AND targeted
|
|
773
|
+
* @mention events directed at other participants. Observers do NOT appear
|
|
774
|
+
* in `listParticipants()` and do not emit join/leave presence events,
|
|
775
|
+
* since they are not participants.
|
|
776
|
+
*
|
|
777
|
+
* Disconnect via `observer.disconnect()` when done.
|
|
778
|
+
*
|
|
779
|
+
* @example
|
|
780
|
+
* const observer = room.observe();
|
|
781
|
+
* for await (const event of observer) {
|
|
782
|
+
* // sees everything, including mentions for other participants
|
|
783
|
+
* }
|
|
784
|
+
*/
|
|
785
|
+
observe(): Channel;
|
|
786
|
+
/**
|
|
787
|
+
* Paginate messages, newest-first. Pass the returned `next_cursor` to get
|
|
788
|
+
* the next (older) page.
|
|
789
|
+
*/
|
|
790
|
+
listMessages(limit?: number, cursor?: string | null): Promise<PaginatedResult<Message>>;
|
|
791
|
+
/**
|
|
792
|
+
* Full-text search across message content, newest-first.
|
|
793
|
+
* `query` is matched case-insensitively against message content.
|
|
794
|
+
*/
|
|
795
|
+
searchMessages(query: string, limit?: number, cursor?: string | null): Promise<PaginatedResult<Message>>;
|
|
796
|
+
/** All currently connected participants (including agents). Observers excluded. */
|
|
797
|
+
listParticipants(): Participant[];
|
|
798
|
+
/**
|
|
799
|
+
* Paginate room events, newest-first.
|
|
800
|
+
* `category` optionally filters to one EventCategory.
|
|
801
|
+
*/
|
|
802
|
+
listEvents(category?: EventCategory | null, limit?: number, cursor?: string | null): Promise<PaginatedResult<RoomEvent>>;
|
|
803
|
+
/** Look up a single message by ID. Returns null if not found. */
|
|
804
|
+
getMessage(id: string): Promise<Message | null>;
|
|
805
|
+
/** Update a participant's authority level at runtime. */
|
|
806
|
+
setParticipantAuthority(participantId: string, authority: AuthorityLevel): boolean;
|
|
807
|
+
/**
|
|
808
|
+
* @internal
|
|
809
|
+
* Store a message, broadcast MessageSentEvent, and fire MentionedEvents.
|
|
810
|
+
*
|
|
811
|
+
* @mention scanning: looks for `@token` patterns in content and matches
|
|
812
|
+
* against each connected participant's `identifier` and display `name`
|
|
813
|
+
* (case-insensitive). Fires a `MentionedEvent` for each match, delivered
|
|
814
|
+
* to the mentioned participant AND all observers.
|
|
815
|
+
*/
|
|
816
|
+
_handleMessage(message: Message): Promise<void>;
|
|
817
|
+
/**
|
|
818
|
+
* @internal
|
|
819
|
+
* Send a ping to a participant. Creates a PingedEvent delivered to the
|
|
820
|
+
* target's channel and all observers (same routing as MentionedEvent).
|
|
821
|
+
*/
|
|
822
|
+
_handlePing(senderId: string, senderName: string, targetId: string): Promise<void>;
|
|
823
|
+
/** @internal Store and broadcast an activity event. */
|
|
824
|
+
_handleEvent(event: RoomEvent): Promise<void>;
|
|
825
|
+
/** @internal Remove a channel and optionally broadcast ParticipantLeftEvent. */
|
|
826
|
+
_disconnectChannel(channel: Channel, silent?: boolean): Promise<void>;
|
|
827
|
+
private _storeAndBroadcast;
|
|
828
|
+
private _broadcast;
|
|
829
|
+
/**
|
|
830
|
+
* Scan message content for `@token` patterns and return matching participant IDs.
|
|
831
|
+
* Matches against both `identifier` (e.g. `@my-agent`) and display `name` (e.g. `@Alice`).
|
|
832
|
+
* Case-insensitive. Deduplicates — each participant appears at most once.
|
|
833
|
+
*/
|
|
834
|
+
private _detectMentions;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
export { type Attachment as A, Channel as C, EventCategory as E, InMemoryStorage as I, type Message as M, type Participant as P, type RoomEvent as R, type StatusChangedEvent as S, type ToolUseEvent as T, type PaginatedResult as a, Room as b, type ParticipantType as c, type AuthorityLevel as d, type ActivityEvent as e, type ContextCompactedEvent as f, EVENT_ROLE as g, type EventRole as h, type MentionedEvent as i, type MessageDeletedEvent as j, type MessageEditedEvent as k, MessageSchema as l, type MessageSentEvent as m, type ParticipantJoinedEvent as n, type ParticipantLeftEvent as o, type ReactionAddedEvent as p, type ReactionRemovedEvent as q, type StorageProtocol as r, createEvent as s };
|