@rool-dev/sdk 0.11.3 → 0.11.4-dev.e9877cb
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/README.md +165 -105
- package/dist/auth-base.d.ts +100 -0
- package/dist/auth-base.d.ts.map +1 -0
- package/dist/auth-base.js +377 -0
- package/dist/auth-base.js.map +1 -0
- package/dist/auth-browser.d.ts +6 -77
- package/dist/auth-browser.d.ts.map +1 -1
- package/dist/auth-browser.js +32 -328
- package/dist/auth-browser.js.map +1 -1
- package/dist/auth-native.d.ts +72 -0
- package/dist/auth-native.d.ts.map +1 -0
- package/dist/auth-native.js +260 -0
- package/dist/auth-native.js.map +1 -0
- package/dist/auth.d.ts +17 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +36 -5
- package/dist/auth.js.map +1 -1
- package/dist/client-info.d.ts +18 -0
- package/dist/client-info.d.ts.map +1 -0
- package/dist/client-info.js +25 -0
- package/dist/client-info.js.map +1 -0
- package/dist/client.d.ts +34 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +79 -26
- package/dist/client.js.map +1 -1
- package/dist/graphql.d.ts +15 -19
- package/dist/graphql.d.ts.map +1 -1
- package/dist/graphql.js +43 -77
- package/dist/graphql.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/reroute.d.ts.map +1 -1
- package/dist/reroute.js +9 -0
- package/dist/reroute.js.map +1 -1
- package/dist/rest.d.ts +3 -0
- package/dist/rest.d.ts.map +1 -1
- package/dist/rest.js +4 -0
- package/dist/rest.js.map +1 -1
- package/dist/router.d.ts +3 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +8 -5
- package/dist/router.js.map +1 -1
- package/dist/{channel.d.ts → space-session.d.ts} +44 -139
- package/dist/space-session.d.ts.map +1 -0
- package/dist/{channel.js → space-session.js} +111 -325
- package/dist/space-session.js.map +1 -0
- package/dist/space.d.ts +21 -48
- package/dist/space.d.ts.map +1 -1
- package/dist/space.js +88 -223
- package/dist/space.js.map +1 -1
- package/dist/subscription.d.ts +5 -2
- package/dist/subscription.d.ts.map +1 -1
- package/dist/subscription.js +13 -33
- package/dist/subscription.js.map +1 -1
- package/dist/types.d.ts +80 -83
- package/dist/types.d.ts.map +1 -1
- package/dist/webdav.d.ts +3 -0
- package/dist/webdav.d.ts.map +1 -1
- package/dist/webdav.js +4 -0
- package/dist/webdav.js.map +1 -1
- package/package.json +1 -1
- package/dist/channel.d.ts.map +0 -1
- package/dist/channel.js.map +0 -1
|
@@ -156,34 +156,29 @@ function base64Body(data) {
|
|
|
156
156
|
return bytes.buffer;
|
|
157
157
|
}
|
|
158
158
|
/**
|
|
159
|
-
*
|
|
159
|
+
* Operational handle for a space.
|
|
160
160
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* Only schema, metadata, object stats, and the channel's own history are cached
|
|
167
|
-
* locally. Object bodies are fetched on demand. Object/file reactivity is
|
|
168
|
-
* exposed at the space level via WebDAV sync notifications.
|
|
161
|
+
* Objects are addressed by machine path (`/space/.../*.json`). Conversation handles
|
|
162
|
+
* control attribution and AI history. Only schema, metadata,
|
|
163
|
+
* object stats, and conversation history are cached locally. Object bodies are
|
|
164
|
+
* fetched on demand. Object/file reactivity is exposed at the space level via
|
|
165
|
+
* WebDAV sync notifications.
|
|
169
166
|
*/
|
|
170
|
-
export class
|
|
167
|
+
export class SpaceOperations extends EventEmitter {
|
|
171
168
|
_id;
|
|
172
169
|
_name;
|
|
173
170
|
_role;
|
|
174
171
|
_userId;
|
|
175
|
-
_channelId;
|
|
176
|
-
_conversationId;
|
|
177
172
|
_closed = false;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
// Local cache for bounded data (schema, metadata,
|
|
173
|
+
_graphqlClient;
|
|
174
|
+
_restClient;
|
|
175
|
+
_webdav;
|
|
176
|
+
_onCloseCallback;
|
|
177
|
+
_logger;
|
|
178
|
+
// Local cache for bounded data (schema, metadata, conversations, object stats)
|
|
184
179
|
_meta;
|
|
185
180
|
_schema;
|
|
186
|
-
|
|
181
|
+
_conversations;
|
|
187
182
|
_objectStats;
|
|
188
183
|
// Active leaf per conversation (client-side tree cursor)
|
|
189
184
|
_activeLeaves = new Map();
|
|
@@ -194,17 +189,15 @@ export class RoolChannel extends EventEmitter {
|
|
|
194
189
|
this._role = config.role;
|
|
195
190
|
this._userId = config.userId;
|
|
196
191
|
this._emitterLogger = config.logger;
|
|
197
|
-
this.
|
|
198
|
-
this.
|
|
199
|
-
this.
|
|
200
|
-
this.
|
|
201
|
-
this.
|
|
202
|
-
this.logger = config.logger;
|
|
203
|
-
this.onCloseCallback = config.onClose;
|
|
192
|
+
this._graphqlClient = config.graphqlClient;
|
|
193
|
+
this._restClient = config.restClient;
|
|
194
|
+
this._webdav = config.webdav;
|
|
195
|
+
this._logger = config.logger;
|
|
196
|
+
this._onCloseCallback = config.onClose;
|
|
204
197
|
// Initialize local cache from server data
|
|
205
198
|
this._meta = config.meta;
|
|
206
199
|
this._schema = config.schema;
|
|
207
|
-
this.
|
|
200
|
+
this._conversations = config.conversations;
|
|
208
201
|
this._objectStats = new Map(Object.entries(config.objectStats));
|
|
209
202
|
}
|
|
210
203
|
/**
|
|
@@ -213,11 +206,11 @@ export class RoolChannel extends EventEmitter {
|
|
|
213
206
|
* @internal
|
|
214
207
|
*/
|
|
215
208
|
_handleEvent(event) {
|
|
216
|
-
this.
|
|
209
|
+
this.applySpaceContentEvent(event);
|
|
217
210
|
}
|
|
218
211
|
/**
|
|
219
212
|
* Apply resync data after reconnection. Called by the client, which
|
|
220
|
-
* fetches space data once and
|
|
213
|
+
* fetches space data once and applies it.
|
|
221
214
|
* @internal
|
|
222
215
|
*/
|
|
223
216
|
_applyResyncData(data) {
|
|
@@ -226,8 +219,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
226
219
|
this._meta = data.meta;
|
|
227
220
|
this._schema = data.schema;
|
|
228
221
|
this._objectStats = new Map(Object.entries(data.objectStats));
|
|
229
|
-
|
|
230
|
-
this._channel = data.channel;
|
|
222
|
+
this._conversations = data.conversations;
|
|
231
223
|
this._activeLeaves.clear();
|
|
232
224
|
this.emit('reset', { source: 'system' });
|
|
233
225
|
}
|
|
@@ -244,39 +236,12 @@ export class RoolChannel extends EventEmitter {
|
|
|
244
236
|
get userId() {
|
|
245
237
|
return this._userId;
|
|
246
238
|
}
|
|
247
|
-
/**
|
|
248
|
-
* Get the channel's display name, or null if not set.
|
|
249
|
-
*/
|
|
250
|
-
get channelName() {
|
|
251
|
-
return this._channel?.name ?? null;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Get the channel ID for this channel.
|
|
255
|
-
* Fixed at open time — cannot be changed.
|
|
256
|
-
*/
|
|
257
|
-
get channelId() {
|
|
258
|
-
return this._channelId;
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Get the conversation ID for this channel.
|
|
262
|
-
* Defaults to 'default' for most apps.
|
|
263
|
-
*/
|
|
264
|
-
get conversationId() {
|
|
265
|
-
return this._conversationId;
|
|
266
|
-
}
|
|
267
239
|
get isReadOnly() {
|
|
268
240
|
return this._role === 'viewer';
|
|
269
241
|
}
|
|
270
|
-
/**
|
|
271
|
-
* Get the active branch of the current conversation as a flat array (root → leaf).
|
|
272
|
-
* Walks from the active leaf up through parentId pointers.
|
|
273
|
-
*/
|
|
274
|
-
getInteractions() {
|
|
275
|
-
return this._getInteractionsImpl(this._conversationId);
|
|
276
|
-
}
|
|
277
242
|
/** @internal */
|
|
278
243
|
_getInteractionsImpl(conversationId) {
|
|
279
|
-
const interactions = this.
|
|
244
|
+
const interactions = this._conversations[conversationId]?.interactions;
|
|
280
245
|
if (!interactions)
|
|
281
246
|
return [];
|
|
282
247
|
// Handle legacy array format
|
|
@@ -287,59 +252,35 @@ export class RoolChannel extends EventEmitter {
|
|
|
287
252
|
return [];
|
|
288
253
|
return walkBranch(interactions, leafId);
|
|
289
254
|
}
|
|
290
|
-
/**
|
|
291
|
-
* Get the full interaction tree for a conversation as a record.
|
|
292
|
-
* For clients that need to render branch navigation UI.
|
|
293
|
-
*/
|
|
294
|
-
getTree() {
|
|
295
|
-
return this._getTreeImpl(this._conversationId);
|
|
296
|
-
}
|
|
297
255
|
/** @internal */
|
|
298
256
|
_getTreeImpl(conversationId) {
|
|
299
|
-
const interactions = this.
|
|
257
|
+
const interactions = this._conversations[conversationId]?.interactions;
|
|
300
258
|
if (!interactions || Array.isArray(interactions))
|
|
301
259
|
return {};
|
|
302
260
|
return interactions;
|
|
303
261
|
}
|
|
304
|
-
/**
|
|
305
|
-
* Get the active leaf interaction ID for a conversation.
|
|
306
|
-
* Returns undefined if the conversation has no interactions.
|
|
307
|
-
*/
|
|
308
|
-
get activeLeafId() {
|
|
309
|
-
return this._getActiveLeafImpl(this._conversationId);
|
|
310
|
-
}
|
|
311
262
|
/** @internal */
|
|
312
263
|
_getActiveLeafImpl(conversationId) {
|
|
313
|
-
return this._activeLeaves.get(conversationId) ?? findDefaultLeaf(this.
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Set the active leaf for a conversation (switch branches).
|
|
317
|
-
* Emits a conversationUpdated event so reactive wrappers refresh.
|
|
318
|
-
*/
|
|
319
|
-
setActiveLeaf(interactionId) {
|
|
320
|
-
this._setActiveLeafImpl(interactionId, this._conversationId);
|
|
264
|
+
return this._activeLeaves.get(conversationId) ?? findDefaultLeaf(this._conversations[conversationId]?.interactions);
|
|
321
265
|
}
|
|
322
266
|
/** @internal */
|
|
323
267
|
_setActiveLeafImpl(interactionId, conversationId) {
|
|
324
|
-
const interactions = this.
|
|
268
|
+
const interactions = this._conversations[conversationId]?.interactions;
|
|
325
269
|
if (!interactions || Array.isArray(interactions) || !interactions[interactionId]) {
|
|
326
270
|
throw new Error(`Interaction "${interactionId}" not found in conversation "${conversationId}"`);
|
|
327
271
|
}
|
|
328
272
|
this._activeLeaves.set(conversationId, interactionId);
|
|
329
273
|
this.emit('conversationUpdated', {
|
|
330
274
|
conversationId,
|
|
331
|
-
channelId: this._channelId,
|
|
332
275
|
source: 'local_user',
|
|
333
276
|
});
|
|
334
277
|
}
|
|
335
278
|
/**
|
|
336
|
-
* Get all conversations in this
|
|
279
|
+
* Get all conversations in this space.
|
|
337
280
|
* Returns summary info (no full interaction data) for each conversation.
|
|
338
281
|
*/
|
|
339
282
|
getConversations() {
|
|
340
|
-
|
|
341
|
-
return [];
|
|
342
|
-
return Object.entries(this._channel.conversations).map(([id, conv]) => ({
|
|
283
|
+
return Object.entries(this._conversations).map(([id, conv]) => ({
|
|
343
284
|
id,
|
|
344
285
|
name: conv.name ?? null,
|
|
345
286
|
systemInstruction: conv.systemInstruction ?? null,
|
|
@@ -349,74 +290,67 @@ export class RoolChannel extends EventEmitter {
|
|
|
349
290
|
}));
|
|
350
291
|
}
|
|
351
292
|
/**
|
|
352
|
-
* Delete a conversation from this
|
|
353
|
-
* Cannot delete the conversation you are currently using.
|
|
293
|
+
* Delete a conversation from this space.
|
|
354
294
|
*/
|
|
355
295
|
async deleteConversation(conversationId) {
|
|
356
|
-
|
|
357
|
-
throw new Error('Cannot delete the active conversation');
|
|
358
|
-
}
|
|
359
|
-
await this.graphqlClient.deleteConversation(this._id, this._channelId, conversationId);
|
|
296
|
+
await this._graphqlClient.deleteConversation(this._id, conversationId);
|
|
360
297
|
// Optimistic local update — remove from cache and emit event
|
|
361
298
|
// in case the server doesn't send a conversation_updated event for deletes
|
|
362
|
-
if (this.
|
|
363
|
-
delete this.
|
|
299
|
+
if (this._conversations[conversationId]) {
|
|
300
|
+
delete this._conversations[conversationId];
|
|
364
301
|
this.emit('conversationUpdated', {
|
|
365
302
|
conversationId,
|
|
366
|
-
channelId: this._channelId,
|
|
367
303
|
source: 'local_user',
|
|
368
304
|
});
|
|
369
305
|
}
|
|
370
306
|
}
|
|
371
307
|
/**
|
|
372
|
-
* Get a handle for a specific conversation
|
|
308
|
+
* Get a handle for a specific conversation.
|
|
373
309
|
*/
|
|
374
310
|
conversation(conversationId) {
|
|
375
311
|
return new ConversationHandle(this, conversationId);
|
|
376
312
|
}
|
|
377
313
|
/**
|
|
378
|
-
* Close this
|
|
379
|
-
* Stops real-time subscription and unregisters from client.
|
|
314
|
+
* Close this space session and clean up resources.
|
|
380
315
|
*/
|
|
381
316
|
close() {
|
|
382
317
|
this._closed = true;
|
|
383
|
-
this.
|
|
318
|
+
this._onCloseCallback();
|
|
384
319
|
this.removeAllListeners();
|
|
385
320
|
}
|
|
386
321
|
/**
|
|
387
322
|
* Create a checkpoint of the current space state.
|
|
388
323
|
*/
|
|
389
324
|
async checkpoint(label = 'Change') {
|
|
390
|
-
const result = await this.
|
|
325
|
+
const result = await this._graphqlClient.checkpoint(this._id, label);
|
|
391
326
|
return result.checkpointId;
|
|
392
327
|
}
|
|
393
328
|
/** Check if undo is available for this space. */
|
|
394
329
|
async canUndo() {
|
|
395
|
-
const status = await this.
|
|
330
|
+
const status = await this._graphqlClient.checkpointStatus(this._id);
|
|
396
331
|
return status.canUndo;
|
|
397
332
|
}
|
|
398
333
|
/** Check if redo is available for this space. */
|
|
399
334
|
async canRedo() {
|
|
400
|
-
const status = await this.
|
|
335
|
+
const status = await this._graphqlClient.checkpointStatus(this._id);
|
|
401
336
|
return status.canRedo;
|
|
402
337
|
}
|
|
403
338
|
/** Restore the space to the most recent checkpoint. */
|
|
404
339
|
async undo() {
|
|
405
|
-
const result = await this.
|
|
340
|
+
const result = await this._graphqlClient.undo(this._id);
|
|
406
341
|
return result.success;
|
|
407
342
|
}
|
|
408
343
|
/** Reapply the most recently undone checkpoint. */
|
|
409
344
|
async redo() {
|
|
410
|
-
const result = await this.
|
|
345
|
+
const result = await this._graphqlClient.redo(this._id);
|
|
411
346
|
return result.success;
|
|
412
347
|
}
|
|
413
348
|
/** Clear the space's checkpoint history. */
|
|
414
349
|
async clearHistory() {
|
|
415
|
-
await this.
|
|
350
|
+
await this._graphqlClient.clearCheckpointHistory(this._id);
|
|
416
351
|
}
|
|
417
352
|
davHeaders(conversationId, interactionId) {
|
|
418
353
|
const headers = new Headers({
|
|
419
|
-
'X-Rool-Channel-Id': this._channelId,
|
|
420
354
|
'X-Rool-Conversation-Id': conversationId,
|
|
421
355
|
});
|
|
422
356
|
if (interactionId)
|
|
@@ -426,7 +360,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
426
360
|
async readObject(path) {
|
|
427
361
|
const canonical = objectPath(path);
|
|
428
362
|
try {
|
|
429
|
-
const response = await this.
|
|
363
|
+
const response = await this._webdav.get(canonical);
|
|
430
364
|
const body = jsonObject(await response.json(), `Object ${canonical}`);
|
|
431
365
|
return { object: objectFromBody(canonical, body), etag: response.headers.get('ETag') };
|
|
432
366
|
}
|
|
@@ -456,7 +390,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
456
390
|
const result = { objects: [], missing: [] };
|
|
457
391
|
for (let i = 0; i < canonical.length; i += GET_OBJECTS_CHUNK_SIZE) {
|
|
458
392
|
const chunk = canonical.slice(i, i + GET_OBJECTS_CHUNK_SIZE);
|
|
459
|
-
const partial = await this.
|
|
393
|
+
const partial = await this._restClient.getObjects(this._id, chunk);
|
|
460
394
|
result.objects.push(...partial.objects);
|
|
461
395
|
result.missing.push(...partial.missing);
|
|
462
396
|
}
|
|
@@ -466,17 +400,13 @@ export class RoolChannel extends EventEmitter {
|
|
|
466
400
|
stat(path) {
|
|
467
401
|
return this._objectStats.get(objectPath(path));
|
|
468
402
|
}
|
|
469
|
-
/** Create or replace an object JSON file at an exact machine path. */
|
|
470
|
-
async putObject(path, body) {
|
|
471
|
-
return this._putObjectImpl(path, body, this._conversationId);
|
|
472
|
-
}
|
|
473
403
|
/** @internal */
|
|
474
404
|
async _putObjectImpl(path, body, conversationId) {
|
|
475
405
|
const canonical = objectPath(path);
|
|
476
406
|
const optimistic = objectFromBody(canonical, body);
|
|
477
407
|
try {
|
|
478
408
|
const interactionId = generateEntityId();
|
|
479
|
-
await this.
|
|
409
|
+
await this._webdav.put(canonical, JSON.stringify(body), {
|
|
480
410
|
contentType: 'application/json',
|
|
481
411
|
headers: this.davHeaders(conversationId, interactionId),
|
|
482
412
|
});
|
|
@@ -484,15 +414,11 @@ export class RoolChannel extends EventEmitter {
|
|
|
484
414
|
return { object: fresh, message: `Put ${canonical}` };
|
|
485
415
|
}
|
|
486
416
|
catch (error) {
|
|
487
|
-
this.
|
|
417
|
+
this._logger.error('[RoolSpace] Failed to put object:', error);
|
|
488
418
|
this.emit('syncError', error instanceof Error ? error : new Error(String(error)));
|
|
489
419
|
throw error;
|
|
490
420
|
}
|
|
491
421
|
}
|
|
492
|
-
/** Patch an existing object. Null or undefined deletes a field. */
|
|
493
|
-
async patchObject(path, options) {
|
|
494
|
-
return this._patchObjectImpl(path, options, this._conversationId);
|
|
495
|
-
}
|
|
496
422
|
/** @internal */
|
|
497
423
|
async _patchObjectImpl(path, options, conversationId) {
|
|
498
424
|
const canonical = objectPath(path);
|
|
@@ -504,7 +430,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
504
430
|
const optimistic = objectFromBody(canonical, body);
|
|
505
431
|
try {
|
|
506
432
|
const interactionId = generateEntityId();
|
|
507
|
-
await this.
|
|
433
|
+
await this._webdav.put(canonical, JSON.stringify(body), {
|
|
508
434
|
contentType: 'application/json',
|
|
509
435
|
ifMatch: current.etag ?? undefined,
|
|
510
436
|
headers: this.davHeaders(conversationId, interactionId),
|
|
@@ -513,15 +439,11 @@ export class RoolChannel extends EventEmitter {
|
|
|
513
439
|
return { object: fresh, message: `Patched ${canonical}` };
|
|
514
440
|
}
|
|
515
441
|
catch (error) {
|
|
516
|
-
this.
|
|
442
|
+
this._logger.error('[RoolSpace] Failed to patch object:', error);
|
|
517
443
|
this.emit('syncError', error instanceof Error ? error : new Error(String(error)));
|
|
518
444
|
throw error;
|
|
519
445
|
}
|
|
520
446
|
}
|
|
521
|
-
/** Move an object JSON file to a new machine path, optionally replacing its body. */
|
|
522
|
-
async moveObject(from, to, options) {
|
|
523
|
-
return this._moveObjectImpl(from, to, options, this._conversationId);
|
|
524
|
-
}
|
|
525
447
|
/** @internal */
|
|
526
448
|
async _moveObjectImpl(from, to, options, conversationId) {
|
|
527
449
|
const fromPath = objectPath(from);
|
|
@@ -529,11 +451,11 @@ export class RoolChannel extends EventEmitter {
|
|
|
529
451
|
const optimistic = objectFromBody(toPath, options?.body ?? {});
|
|
530
452
|
try {
|
|
531
453
|
const interactionId = generateEntityId();
|
|
532
|
-
await this.
|
|
454
|
+
await this._webdav.move(fromPath, toPath, {
|
|
533
455
|
headers: this.davHeaders(conversationId, interactionId),
|
|
534
456
|
});
|
|
535
457
|
if (options?.body) {
|
|
536
|
-
await this.
|
|
458
|
+
await this._webdav.put(toPath, JSON.stringify(options.body), {
|
|
537
459
|
contentType: 'application/json',
|
|
538
460
|
headers: this.davHeaders(conversationId, interactionId),
|
|
539
461
|
});
|
|
@@ -543,19 +465,11 @@ export class RoolChannel extends EventEmitter {
|
|
|
543
465
|
return { object: fresh, message: `Moved ${fromPath} to ${toPath}` };
|
|
544
466
|
}
|
|
545
467
|
catch (error) {
|
|
546
|
-
this.
|
|
468
|
+
this._logger.error('[RoolSpace] Failed to move object:', error);
|
|
547
469
|
this.emit('syncError', error instanceof Error ? error : new Error(String(error)));
|
|
548
470
|
throw error;
|
|
549
471
|
}
|
|
550
472
|
}
|
|
551
|
-
/** Delete object JSON files by machine path. */
|
|
552
|
-
async deleteObjects(paths) {
|
|
553
|
-
return this._deleteObjectsImpl(paths, this._conversationId);
|
|
554
|
-
}
|
|
555
|
-
/** @deprecated Use deleteObjects instead. */
|
|
556
|
-
async deletePaths(paths) {
|
|
557
|
-
return this.deleteObjects(paths);
|
|
558
|
-
}
|
|
559
473
|
/** @internal */
|
|
560
474
|
async _deleteObjectsImpl(paths, conversationId) {
|
|
561
475
|
if (paths.length === 0)
|
|
@@ -564,14 +478,14 @@ export class RoolChannel extends EventEmitter {
|
|
|
564
478
|
try {
|
|
565
479
|
const interactionId = generateEntityId();
|
|
566
480
|
for (const path of canonical) {
|
|
567
|
-
await this.
|
|
481
|
+
await this._webdav.delete(path, {
|
|
568
482
|
headers: this.davHeaders(conversationId, interactionId),
|
|
569
483
|
});
|
|
570
484
|
this._objectStats.delete(path);
|
|
571
485
|
}
|
|
572
486
|
}
|
|
573
487
|
catch (error) {
|
|
574
|
-
this.
|
|
488
|
+
this._logger.error('[RoolSpace] Failed to delete paths:', error);
|
|
575
489
|
this.emit('syncError', error instanceof Error ? error : new Error(String(error)));
|
|
576
490
|
throw error;
|
|
577
491
|
}
|
|
@@ -580,10 +494,6 @@ export class RoolChannel extends EventEmitter {
|
|
|
580
494
|
getSchema() {
|
|
581
495
|
return this._schema;
|
|
582
496
|
}
|
|
583
|
-
/** Create a new collection schema. */
|
|
584
|
-
async createCollection(name, fields, options) {
|
|
585
|
-
return this._createCollectionImpl(name, fields, options, this._conversationId);
|
|
586
|
-
}
|
|
587
497
|
/** @internal */
|
|
588
498
|
async _createCollectionImpl(name, fields, options, conversationId) {
|
|
589
499
|
if (this._schema[name]) {
|
|
@@ -593,8 +503,8 @@ export class RoolChannel extends EventEmitter {
|
|
|
593
503
|
const optimisticDef = collectionDef(fields, options);
|
|
594
504
|
this._schema[name] = optimisticDef;
|
|
595
505
|
try {
|
|
596
|
-
await this.
|
|
597
|
-
await this.
|
|
506
|
+
await this._webdav.mkcol(collectionPath(name), { headers: this.davHeaders(conversationId, generateEntityId()) });
|
|
507
|
+
await this._webdav.put(schemaPath(name), JSON.stringify(optimisticDef), {
|
|
598
508
|
contentType: 'application/json',
|
|
599
509
|
headers: this.davHeaders(conversationId, generateEntityId()),
|
|
600
510
|
});
|
|
@@ -602,15 +512,11 @@ export class RoolChannel extends EventEmitter {
|
|
|
602
512
|
return optimisticDef;
|
|
603
513
|
}
|
|
604
514
|
catch (error) {
|
|
605
|
-
this.
|
|
515
|
+
this._logger.error('[RoolSpace] Failed to create collection:', error);
|
|
606
516
|
delete this._schema[name];
|
|
607
517
|
throw error;
|
|
608
518
|
}
|
|
609
519
|
}
|
|
610
|
-
/** Alter an existing collection schema, replacing its field definitions. */
|
|
611
|
-
async alterCollection(name, fields, options) {
|
|
612
|
-
return this._alterCollectionImpl(name, fields, options, this._conversationId);
|
|
613
|
-
}
|
|
614
520
|
/** @internal */
|
|
615
521
|
async _alterCollectionImpl(name, fields, options, conversationId) {
|
|
616
522
|
if (!this._schema[name]) {
|
|
@@ -620,7 +526,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
620
526
|
this._schema[name] = collectionDef(fields, options);
|
|
621
527
|
try {
|
|
622
528
|
const updated = this._schema[name];
|
|
623
|
-
await this.
|
|
529
|
+
await this._webdav.put(schemaPath(name), JSON.stringify(updated), {
|
|
624
530
|
contentType: 'application/json',
|
|
625
531
|
headers: this.davHeaders(conversationId, generateEntityId()),
|
|
626
532
|
});
|
|
@@ -628,15 +534,11 @@ export class RoolChannel extends EventEmitter {
|
|
|
628
534
|
return updated;
|
|
629
535
|
}
|
|
630
536
|
catch (error) {
|
|
631
|
-
this.
|
|
537
|
+
this._logger.error('[RoolSpace] Failed to alter collection:', error);
|
|
632
538
|
this._schema[name] = previous;
|
|
633
539
|
throw error;
|
|
634
540
|
}
|
|
635
541
|
}
|
|
636
|
-
/** Drop a collection schema. */
|
|
637
|
-
async dropCollection(name) {
|
|
638
|
-
return this._dropCollectionImpl(name, this._conversationId);
|
|
639
|
-
}
|
|
640
542
|
/** @internal */
|
|
641
543
|
async _dropCollectionImpl(name, conversationId) {
|
|
642
544
|
if (!this._schema[name]) {
|
|
@@ -645,33 +547,23 @@ export class RoolChannel extends EventEmitter {
|
|
|
645
547
|
const previous = this._schema[name];
|
|
646
548
|
delete this._schema[name];
|
|
647
549
|
try {
|
|
648
|
-
await this.
|
|
550
|
+
await this._webdav.delete(collectionPath(name), { collection: true, headers: this.davHeaders(conversationId, generateEntityId()) });
|
|
649
551
|
this.emit('schemaUpdated', { schema: this._schema, source: 'local_user' });
|
|
650
552
|
}
|
|
651
553
|
catch (error) {
|
|
652
|
-
this.
|
|
554
|
+
this._logger.error('[RoolSpace] Failed to drop collection:', error);
|
|
653
555
|
this._schema[name] = previous;
|
|
654
556
|
throw error;
|
|
655
557
|
}
|
|
656
558
|
}
|
|
657
|
-
/**
|
|
658
|
-
* Get the system instruction for the current conversation.
|
|
659
|
-
*/
|
|
660
|
-
getSystemInstruction() {
|
|
661
|
-
return this._getSystemInstructionImpl(this._conversationId);
|
|
662
|
-
}
|
|
663
559
|
/** @internal */
|
|
664
560
|
_getSystemInstructionImpl(conversationId) {
|
|
665
|
-
return this.
|
|
666
|
-
}
|
|
667
|
-
/** Set the system instruction for the current conversation. */
|
|
668
|
-
async setSystemInstruction(instruction) {
|
|
669
|
-
return this._setSystemInstructionImpl(instruction, this._conversationId);
|
|
561
|
+
return this._conversations[conversationId]?.systemInstruction;
|
|
670
562
|
}
|
|
671
563
|
/** @internal */
|
|
672
564
|
async _setSystemInstructionImpl(instruction, conversationId) {
|
|
673
565
|
this._ensureConversationImpl(conversationId);
|
|
674
|
-
const conv = this.
|
|
566
|
+
const conv = this._conversations[conversationId];
|
|
675
567
|
const previousInstruction = conv.systemInstruction;
|
|
676
568
|
if (instruction === null) {
|
|
677
569
|
delete conv.systemInstruction;
|
|
@@ -681,20 +573,13 @@ export class RoolChannel extends EventEmitter {
|
|
|
681
573
|
}
|
|
682
574
|
this.emit('conversationUpdated', {
|
|
683
575
|
conversationId,
|
|
684
|
-
channelId: this._channelId,
|
|
685
576
|
source: 'local_user',
|
|
686
577
|
});
|
|
687
|
-
if (conversationId === this._conversationId) {
|
|
688
|
-
this.emit('channelUpdated', {
|
|
689
|
-
channelId: this._channelId,
|
|
690
|
-
source: 'local_user',
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
578
|
try {
|
|
694
|
-
await this.
|
|
579
|
+
await this._graphqlClient.updateConversation(this._id, conversationId, { systemInstruction: instruction });
|
|
695
580
|
}
|
|
696
581
|
catch (error) {
|
|
697
|
-
this.
|
|
582
|
+
this._logger.error('[RoolSpace] Failed to set system instruction:', error);
|
|
698
583
|
if (previousInstruction === undefined) {
|
|
699
584
|
delete conv.systemInstruction;
|
|
700
585
|
}
|
|
@@ -704,65 +589,43 @@ export class RoolChannel extends EventEmitter {
|
|
|
704
589
|
throw error;
|
|
705
590
|
}
|
|
706
591
|
}
|
|
707
|
-
/** Rename the current conversation. */
|
|
708
|
-
async renameConversation(name) {
|
|
709
|
-
return this._renameConversationImpl(name, this._conversationId);
|
|
710
|
-
}
|
|
711
592
|
/** @internal */
|
|
712
593
|
async _renameConversationImpl(name, conversationId) {
|
|
713
594
|
this._ensureConversationImpl(conversationId);
|
|
714
|
-
const conv = this.
|
|
595
|
+
const conv = this._conversations[conversationId];
|
|
715
596
|
const previousName = conv.name;
|
|
716
597
|
conv.name = name;
|
|
717
598
|
this.emit('conversationUpdated', {
|
|
718
599
|
conversationId,
|
|
719
|
-
channelId: this._channelId,
|
|
720
600
|
source: 'local_user',
|
|
721
601
|
});
|
|
722
|
-
if (conversationId === this._conversationId) {
|
|
723
|
-
this.emit('channelUpdated', {
|
|
724
|
-
channelId: this._channelId,
|
|
725
|
-
source: 'local_user',
|
|
726
|
-
});
|
|
727
|
-
}
|
|
728
602
|
try {
|
|
729
|
-
await this.
|
|
603
|
+
await this._graphqlClient.updateConversation(this._id, conversationId, { name });
|
|
730
604
|
}
|
|
731
605
|
catch (error) {
|
|
732
|
-
this.
|
|
606
|
+
this._logger.error('[RoolSpace] Failed to rename conversation:', error);
|
|
733
607
|
conv.name = previousName;
|
|
734
608
|
throw error;
|
|
735
609
|
}
|
|
736
610
|
}
|
|
737
611
|
/** @internal */
|
|
738
612
|
_ensureConversationImpl(conversationId) {
|
|
739
|
-
if (!this.
|
|
740
|
-
this.
|
|
741
|
-
createdAt: Date.now(),
|
|
742
|
-
createdBy: this._userId,
|
|
743
|
-
conversations: {},
|
|
744
|
-
};
|
|
745
|
-
}
|
|
746
|
-
if (!this._channel.conversations[conversationId]) {
|
|
747
|
-
this._channel.conversations[conversationId] = {
|
|
613
|
+
if (!this._conversations[conversationId]) {
|
|
614
|
+
this._conversations[conversationId] = {
|
|
748
615
|
createdAt: Date.now(),
|
|
749
616
|
createdBy: this._userId,
|
|
750
617
|
interactions: {},
|
|
751
618
|
};
|
|
752
619
|
}
|
|
753
620
|
}
|
|
754
|
-
/** Set a space-level metadata value. */
|
|
755
|
-
setMetadata(key, value) {
|
|
756
|
-
this._setMetadataImpl(key, value, this._conversationId);
|
|
757
|
-
}
|
|
758
621
|
/** @internal */
|
|
759
622
|
_setMetadataImpl(key, value, conversationId) {
|
|
760
623
|
this._meta[key] = value;
|
|
761
624
|
this.emit('metadataUpdated', { metadata: this._meta, source: 'local_user' });
|
|
762
625
|
// Fire-and-forget server call
|
|
763
|
-
this.
|
|
626
|
+
this._graphqlClient.setSpaceMeta(this._id, this._meta, conversationId)
|
|
764
627
|
.catch((error) => {
|
|
765
|
-
this.
|
|
628
|
+
this._logger.error('[RoolSpace] Failed to set meta:', error);
|
|
766
629
|
});
|
|
767
630
|
}
|
|
768
631
|
/** Get a space-level metadata value. */
|
|
@@ -773,13 +636,6 @@ export class RoolChannel extends EventEmitter {
|
|
|
773
636
|
getAllMetadata() {
|
|
774
637
|
return this._meta;
|
|
775
638
|
}
|
|
776
|
-
/**
|
|
777
|
-
* Send a prompt to the AI agent for space manipulation.
|
|
778
|
-
* @returns The message from the AI and the list of objects that were created or modified.
|
|
779
|
-
*/
|
|
780
|
-
async prompt(prompt, options) {
|
|
781
|
-
return this._promptImpl(prompt, options, this._conversationId);
|
|
782
|
-
}
|
|
783
639
|
/** @internal */
|
|
784
640
|
async _promptImpl(prompt, options, conversationId) {
|
|
785
641
|
const { attachments, parentInteractionId: explicitParent, signal, ...rest } = options ?? {};
|
|
@@ -811,7 +667,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
811
667
|
}
|
|
812
668
|
let result;
|
|
813
669
|
try {
|
|
814
|
-
result = await this.
|
|
670
|
+
result = await this._graphqlClient.prompt(this._id, prompt, conversationId, {
|
|
815
671
|
...rest,
|
|
816
672
|
attachmentRefs,
|
|
817
673
|
interactionId,
|
|
@@ -833,32 +689,21 @@ export class RoolChannel extends EventEmitter {
|
|
|
833
689
|
objects,
|
|
834
690
|
};
|
|
835
691
|
}
|
|
836
|
-
/**
|
|
837
|
-
* Stop the in-flight interaction on the default conversation, if any.
|
|
838
|
-
*
|
|
839
|
-
* No-op returning `false` when the active leaf is already finished or the
|
|
840
|
-
* conversation has no interactions. Stopping is best-effort: the server
|
|
841
|
-
* halts the agent loop and closes the stream, but an LLM turn already in
|
|
842
|
-
* flight keeps generating server-side and is billed.
|
|
843
|
-
*/
|
|
844
|
-
async stop() {
|
|
845
|
-
return this._stopImpl(this._conversationId);
|
|
846
|
-
}
|
|
847
692
|
/**
|
|
848
693
|
* Request that the server stop a specific in-flight interaction by ID.
|
|
849
694
|
*
|
|
850
695
|
* Returns whether the server stopped an interaction (`false` if it had
|
|
851
|
-
* already finished). Stopping is best-effort — see {@link stop}.
|
|
696
|
+
* already finished). Stopping is best-effort — see {@link ConversationHandle.stop}.
|
|
852
697
|
*/
|
|
853
698
|
async stopInteraction(interactionId) {
|
|
854
|
-
return this.
|
|
699
|
+
return this._graphqlClient.stopInteraction(this._id, interactionId);
|
|
855
700
|
}
|
|
856
701
|
/** @internal */
|
|
857
702
|
async _stopImpl(conversationId) {
|
|
858
703
|
const leafId = this._getActiveLeafImpl(conversationId);
|
|
859
704
|
if (!leafId)
|
|
860
705
|
return false;
|
|
861
|
-
const interactions = this.
|
|
706
|
+
const interactions = this._conversations[conversationId]?.interactions;
|
|
862
707
|
const interaction = interactions && !Array.isArray(interactions) ? interactions[leafId] : undefined;
|
|
863
708
|
// Skip the round trip when we already know the interaction has settled.
|
|
864
709
|
if (interaction && (interaction.status === 'done' || interaction.status === 'error')) {
|
|
@@ -866,29 +711,11 @@ export class RoolChannel extends EventEmitter {
|
|
|
866
711
|
}
|
|
867
712
|
return this.stopInteraction(leafId);
|
|
868
713
|
}
|
|
869
|
-
/** Rename this channel. */
|
|
870
|
-
async rename(newName) {
|
|
871
|
-
const previousName = this._channel?.name;
|
|
872
|
-
if (this._channel) {
|
|
873
|
-
this._channel.name = newName;
|
|
874
|
-
}
|
|
875
|
-
this.emit('channelUpdated', { channelId: this._channelId, source: 'local_user' });
|
|
876
|
-
try {
|
|
877
|
-
await this.graphqlClient.renameChannel(this._id, this._channelId, newName);
|
|
878
|
-
}
|
|
879
|
-
catch (error) {
|
|
880
|
-
this.logger.error('[RoolChannel] Failed to rename channel:', error);
|
|
881
|
-
if (this._channel) {
|
|
882
|
-
this._channel.name = previousName;
|
|
883
|
-
}
|
|
884
|
-
throw error;
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
714
|
/**
|
|
888
715
|
* Fetch an external URL via the server proxy, bypassing CORS restrictions.
|
|
889
716
|
*/
|
|
890
717
|
async fetch(url, init) {
|
|
891
|
-
return this.
|
|
718
|
+
return this._restClient.proxyFetch(this._id, url, init);
|
|
892
719
|
}
|
|
893
720
|
async uploadAttachment(file, conversationId) {
|
|
894
721
|
await this.ensureCollection('/rool-drive/attachments');
|
|
@@ -896,70 +723,32 @@ export class RoolChannel extends EventEmitter {
|
|
|
896
723
|
await this.ensureCollection(directory);
|
|
897
724
|
const attachment = attachmentBody(file);
|
|
898
725
|
const path = `${directory}/${attachment.filename}`;
|
|
899
|
-
await this.
|
|
726
|
+
await this._webdav.put(path, attachment.body, { contentType: attachment.contentType });
|
|
900
727
|
return path;
|
|
901
728
|
}
|
|
902
729
|
async ensureCollection(path) {
|
|
903
|
-
const response = await this.
|
|
730
|
+
const response = await this._webdav.request('MKCOL', path, { collection: true });
|
|
904
731
|
if (response.status === 201 || response.status === 405)
|
|
905
732
|
return;
|
|
906
733
|
throw new Error(`Failed to create collection ${path}: ${response.status} ${await response.text()}`);
|
|
907
734
|
}
|
|
908
735
|
/**
|
|
909
|
-
* Handle a
|
|
736
|
+
* Handle a space event from the subscription.
|
|
910
737
|
* @internal
|
|
911
738
|
*/
|
|
912
|
-
|
|
739
|
+
applySpaceContentEvent(event) {
|
|
913
740
|
if (this._closed)
|
|
914
741
|
return;
|
|
915
742
|
const changeSource = event.source === 'agent' ? 'remote_agent' : 'remote_user';
|
|
916
743
|
switch (event.type) {
|
|
917
|
-
case 'connected':
|
|
918
|
-
// Resync is handled by the client via _applyResyncData.
|
|
919
|
-
break;
|
|
920
|
-
case 'schema_updated':
|
|
921
|
-
if (event.schema) {
|
|
922
|
-
this._schema = event.schema;
|
|
923
|
-
this.emit('schemaUpdated', { schema: this._schema, source: changeSource });
|
|
924
|
-
}
|
|
925
|
-
break;
|
|
926
|
-
case 'metadata_updated':
|
|
927
|
-
if (event.metadata) {
|
|
928
|
-
this._meta = event.metadata;
|
|
929
|
-
this.emit('metadataUpdated', { metadata: this._meta, source: changeSource });
|
|
930
|
-
}
|
|
931
|
-
break;
|
|
932
|
-
case 'channel_updated':
|
|
933
|
-
if (event.channelId === this._channelId && event.channel) {
|
|
934
|
-
const changed = JSON.stringify(this._channel) !== JSON.stringify(event.channel);
|
|
935
|
-
this._channel = event.channel;
|
|
936
|
-
if (changed) {
|
|
937
|
-
this.emit('channelUpdated', { channelId: event.channelId, source: changeSource });
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
break;
|
|
941
|
-
case 'channel_deleted':
|
|
942
|
-
if (event.channelId === this._channelId) {
|
|
943
|
-
this._channel = undefined;
|
|
944
|
-
this._activeLeaves.clear();
|
|
945
|
-
this.emit('reset', { source: changeSource });
|
|
946
|
-
}
|
|
947
|
-
break;
|
|
948
744
|
case 'conversation_updated':
|
|
949
|
-
if (event.
|
|
950
|
-
|
|
951
|
-
this._channel = {
|
|
952
|
-
createdAt: Date.now(),
|
|
953
|
-
createdBy: this._userId,
|
|
954
|
-
conversations: {},
|
|
955
|
-
};
|
|
956
|
-
}
|
|
957
|
-
const prev = this._channel.conversations[event.conversationId];
|
|
745
|
+
if (event.conversationId) {
|
|
746
|
+
const prev = this._conversations[event.conversationId];
|
|
958
747
|
if (event.conversation) {
|
|
959
|
-
this.
|
|
748
|
+
this._conversations[event.conversationId] = event.conversation;
|
|
960
749
|
}
|
|
961
750
|
else {
|
|
962
|
-
delete this.
|
|
751
|
+
delete this._conversations[event.conversationId];
|
|
963
752
|
}
|
|
964
753
|
if (JSON.stringify(prev) === JSON.stringify(event.conversation))
|
|
965
754
|
break;
|
|
@@ -976,77 +765,74 @@ export class RoolChannel extends EventEmitter {
|
|
|
976
765
|
}
|
|
977
766
|
this.emit('conversationUpdated', {
|
|
978
767
|
conversationId: event.conversationId,
|
|
979
|
-
channelId: event.channelId,
|
|
980
768
|
source: changeSource,
|
|
981
769
|
});
|
|
982
|
-
if (event.conversationId === this._conversationId) {
|
|
983
|
-
this.emit('channelUpdated', { channelId: event.channelId, source: changeSource });
|
|
984
|
-
}
|
|
985
770
|
}
|
|
986
771
|
break;
|
|
987
|
-
case 'space_changed':
|
|
988
|
-
// Resync is handled by the client via _applyResyncData.
|
|
989
|
-
break;
|
|
990
772
|
}
|
|
991
773
|
}
|
|
992
774
|
}
|
|
993
775
|
/**
|
|
994
|
-
* A lightweight handle for a specific conversation
|
|
776
|
+
* A lightweight handle for a specific conversation.
|
|
995
777
|
*/
|
|
996
778
|
export class ConversationHandle {
|
|
997
779
|
/** @internal */
|
|
998
|
-
|
|
780
|
+
_space;
|
|
999
781
|
_conversationId;
|
|
1000
782
|
/** @internal */
|
|
1001
|
-
constructor(
|
|
1002
|
-
this.
|
|
783
|
+
constructor(space, conversationId) {
|
|
784
|
+
this._space = space;
|
|
1003
785
|
this._conversationId = conversationId;
|
|
1004
786
|
}
|
|
1005
787
|
/** The conversation ID this handle is scoped to. */
|
|
1006
788
|
get conversationId() { return this._conversationId; }
|
|
1007
789
|
/** Get the active branch of this conversation as a flat array (root → leaf). */
|
|
1008
790
|
getInteractions() {
|
|
1009
|
-
return this.
|
|
791
|
+
return this._space._getInteractionsImpl(this._conversationId);
|
|
1010
792
|
}
|
|
1011
793
|
/** Get the full interaction tree as a record. */
|
|
1012
794
|
getTree() {
|
|
1013
|
-
return this.
|
|
795
|
+
return this._space._getTreeImpl(this._conversationId);
|
|
1014
796
|
}
|
|
1015
797
|
/** Get the active leaf interaction ID, or undefined if empty. */
|
|
1016
798
|
get activeLeafId() {
|
|
1017
|
-
return this.
|
|
799
|
+
return this._space._getActiveLeafImpl(this._conversationId);
|
|
1018
800
|
}
|
|
1019
801
|
/** Switch to a different branch by setting the active leaf. */
|
|
1020
802
|
setActiveLeaf(interactionId) {
|
|
1021
|
-
this.
|
|
803
|
+
this._space._setActiveLeafImpl(interactionId, this._conversationId);
|
|
1022
804
|
}
|
|
1023
805
|
/** Get the system instruction for this conversation. */
|
|
1024
806
|
getSystemInstruction() {
|
|
1025
|
-
return this.
|
|
807
|
+
return this._space._getSystemInstructionImpl(this._conversationId);
|
|
1026
808
|
}
|
|
1027
809
|
/** Set the system instruction for this conversation. Pass null to clear. */
|
|
1028
810
|
async setSystemInstruction(instruction) {
|
|
1029
|
-
return this.
|
|
811
|
+
return this._space._setSystemInstructionImpl(instruction, this._conversationId);
|
|
1030
812
|
}
|
|
1031
813
|
/** Rename this conversation. */
|
|
1032
814
|
async rename(name) {
|
|
1033
|
-
return this.
|
|
815
|
+
return this._space._renameConversationImpl(name, this._conversationId);
|
|
816
|
+
}
|
|
817
|
+
/** Delete this conversation. */
|
|
818
|
+
async delete() {
|
|
819
|
+
return this._space.deleteConversation(this._conversationId);
|
|
1034
820
|
}
|
|
1035
821
|
/** Create or replace an object JSON file. */
|
|
1036
822
|
async putObject(path, body) {
|
|
1037
|
-
return this.
|
|
823
|
+
return this._space._putObjectImpl(path, body, this._conversationId);
|
|
1038
824
|
}
|
|
1039
825
|
/** Patch an existing object JSON file. */
|
|
1040
826
|
async patchObject(path, options) {
|
|
1041
|
-
return this.
|
|
827
|
+
return this._space._patchObjectImpl(path, options, this._conversationId);
|
|
1042
828
|
}
|
|
1043
829
|
/** Move (rename/relocate) an object. */
|
|
1044
830
|
async moveObject(from, to, options) {
|
|
1045
|
-
return this.
|
|
831
|
+
return this._space._moveObjectImpl(from, to, options, this._conversationId);
|
|
1046
832
|
}
|
|
1047
833
|
/** Delete object JSON files by path. */
|
|
1048
834
|
async deleteObjects(paths) {
|
|
1049
|
-
return this.
|
|
835
|
+
return this._space._deleteObjectsImpl(paths, this._conversationId);
|
|
1050
836
|
}
|
|
1051
837
|
/** @deprecated Use deleteObjects instead. */
|
|
1052
838
|
async deletePaths(paths) {
|
|
@@ -1054,30 +840,30 @@ export class ConversationHandle {
|
|
|
1054
840
|
}
|
|
1055
841
|
/** Send a prompt to the AI agent, scoped to this conversation's history. */
|
|
1056
842
|
async prompt(text, options) {
|
|
1057
|
-
return this.
|
|
843
|
+
return this._space._promptImpl(text, options, this._conversationId);
|
|
1058
844
|
}
|
|
1059
845
|
/**
|
|
1060
846
|
* Stop this conversation's in-flight interaction, if any. No-op returning
|
|
1061
847
|
* `false` when nothing is running. Stopping is best-effort — see
|
|
1062
|
-
* {@link
|
|
848
|
+
* {@link RoolSpace.stopInteraction}.
|
|
1063
849
|
*/
|
|
1064
850
|
async stop() {
|
|
1065
|
-
return this.
|
|
851
|
+
return this._space._stopImpl(this._conversationId);
|
|
1066
852
|
}
|
|
1067
853
|
/** Create a new collection schema. */
|
|
1068
854
|
async createCollection(name, fields, options) {
|
|
1069
|
-
return this.
|
|
855
|
+
return this._space._createCollectionImpl(name, fields, options, this._conversationId);
|
|
1070
856
|
}
|
|
1071
857
|
/** Alter an existing collection schema. */
|
|
1072
858
|
async alterCollection(name, fields, options) {
|
|
1073
|
-
return this.
|
|
859
|
+
return this._space._alterCollectionImpl(name, fields, options, this._conversationId);
|
|
1074
860
|
}
|
|
1075
861
|
/** Drop a collection schema. */
|
|
1076
862
|
async dropCollection(name) {
|
|
1077
|
-
return this.
|
|
863
|
+
return this._space._dropCollectionImpl(name, this._conversationId);
|
|
1078
864
|
}
|
|
1079
865
|
setMetadata(key, value) {
|
|
1080
|
-
return this.
|
|
866
|
+
return this._space._setMetadataImpl(key, value, this._conversationId);
|
|
1081
867
|
}
|
|
1082
868
|
}
|
|
1083
|
-
//# sourceMappingURL=
|
|
869
|
+
//# sourceMappingURL=space-session.js.map
|