@agentshouse/mdruntime-adapter 0.1.0-cd673d02b6e50 → 0.1.0-cd75dfaf57319

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/actions.d.ts +2 -47
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js +7 -225
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +69 -214
  6. package/dist/discovery.d.ts +18 -5
  7. package/dist/discovery.d.ts.map +1 -1
  8. package/dist/discovery.js +60 -26
  9. package/dist/history.d.ts +12 -0
  10. package/dist/history.d.ts.map +1 -0
  11. package/dist/history.js +92 -0
  12. package/dist/house-model.d.ts +718 -1
  13. package/dist/house-model.d.ts.map +1 -1
  14. package/dist/house-model.js +393 -486
  15. package/dist/index.d.ts +6 -3
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +6 -3
  18. package/dist/model.d.ts +5 -4
  19. package/dist/model.d.ts.map +1 -1
  20. package/dist/model.js +27 -22
  21. package/dist/read.d.ts +11 -44
  22. package/dist/read.d.ts.map +1 -1
  23. package/dist/read.js +25 -174
  24. package/dist/refusal.d.ts +0 -3
  25. package/dist/refusal.d.ts.map +1 -1
  26. package/dist/refusal.js +0 -5
  27. package/dist/room-stream.d.ts +2 -1
  28. package/dist/room-stream.d.ts.map +1 -1
  29. package/dist/room-stream.js +2 -2
  30. package/dist/room-types.d.ts +2 -2
  31. package/dist/room-types.d.ts.map +1 -1
  32. package/dist/room-types.js +7 -9
  33. package/dist/search.d.ts +5 -0
  34. package/dist/search.d.ts.map +1 -0
  35. package/dist/search.js +47 -0
  36. package/dist/site.d.ts.map +1 -1
  37. package/dist/site.js +50 -92
  38. package/dist/space-schema.d.ts +7 -0
  39. package/dist/space-schema.d.ts.map +1 -0
  40. package/dist/space-schema.js +18 -0
  41. package/dist/stream.d.ts +14 -14
  42. package/dist/stream.d.ts.map +1 -1
  43. package/dist/stream.js +169 -424
  44. package/dist/transport.d.ts +44 -35
  45. package/dist/transport.d.ts.map +1 -1
  46. package/dist/transport.js +54 -12
  47. package/dist/upload.d.ts.map +1 -1
  48. package/dist/upload.js +2 -2
  49. package/dist/write.d.ts +2 -1
  50. package/dist/write.d.ts.map +1 -1
  51. package/dist/write.js +8 -23
  52. package/package.json +2 -2
  53. package/dist/gather.d.ts +0 -3
  54. package/dist/gather.d.ts.map +0 -1
  55. package/dist/gather.js +0 -35
package/dist/adapter.js CHANGED
@@ -1,19 +1,20 @@
1
1
  import { stepped } from '@agentshouse/mdruntime';
2
- import { DISCOVER_PREFIXES, capabilities, discoveredRoom, mapDiscovery, parseDiscovery, trackedFrom, } from './discovery.js';
3
- import { streamedModels, viewModels } from './model.js';
4
- import { gathered, selections } from './gather.js';
2
+ import { capabilities, discoveredRoom, mapDiscovery, parseAuthorityChange, parseDiscovery, trackedFrom, } from './discovery.js';
5
3
  import { createSiteAdapter } from './site.js';
6
- import { authorityRoot, bootstrapping, parseEnumeration, parseFileAddress, parseGrant, refreshFrom, viewOf, wholeView, } from './read.js';
4
+ import { authorityRoot, bootstrapping, parseFileAddress, parseGrant, } from './read.js';
7
5
  import { roomStreams } from './room-stream.js';
6
+ import { spaceSchemas } from './space-schema.js';
8
7
  import { sha256Hex } from './digest.js';
9
8
  import { finishedUpload, houseUpload } from './upload.js';
10
9
  import { houseAction } from './actions.js';
11
- import { classifyDoor, classifyRead, discoveryFailure, doorRefusal } from './refusal.js';
12
- import { houseNotifications } from './stream.js';
13
- import { DOOR_BATCH, DOOR_BATCH_UPLOAD, DOOR_BOOTSTRAP, DOOR_DISCOVER, DOOR_ENUMERATE, DOOR_FILES_ATTACH, DOOR_FILES_GET, DOOR_REVISIONS, } from './transport.js';
10
+ import { houseSearch } from './search.js';
11
+ import { classifyDoor, doorRefusal } from './refusal.js';
12
+ import { houseNotifications, } from './stream.js';
13
+ import { houseDoorRoute, } from './transport.js';
14
14
  import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, houseMove, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable, } from './write.js';
15
+ import { HOUSE_TYPED_PATHS } from './house-model.js';
15
16
  import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
16
- import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
17
+ import { followsVersion, logPosition, presented, reachedVersion, roomVersion } from './version.js';
17
18
  const UNCERTAIN = { kind: 'transport-uncertainty' };
18
19
  const UNCERTAIN_READ = { kind: 'transport-uncertainty' };
19
20
  const OCTET_STREAM = 'application/octet-stream';
@@ -51,18 +52,50 @@ export function createAgentsHouseAdapter(options) {
51
52
  if ('site' in options)
52
53
  return createSiteAdapter(options.site, options.snapshot === true);
53
54
  const transport = options.transport;
54
- const notifications = houseNotifications(transport, 'credential');
55
+ const spaces = spaceSchemas();
56
+ const notifications = houseNotifications(transport, 'credential', {
57
+ opened: async (frame) => (frame === null ? null : opened(frame)),
58
+ changed,
59
+ }, spaces);
55
60
  const tracked = new Map();
56
- const handed = new Map();
57
- const rooms = roomStreams('credential');
61
+ const rooms = roomStreams('credential', spaces);
58
62
  const unreused = new Set();
59
- let heldRevisions;
60
63
  let bounds;
61
64
  function declared() {
62
65
  if (bounds === undefined)
63
66
  throw new Error('no Discovery declared the bounds');
64
67
  return bounds;
65
68
  }
69
+ function opened(frame) {
70
+ const document = parseDiscovery(frame);
71
+ if (document === null)
72
+ return null;
73
+ bounds = document.bounds;
74
+ tracked.clear();
75
+ for (const entry of trackedFrom(document))
76
+ tracked.set(entry.locator, entry);
77
+ notifications.track([...tracked.values()]);
78
+ return {
79
+ ...mapDiscovery(document, document.authorities.map((authority) => discoveredRoom(authority)), capabilities(document.actions)),
80
+ member: document.member,
81
+ };
82
+ }
83
+ function changed(frame) {
84
+ const change = parseAuthorityChange(frame);
85
+ if (change === null)
86
+ return null;
87
+ for (const locator of change.left)
88
+ tracked.delete(locator);
89
+ for (const entry of trackedFrom(change))
90
+ tracked.set(entry.locator, entry);
91
+ notifications.track([...tracked.values()]);
92
+ return {
93
+ kind: 'authority-changed',
94
+ rooms: change.authorities.map((authority) => discoveredRoom(authority)),
95
+ left: change.left,
96
+ member: change.member,
97
+ };
98
+ }
66
99
  async function streamedPage(entry, token, held) {
67
100
  const part = await rooms.part(entry, token);
68
101
  if ('kind' in part)
@@ -72,11 +105,6 @@ export function createAgentsHouseAdapter(options) {
72
105
  unreused.add(entry.locator);
73
106
  return UNCERTAIN_READ;
74
107
  }
75
- if (part.first && part.ended)
76
- handed.set(entry.locator, roomVersion(scope));
77
- else
78
- handed.delete(entry.locator);
79
- notifications.reach(entry.authority, scope);
80
108
  return {
81
109
  ...(await stepped(bootstrapping(scope))),
82
110
  ...(part.models === undefined ? {} : { models: part.models }),
@@ -89,7 +117,8 @@ export function createAgentsHouseAdapter(options) {
89
117
  const files = reusing === undefined
90
118
  ? null
91
119
  : await heldFiles(entry.authority, reusing, declared().max_held_files);
92
- const answered = await transport.streamed(DOOR_BOOTSTRAP, {
120
+ const answered = await transport.streamed(houseDoorRoute('bootstrap'), {
121
+ room_ref: entry.authority,
93
122
  prefixes: [authorityRoot(entry.handle)],
94
123
  ...(files === null ? {} : { held: [files] }),
95
124
  }, request.signal ?? new AbortController().signal);
@@ -97,84 +126,12 @@ export function createAgentsHouseAdapter(options) {
97
126
  return classifyDoor(answered.status, answered.body, entry.locator) ?? UNCERTAIN_READ;
98
127
  return rooms.head(entry, answered.room, request.arriving, request.signal);
99
128
  }
100
- async function enumeratedPage(ask, page) {
101
- const answer = await transport.door(DOOR_ENUMERATE, {
102
- prefixes: [authorityRoot(ask.entry.handle)],
103
- positions: [
104
- {
105
- ...presented(ask.entry.authority, { position: page.after, logEpoch: ask.from.logEpoch }),
106
- page: { through: page.through, read: page.read },
107
- },
108
- ],
109
- });
110
- const failure = classifyRead(answer.status, answer.body, ask.entry.locator);
111
- if (failure !== null)
112
- return failure;
113
- const enumeration = parseEnumeration(answer.body, 'credential');
114
- if (enumeration === null)
115
- return UNCERTAIN_READ;
116
- return (viewOf(enumeration, ask.entry) ?? { kind: 'room-not-readable', locator: ask.entry.locator });
117
- }
118
- async function enumeratedRoom(enumeration, ask) {
119
- const first = viewOf(enumeration, ask.entry);
120
- if (first === undefined)
121
- return { kind: 'room-not-readable', locator: ask.entry.locator };
122
- const view = await wholeView(first, (page) => enumeratedPage(ask, page));
123
- if ('kind' in view)
124
- return view;
125
- notifications.reach(ask.entry.authority, view);
126
- const answer = await refreshFrom(view, ask.fromRoomVersion);
127
- if (answer.kind !== 'net-advancement')
128
- return answer;
129
- handed.set(ask.entry.locator, roomVersion(view));
130
- const models = await viewModels(view, ask.entry);
131
- return models === undefined ? answer : { ...answer, models };
132
- }
133
- async function streamed(entry, request, from) {
134
- if (handed.get(entry.locator) !== request.fromRoomVersion)
135
- return null;
136
- const asked = notifications.edited(entry, from);
137
- const kept = asked.length === 0 || heldRevisions === undefined
138
- ? new Map()
139
- : await heldRevisions(entry.locator, asked);
140
- const advanced = await stepped(notifications.advance(entry, from, (path, revision) => kept.get(path) === revision));
141
- if (advanced === null)
142
- return null;
143
- handed.set(entry.locator, advanced.page.roomVersion);
144
- const models = await streamedModels(advanced.schemas, entry, 'credential');
145
- return models === undefined ? advanced.page : { ...advanced.page, models };
146
- }
147
129
  function held(rooms) {
148
- const kept = rooms.flatMap((room) => {
130
+ notifications.send(rooms.flatMap((room) => {
149
131
  const entry = tracked.get(room.locator);
150
132
  const at = logPosition(room.roomVersion);
151
- if (entry === undefined || at === null)
152
- return [];
153
- handed.set(room.locator, room.roomVersion);
154
- notifications.reach(entry.authority, at);
155
- return [presented(entry.authority, at)];
156
- });
157
- notifications.send(kept);
158
- }
159
- async function adoptedMove(entry, into, outcome) {
160
- if (outcome.kind === 'accepted' && outcome.destination !== undefined) {
161
- await adopted(into, { kind: 'accepted', ...outcome.destination });
162
- }
163
- return adopted(entry, outcome);
164
- }
165
- async function adopted(entry, outcome) {
166
- if (outcome.kind !== 'accepted')
167
- return outcome;
168
- const held = handed.get(entry.locator);
169
- if (held === undefined)
170
- return outcome;
171
- const follows = followsVersion(held, outcome.roomVersion);
172
- if (follows)
173
- handed.set(entry.locator, outcome.roomVersion);
174
- const at = logPosition(outcome.roomVersion);
175
- if (follows && at !== null)
176
- notifications.reach(entry.authority, at);
177
- return outcome;
133
+ return entry === undefined || at === null ? [] : [presented(entry.authority, at)];
134
+ }));
178
135
  }
179
136
  function authorityFor(locator) {
180
137
  return tracked.get(locator);
@@ -193,60 +150,18 @@ export function createAgentsHouseAdapter(options) {
193
150
  return result;
194
151
  return { ...result, at: { locator, roomVersion: roomVersion({ position, logEpoch }) } };
195
152
  }
196
- function layered(asks) {
197
- const depths = new Map();
198
- const layers = [];
199
- for (const ask of asks) {
200
- const depth = depths.get(ask.ask.entry.authority) ?? 0;
201
- depths.set(ask.ask.entry.authority, depth + 1);
202
- (layers[depth] ??= []).push(ask);
203
- }
204
- return layers;
205
- }
206
- async function enumerated(asks) {
207
- const answers = [];
208
- const parts = layered(asks.map((ask, index) => ({ ask, index }))).flatMap((layer) => selections(layer, declared().max_prefixes));
209
- for (const part of parts) {
210
- let open = [...part];
211
- while (open.length > 0) {
212
- const answer = await transport.door(DOOR_ENUMERATE, {
213
- prefixes: open.map(({ ask }) => authorityRoot(ask.entry.handle)),
214
- positions: open.map(({ ask }) => presented(ask.entry.authority, ask.from)),
215
- });
216
- const classified = open.map(({ ask }) => classifyRead(answer.status, answer.body, ask.entry.locator));
217
- if (classified[0]?.kind === 'beyond-horizon') {
218
- const named = doorRefusal(answer.body)?.fields.authority;
219
- const expired = open.filter(({ ask }) => ask.entry.authority === named);
220
- const answered = expired.length === 0 ? UNCERTAIN_READ : { kind: 'beyond-horizon' };
221
- const gone = expired.length === 0 ? open : expired;
222
- for (const ask of gone)
223
- answers[ask.index] = answered;
224
- open = open.filter((ask) => !gone.includes(ask));
225
- continue;
226
- }
227
- const enumeration = classified[0] === null ? parseEnumeration(answer.body, 'credential') : null;
228
- for (const [answerIndex, { ask, index }] of open.entries()) {
229
- const failure = classified[answerIndex];
230
- if (failure !== null && failure !== undefined) {
231
- answers[index] = failure;
232
- continue;
233
- }
234
- answers[index] =
235
- enumeration === null ? UNCERTAIN_READ : await enumeratedRoom(enumeration, ask);
236
- }
237
- open = [];
238
- }
239
- }
240
- return answers;
241
- }
242
- const enumerateTogether = gathered(enumerated);
243
153
  async function uploaded(head, changes, delta, bytes, entry, handed, keep) {
244
154
  const paths = batchPaths(changes);
245
155
  const sha256 = await deltaDigest(delta);
246
156
  if (handed !== undefined && handed.sha256 === sha256) {
247
157
  return { body: { ...head, paths, upload: handed, runtime: notifications.runtime } };
248
158
  }
249
- const minted = await transport.door(DOOR_BATCH_UPLOAD, { ...head, paths, bytes, sha256 });
159
+ const minted = await transport.door(houseDoorRoute('batch-upload'), {
160
+ ...head,
161
+ paths,
162
+ bytes,
163
+ sha256,
164
+ });
250
165
  if (minted.status !== 200) {
251
166
  return {
252
167
  outcome: await stepped(mutationOutcome(minted.status, minted.body, entry.locator, entry.handle)),
@@ -294,11 +209,11 @@ export function createAgentsHouseAdapter(options) {
294
209
  : { body: inline };
295
210
  if ('outcome' in prepared)
296
211
  return prepared.outcome;
297
- const answer = await transport.door(DOOR_BATCH, prepared.body);
212
+ const answer = await transport.door(houseDoorRoute('batch'), prepared.body);
298
213
  const stagedFiles = await staged(answer, request);
299
214
  if (stagedFiles === false)
300
215
  return UNCERTAIN;
301
- const settled = stagedFiles === null ? answer : await transport.door(DOOR_BATCH, prepared.body);
216
+ const settled = stagedFiles === null ? answer : await transport.door(houseDoorRoute('batch'), prepared.body);
302
217
  if (stagedFiles === true && (await staged(settled, request)) !== null)
303
218
  return UNCERTAIN;
304
219
  return stepped(mutationOutcome(settled.status, settled.body, entry.locator, entry.handle, into === undefined
@@ -366,7 +281,7 @@ export function createAgentsHouseAdapter(options) {
366
281
  const entry = authorityFor(request.locator);
367
282
  if (entry === undefined)
368
283
  return null;
369
- return () => transport.door(DOOR_FILES_GET, {
284
+ return () => transport.door(houseDoorRoute('files/get'), {
370
285
  room_ref: entry.authority,
371
286
  path: request.path,
372
287
  revision: request.revision,
@@ -375,49 +290,10 @@ export function createAgentsHouseAdapter(options) {
375
290
  return {
376
291
  roomTypes: HOUSE_ROOM_TYPES,
377
292
  nameableRoomTypes: HOUSE_NAMEABLE_ROOM_TYPES,
293
+ typedPaths: HOUSE_TYPED_PATHS,
378
294
  async authorize() {
379
295
  return options.authorize();
380
296
  },
381
- async discover(_authorization, scope) {
382
- const answer = await transport.door(DOOR_DISCOVER, {
383
- prefixes: [...DISCOVER_PREFIXES],
384
- ...(scope === undefined ? {} : { rooms: scope.authorities }),
385
- });
386
- const failed = discoveryFailure(answer.status, answer.body);
387
- if (failed !== null)
388
- return failed;
389
- const document = parseDiscovery(answer.body);
390
- if (document === null)
391
- return { kind: 'transport-uncertainty' };
392
- bounds = document.bounds;
393
- const entries = trackedFrom(document);
394
- const covered = scope === undefined
395
- ? null
396
- : [
397
- ...new Set([
398
- ...[...tracked.values()]
399
- .filter((entry) => scope.authorities.includes(entry.authority))
400
- .map((entry) => entry.locator),
401
- ...entries.map((entry) => entry.locator),
402
- ]),
403
- ];
404
- if (covered === null)
405
- tracked.clear();
406
- else
407
- for (const locator of covered)
408
- tracked.delete(locator);
409
- for (const entry of entries)
410
- tracked.set(entry.locator, entry);
411
- for (const locator of handed.keys())
412
- if (!tracked.has(locator))
413
- handed.delete(locator);
414
- notifications.track([...tracked.values()]);
415
- return {
416
- ...mapDiscovery(document, document.authorities.map((authority) => discoveredRoom(authority)), capabilities(document.actions, [...tracked.values()])),
417
- member: document.member,
418
- ...(covered === null ? {} : { covered }),
419
- };
420
- },
421
297
  async bootstrap(_authorization, request) {
422
298
  const entry = authorityFor(request.locator);
423
299
  if (entry === undefined)
@@ -426,20 +302,6 @@ export function createAgentsHouseAdapter(options) {
426
302
  ? openedRoom(entry, request)
427
303
  : streamedPage(entry, request.pageToken, request.held);
428
304
  },
429
- async refresh(_authorization, request) {
430
- const entry = authorityFor(request.locator);
431
- if (entry === undefined)
432
- return { kind: 'room-not-readable', locator: request.locator };
433
- if (request.pageToken !== undefined)
434
- return { kind: 'transport-uncertainty' };
435
- const from = logPosition(request.fromRoomVersion);
436
- if (from === null)
437
- return { kind: 'beyond-horizon' };
438
- const answered = await streamed(entry, request, from);
439
- if (answered !== null)
440
- return answered;
441
- return enumerateTogether({ entry, from, fromRoomVersion: request.fromRoomVersion });
442
- },
443
305
  async mutate(_authorization, request, keep) {
444
306
  const entry = authorityFor(request.locator);
445
307
  if (entry === undefined)
@@ -455,22 +317,21 @@ export function createAgentsHouseAdapter(options) {
455
317
  : houseMove(batch, entry.handle, into.handle);
456
318
  if (mapped.kind === 'unmapped')
457
319
  return rejectedMapping(mapped);
458
- const head = operationHead(batch);
320
+ const head = operationHead(batch, entry.authority);
459
321
  const delta = deltaBody(mapped.changes);
460
322
  const bytes = deltaBytes(delta);
461
323
  const handed = request.upload;
462
324
  const answer = (upload) => submit(request, head, mapped.changes, delta, bytes, entry, upload, keep, into);
463
- const settle = (outcome) => into === undefined ? adopted(entry, outcome) : adoptedMove(entry, into, outcome);
464
325
  const outcome = await answer(handed);
465
326
  if (handed === undefined || !lapsedGrant(outcome))
466
- return settle(outcome);
467
- return settle(await answer(undefined));
327
+ return outcome;
328
+ return answer(undefined);
468
329
  },
469
330
  async history(_authorization, request) {
470
331
  const entry = authorityFor(request.locator);
471
332
  if (entry === undefined)
472
333
  return { kind: 'room-not-readable', locator: request.locator };
473
- const answer = await transport.door(DOOR_REVISIONS, revisionBody({
334
+ const answer = await transport.door(houseDoorRoute('revisions'), revisionBody({
474
335
  path: request.path,
475
336
  handle: entry.handle,
476
337
  ...(request.revision === undefined ? {} : { revision: request.revision }),
@@ -497,7 +358,7 @@ export function createAgentsHouseAdapter(options) {
497
358
  const entry = authorityFor(request.locator);
498
359
  if (entry === undefined)
499
360
  return { kind: 'room-not-readable', locator: request.locator };
500
- const declared = await transport.door(DOOR_FILES_ATTACH, {
361
+ const declared = await transport.door(houseDoorRoute('files/attach'), {
501
362
  room_ref: entry.authority,
502
363
  name: request.name,
503
364
  bytes: request.byteLength,
@@ -531,18 +392,12 @@ export function createAgentsHouseAdapter(options) {
531
392
  async action(_authorization, request) {
532
393
  return withAt(await houseAction(transport, request));
533
394
  },
395
+ search(_authorization, request) {
396
+ return houseSearch(transport, [...tracked.values()], request);
397
+ },
534
398
  roomStream: {
535
399
  hold: held,
536
- reopen: notifications.reopen,
537
- observe(notify, receipts, revisions) {
538
- heldRevisions = revisions;
539
- return notifications.observe(notify, receipts);
540
- },
541
- published(locator, roomVersion) {
542
- const at = logPosition(roomVersion);
543
- if (at !== null)
544
- notifications.published(locator, at);
545
- },
400
+ observe: notifications.observe,
546
401
  },
547
402
  conversations: notifications.conversations,
548
403
  serviceMode: notifications.serviceMode,
@@ -1,7 +1,6 @@
1
1
  import type { Capability, DiscoveredRoom, Discovery, Member, ProviderLimit, Retention } from '@agentshouse/mdruntime';
2
2
  import { type LogPosition } from './version.js';
3
3
  export declare const PROVIDER_ACTIONS = "provider-actions";
4
- export declare const DISCOVER_PREFIXES: readonly string[];
5
4
  export type HouseBounds = {
6
5
  max_authored_file_bytes: number;
7
6
  max_batch_operations: number;
@@ -15,12 +14,11 @@ export type HouseBounds = {
15
14
  max_prefixes: number;
16
15
  max_held_files: number;
17
16
  change_retention_seconds: number;
18
- operation_retention_seconds: number;
19
17
  max_move_documents?: number;
20
18
  };
21
19
  export type HouseOperations = {
22
20
  write: readonly string[];
23
- delete: readonly string[];
21
+ erase: readonly string[];
24
22
  };
25
23
  export type HouseAccessLevel = 'search' | 'open' | 'keep';
26
24
  export type HouseAuthority = LogPosition & {
@@ -40,6 +38,11 @@ export type HouseDiscoveryDocument = {
40
38
  authorities: readonly HouseAuthority[];
41
39
  actions: readonly string[];
42
40
  };
41
+ export type HouseAuthorityChange = {
42
+ member: Member;
43
+ authorities: readonly HouseAuthority[];
44
+ left: readonly string[];
45
+ };
43
46
  export type TrackedAuthority = LogPosition & {
44
47
  locator: string;
45
48
  authority: string;
@@ -56,14 +59,24 @@ export type HouseSiteDiscovery = {
56
59
  bounds: HouseBounds;
57
60
  authorities: readonly HouseSiteAuthority[];
58
61
  };
62
+ type RoomOwn = 'room_ref' | 'room_handle' | 'name' | 'position';
63
+ type Folded<A extends Record<RoomOwn, unknown>> = {
64
+ readonly shapes: readonly Omit<A, RoomOwn>[];
65
+ readonly rooms: readonly (Pick<A, RoomOwn> & {
66
+ readonly shape: number;
67
+ })[];
68
+ };
69
+ export declare function foldedAuthorities<A extends Record<RoomOwn, unknown>>(authorities: readonly A[]): Folded<A>;
59
70
  export declare function parseDiscovery(body: unknown): HouseDiscoveryDocument | null;
71
+ export declare function parseAuthorityChange(body: unknown): HouseAuthorityChange | null;
60
72
  export declare function parseSiteDiscovery(body: unknown): HouseSiteDiscovery | null;
61
73
  export declare function siteTracked(document: HouseSiteDiscovery): TrackedAuthority[];
62
- export declare function trackedFrom(document: HouseDiscoveryDocument): TrackedAuthority[];
74
+ export declare function trackedFrom(document: Pick<HouseDiscoveryDocument, 'authorities'>): TrackedAuthority[];
63
75
  export declare function providerLimits(bounds: HouseBounds): readonly ProviderLimit[];
64
76
  export declare function declaredRetention(bounds: HouseBounds): Retention;
65
- export declare function capabilities(actions: HouseDiscoveryDocument['actions'], rooms: readonly Pick<TrackedAuthority, 'authority' | 'handle'>[]): readonly Capability[];
77
+ export declare function capabilities(actions: HouseDiscoveryDocument['actions']): readonly Capability[];
66
78
  export declare function siteCapabilities(): readonly Capability[];
67
79
  export declare function discoveredRoom(authority: HouseAuthority): DiscoveredRoom;
68
80
  export declare function mapDiscovery(document: Pick<HouseDiscoveryDocument, 'bounds'>, rooms: readonly DiscoveredRoom[], declared: readonly Capability[]): Discovery;
81
+ export {};
69
82
  //# sourceMappingURL=discovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
package/dist/discovery.js CHANGED
@@ -1,8 +1,7 @@
1
- import { declaredActions, houseConversationAgents, SITE_SUBMIT } from './actions.js';
1
+ import { declaredActions } from './actions.js';
2
+ import { SITE_SUBMISSION } from './transport.js';
2
3
  import { readPosition, roomVersion } from './version.js';
3
4
  export const PROVIDER_ACTIONS = 'provider-actions';
4
- export const DISCOVER_PREFIXES = ['/'];
5
- const PRIVATE_HANDLE = 'private';
6
5
  const BOUND_KEYS = [
7
6
  'max_authored_file_bytes',
8
7
  'max_batch_operations',
@@ -16,9 +15,8 @@ const BOUND_KEYS = [
16
15
  'max_prefixes',
17
16
  'max_held_files',
18
17
  'change_retention_seconds',
19
- 'operation_retention_seconds',
20
18
  ];
21
- const OPERATION_KEYS = ['write', 'delete'];
19
+ const OPERATION_KEYS = ['write', 'erase'];
22
20
  const ACCESS_LEVELS = ['search', 'open', 'keep'];
23
21
  function stringList(value) {
24
22
  if (!Array.isArray(value))
@@ -111,6 +109,47 @@ function parseAuthority(value) {
111
109
  ...at,
112
110
  };
113
111
  }
112
+ function parseAuthorities(value) {
113
+ if (!Array.isArray(value))
114
+ return null;
115
+ const authorities = [];
116
+ for (const entry of value) {
117
+ const authority = parseAuthority(entry);
118
+ if (authority === null)
119
+ return null;
120
+ authorities.push(authority);
121
+ }
122
+ return authorities;
123
+ }
124
+ export function foldedAuthorities(authorities) {
125
+ const shapes = [];
126
+ const known = new Map();
127
+ const rooms = authorities.map(({ room_ref, room_handle, name, position, ...shape }) => {
128
+ const key = JSON.stringify(shape);
129
+ let held = known.get(key);
130
+ if (held === undefined) {
131
+ held = shapes.push(shape) - 1;
132
+ known.set(key, held);
133
+ }
134
+ return { room_ref, room_handle, name, position, shape: held };
135
+ });
136
+ return { shapes, rooms };
137
+ }
138
+ function unfolded(shapes, rooms) {
139
+ if (!Array.isArray(shapes) || !Array.isArray(rooms))
140
+ return null;
141
+ const authorities = [];
142
+ for (const room of rooms) {
143
+ if (typeof room !== 'object' || room === null)
144
+ return null;
145
+ const { shape, ...own } = room;
146
+ const held = typeof shape === 'number' ? shapes[shape] : undefined;
147
+ if (typeof held !== 'object' || held === null)
148
+ return null;
149
+ authorities.push({ ...held, ...own });
150
+ }
151
+ return authorities;
152
+ }
114
153
  export function parseDiscovery(body) {
115
154
  if (typeof body !== 'object' || body === null)
116
155
  return null;
@@ -126,16 +165,19 @@ export function parseDiscovery(body) {
126
165
  new Set(actions).size !== actions.length ||
127
166
  actions.some((name) => name.length === 0))
128
167
  return null;
129
- if (!Array.isArray(held.authorities))
168
+ const authorities = parseAuthorities(unfolded(held.shapes, held.rooms));
169
+ return authorities === null ? null : { member, bounds, authorities, actions };
170
+ }
171
+ export function parseAuthorityChange(body) {
172
+ if (typeof body !== 'object' || body === null)
130
173
  return null;
131
- const authorities = [];
132
- for (const entry of held.authorities) {
133
- const authority = parseAuthority(entry);
134
- if (authority === null)
135
- return null;
136
- authorities.push(authority);
137
- }
138
- return { member, bounds, authorities, actions };
174
+ const held = body;
175
+ const member = parseMember(held.member);
176
+ const authorities = parseAuthorities(held.authorities);
177
+ const left = stringList(held.left);
178
+ if (member === null || authorities === null || left === null)
179
+ return null;
180
+ return { member, authorities, left };
139
181
  }
140
182
  function parseSiteAuthority(value) {
141
183
  if (typeof value !== 'object' || value === null)
@@ -216,25 +258,17 @@ export function providerLimits(bounds) {
216
258
  export function declaredRetention(bounds) {
217
259
  return {
218
260
  history: { kind: 'no-declared-time-bound' },
219
- outcome: bounds.operation_retention_seconds,
220
261
  refreshHorizon: bounds.change_retention_seconds,
221
262
  };
222
263
  }
223
- export function capabilities(actions, rooms) {
224
- const own = rooms.find((room) => room.handle === PRIVATE_HANDLE);
225
- return [
226
- {
227
- name: PROVIDER_ACTIONS,
228
- actions: declaredActions(actions),
229
- ...(own === undefined ? {} : { conversationAgents: houseConversationAgents(own.authority) }),
230
- },
231
- ];
264
+ export function capabilities(actions) {
265
+ return [{ name: PROVIDER_ACTIONS, actions: declaredActions(actions) }];
232
266
  }
233
267
  export function siteCapabilities() {
234
268
  return [
235
269
  {
236
270
  name: PROVIDER_ACTIONS,
237
- actions: [{ name: SITE_SUBMIT, inputShape: {}, resultKind: 'house' }],
271
+ actions: [{ name: SITE_SUBMISSION, inputShape: {}, resultKind: 'house' }],
238
272
  },
239
273
  ];
240
274
  }
@@ -247,7 +281,7 @@ export function discoveredRoom(authority) {
247
281
  roomVersion: roomVersion(authority),
248
282
  operations: {
249
283
  write: [...authority.operations.write],
250
- delete: [...authority.operations.delete],
284
+ erase: [...authority.operations.erase],
251
285
  },
252
286
  replica: {
253
287
  selection: locator,
@@ -0,0 +1,12 @@
1
+ import type { AcceptedMessage, ActionResult, ConversationHistoryRequest } from '@agentshouse/mdruntime';
2
+ import { type HouseDoor } from './transport.js';
3
+ export declare const HISTORY_PAGE = 100;
4
+ type HistoryCursor = {
5
+ accepted_at: string;
6
+ message_id: string;
7
+ };
8
+ export declare function cursorPosition(cursor: HistoryCursor): string;
9
+ export declare function acceptedMessage(entry: unknown): AcceptedMessage | null;
10
+ export declare function houseHistory(transport: HouseDoor, request: ConversationHistoryRequest): Promise<ActionResult>;
11
+ export {};
12
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAGZ,0BAA0B,EAC3B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhE,eAAO,MAAM,YAAY,MAAM,CAAC;AAIhC,KAAK,aAAa,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAkBjE,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAE5D;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAUtE;AA8BD,wBAAsB,YAAY,CAChC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,YAAY,CAAC,CAqBvB"}