@rool-dev/sdk 0.3.1-dev.7549492 → 0.3.1-dev.94e9f4d

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/dist/channel.js CHANGED
@@ -36,6 +36,7 @@ export class RoolChannel extends EventEmitter {
36
36
  _linkAccess;
37
37
  _userId;
38
38
  _channelId;
39
+ _conversationId;
39
40
  _closed = false;
40
41
  graphqlClient;
41
42
  mediaClient;
@@ -49,6 +50,7 @@ export class RoolChannel extends EventEmitter {
49
50
  _channel;
50
51
  _objectIds;
51
52
  _objectStats;
53
+ _hasConnected = false;
52
54
  // Object collection: tracks pending local mutations for dedup
53
55
  // Maps objectId → optimistic object data (for create/update) or null (for delete)
54
56
  _pendingMutations = new Map();
@@ -65,6 +67,7 @@ export class RoolChannel extends EventEmitter {
65
67
  this._userId = config.userId;
66
68
  this._emitterLogger = config.logger;
67
69
  this._channelId = config.channelId;
70
+ this._conversationId = 'default';
68
71
  this.graphqlClient = config.graphqlClient;
69
72
  this.mediaClient = config.mediaClient;
70
73
  this.logger = config.logger;
@@ -133,17 +136,83 @@ export class RoolChannel extends EventEmitter {
133
136
  get channelId() {
134
137
  return this._channelId;
135
138
  }
139
+ /**
140
+ * Get the conversation ID for this channel.
141
+ * Defaults to 'default' for most apps.
142
+ */
143
+ get conversationId() {
144
+ return this._conversationId;
145
+ }
136
146
  get isReadOnly() {
137
147
  return this._role === 'viewer';
138
148
  }
149
+ /**
150
+ * Get the app URL if this channel was created via installApp, or null.
151
+ */
152
+ get appUrl() {
153
+ return this._channel?.appUrl ?? null;
154
+ }
139
155
  // ===========================================================================
140
156
  // Channel History Access
141
157
  // ===========================================================================
142
158
  /**
143
- * Get interactions for this channel.
159
+ * Get interactions for the current conversation.
144
160
  */
145
161
  getInteractions() {
146
- return this._channel?.interactions ?? [];
162
+ return this._getInteractionsImpl(this._conversationId);
163
+ }
164
+ /** @internal */
165
+ _getInteractionsImpl(conversationId) {
166
+ return this._channel?.conversations[conversationId]?.interactions ?? [];
167
+ }
168
+ /**
169
+ * Get all conversations in this channel.
170
+ * Returns summary info (no full interaction data) for each conversation.
171
+ */
172
+ getConversations() {
173
+ if (!this._channel)
174
+ return [];
175
+ return Object.entries(this._channel.conversations).map(([id, conv]) => ({
176
+ id,
177
+ name: conv.name ?? null,
178
+ systemInstruction: conv.systemInstruction ?? null,
179
+ createdAt: conv.createdAt,
180
+ createdBy: conv.createdBy,
181
+ interactionCount: conv.interactions.length,
182
+ }));
183
+ }
184
+ /**
185
+ * Delete a conversation from this channel.
186
+ * Cannot delete the conversation you are currently using.
187
+ */
188
+ async deleteConversation(conversationId) {
189
+ if (conversationId === this._conversationId) {
190
+ throw new Error('Cannot delete the active conversation');
191
+ }
192
+ await this.graphqlClient.deleteConversation(this._id, this._channelId, conversationId);
193
+ // Optimistic local update — remove from cache and emit event
194
+ // in case the server doesn't send a conversation_updated event for deletes
195
+ if (this._channel?.conversations[conversationId]) {
196
+ delete this._channel.conversations[conversationId];
197
+ this.emit('conversationUpdated', {
198
+ conversationId,
199
+ channelId: this._channelId,
200
+ source: 'local_user',
201
+ });
202
+ }
203
+ }
204
+ // ===========================================================================
205
+ // Conversations
206
+ // ===========================================================================
207
+ /**
208
+ * Get a handle for a specific conversation within this channel.
209
+ * The handle scopes AI and mutation operations to that conversation's
210
+ * interaction history, while sharing the channel's single SSE connection.
211
+ *
212
+ * Conversations are auto-created on first interaction — no explicit create needed.
213
+ */
214
+ conversation(conversationId) {
215
+ return new ConversationHandle(this, conversationId);
147
216
  }
148
217
  // ===========================================================================
149
218
  // Channel Lifecycle
@@ -246,7 +315,11 @@ export class RoolChannel extends EventEmitter {
246
315
  * @returns The matching objects and a descriptive message.
247
316
  */
248
317
  async findObjects(options) {
249
- return this.graphqlClient.findObjects(this._id, options, this._channelId);
318
+ return this._findObjectsImpl(options, this._conversationId);
319
+ }
320
+ /** @internal */
321
+ _findObjectsImpl(options, conversationId) {
322
+ return this.graphqlClient.findObjects(this._id, options, this._channelId, conversationId);
250
323
  }
251
324
  /**
252
325
  * Get all object IDs (sync, from local cache).
@@ -271,6 +344,10 @@ export class RoolChannel extends EventEmitter {
271
344
  * @returns The created object (with AI-filled content) and message
272
345
  */
273
346
  async createObject(options) {
347
+ return this._createObjectImpl(options, this._conversationId);
348
+ }
349
+ /** @internal */
350
+ async _createObjectImpl(options, conversationId) {
274
351
  const { data, ephemeral } = options;
275
352
  // Use data.id if provided (string), otherwise generate
276
353
  const objectId = typeof data.id === 'string' ? data.id : generateEntityId();
@@ -285,7 +362,7 @@ export class RoolChannel extends EventEmitter {
285
362
  try {
286
363
  // Await mutation — server processes AI placeholders before responding.
287
364
  // SSE events arrive during the await and are buffered via _deliverObject.
288
- const { message } = await this.graphqlClient.createObject(this.id, dataWithId, this._channelId, ephemeral);
365
+ const { message } = await this.graphqlClient.createObject(this.id, dataWithId, this._channelId, conversationId, ephemeral);
289
366
  // Collect resolved object from buffer (or wait if not yet arrived)
290
367
  const object = await this._collectObject(objectId);
291
368
  return { object, message };
@@ -309,6 +386,10 @@ export class RoolChannel extends EventEmitter {
309
386
  * @returns The updated object (with AI-filled content) and message
310
387
  */
311
388
  async updateObject(objectId, options) {
389
+ return this._updateObjectImpl(objectId, options, this._conversationId);
390
+ }
391
+ /** @internal */
392
+ async _updateObjectImpl(objectId, options, conversationId) {
312
393
  const { data, ephemeral } = options;
313
394
  // id is immutable after creation (but null/undefined means delete attempt, which we also reject)
314
395
  if (data?.id !== undefined && data.id !== null) {
@@ -334,7 +415,7 @@ export class RoolChannel extends EventEmitter {
334
415
  this.emit('objectUpdated', { objectId, object: optimistic, source: 'local_user' });
335
416
  }
336
417
  try {
337
- const { message } = await this.graphqlClient.updateObject(this.id, objectId, this._channelId, serverData, options.prompt, ephemeral);
418
+ const { message } = await this.graphqlClient.updateObject(this.id, objectId, this._channelId, conversationId, serverData, options.prompt, ephemeral);
338
419
  const object = await this._collectObject(objectId);
339
420
  return { object, message };
340
421
  }
@@ -352,6 +433,10 @@ export class RoolChannel extends EventEmitter {
352
433
  * Other objects that reference deleted objects via data fields will retain stale ref values.
353
434
  */
354
435
  async deleteObjects(objectIds) {
436
+ return this._deleteObjectsImpl(objectIds, this._conversationId);
437
+ }
438
+ /** @internal */
439
+ async _deleteObjectsImpl(objectIds, conversationId) {
355
440
  if (objectIds.length === 0)
356
441
  return;
357
442
  // Track for dedup and emit optimistic events
@@ -360,7 +445,7 @@ export class RoolChannel extends EventEmitter {
360
445
  this.emit('objectDeleted', { objectId, source: 'local_user' });
361
446
  }
362
447
  try {
363
- await this.graphqlClient.deleteObjects(this.id, objectIds, this._channelId);
448
+ await this.graphqlClient.deleteObjects(this.id, objectIds, this._channelId, conversationId);
364
449
  }
365
450
  catch (error) {
366
451
  this.logger.error('[RoolChannel] Failed to delete objects:', error);
@@ -389,6 +474,10 @@ export class RoolChannel extends EventEmitter {
389
474
  * @returns The created CollectionDef
390
475
  */
391
476
  async createCollection(name, fields) {
477
+ return this._createCollectionImpl(name, fields, this._conversationId);
478
+ }
479
+ /** @internal */
480
+ async _createCollectionImpl(name, fields, conversationId) {
392
481
  if (this._schema[name]) {
393
482
  throw new Error(`Collection "${name}" already exists`);
394
483
  }
@@ -396,7 +485,7 @@ export class RoolChannel extends EventEmitter {
396
485
  const optimisticDef = { fields: fields.map(f => ({ name: f.name, type: f.type })) };
397
486
  this._schema[name] = optimisticDef;
398
487
  try {
399
- return await this.graphqlClient.createCollection(this._id, name, fields, this._channelId);
488
+ return await this.graphqlClient.createCollection(this._id, name, fields, this._channelId, conversationId);
400
489
  }
401
490
  catch (error) {
402
491
  this.logger.error('[RoolChannel] Failed to create collection:', error);
@@ -411,6 +500,10 @@ export class RoolChannel extends EventEmitter {
411
500
  * @returns The updated CollectionDef
412
501
  */
413
502
  async alterCollection(name, fields) {
503
+ return this._alterCollectionImpl(name, fields, this._conversationId);
504
+ }
505
+ /** @internal */
506
+ async _alterCollectionImpl(name, fields, conversationId) {
414
507
  if (!this._schema[name]) {
415
508
  throw new Error(`Collection "${name}" not found`);
416
509
  }
@@ -418,7 +511,7 @@ export class RoolChannel extends EventEmitter {
418
511
  // Optimistic local update
419
512
  this._schema[name] = { fields: fields.map(f => ({ name: f.name, type: f.type })) };
420
513
  try {
421
- return await this.graphqlClient.alterCollection(this._id, name, fields, this._channelId);
514
+ return await this.graphqlClient.alterCollection(this._id, name, fields, this._channelId, conversationId);
422
515
  }
423
516
  catch (error) {
424
517
  this.logger.error('[RoolChannel] Failed to alter collection:', error);
@@ -431,6 +524,10 @@ export class RoolChannel extends EventEmitter {
431
524
  * @param name - Name of the collection to drop
432
525
  */
433
526
  async dropCollection(name) {
527
+ return this._dropCollectionImpl(name, this._conversationId);
528
+ }
529
+ /** @internal */
530
+ async _dropCollectionImpl(name, conversationId) {
434
531
  if (!this._schema[name]) {
435
532
  throw new Error(`Collection "${name}" not found`);
436
533
  }
@@ -438,7 +535,7 @@ export class RoolChannel extends EventEmitter {
438
535
  // Optimistic local update
439
536
  delete this._schema[name];
440
537
  try {
441
- await this.graphqlClient.dropCollection(this._id, name, this._channelId);
538
+ await this.graphqlClient.dropCollection(this._id, name, this._channelId, conversationId);
442
539
  }
443
540
  catch (error) {
444
541
  this.logger.error('[RoolChannel] Failed to drop collection:', error);
@@ -450,48 +547,118 @@ export class RoolChannel extends EventEmitter {
450
547
  // System Instructions
451
548
  // ===========================================================================
452
549
  /**
453
- * Get the system instruction for this channel.
550
+ * Get the system instruction for the current conversation.
454
551
  * Returns undefined if no system instruction is set.
455
552
  */
456
553
  getSystemInstruction() {
457
- return this._channel?.systemInstruction;
554
+ return this._getSystemInstructionImpl(this._conversationId);
555
+ }
556
+ /** @internal */
557
+ _getSystemInstructionImpl(conversationId) {
558
+ return this._channel?.conversations[conversationId]?.systemInstruction;
458
559
  }
459
560
  /**
460
- * Set the system instruction for this channel.
561
+ * Set the system instruction for the current conversation.
461
562
  * Pass null to clear the instruction.
462
563
  */
463
564
  async setSystemInstruction(instruction) {
565
+ return this._setSystemInstructionImpl(instruction, this._conversationId);
566
+ }
567
+ /** @internal */
568
+ async _setSystemInstructionImpl(instruction, conversationId) {
464
569
  // Optimistic local update
465
- if (!this._channel) {
466
- this._channel = {
467
- createdAt: Date.now(),
468
- createdBy: this._userId,
469
- interactions: [],
470
- };
471
- }
472
- const previous = this._channel;
570
+ this._ensureConversationImpl(conversationId);
571
+ const conv = this._channel.conversations[conversationId];
572
+ const previousInstruction = conv.systemInstruction;
473
573
  if (instruction === null) {
474
- const { systemInstruction: _, ...rest } = this._channel;
475
- this._channel = rest;
574
+ delete conv.systemInstruction;
476
575
  }
477
576
  else {
478
- this._channel = { ...this._channel, systemInstruction: instruction };
577
+ conv.systemInstruction = instruction;
479
578
  }
480
- // Emit event
481
- this.emit('channelUpdated', {
579
+ // Emit events for backward compat and new API
580
+ this.emit('conversationUpdated', {
581
+ conversationId,
482
582
  channelId: this._channelId,
483
583
  source: 'local_user',
484
584
  });
585
+ if (conversationId === this._conversationId) {
586
+ this.emit('channelUpdated', {
587
+ channelId: this._channelId,
588
+ source: 'local_user',
589
+ });
590
+ }
485
591
  // Call server
486
592
  try {
487
- await this.graphqlClient.setSystemInstruction(this.id, this._channelId, instruction);
593
+ await this.graphqlClient.updateConversation(this._id, this._channelId, conversationId, { systemInstruction: instruction });
488
594
  }
489
595
  catch (error) {
490
596
  this.logger.error('[RoolChannel] Failed to set system instruction:', error);
491
- this._channel = previous;
597
+ // Rollback
598
+ if (previousInstruction === undefined) {
599
+ delete conv.systemInstruction;
600
+ }
601
+ else {
602
+ conv.systemInstruction = previousInstruction;
603
+ }
604
+ throw error;
605
+ }
606
+ }
607
+ /**
608
+ * Rename the current conversation.
609
+ */
610
+ async renameConversation(name) {
611
+ return this._renameConversationImpl(name, this._conversationId);
612
+ }
613
+ /** @internal */
614
+ async _renameConversationImpl(name, conversationId) {
615
+ // Optimistic local update
616
+ this._ensureConversationImpl(conversationId);
617
+ const conv = this._channel.conversations[conversationId];
618
+ const previousName = conv.name;
619
+ conv.name = name;
620
+ this.emit('conversationUpdated', {
621
+ conversationId,
622
+ channelId: this._channelId,
623
+ source: 'local_user',
624
+ });
625
+ if (conversationId === this._conversationId) {
626
+ this.emit('channelUpdated', {
627
+ channelId: this._channelId,
628
+ source: 'local_user',
629
+ });
630
+ }
631
+ // Call server
632
+ try {
633
+ await this.graphqlClient.updateConversation(this._id, this._channelId, conversationId, { name });
634
+ }
635
+ catch (error) {
636
+ this.logger.error('[RoolChannel] Failed to rename conversation:', error);
637
+ // Rollback
638
+ conv.name = previousName;
492
639
  throw error;
493
640
  }
494
641
  }
642
+ /**
643
+ * Ensure a conversation exists in the local channel cache.
644
+ * @internal
645
+ */
646
+ _ensureConversationImpl(conversationId) {
647
+ if (!this._channel) {
648
+ this._channel = {
649
+ createdAt: Date.now(),
650
+ createdBy: this._userId,
651
+ conversations: {},
652
+ };
653
+ }
654
+ if (!this._channel.conversations[conversationId]) {
655
+ this._channel.conversations[conversationId] = {
656
+ createdAt: Date.now(),
657
+ createdBy: this._userId,
658
+ interactions: [],
659
+ };
660
+ }
661
+ }
495
662
  // ===========================================================================
496
663
  // Metadata Operations
497
664
  // ===========================================================================
@@ -500,10 +667,14 @@ export class RoolChannel extends EventEmitter {
500
667
  * Metadata is stored in meta and hidden from AI operations.
501
668
  */
502
669
  setMetadata(key, value) {
670
+ this._setMetadataImpl(key, value, this._conversationId);
671
+ }
672
+ /** @internal */
673
+ _setMetadataImpl(key, value, conversationId) {
503
674
  this._meta[key] = value;
504
675
  this.emit('metadataUpdated', { metadata: this._meta, source: 'local_user' });
505
676
  // Fire-and-forget server call
506
- this.graphqlClient.setSpaceMeta(this.id, this._meta, this._channelId)
677
+ this.graphqlClient.setSpaceMeta(this.id, this._meta, this._channelId, conversationId)
507
678
  .catch((error) => {
508
679
  this.logger.error('[RoolChannel] Failed to set meta:', error);
509
680
  });
@@ -528,13 +699,17 @@ export class RoolChannel extends EventEmitter {
528
699
  * @returns The message from the AI and the list of objects that were created or modified
529
700
  */
530
701
  async prompt(prompt, options) {
702
+ return this._promptImpl(prompt, options, this._conversationId);
703
+ }
704
+ /** @internal */
705
+ async _promptImpl(prompt, options, conversationId) {
531
706
  // Upload attachments via media endpoint, then send URLs to the server
532
707
  const { attachments, ...rest } = options ?? {};
533
708
  let attachmentUrls;
534
709
  if (attachments?.length) {
535
710
  attachmentUrls = await Promise.all(attachments.map(file => this.mediaClient.upload(this._id, file)));
536
711
  }
537
- const result = await this.graphqlClient.prompt(this._id, prompt, this._channelId, { ...rest, attachmentUrls });
712
+ const result = await this.graphqlClient.prompt(this._id, prompt, this._channelId, conversationId, { ...rest, attachmentUrls });
538
713
  // Collect modified objects — they arrive via SSE events during/after the mutation.
539
714
  // Try collecting from buffer first, then fetch any missing from server.
540
715
  const objects = [];
@@ -569,7 +744,24 @@ export class RoolChannel extends EventEmitter {
569
744
  * Rename this channel.
570
745
  */
571
746
  async rename(newName) {
572
- await this.graphqlClient.renameChannel(this._id, this._channelId, newName);
747
+ // Optimistic local update
748
+ const previousName = this._channel?.name;
749
+ if (this._channel) {
750
+ this._channel.name = newName;
751
+ }
752
+ this.emit('channelUpdated', { channelId: this._channelId, source: 'local_user' });
753
+ // Call server
754
+ try {
755
+ await this.graphqlClient.renameChannel(this._id, this._channelId, newName);
756
+ }
757
+ catch (error) {
758
+ this.logger.error('[RoolChannel] Failed to rename channel:', error);
759
+ // Rollback
760
+ if (this._channel) {
761
+ this._channel.name = previousName;
762
+ }
763
+ throw error;
764
+ }
573
765
  }
574
766
  // ===========================================================================
575
767
  // Media Operations
@@ -671,6 +863,23 @@ export class RoolChannel extends EventEmitter {
671
863
  return;
672
864
  const changeSource = event.source === 'agent' ? 'remote_agent' : 'remote_user';
673
865
  switch (event.type) {
866
+ case 'connected':
867
+ // On reconnection, do a full reload to catch up on missed events.
868
+ // Skip on initial connection — data was already fetched by openChannel.
869
+ if (this._hasConnected) {
870
+ void this.graphqlClient.openChannel(this._id, this._channelId).then((result) => {
871
+ if (this._closed)
872
+ return;
873
+ this._meta = result.meta;
874
+ this._schema = result.schema;
875
+ this._channel = result.channel;
876
+ this._objectIds = result.objectIds;
877
+ this._objectStats = new Map(Object.entries(result.objectStats));
878
+ this.emit('reset', { source: 'system' });
879
+ });
880
+ }
881
+ this._hasConnected = true;
882
+ break;
674
883
  case 'object_created':
675
884
  if (event.objectId && event.object) {
676
885
  if (event.objectStat)
@@ -694,6 +903,7 @@ export class RoolChannel extends EventEmitter {
694
903
  case 'schema_updated':
695
904
  if (event.schema) {
696
905
  this._schema = event.schema;
906
+ this.emit('schemaUpdated', { schema: this._schema, source: changeSource });
697
907
  }
698
908
  break;
699
909
  case 'metadata_updated':
@@ -703,10 +913,47 @@ export class RoolChannel extends EventEmitter {
703
913
  }
704
914
  break;
705
915
  case 'channel_updated':
706
- // Only update if it's our channel
916
+ // Only update if it's our channel — channel_updated is now metadata-only (name, appUrl)
707
917
  if (event.channelId === this._channelId && event.channel) {
918
+ const changed = JSON.stringify(this._channel) !== JSON.stringify(event.channel);
708
919
  this._channel = event.channel;
709
- this.emit('channelUpdated', { channelId: event.channelId, source: changeSource });
920
+ if (changed) {
921
+ this.emit('channelUpdated', { channelId: event.channelId, source: changeSource });
922
+ }
923
+ }
924
+ break;
925
+ case 'conversation_updated':
926
+ // Only update if it's our channel
927
+ if (event.channelId === this._channelId && event.conversationId) {
928
+ if (!this._channel) {
929
+ this._channel = {
930
+ createdAt: Date.now(),
931
+ createdBy: this._userId,
932
+ conversations: {},
933
+ };
934
+ }
935
+ const prev = this._channel.conversations[event.conversationId];
936
+ if (event.conversation) {
937
+ // Update or create conversation in local cache
938
+ this._channel.conversations[event.conversationId] = event.conversation;
939
+ }
940
+ else {
941
+ // Conversation was deleted
942
+ delete this._channel.conversations[event.conversationId];
943
+ }
944
+ // Skip emit if data is unchanged (e.g. echo of our own optimistic update)
945
+ if (JSON.stringify(prev) === JSON.stringify(event.conversation))
946
+ break;
947
+ // Emit the new conversationUpdated event
948
+ this.emit('conversationUpdated', {
949
+ conversationId: event.conversationId,
950
+ channelId: event.channelId,
951
+ source: changeSource,
952
+ });
953
+ // Backward compat: also emit channelUpdated when the active conversation updates
954
+ if (event.conversationId === this._conversationId) {
955
+ this.emit('channelUpdated', { channelId: event.channelId, source: changeSource });
956
+ }
710
957
  }
711
958
  break;
712
959
  case 'space_changed':
@@ -797,4 +1044,95 @@ export class RoolChannel extends EventEmitter {
797
1044
  }
798
1045
  }
799
1046
  }
1047
+ // =============================================================================
1048
+ // ConversationHandle — Scoped proxy for a specific conversation
1049
+ // =============================================================================
1050
+ /**
1051
+ * A lightweight handle for a specific conversation within a channel.
1052
+ *
1053
+ * Scopes AI and mutation operations to a particular conversation's interaction
1054
+ * history, while sharing the channel's single SSE connection and object state.
1055
+ *
1056
+ * Obtain via `channel.conversation('thread-id')`.
1057
+ * Conversations are auto-created on first interaction.
1058
+ */
1059
+ export class ConversationHandle {
1060
+ /** @internal */
1061
+ _channel;
1062
+ _conversationId;
1063
+ /** @internal */
1064
+ constructor(channel, conversationId) {
1065
+ this._channel = channel;
1066
+ this._conversationId = conversationId;
1067
+ }
1068
+ /** The conversation ID this handle is scoped to. */
1069
+ get conversationId() { return this._conversationId; }
1070
+ // ---------------------------------------------------------------------------
1071
+ // Conversation History
1072
+ // ---------------------------------------------------------------------------
1073
+ /** Get interactions for this conversation. */
1074
+ getInteractions() {
1075
+ return this._channel._getInteractionsImpl(this._conversationId);
1076
+ }
1077
+ /** Get the system instruction for this conversation. */
1078
+ getSystemInstruction() {
1079
+ return this._channel._getSystemInstructionImpl(this._conversationId);
1080
+ }
1081
+ /** Set the system instruction for this conversation. Pass null to clear. */
1082
+ async setSystemInstruction(instruction) {
1083
+ return this._channel._setSystemInstructionImpl(instruction, this._conversationId);
1084
+ }
1085
+ /** Rename this conversation. */
1086
+ async rename(name) {
1087
+ return this._channel._renameConversationImpl(name, this._conversationId);
1088
+ }
1089
+ // ---------------------------------------------------------------------------
1090
+ // Object Operations (scoped to this conversation's interaction history)
1091
+ // ---------------------------------------------------------------------------
1092
+ /** Find objects using structured filters and/or natural language. */
1093
+ async findObjects(options) {
1094
+ return this._channel._findObjectsImpl(options, this._conversationId);
1095
+ }
1096
+ /** Create a new object. */
1097
+ async createObject(options) {
1098
+ return this._channel._createObjectImpl(options, this._conversationId);
1099
+ }
1100
+ /** Update an existing object. */
1101
+ async updateObject(objectId, options) {
1102
+ return this._channel._updateObjectImpl(objectId, options, this._conversationId);
1103
+ }
1104
+ /** Delete objects by IDs. */
1105
+ async deleteObjects(objectIds) {
1106
+ return this._channel._deleteObjectsImpl(objectIds, this._conversationId);
1107
+ }
1108
+ // ---------------------------------------------------------------------------
1109
+ // AI
1110
+ // ---------------------------------------------------------------------------
1111
+ /** Send a prompt to the AI agent, scoped to this conversation's history. */
1112
+ async prompt(text, options) {
1113
+ return this._channel._promptImpl(text, options, this._conversationId);
1114
+ }
1115
+ // ---------------------------------------------------------------------------
1116
+ // Schema (scoped to this conversation's interaction history)
1117
+ // ---------------------------------------------------------------------------
1118
+ /** Create a new collection schema. */
1119
+ async createCollection(name, fields) {
1120
+ return this._channel._createCollectionImpl(name, fields, this._conversationId);
1121
+ }
1122
+ /** Alter an existing collection schema. */
1123
+ async alterCollection(name, fields) {
1124
+ return this._channel._alterCollectionImpl(name, fields, this._conversationId);
1125
+ }
1126
+ /** Drop a collection schema. */
1127
+ async dropCollection(name) {
1128
+ return this._channel._dropCollectionImpl(name, this._conversationId);
1129
+ }
1130
+ // ---------------------------------------------------------------------------
1131
+ // Metadata (scoped to this conversation's interaction history)
1132
+ // ---------------------------------------------------------------------------
1133
+ /** Set a space-level metadata value. */
1134
+ setMetadata(key, value) {
1135
+ return this._channel._setMetadataImpl(key, value, this._conversationId);
1136
+ }
1137
+ }
800
1138
  //# sourceMappingURL=channel.js.map