@rool-dev/sdk 0.10.2-dev.9df035a → 0.10.2-dev.a0fe230
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 +437 -1108
- package/dist/channel.d.ts +29 -61
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +92 -133
- package/dist/channel.js.map +1 -1
- package/dist/client.d.ts +0 -6
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +0 -8
- package/dist/client.js.map +1 -1
- package/dist/graphql.d.ts +1 -2
- package/dist/graphql.d.ts.map +1 -1
- package/dist/graphql.js +20 -42
- package/dist/graphql.js.map +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/path.d.ts +6 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +47 -0
- package/dist/path.js.map +1 -0
- package/dist/reroute.d.ts +22 -0
- package/dist/reroute.d.ts.map +1 -0
- package/dist/reroute.js +61 -0
- package/dist/reroute.js.map +1 -0
- package/dist/rest.d.ts +1 -1
- package/dist/rest.d.ts.map +1 -1
- package/dist/rest.js +14 -25
- package/dist/rest.js.map +1 -1
- package/dist/space.d.ts +2 -3
- package/dist/space.d.ts.map +1 -1
- package/dist/space.js +7 -15
- package/dist/space.js.map +1 -1
- package/dist/subscription.js +0 -2
- package/dist/subscription.js.map +1 -1
- package/dist/types.d.ts +14 -41
- package/dist/types.d.ts.map +1 -1
- package/dist/webdav.d.ts +21 -21
- package/dist/webdav.d.ts.map +1 -1
- package/dist/webdav.js +37 -101
- package/dist/webdav.js.map +1 -1
- package/package.json +1 -1
- package/dist/locations.d.ts +0 -29
- package/dist/locations.d.ts.map +0 -1
- package/dist/locations.js +0 -78
- package/dist/locations.js.map +0 -1
- package/dist/machine.d.ts +0 -16
- package/dist/machine.d.ts.map +0 -1
- package/dist/machine.js +0 -51
- package/dist/machine.js.map +0 -1
package/dist/channel.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { GraphQLClient } from './graphql.js';
|
|
|
3
3
|
import type { RestClient } from './rest.js';
|
|
4
4
|
import { type RoolWebDAV } from './webdav.js';
|
|
5
5
|
import type { Logger } from './logger.js';
|
|
6
|
-
import type { RoolObject, GetObjectsResult, RoolObjectStat, ChannelEvents, RoolUserRole, PromptOptions,
|
|
6
|
+
import type { RoolObject, GetObjectsResult, RoolObjectStat, ChannelEvents, RoolUserRole, PromptOptions, UpdateObjectOptions, MoveObjectOptions, ChannelEvent, Interaction, Channel, ConversationInfo, LinkAccess, SpaceSchema, CollectionDef, FieldDef, CollectionOptions } from './types.js';
|
|
7
7
|
export declare function generateEntityId(): string;
|
|
8
8
|
export interface ChannelConfig {
|
|
9
9
|
id: string;
|
|
@@ -12,7 +12,7 @@ export interface ChannelConfig {
|
|
|
12
12
|
linkAccess: LinkAccess;
|
|
13
13
|
/** Current user's ID (for identifying own interactions) */
|
|
14
14
|
userId: string;
|
|
15
|
-
/** Object stats keyed by
|
|
15
|
+
/** Object stats keyed by path */
|
|
16
16
|
objectStats: Record<string, RoolObjectStat>;
|
|
17
17
|
/** Collection schema */
|
|
18
18
|
schema: SpaceSchema;
|
|
@@ -35,7 +35,7 @@ export interface ChannelConfig {
|
|
|
35
35
|
* at open time and cannot be changed. To use a different channel,
|
|
36
36
|
* open a second one.
|
|
37
37
|
*
|
|
38
|
-
* Objects are addressed by
|
|
38
|
+
* Objects are addressed by machine path (`/space/.../*.json`).
|
|
39
39
|
* Only schema, metadata, object stats, and the channel's own history are cached
|
|
40
40
|
* locally. Object bodies are fetched on demand. Object/file reactivity is
|
|
41
41
|
* exposed at the space level via WebDAV sync notifications.
|
|
@@ -161,66 +161,33 @@ export declare class RoolChannel extends EventEmitter<ChannelEvents> {
|
|
|
161
161
|
clearHistory(): Promise<void>;
|
|
162
162
|
private davHeaders;
|
|
163
163
|
private readObject;
|
|
164
|
-
/**
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
* Get objects by location in bulk.
|
|
173
|
-
*
|
|
174
|
-
* Accepts either canonical locations (`/space/<collection>/<basename>.json`)
|
|
175
|
-
* or short locations (`<collection>/<basename>`). Duplicate locations are
|
|
176
|
-
* fetched once, preserving their first requested order.
|
|
177
|
-
*/
|
|
178
|
-
getObjects(locations: string[]): Promise<GetObjectsResult>;
|
|
179
|
-
/**
|
|
180
|
-
* Get an object's stat (audit information).
|
|
181
|
-
* Returns the cached stat or undefined if not known.
|
|
182
|
-
*/
|
|
183
|
-
stat(location: string): RoolObjectStat | undefined;
|
|
184
|
-
/**
|
|
185
|
-
* Create a new object in the given collection.
|
|
186
|
-
*
|
|
187
|
-
* @param collection - The collection (must exist in the schema)
|
|
188
|
-
* @param body - Object body fields. Fields prefixed with `_` are hidden from AI.
|
|
189
|
-
* @param options.basename - Specific basename to use. If omitted, the SDK generates a random one.
|
|
190
|
-
* @returns The created object and a status message.
|
|
191
|
-
*/
|
|
192
|
-
createObject(collection: string, body: Record<string, unknown>, options?: CreateObjectOptions): Promise<{
|
|
164
|
+
/** Get an object JSON file by machine path. Fetches from the server on each call. */
|
|
165
|
+
getObject(path: string): Promise<RoolObject | undefined>;
|
|
166
|
+
/** Get object JSON files by machine path in bulk. Duplicate paths are fetched once. */
|
|
167
|
+
getObjects(paths: string[]): Promise<GetObjectsResult>;
|
|
168
|
+
/** Get an object's cached audit information. */
|
|
169
|
+
stat(path: string): RoolObjectStat | undefined;
|
|
170
|
+
/** Create or replace an object JSON file at an exact machine path. */
|
|
171
|
+
putObject(path: string, body: Record<string, unknown>): Promise<{
|
|
193
172
|
object: RoolObject;
|
|
194
173
|
message: string;
|
|
195
174
|
}>;
|
|
196
175
|
/** @internal */
|
|
197
|
-
|
|
176
|
+
_putObjectImpl(path: string, body: Record<string, unknown>, conversationId: string): Promise<{
|
|
198
177
|
object: RoolObject;
|
|
199
178
|
message: string;
|
|
200
179
|
}>;
|
|
201
|
-
/**
|
|
202
|
-
|
|
203
|
-
*
|
|
204
|
-
* @param location - The object's location (canonical or short form)
|
|
205
|
-
* @param options.data - Fields to add or update. Pass `null` to delete a field.
|
|
206
|
-
*/
|
|
207
|
-
updateObject(location: string, options: UpdateObjectOptions): Promise<{
|
|
180
|
+
/** Patch an existing object. Null or undefined deletes a field. */
|
|
181
|
+
patchObject(path: string, options: UpdateObjectOptions): Promise<{
|
|
208
182
|
object: RoolObject;
|
|
209
183
|
message: string;
|
|
210
184
|
}>;
|
|
211
185
|
/** @internal */
|
|
212
|
-
|
|
186
|
+
_patchObjectImpl(path: string, options: UpdateObjectOptions, conversationId: string): Promise<{
|
|
213
187
|
object: RoolObject;
|
|
214
188
|
message: string;
|
|
215
189
|
}>;
|
|
216
|
-
/**
|
|
217
|
-
* Move (rename or relocate) an object to a new location.
|
|
218
|
-
* Use this to rename, change collection, or atomically rewrite the body.
|
|
219
|
-
*
|
|
220
|
-
* @param from - Current location
|
|
221
|
-
* @param to - New location
|
|
222
|
-
* @param options.body - Replace the body atomically as part of the move.
|
|
223
|
-
*/
|
|
190
|
+
/** Move an object JSON file to a new machine path, optionally replacing its body. */
|
|
224
191
|
moveObject(from: string, to: string, options?: MoveObjectOptions): Promise<{
|
|
225
192
|
object: RoolObject;
|
|
226
193
|
message: string;
|
|
@@ -230,13 +197,12 @@ export declare class RoolChannel extends EventEmitter<ChannelEvents> {
|
|
|
230
197
|
object: RoolObject;
|
|
231
198
|
message: string;
|
|
232
199
|
}>;
|
|
233
|
-
/**
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
deleteObjects(locations: string[]): Promise<void>;
|
|
200
|
+
/** Delete object JSON files by machine path. */
|
|
201
|
+
deleteObjects(paths: string[]): Promise<void>;
|
|
202
|
+
/** @deprecated Use deleteObjects instead. */
|
|
203
|
+
deletePaths(paths: string[]): Promise<void>;
|
|
238
204
|
/** @internal */
|
|
239
|
-
_deleteObjectsImpl(
|
|
205
|
+
_deleteObjectsImpl(paths: string[], conversationId: string): Promise<void>;
|
|
240
206
|
/** Get the current schema for this space. */
|
|
241
207
|
getSchema(): SpaceSchema;
|
|
242
208
|
/** Create a new collection schema. */
|
|
@@ -331,13 +297,13 @@ export declare class ConversationHandle {
|
|
|
331
297
|
setSystemInstruction(instruction: string | null): Promise<void>;
|
|
332
298
|
/** Rename this conversation. */
|
|
333
299
|
rename(name: string): Promise<void>;
|
|
334
|
-
/** Create
|
|
335
|
-
|
|
300
|
+
/** Create or replace an object JSON file. */
|
|
301
|
+
putObject(path: string, body: Record<string, unknown>): Promise<{
|
|
336
302
|
object: RoolObject;
|
|
337
303
|
message: string;
|
|
338
304
|
}>;
|
|
339
|
-
/**
|
|
340
|
-
|
|
305
|
+
/** Patch an existing object JSON file. */
|
|
306
|
+
patchObject(path: string, options: UpdateObjectOptions): Promise<{
|
|
341
307
|
object: RoolObject;
|
|
342
308
|
message: string;
|
|
343
309
|
}>;
|
|
@@ -346,8 +312,10 @@ export declare class ConversationHandle {
|
|
|
346
312
|
object: RoolObject;
|
|
347
313
|
message: string;
|
|
348
314
|
}>;
|
|
349
|
-
/** Delete
|
|
350
|
-
deleteObjects(
|
|
315
|
+
/** Delete object JSON files by path. */
|
|
316
|
+
deleteObjects(paths: string[]): Promise<void>;
|
|
317
|
+
/** @deprecated Use deleteObjects instead. */
|
|
318
|
+
deletePaths(paths: string[]): Promise<void>;
|
|
351
319
|
/** Send a prompt to the AI agent, scoped to this conversation's history. */
|
|
352
320
|
prompt(text: string, options?: PromptOptions): Promise<{
|
|
353
321
|
message: string;
|
package/dist/channel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"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"}
|
package/dist/channel.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from './event-emitter.js';
|
|
2
2
|
import { WebDAVError } from './webdav.js';
|
|
3
|
-
import {
|
|
4
|
-
import { resolveMachineResource } from './machine.js';
|
|
3
|
+
import { isObjectPath, machinePath, machineUri } from './path.js';
|
|
5
4
|
// 6-character alphanumeric ID — used for object names, interactionIds, conversationIds, etc.
|
|
6
5
|
const ENTITY_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
7
6
|
const GET_OBJECTS_CHUNK_SIZE = 500;
|
|
@@ -44,20 +43,21 @@ function findDefaultLeaf(interactions) {
|
|
|
44
43
|
}
|
|
45
44
|
return best?.id;
|
|
46
45
|
}
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
function objectPath(input) {
|
|
47
|
+
const path = machinePath(input);
|
|
48
|
+
if (!isObjectPath(path)) {
|
|
49
|
+
throw new Error(`Object path must be /space/<collection>/<name>.json without dotfiles: ${input}`);
|
|
50
|
+
}
|
|
51
|
+
return path;
|
|
50
52
|
}
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
return `/space/${name}/`;
|
|
53
|
+
function collectionPath(name) {
|
|
54
|
+
return machinePath(`/space/${name}`);
|
|
54
55
|
}
|
|
55
|
-
function
|
|
56
|
-
return `${
|
|
56
|
+
function schemaPath(name) {
|
|
57
|
+
return `${collectionPath(name)}/.schema.json`;
|
|
57
58
|
}
|
|
58
|
-
function objectFromBody(
|
|
59
|
-
|
|
60
|
-
return { location, collection, basename, body };
|
|
59
|
+
function objectFromBody(path, body) {
|
|
60
|
+
return { path, body };
|
|
61
61
|
}
|
|
62
62
|
function jsonObject(value, label) {
|
|
63
63
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
@@ -162,7 +162,7 @@ function base64Body(data) {
|
|
|
162
162
|
* at open time and cannot be changed. To use a different channel,
|
|
163
163
|
* open a second one.
|
|
164
164
|
*
|
|
165
|
-
* Objects are addressed by
|
|
165
|
+
* Objects are addressed by machine path (`/space/.../*.json`).
|
|
166
166
|
* Only schema, metadata, object stats, and the channel's own history are cached
|
|
167
167
|
* locally. Object bodies are fetched on demand. Object/file reactivity is
|
|
168
168
|
* exposed at the space level via WebDAV sync notifications.
|
|
@@ -206,7 +206,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
206
206
|
// Initialize local cache from server data
|
|
207
207
|
this._meta = config.meta;
|
|
208
208
|
this._schema = config.schema;
|
|
209
|
-
this._channel = config.channel;
|
|
209
|
+
this._channel = config.channel ?? undefined;
|
|
210
210
|
this._objectStats = new Map(Object.entries(config.objectStats));
|
|
211
211
|
}
|
|
212
212
|
/**
|
|
@@ -428,10 +428,10 @@ export class RoolChannel extends EventEmitter {
|
|
|
428
428
|
headers.set('X-Rool-Interaction-Id', interactionId);
|
|
429
429
|
return headers;
|
|
430
430
|
}
|
|
431
|
-
async readObject(
|
|
432
|
-
const canonical =
|
|
431
|
+
async readObject(path) {
|
|
432
|
+
const canonical = objectPath(path);
|
|
433
433
|
try {
|
|
434
|
-
const response = await this.webdav.get(
|
|
434
|
+
const response = await this.webdav.get(canonical);
|
|
435
435
|
const body = jsonObject(await response.json(), `Object ${canonical}`);
|
|
436
436
|
return { object: objectFromBody(canonical, body), etag: response.headers.get('ETag') };
|
|
437
437
|
}
|
|
@@ -443,27 +443,16 @@ export class RoolChannel extends EventEmitter {
|
|
|
443
443
|
throw error;
|
|
444
444
|
}
|
|
445
445
|
}
|
|
446
|
-
/**
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
* Accepts either the canonical form (`/space/<collection>/<basename>.json`)
|
|
450
|
-
* or the short form (`<collection>/<basename>`).
|
|
451
|
-
*/
|
|
452
|
-
async getObject(location) {
|
|
453
|
-
return (await this.readObject(location))?.object;
|
|
446
|
+
/** Get an object JSON file by machine path. Fetches from the server on each call. */
|
|
447
|
+
async getObject(path) {
|
|
448
|
+
return (await this.readObject(path))?.object;
|
|
454
449
|
}
|
|
455
|
-
/**
|
|
456
|
-
|
|
457
|
-
*
|
|
458
|
-
* Accepts either canonical locations (`/space/<collection>/<basename>.json`)
|
|
459
|
-
* or short locations (`<collection>/<basename>`). Duplicate locations are
|
|
460
|
-
* fetched once, preserving their first requested order.
|
|
461
|
-
*/
|
|
462
|
-
async getObjects(locations) {
|
|
450
|
+
/** Get object JSON files by machine path in bulk. Duplicate paths are fetched once. */
|
|
451
|
+
async getObjects(paths) {
|
|
463
452
|
const canonical = [];
|
|
464
453
|
const seen = new Set();
|
|
465
|
-
for (const
|
|
466
|
-
const normalized =
|
|
454
|
+
for (const path of paths) {
|
|
455
|
+
const normalized = objectPath(path);
|
|
467
456
|
if (seen.has(normalized))
|
|
468
457
|
continue;
|
|
469
458
|
seen.add(normalized);
|
|
@@ -478,57 +467,40 @@ export class RoolChannel extends EventEmitter {
|
|
|
478
467
|
}
|
|
479
468
|
return result;
|
|
480
469
|
}
|
|
481
|
-
/**
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
*/
|
|
485
|
-
stat(location) {
|
|
486
|
-
return this._objectStats.get(normalizeLocation(location));
|
|
470
|
+
/** Get an object's cached audit information. */
|
|
471
|
+
stat(path) {
|
|
472
|
+
return this._objectStats.get(objectPath(path));
|
|
487
473
|
}
|
|
488
|
-
/**
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
* @param collection - The collection (must exist in the schema)
|
|
492
|
-
* @param body - Object body fields. Fields prefixed with `_` are hidden from AI.
|
|
493
|
-
* @param options.basename - Specific basename to use. If omitted, the SDK generates a random one.
|
|
494
|
-
* @returns The created object and a status message.
|
|
495
|
-
*/
|
|
496
|
-
async createObject(collection, body, options) {
|
|
497
|
-
return this._createObjectImpl(collection, body, options, this._conversationId);
|
|
474
|
+
/** Create or replace an object JSON file at an exact machine path. */
|
|
475
|
+
async putObject(path, body) {
|
|
476
|
+
return this._putObjectImpl(path, body, this._conversationId);
|
|
498
477
|
}
|
|
499
478
|
/** @internal */
|
|
500
|
-
async
|
|
501
|
-
const
|
|
502
|
-
const
|
|
503
|
-
const optimistic = { location, collection, basename, body };
|
|
479
|
+
async _putObjectImpl(path, body, conversationId) {
|
|
480
|
+
const canonical = objectPath(path);
|
|
481
|
+
const optimistic = objectFromBody(canonical, body);
|
|
504
482
|
try {
|
|
505
483
|
const interactionId = generateEntityId();
|
|
506
|
-
await this.webdav.put(
|
|
484
|
+
await this.webdav.put(canonical, JSON.stringify(body), {
|
|
507
485
|
contentType: 'application/json',
|
|
508
|
-
ifNoneMatch: '*',
|
|
509
486
|
headers: this.davHeaders(conversationId, interactionId),
|
|
510
487
|
});
|
|
511
|
-
const fresh = await this.getObject(
|
|
512
|
-
return { object: fresh, message: `
|
|
488
|
+
const fresh = await this.getObject(canonical) ?? optimistic;
|
|
489
|
+
return { object: fresh, message: `Put ${canonical}` };
|
|
513
490
|
}
|
|
514
491
|
catch (error) {
|
|
515
|
-
this.logger.error('[RoolChannel] Failed to
|
|
492
|
+
this.logger.error('[RoolChannel] Failed to put object:', error);
|
|
516
493
|
this.emit('syncError', error instanceof Error ? error : new Error(String(error)));
|
|
517
494
|
throw error;
|
|
518
495
|
}
|
|
519
496
|
}
|
|
520
|
-
/**
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
* @param location - The object's location (canonical or short form)
|
|
524
|
-
* @param options.data - Fields to add or update. Pass `null` to delete a field.
|
|
525
|
-
*/
|
|
526
|
-
async updateObject(location, options) {
|
|
527
|
-
return this._updateObjectImpl(location, options, this._conversationId);
|
|
497
|
+
/** Patch an existing object. Null or undefined deletes a field. */
|
|
498
|
+
async patchObject(path, options) {
|
|
499
|
+
return this._patchObjectImpl(path, options, this._conversationId);
|
|
528
500
|
}
|
|
529
501
|
/** @internal */
|
|
530
|
-
async
|
|
531
|
-
const canonical =
|
|
502
|
+
async _patchObjectImpl(path, options, conversationId) {
|
|
503
|
+
const canonical = objectPath(path);
|
|
532
504
|
const data = options.data ?? {};
|
|
533
505
|
const current = await this.readObject(canonical);
|
|
534
506
|
if (!current)
|
|
@@ -537,57 +509,43 @@ export class RoolChannel extends EventEmitter {
|
|
|
537
509
|
const optimistic = objectFromBody(canonical, body);
|
|
538
510
|
try {
|
|
539
511
|
const interactionId = generateEntityId();
|
|
540
|
-
await this.webdav.put(
|
|
512
|
+
await this.webdav.put(canonical, JSON.stringify(body), {
|
|
541
513
|
contentType: 'application/json',
|
|
542
514
|
ifMatch: current.etag ?? undefined,
|
|
543
515
|
headers: this.davHeaders(conversationId, interactionId),
|
|
544
516
|
});
|
|
545
517
|
const fresh = await this.getObject(canonical) ?? optimistic;
|
|
546
|
-
return { object: fresh, message: `
|
|
518
|
+
return { object: fresh, message: `Patched ${canonical}` };
|
|
547
519
|
}
|
|
548
520
|
catch (error) {
|
|
549
|
-
this.logger.error('[RoolChannel] Failed to
|
|
521
|
+
this.logger.error('[RoolChannel] Failed to patch object:', error);
|
|
550
522
|
this.emit('syncError', error instanceof Error ? error : new Error(String(error)));
|
|
551
523
|
throw error;
|
|
552
524
|
}
|
|
553
525
|
}
|
|
554
|
-
/**
|
|
555
|
-
* Move (rename or relocate) an object to a new location.
|
|
556
|
-
* Use this to rename, change collection, or atomically rewrite the body.
|
|
557
|
-
*
|
|
558
|
-
* @param from - Current location
|
|
559
|
-
* @param to - New location
|
|
560
|
-
* @param options.body - Replace the body atomically as part of the move.
|
|
561
|
-
*/
|
|
526
|
+
/** Move an object JSON file to a new machine path, optionally replacing its body. */
|
|
562
527
|
async moveObject(from, to, options) {
|
|
563
528
|
return this._moveObjectImpl(from, to, options, this._conversationId);
|
|
564
529
|
}
|
|
565
530
|
/** @internal */
|
|
566
531
|
async _moveObjectImpl(from, to, options, conversationId) {
|
|
567
|
-
const
|
|
568
|
-
const
|
|
569
|
-
|
|
570
|
-
const { collection, basename } = parseLocation(toLoc);
|
|
571
|
-
const optimistic = {
|
|
572
|
-
location: toLoc,
|
|
573
|
-
collection,
|
|
574
|
-
basename,
|
|
575
|
-
body: options?.body ?? {},
|
|
576
|
-
};
|
|
532
|
+
const fromPath = objectPath(from);
|
|
533
|
+
const toPath = objectPath(to);
|
|
534
|
+
const optimistic = objectFromBody(toPath, options?.body ?? {});
|
|
577
535
|
try {
|
|
578
536
|
const interactionId = generateEntityId();
|
|
579
|
-
await this.webdav.move(
|
|
537
|
+
await this.webdav.move(fromPath, toPath, {
|
|
580
538
|
headers: this.davHeaders(conversationId, interactionId),
|
|
581
539
|
});
|
|
582
540
|
if (options?.body) {
|
|
583
|
-
await this.webdav.put(
|
|
541
|
+
await this.webdav.put(toPath, JSON.stringify(options.body), {
|
|
584
542
|
contentType: 'application/json',
|
|
585
543
|
headers: this.davHeaders(conversationId, interactionId),
|
|
586
544
|
});
|
|
587
545
|
}
|
|
588
|
-
this._objectStats.delete(
|
|
589
|
-
const fresh = await this.getObject(
|
|
590
|
-
return { object: fresh, message: `Moved ${
|
|
546
|
+
this._objectStats.delete(fromPath);
|
|
547
|
+
const fresh = await this.getObject(toPath) ?? optimistic;
|
|
548
|
+
return { object: fresh, message: `Moved ${fromPath} to ${toPath}` };
|
|
591
549
|
}
|
|
592
550
|
catch (error) {
|
|
593
551
|
this.logger.error('[RoolChannel] Failed to move object:', error);
|
|
@@ -595,29 +553,30 @@ export class RoolChannel extends EventEmitter {
|
|
|
595
553
|
throw error;
|
|
596
554
|
}
|
|
597
555
|
}
|
|
598
|
-
/**
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
556
|
+
/** Delete object JSON files by machine path. */
|
|
557
|
+
async deleteObjects(paths) {
|
|
558
|
+
return this._deleteObjectsImpl(paths, this._conversationId);
|
|
559
|
+
}
|
|
560
|
+
/** @deprecated Use deleteObjects instead. */
|
|
561
|
+
async deletePaths(paths) {
|
|
562
|
+
return this.deleteObjects(paths);
|
|
604
563
|
}
|
|
605
564
|
/** @internal */
|
|
606
|
-
async _deleteObjectsImpl(
|
|
607
|
-
if (
|
|
565
|
+
async _deleteObjectsImpl(paths, conversationId) {
|
|
566
|
+
if (paths.length === 0)
|
|
608
567
|
return;
|
|
609
|
-
const canonical =
|
|
568
|
+
const canonical = paths.map(objectPath);
|
|
610
569
|
try {
|
|
611
570
|
const interactionId = generateEntityId();
|
|
612
|
-
for (const
|
|
613
|
-
await this.webdav.delete(
|
|
571
|
+
for (const path of canonical) {
|
|
572
|
+
await this.webdav.delete(path, {
|
|
614
573
|
headers: this.davHeaders(conversationId, interactionId),
|
|
615
574
|
});
|
|
616
|
-
this._objectStats.delete(
|
|
575
|
+
this._objectStats.delete(path);
|
|
617
576
|
}
|
|
618
577
|
}
|
|
619
578
|
catch (error) {
|
|
620
|
-
this.logger.error('[RoolChannel] Failed to delete
|
|
579
|
+
this.logger.error('[RoolChannel] Failed to delete paths:', error);
|
|
621
580
|
this.emit('syncError', error instanceof Error ? error : new Error(String(error)));
|
|
622
581
|
throw error;
|
|
623
582
|
}
|
|
@@ -639,8 +598,8 @@ export class RoolChannel extends EventEmitter {
|
|
|
639
598
|
const optimisticDef = collectionDef(fields, options);
|
|
640
599
|
this._schema[name] = optimisticDef;
|
|
641
600
|
try {
|
|
642
|
-
await this.webdav.mkcol(
|
|
643
|
-
await this.webdav.put(
|
|
601
|
+
await this.webdav.mkcol(collectionPath(name), { headers: this.davHeaders(conversationId, generateEntityId()) });
|
|
602
|
+
await this.webdav.put(schemaPath(name), JSON.stringify(optimisticDef), {
|
|
644
603
|
contentType: 'application/json',
|
|
645
604
|
headers: this.davHeaders(conversationId, generateEntityId()),
|
|
646
605
|
});
|
|
@@ -666,7 +625,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
666
625
|
this._schema[name] = collectionDef(fields, options);
|
|
667
626
|
try {
|
|
668
627
|
const updated = this._schema[name];
|
|
669
|
-
await this.webdav.put(
|
|
628
|
+
await this.webdav.put(schemaPath(name), JSON.stringify(updated), {
|
|
670
629
|
contentType: 'application/json',
|
|
671
630
|
headers: this.davHeaders(conversationId, generateEntityId()),
|
|
672
631
|
});
|
|
@@ -691,7 +650,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
691
650
|
const previous = this._schema[name];
|
|
692
651
|
delete this._schema[name];
|
|
693
652
|
try {
|
|
694
|
-
await this.webdav.delete(
|
|
653
|
+
await this.webdav.delete(collectionPath(name), { collection: true, headers: this.davHeaders(conversationId, generateEntityId()) });
|
|
695
654
|
this.emit('schemaUpdated', { schema: this._schema, source: 'local_user' });
|
|
696
655
|
}
|
|
697
656
|
catch (error) {
|
|
@@ -833,8 +792,8 @@ export class RoolChannel extends EventEmitter {
|
|
|
833
792
|
let attachmentRefs;
|
|
834
793
|
if (attachments?.length) {
|
|
835
794
|
attachmentRefs = await Promise.all(attachments.map(async (attachment) => {
|
|
836
|
-
const
|
|
837
|
-
return
|
|
795
|
+
const path = typeof attachment === 'string' ? machinePath(attachment) : await this.uploadAttachment(attachment, conversationId);
|
|
796
|
+
return machineUri(path);
|
|
838
797
|
}));
|
|
839
798
|
}
|
|
840
799
|
// Auto-continue from active leaf if no explicit parent provided
|
|
@@ -869,7 +828,7 @@ export class RoolChannel extends EventEmitter {
|
|
|
869
828
|
signal.removeEventListener('abort', onAbort);
|
|
870
829
|
}
|
|
871
830
|
const objects = [];
|
|
872
|
-
const fetched = await Promise.all(result.
|
|
831
|
+
const fetched = await Promise.all(result.modifiedObjectPaths.map((path) => this.getObject(path)));
|
|
873
832
|
for (const object of fetched) {
|
|
874
833
|
if (object)
|
|
875
834
|
objects.push(object);
|
|
@@ -904,19 +863,15 @@ export class RoolChannel extends EventEmitter {
|
|
|
904
863
|
return this.restClient.proxyFetch(this._id, url, init);
|
|
905
864
|
}
|
|
906
865
|
async uploadAttachment(file, conversationId) {
|
|
907
|
-
await this.ensureCollection('attachments');
|
|
908
|
-
const directory =
|
|
866
|
+
await this.ensureCollection('/rool-drive/attachments');
|
|
867
|
+
const directory = `/rool-drive/attachments/${conversationId}`;
|
|
909
868
|
await this.ensureCollection(directory);
|
|
910
869
|
const attachment = attachmentBody(file);
|
|
911
870
|
const path = `${directory}/${attachment.filename}`;
|
|
912
871
|
await this.webdav.put(path, attachment.body, { contentType: attachment.contentType });
|
|
913
|
-
|
|
914
|
-
if (!resource)
|
|
915
|
-
throw new Error('Failed to resolve uploaded attachment');
|
|
916
|
-
return resource;
|
|
872
|
+
return path;
|
|
917
873
|
}
|
|
918
874
|
async ensureCollection(path) {
|
|
919
|
-
// Note: not an object collection, a folder, which is "collection" in webdav land
|
|
920
875
|
const response = await this.webdav.request('MKCOL', path, { collection: true });
|
|
921
876
|
if (response.status === 201 || response.status === 405)
|
|
922
877
|
return;
|
|
@@ -1049,21 +1004,25 @@ export class ConversationHandle {
|
|
|
1049
1004
|
async rename(name) {
|
|
1050
1005
|
return this._channel._renameConversationImpl(name, this._conversationId);
|
|
1051
1006
|
}
|
|
1052
|
-
/** Create
|
|
1053
|
-
async
|
|
1054
|
-
return this._channel.
|
|
1007
|
+
/** Create or replace an object JSON file. */
|
|
1008
|
+
async putObject(path, body) {
|
|
1009
|
+
return this._channel._putObjectImpl(path, body, this._conversationId);
|
|
1055
1010
|
}
|
|
1056
|
-
/**
|
|
1057
|
-
async
|
|
1058
|
-
return this._channel.
|
|
1011
|
+
/** Patch an existing object JSON file. */
|
|
1012
|
+
async patchObject(path, options) {
|
|
1013
|
+
return this._channel._patchObjectImpl(path, options, this._conversationId);
|
|
1059
1014
|
}
|
|
1060
1015
|
/** Move (rename/relocate) an object. */
|
|
1061
1016
|
async moveObject(from, to, options) {
|
|
1062
1017
|
return this._channel._moveObjectImpl(from, to, options, this._conversationId);
|
|
1063
1018
|
}
|
|
1064
|
-
/** Delete
|
|
1065
|
-
async deleteObjects(
|
|
1066
|
-
return this._channel._deleteObjectsImpl(
|
|
1019
|
+
/** Delete object JSON files by path. */
|
|
1020
|
+
async deleteObjects(paths) {
|
|
1021
|
+
return this._channel._deleteObjectsImpl(paths, this._conversationId);
|
|
1022
|
+
}
|
|
1023
|
+
/** @deprecated Use deleteObjects instead. */
|
|
1024
|
+
async deletePaths(paths) {
|
|
1025
|
+
return this.deleteObjects(paths);
|
|
1067
1026
|
}
|
|
1068
1027
|
/** Send a prompt to the AI agent, scoped to this conversation's history. */
|
|
1069
1028
|
async prompt(text, options) {
|