@meshagent/meshagent-agents 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/LICENSE +1 -0
  3. package/README.md +206 -0
  4. package/dist/browser/agent-messages.d.ts +343 -0
  5. package/dist/browser/agent-messages.js +1015 -0
  6. package/dist/browser/change-emitter.d.ts +8 -0
  7. package/dist/browser/change-emitter.js +20 -0
  8. package/dist/browser/chat-client.d.ts +225 -0
  9. package/dist/browser/chat-client.js +642 -0
  10. package/dist/browser/images-dataset.d.ts +83 -0
  11. package/dist/browser/images-dataset.js +282 -0
  12. package/dist/browser/index.d.ts +6 -0
  13. package/dist/browser/index.js +22 -0
  14. package/dist/browser/package.json +1 -0
  15. package/dist/browser/room-shell-toolkit.d.ts +14 -0
  16. package/dist/browser/room-shell-toolkit.js +274 -0
  17. package/dist/browser/room-storage-toolkit.d.ts +11 -0
  18. package/dist/browser/room-storage-toolkit.js +513 -0
  19. package/dist/browser/thread-storage.d.ts +102 -0
  20. package/dist/browser/thread-storage.js +476 -0
  21. package/dist/esm/agent-messages.d.ts +343 -0
  22. package/dist/esm/agent-messages.js +989 -0
  23. package/dist/esm/change-emitter.d.ts +8 -0
  24. package/dist/esm/change-emitter.js +16 -0
  25. package/dist/esm/chat-client.d.ts +225 -0
  26. package/dist/esm/chat-client.js +632 -0
  27. package/dist/esm/images-dataset.d.ts +83 -0
  28. package/dist/esm/images-dataset.js +274 -0
  29. package/dist/esm/index.d.ts +6 -0
  30. package/dist/esm/index.js +6 -0
  31. package/dist/esm/package.json +1 -0
  32. package/dist/esm/room-shell-toolkit.d.ts +14 -0
  33. package/dist/esm/room-shell-toolkit.js +270 -0
  34. package/dist/esm/room-storage-toolkit.d.ts +11 -0
  35. package/dist/esm/room-storage-toolkit.js +509 -0
  36. package/dist/esm/thread-storage.d.ts +102 -0
  37. package/dist/esm/thread-storage.js +465 -0
  38. package/dist/node/agent-messages.d.ts +343 -0
  39. package/dist/node/agent-messages.js +1015 -0
  40. package/dist/node/change-emitter.d.ts +8 -0
  41. package/dist/node/change-emitter.js +20 -0
  42. package/dist/node/chat-client.d.ts +225 -0
  43. package/dist/node/chat-client.js +642 -0
  44. package/dist/node/images-dataset.d.ts +83 -0
  45. package/dist/node/images-dataset.js +282 -0
  46. package/dist/node/index.d.ts +6 -0
  47. package/dist/node/index.js +22 -0
  48. package/dist/node/package.json +1 -0
  49. package/dist/node/room-shell-toolkit.d.ts +14 -0
  50. package/dist/node/room-shell-toolkit.js +274 -0
  51. package/dist/node/room-storage-toolkit.d.ts +11 -0
  52. package/dist/node/room-storage-toolkit.js +513 -0
  53. package/dist/node/thread-storage.d.ts +102 -0
  54. package/dist/node/thread-storage.js +476 -0
  55. package/package.json +57 -0
@@ -0,0 +1,11 @@
1
+ import { Meshagent, Toolkit } from "@meshagent/meshagent";
2
+ export declare const defaultRoomStorageToolkitMaxLength = 20000;
3
+ export declare class RoomStorageToolkit extends Toolkit {
4
+ constructor({ client, projectId, rooms, readOnly, maxLength, }: {
5
+ client: Meshagent;
6
+ projectId: string;
7
+ rooms: string[];
8
+ readOnly?: boolean;
9
+ maxLength?: number;
10
+ });
11
+ }
@@ -0,0 +1,513 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RoomStorageToolkit = exports.defaultRoomStorageToolkitMaxLength = void 0;
4
+ const meshagent_1 = require("@meshagent/meshagent");
5
+ exports.defaultRoomStorageToolkitMaxLength = 20000;
6
+ class RoomStorageToolkit extends meshagent_1.Toolkit {
7
+ constructor({ client, projectId, rooms, readOnly = false, maxLength = exports.defaultRoomStorageToolkitMaxLength, }) {
8
+ const config = new RoomStorageToolkitConfig({
9
+ client,
10
+ projectId,
11
+ rooms: normalizeRooms(rooms),
12
+ maxLength,
13
+ });
14
+ super({
15
+ name: "room_storage",
16
+ title: "room storage",
17
+ description: "tools for interacting with explicitly shared room storage",
18
+ tools: roomStorageTools({ config, readOnly }),
19
+ });
20
+ }
21
+ }
22
+ exports.RoomStorageToolkit = RoomStorageToolkit;
23
+ function roomStorageTools({ config, readOnly, }) {
24
+ const tools = [
25
+ new ListRoomFilesTool(config),
26
+ new ReadRoomFileTool(config),
27
+ new GrepRoomFileTool(config),
28
+ new GetRoomFileDownloadUrlTool(config),
29
+ ];
30
+ if (!readOnly) {
31
+ tools.push(new WriteRoomFileTool(config), new CopyRoomFileTool(config), new DeleteRoomFileTool(config));
32
+ }
33
+ return tools;
34
+ }
35
+ class RoomStorageToolkitConfig {
36
+ constructor({ client, projectId, rooms, maxLength, }) {
37
+ if (rooms.length === 0) {
38
+ throw new TypeError("RoomStorageToolkit requires at least one allowed room.");
39
+ }
40
+ if (maxLength <= 0) {
41
+ throw new TypeError("maxLength must be positive.");
42
+ }
43
+ this.client = client;
44
+ this.projectId = projectId;
45
+ this.rooms = rooms;
46
+ this.allowedRooms = new Set(rooms);
47
+ this.maxLength = maxLength;
48
+ }
49
+ requireRoom(value) {
50
+ return this.requireRoomField(value, "room_name");
51
+ }
52
+ requireRoomField(value, field) {
53
+ if (typeof value !== "string" || value.trim() === "") {
54
+ throw new meshagent_1.RoomServerException(`${field} is required.`);
55
+ }
56
+ const roomName = value.trim();
57
+ if (!this.allowedRooms.has(roomName)) {
58
+ throw new meshagent_1.RoomServerException(`room '${roomName}' is not shared with this toolkit.`);
59
+ }
60
+ return roomName;
61
+ }
62
+ requirePath(value) {
63
+ return this.requirePathField(value, "path");
64
+ }
65
+ requirePathField(value, field) {
66
+ if (typeof value !== "string") {
67
+ throw new meshagent_1.RoomServerException(`${field} is required.`);
68
+ }
69
+ const path = value.trim();
70
+ const parts = path.split("/").filter((part) => part !== "");
71
+ if (parts.some((part) => part === "." || part === "..")) {
72
+ throw new meshagent_1.RoomServerException(`${field} may not contain . or .. segments.`);
73
+ }
74
+ return path;
75
+ }
76
+ async withRoom(roomName, callback) {
77
+ const connection = await this.client.connectRoom(this.projectId, roomName);
78
+ const room = new meshagent_1.RoomClient({
79
+ protocolFactory: meshagent_1.WebSocketClientProtocol.createFactory({
80
+ url: connection.roomUrl,
81
+ token: connection.jwt,
82
+ }),
83
+ reconnectTimeout: 0,
84
+ });
85
+ try {
86
+ await room.start();
87
+ await room.ready;
88
+ return await callback(room);
89
+ }
90
+ finally {
91
+ room.dispose();
92
+ }
93
+ }
94
+ }
95
+ class RoomStorageTool extends meshagent_1.Tool {
96
+ constructor(config, params) {
97
+ super({
98
+ name: params.name,
99
+ title: params.title,
100
+ description: params.description,
101
+ inputSchema: schema(config.rooms, params.properties, params.requiredFields),
102
+ outputSpec: params.outputSpec,
103
+ });
104
+ this.config = config;
105
+ }
106
+ roomName(args) {
107
+ return this.config.requireRoom(args.room_name);
108
+ }
109
+ path(args) {
110
+ return this.config.requirePath(args.path);
111
+ }
112
+ }
113
+ class ListRoomFilesTool extends RoomStorageTool {
114
+ constructor(config) {
115
+ super(config, {
116
+ name: "list_files_in_room",
117
+ title: "list files in room",
118
+ description: "list files in shared room storage",
119
+ properties: {
120
+ path: {
121
+ type: "string",
122
+ description: "The room storage directory path to list.",
123
+ },
124
+ },
125
+ requiredFields: ["path"],
126
+ outputSpec: new meshagent_1.ToolContentSpec({ types: ["json"], stream: false }),
127
+ });
128
+ }
129
+ async execute(args) {
130
+ const selectedRoom = this.roomName(args);
131
+ const selectedPath = this.path(args);
132
+ return await this.config.withRoom(selectedRoom, async (room) => {
133
+ const entries = await room.storage.list(selectedPath);
134
+ return new meshagent_1.JsonContent({
135
+ json: { files: entries.map(storageEntryJson) },
136
+ });
137
+ });
138
+ }
139
+ }
140
+ class ReadRoomFileTool extends RoomStorageTool {
141
+ constructor(config) {
142
+ super(config, {
143
+ name: "read_file",
144
+ title: "read file",
145
+ description: "read a file from shared room storage",
146
+ properties: {
147
+ path: {
148
+ type: "string",
149
+ description: "The room storage file path to read.",
150
+ },
151
+ offset: {
152
+ type: ["integer", "null"],
153
+ description: "Optional character offset for text files.",
154
+ },
155
+ },
156
+ requiredFields: ["path", "offset"],
157
+ outputSpec: new meshagent_1.ToolContentSpec({
158
+ types: ["text", "file"],
159
+ stream: false,
160
+ }),
161
+ });
162
+ }
163
+ async execute(args) {
164
+ const selectedRoom = this.roomName(args);
165
+ const selectedPath = this.path(args);
166
+ const offset = optionalNonNegativeInt(args.offset, "offset") ?? 0;
167
+ return await this.config.withRoom(selectedRoom, async (room) => {
168
+ const content = await room.storage.download(selectedPath);
169
+ if (!isTextLike(content)) {
170
+ return content;
171
+ }
172
+ const text = new TextDecoder().decode(content.data);
173
+ return new meshagent_1.TextContent({
174
+ text: sliceText(text, offset, this.config.maxLength),
175
+ });
176
+ });
177
+ }
178
+ }
179
+ class GrepRoomFileTool extends RoomStorageTool {
180
+ constructor(config) {
181
+ super(config, {
182
+ name: "grep_file",
183
+ title: "grep file",
184
+ description: "search a text file in shared room storage with a regular expression",
185
+ properties: {
186
+ path: {
187
+ type: "string",
188
+ description: "The room storage file path to search.",
189
+ },
190
+ pattern: {
191
+ type: "string",
192
+ description: "A JavaScript regular expression pattern.",
193
+ },
194
+ offset: {
195
+ type: ["integer", "null"],
196
+ description: "Optional match offset.",
197
+ },
198
+ before: {
199
+ type: ["integer", "null"],
200
+ description: "Optional number of context lines before each match.",
201
+ },
202
+ after: {
203
+ type: ["integer", "null"],
204
+ description: "Optional number of context lines after each match.",
205
+ },
206
+ },
207
+ requiredFields: ["path", "pattern", "offset", "before", "after"],
208
+ outputSpec: new meshagent_1.ToolContentSpec({ types: ["text"], stream: false }),
209
+ });
210
+ }
211
+ async execute(args) {
212
+ const selectedRoom = this.roomName(args);
213
+ const selectedPath = this.path(args);
214
+ if (typeof args.pattern !== "string" || args.pattern === "") {
215
+ throw new meshagent_1.RoomServerException("pattern is required.");
216
+ }
217
+ const offset = optionalNonNegativeInt(args.offset, "offset") ?? 0;
218
+ const before = optionalNonNegativeInt(args.before, "before") ?? 0;
219
+ const after = optionalNonNegativeInt(args.after, "after") ?? 0;
220
+ const pattern = new RegExp(args.pattern);
221
+ return await this.config.withRoom(selectedRoom, async (room) => {
222
+ const content = await room.storage.download(selectedPath);
223
+ if (!isTextLike(content)) {
224
+ return new meshagent_1.TextContent({
225
+ text: "grep_file only supports text-like files. Use read_file for binary files.",
226
+ });
227
+ }
228
+ const text = new TextDecoder().decode(content.data);
229
+ return new meshagent_1.TextContent({
230
+ text: grepText(text, pattern, offset, before, after, this.config.maxLength),
231
+ });
232
+ });
233
+ }
234
+ }
235
+ class GetRoomFileDownloadUrlTool extends RoomStorageTool {
236
+ constructor(config) {
237
+ super(config, {
238
+ name: "get_file_download_url",
239
+ title: "get file download url",
240
+ description: "get a temporary download URL for a file in shared room storage",
241
+ properties: {
242
+ path: {
243
+ type: "string",
244
+ description: "The room storage file path.",
245
+ },
246
+ },
247
+ requiredFields: ["path"],
248
+ outputSpec: new meshagent_1.ToolContentSpec({ types: ["link"], stream: false }),
249
+ });
250
+ }
251
+ async execute(args) {
252
+ const selectedRoom = this.roomName(args);
253
+ const selectedPath = this.path(args);
254
+ return await this.config.withRoom(selectedRoom, async (room) => {
255
+ const url = await room.storage.downloadUrl(selectedPath);
256
+ return new meshagent_1.LinkContent({ url, name: basename(selectedPath) });
257
+ });
258
+ }
259
+ }
260
+ class WriteRoomFileTool extends RoomStorageTool {
261
+ constructor(config) {
262
+ super(config, {
263
+ name: "write_file",
264
+ title: "write file",
265
+ description: "write a text file to shared room storage",
266
+ properties: {
267
+ path: {
268
+ type: "string",
269
+ description: "The room storage file path to write.",
270
+ },
271
+ text: { type: "string", description: "The text content to write." },
272
+ overwrite: {
273
+ type: "boolean",
274
+ description: "Whether to overwrite an existing file.",
275
+ },
276
+ },
277
+ requiredFields: ["path", "text", "overwrite"],
278
+ outputSpec: new meshagent_1.ToolContentSpec({ types: ["text"], stream: false }),
279
+ });
280
+ }
281
+ async execute(args) {
282
+ const selectedRoom = this.roomName(args);
283
+ const selectedPath = this.path(args);
284
+ if (typeof args.text !== "string") {
285
+ throw new meshagent_1.RoomServerException("text is required.");
286
+ }
287
+ return await this.config.withRoom(selectedRoom, async (room) => {
288
+ await room.storage.upload(selectedPath, new TextEncoder().encode(args.text), {
289
+ overwrite: args.overwrite === true,
290
+ name: basename(selectedPath),
291
+ mimeType: "text/plain",
292
+ });
293
+ return new meshagent_1.TextContent({ text: "the file was saved" });
294
+ });
295
+ }
296
+ }
297
+ class DeleteRoomFileTool extends RoomStorageTool {
298
+ constructor(config) {
299
+ super(config, {
300
+ name: "delete_file",
301
+ title: "delete file",
302
+ description: "delete a file or directory from shared room storage",
303
+ properties: {
304
+ path: {
305
+ type: "string",
306
+ description: "The room storage path to delete.",
307
+ },
308
+ recursive: {
309
+ type: "boolean",
310
+ description: "Whether to recursively delete directories.",
311
+ },
312
+ },
313
+ requiredFields: ["path", "recursive"],
314
+ outputSpec: new meshagent_1.ToolContentSpec({ types: ["empty"], stream: false }),
315
+ });
316
+ }
317
+ async execute(args) {
318
+ const selectedRoom = this.roomName(args);
319
+ const selectedPath = this.path(args);
320
+ return await this.config.withRoom(selectedRoom, async (room) => {
321
+ await room.storage.delete(selectedPath, {
322
+ recursive: args.recursive === true,
323
+ });
324
+ return new meshagent_1.EmptyContent();
325
+ });
326
+ }
327
+ }
328
+ class CopyRoomFileTool extends meshagent_1.Tool {
329
+ constructor(config) {
330
+ super({
331
+ name: "copy_file",
332
+ title: "copy file",
333
+ description: "copy a file between explicitly shared room storage",
334
+ inputSchema: {
335
+ type: "object",
336
+ additionalProperties: false,
337
+ required: [
338
+ "source_room_name",
339
+ "source_path",
340
+ "destination_room_name",
341
+ "destination_path",
342
+ "overwrite",
343
+ ],
344
+ properties: {
345
+ source_room_name: {
346
+ type: "string",
347
+ enum: config.rooms,
348
+ description: "The shared room to copy the file from.",
349
+ },
350
+ source_path: {
351
+ type: "string",
352
+ description: "The room storage file path to copy from.",
353
+ },
354
+ destination_room_name: {
355
+ type: "string",
356
+ enum: config.rooms,
357
+ description: "The shared room to copy the file to.",
358
+ },
359
+ destination_path: {
360
+ type: "string",
361
+ description: "The room storage file path to copy to.",
362
+ },
363
+ overwrite: {
364
+ type: "boolean",
365
+ description: "Whether to overwrite an existing destination file.",
366
+ },
367
+ },
368
+ },
369
+ outputSpec: new meshagent_1.ToolContentSpec({ types: ["text"], stream: false }),
370
+ });
371
+ this.config = config;
372
+ }
373
+ async execute(args) {
374
+ const sourceRoom = this.config.requireRoomField(args.source_room_name, "source_room_name");
375
+ const sourcePath = this.config.requirePathField(args.source_path, "source_path");
376
+ const destinationRoom = this.config.requireRoomField(args.destination_room_name, "destination_room_name");
377
+ const destinationPath = this.config.requirePathField(args.destination_path, "destination_path");
378
+ const overwrite = args.overwrite === true;
379
+ if (sourceRoom === destinationRoom) {
380
+ return await this.config.withRoom(sourceRoom, async (room) => {
381
+ const content = await room.storage.download(sourcePath);
382
+ await room.storage.upload(destinationPath, content.data, {
383
+ overwrite,
384
+ name: basename(destinationPath),
385
+ mimeType: content.mimeType,
386
+ });
387
+ return new meshagent_1.TextContent({ text: "the file was copied" });
388
+ });
389
+ }
390
+ const content = await this.config.withRoom(sourceRoom, (room) => room.storage.download(sourcePath));
391
+ return await this.config.withRoom(destinationRoom, async (room) => {
392
+ await room.storage.upload(destinationPath, content.data, {
393
+ overwrite,
394
+ name: basename(destinationPath),
395
+ mimeType: content.mimeType,
396
+ });
397
+ return new meshagent_1.TextContent({ text: "the file was copied" });
398
+ });
399
+ }
400
+ }
401
+ function schema(rooms, properties, requiredFields) {
402
+ return {
403
+ type: "object",
404
+ additionalProperties: false,
405
+ required: ["room_name", ...requiredFields],
406
+ properties: {
407
+ room_name: {
408
+ type: "string",
409
+ enum: rooms,
410
+ description: "The shared room whose storage should be used.",
411
+ },
412
+ ...properties,
413
+ },
414
+ };
415
+ }
416
+ function normalizeRooms(rooms) {
417
+ return [
418
+ ...new Set(rooms.map((room) => room.trim()).filter((room) => room !== "")),
419
+ ];
420
+ }
421
+ function storageEntryJson(entry) {
422
+ return {
423
+ name: entry.name,
424
+ is_folder: entry.isFolder,
425
+ ...(entry.size != null ? { size: entry.size } : {}),
426
+ ...(entry.createdAt != null
427
+ ? { created_at: entry.createdAt.toISOString() }
428
+ : {}),
429
+ ...(entry.updatedAt != null
430
+ ? { updated_at: entry.updatedAt.toISOString() }
431
+ : {}),
432
+ };
433
+ }
434
+ function optionalNonNegativeInt(value, field) {
435
+ if (value == null)
436
+ return undefined;
437
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
438
+ throw new meshagent_1.RoomServerException(`${field} must be a non-negative integer.`);
439
+ }
440
+ return value;
441
+ }
442
+ function isTextLike(content) {
443
+ const mimeType = content.mimeType.toLowerCase();
444
+ if (mimeType.startsWith("text/") ||
445
+ mimeType === "application/json" ||
446
+ mimeType === "application/xml" ||
447
+ mimeType === "image/svg+xml") {
448
+ return true;
449
+ }
450
+ const name = content.name.toLowerCase();
451
+ return [
452
+ ".csv",
453
+ ".htm",
454
+ ".html",
455
+ ".js",
456
+ ".json",
457
+ ".md",
458
+ ".txt",
459
+ ".ts",
460
+ ".tsx",
461
+ ".xml",
462
+ ".yaml",
463
+ ".yml",
464
+ ].some((suffix) => name.endsWith(suffix));
465
+ }
466
+ function sliceText(text, offset, maxLength) {
467
+ const start = Math.min(offset, text.length);
468
+ const end = Math.min(start + maxLength, text.length);
469
+ const sliced = text.slice(start, end);
470
+ return end >= text.length
471
+ ? sliced
472
+ : `${sliced}\n... truncated at ${end} of ${text.length} characters ...`;
473
+ }
474
+ function grepText(text, pattern, offset, before, after, maxLength) {
475
+ const lines = text.split("\n");
476
+ const selected = new Set();
477
+ let matchCount = 0;
478
+ for (let index = 0; index < lines.length; index += 1) {
479
+ if (!pattern.test(lines[index]))
480
+ continue;
481
+ pattern.lastIndex = 0;
482
+ if (matchCount < offset) {
483
+ matchCount += 1;
484
+ continue;
485
+ }
486
+ matchCount += 1;
487
+ for (let line = Math.max(0, index - before); line <= Math.min(lines.length - 1, index + after); line += 1) {
488
+ selected.add(line);
489
+ }
490
+ }
491
+ if (selected.size === 0)
492
+ return "No matches found.";
493
+ const sorted = [...selected].sort((a, b) => a - b);
494
+ let previous = -2;
495
+ let output = "";
496
+ for (const index of sorted) {
497
+ if (previous >= 0 && index !== previous + 1)
498
+ output += "--\n";
499
+ output += `${index + 1}: ${lines[index]}\n`;
500
+ previous = index;
501
+ if (output.length > maxLength) {
502
+ return `${output.slice(0, maxLength)}\n... truncated ...`;
503
+ }
504
+ }
505
+ return output;
506
+ }
507
+ function basename(path) {
508
+ const parts = path
509
+ .replace(/\\/g, "/")
510
+ .split("/")
511
+ .filter((part) => part !== "");
512
+ return parts.length === 0 ? "download" : parts[parts.length - 1];
513
+ }
@@ -0,0 +1,102 @@
1
+ import { Schema } from "apache-arrow";
2
+ import type { Participant, RoomClient } from "@meshagent/meshagent";
3
+ import { ChangeEmitter } from "./change-emitter.js";
4
+ import { BaseChatClient } from "./chat-client.js";
5
+ import { type AgentThreadMessage } from "./agent-messages.js";
6
+ export declare const defaultUntitledThreadName = "New Chat";
7
+ export declare class ThreadListEntry {
8
+ readonly path: string;
9
+ readonly name: string;
10
+ readonly createdAt: string;
11
+ readonly modifiedAt: string;
12
+ constructor({ path, name, createdAt, modifiedAt }: {
13
+ path: string;
14
+ name: string;
15
+ createdAt: string;
16
+ modifiedAt: string;
17
+ });
18
+ renamed(name: string, modifiedAt: string): ThreadListEntry;
19
+ static fromDatasetRow(row: Record<string, unknown>): ThreadListEntry | null;
20
+ }
21
+ export declare abstract class ThreadStorage {
22
+ abstract get path(): string;
23
+ abstract start(): Promise<void>;
24
+ abstract stop(): Promise<void>;
25
+ abstract waitUntilReady(): Promise<void>;
26
+ abstract agentMessages(): AgentThreadMessage[];
27
+ abstract pushMessage({ message, sender }: {
28
+ message: AgentThreadMessage;
29
+ sender?: Participant;
30
+ }): void;
31
+ }
32
+ export declare abstract class ThreadStorageRepository extends ChangeEmitter {
33
+ abstract open(): Promise<void>;
34
+ abstract close(): Promise<void>;
35
+ abstract entries(): ThreadListEntry[];
36
+ abstract addOrUpdateThread(entry: ThreadListEntry): Promise<void>;
37
+ abstract deleteThread(threadPath: string): Promise<void>;
38
+ abstract renameThread(threadPath: string, name: string): Promise<void>;
39
+ }
40
+ export declare class DatasetThreadListRef {
41
+ readonly namespace?: string[];
42
+ readonly table: string;
43
+ constructor({ namespace, table }: {
44
+ namespace?: string[];
45
+ table: string;
46
+ });
47
+ static parse(url: string): DatasetThreadListRef;
48
+ }
49
+ export declare class DatasetThreadStorageRepository extends ThreadStorageRepository {
50
+ static readonly schema: Schema<any>;
51
+ readonly room: RoomClient;
52
+ readonly path: string;
53
+ readonly ref: DatasetThreadListRef;
54
+ private readonly entriesByPath;
55
+ private abortController?;
56
+ private refreshEntriesFuture?;
57
+ private watchTask?;
58
+ private initialSnapshotReady;
59
+ private closed;
60
+ constructor({ room, path }: {
61
+ room: RoomClient;
62
+ path: string;
63
+ });
64
+ open(): Promise<void>;
65
+ private watchLoop;
66
+ close(): Promise<void>;
67
+ entries(): ThreadListEntry[];
68
+ addOrUpdateThread(entry: ThreadListEntry): Promise<void>;
69
+ deleteThread(threadPath: string): Promise<void>;
70
+ renameThread(threadPath: string, name: string): Promise<void>;
71
+ private ensureTable;
72
+ private handleWatchEvent;
73
+ private refreshEntries;
74
+ private batchFor;
75
+ }
76
+ export declare class AgentThreadStorageRepository extends ThreadStorageRepository {
77
+ readonly chatClient: BaseChatClient;
78
+ readonly limit: number;
79
+ private readonly entriesByPath;
80
+ private subscription?;
81
+ private pendingOpen?;
82
+ private pendingListMessageId?;
83
+ private closed;
84
+ constructor({ chatClient, limit }: {
85
+ chatClient: BaseChatClient;
86
+ limit?: number;
87
+ });
88
+ open(): Promise<void>;
89
+ close(): Promise<void>;
90
+ entries(): ThreadListEntry[];
91
+ addOrUpdateThread(_entry: ThreadListEntry): Promise<void>;
92
+ deleteThread(threadPath: string): Promise<void>;
93
+ renameThread(threadPath: string, name: string): Promise<void>;
94
+ private requestList;
95
+ private handleEvent;
96
+ private handleThreadsListed;
97
+ private upsertThread;
98
+ private entryFromAgentThread;
99
+ }
100
+ export declare class DatasetThreadStorage extends DatasetThreadStorageRepository {
101
+ }
102
+ export declare function defaultThreadDisplayNameFromPath(path: string): string;