@agentshouse/mdruntime-adapter 0.1.0-cf41d9210cb6b → 0.1.0-cf75412975d5b

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 (52) hide show
  1. package/dist/actions.d.ts +2 -52
  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 +75 -214
  6. package/dist/discovery.d.ts +17 -3
  7. package/dist/discovery.d.ts.map +1 -1
  8. package/dist/discovery.js +58 -22
  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 +910 -1
  13. package/dist/house-model.d.ts.map +1 -1
  14. package/dist/house-model.js +496 -489
  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 +1 -2
  19. package/dist/model.d.ts.map +1 -1
  20. package/dist/model.js +0 -17
  21. package/dist/read.d.ts +5 -44
  22. package/dist/read.d.ts.map +1 -1
  23. package/dist/read.js +30 -175
  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 +1 -0
  28. package/dist/room-stream.d.ts.map +1 -1
  29. package/dist/room-stream.js +23 -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 +6 -6
  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 +54 -90
  38. package/dist/stream.d.ts +13 -14
  39. package/dist/stream.d.ts.map +1 -1
  40. package/dist/stream.js +168 -429
  41. package/dist/transport.d.ts +38 -34
  42. package/dist/transport.d.ts.map +1 -1
  43. package/dist/transport.js +54 -12
  44. package/dist/upload.d.ts.map +1 -1
  45. package/dist/upload.js +2 -2
  46. package/dist/write.d.ts +2 -1
  47. package/dist/write.d.ts.map +1 -1
  48. package/dist/write.js +7 -17
  49. package/package.json +2 -2
  50. package/dist/gather.d.ts +0 -3
  51. package/dist/gather.d.ts.map +0 -1
  52. package/dist/gather.js +0 -35
package/dist/adapter.js CHANGED
@@ -1,19 +1,19 @@
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';
8
6
  import { sha256Hex } from './digest.js';
9
7
  import { finishedUpload, houseUpload } from './upload.js';
10
8
  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';
9
+ import { houseSearch } from './search.js';
10
+ import { classifyDoor, doorRefusal } from './refusal.js';
11
+ import { houseNotifications, } from './stream.js';
12
+ import { houseDoorRoute, } from './transport.js';
14
13
  import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, houseMove, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable, } from './write.js';
14
+ import { HOUSE_TYPED_PATHS } from './house-model.js';
15
15
  import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
16
- import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
16
+ import { followsVersion, logPosition, presented, reachedVersion, roomVersion } from './version.js';
17
17
  const UNCERTAIN = { kind: 'transport-uncertainty' };
18
18
  const UNCERTAIN_READ = { kind: 'transport-uncertainty' };
19
19
  const OCTET_STREAM = 'application/octet-stream';
@@ -30,7 +30,7 @@ async function heldFiles(authority, held, bound) {
30
30
  async function reused(scope, held) {
31
31
  const sent = new Set(scope.contents.map((entry) => entry.path));
32
32
  const contents = [...scope.contents];
33
- const asked = scope.files.filter((file) => file.binary === undefined && !sent.has(file.path));
33
+ const asked = scope.files.filter((file) => file.binary === undefined && file.outline === undefined && !sent.has(file.path));
34
34
  if (asked.length === 0)
35
35
  return scope;
36
36
  if (held === undefined)
@@ -51,18 +51,49 @@ export function createAgentsHouseAdapter(options) {
51
51
  if ('site' in options)
52
52
  return createSiteAdapter(options.site, options.snapshot === true);
53
53
  const transport = options.transport;
54
- const notifications = houseNotifications(transport, 'credential');
54
+ const notifications = houseNotifications(transport, 'credential', {
55
+ opened: async (frame) => (frame === null ? null : opened(frame)),
56
+ changed,
57
+ });
55
58
  const tracked = new Map();
56
- const handed = new Map();
57
59
  const rooms = roomStreams('credential');
58
60
  const unreused = new Set();
59
- let heldRevisions;
60
61
  let bounds;
61
62
  function declared() {
62
63
  if (bounds === undefined)
63
64
  throw new Error('no Discovery declared the bounds');
64
65
  return bounds;
65
66
  }
67
+ function opened(frame) {
68
+ const document = parseDiscovery(frame);
69
+ if (document === null)
70
+ return null;
71
+ bounds = document.bounds;
72
+ tracked.clear();
73
+ for (const entry of trackedFrom(document))
74
+ tracked.set(entry.locator, entry);
75
+ notifications.track([...tracked.values()]);
76
+ return {
77
+ ...mapDiscovery(document, document.authorities.map((authority) => discoveredRoom(authority)), capabilities(document.actions)),
78
+ member: document.member,
79
+ };
80
+ }
81
+ function changed(frame) {
82
+ const change = parseAuthorityChange(frame);
83
+ if (change === null)
84
+ return null;
85
+ for (const locator of change.left)
86
+ tracked.delete(locator);
87
+ for (const entry of trackedFrom(change))
88
+ tracked.set(entry.locator, entry);
89
+ notifications.track([...tracked.values()]);
90
+ return {
91
+ kind: 'authority-changed',
92
+ rooms: change.authorities.map((authority) => discoveredRoom(authority)),
93
+ left: change.left,
94
+ member: change.member,
95
+ };
96
+ }
66
97
  async function streamedPage(entry, token, held) {
67
98
  const part = await rooms.part(entry, token);
68
99
  if ('kind' in part)
@@ -72,11 +103,6 @@ export function createAgentsHouseAdapter(options) {
72
103
  unreused.add(entry.locator);
73
104
  return UNCERTAIN_READ;
74
105
  }
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
106
  return {
81
107
  ...(await stepped(bootstrapping(scope))),
82
108
  ...(part.models === undefined ? {} : { models: part.models }),
@@ -84,12 +110,19 @@ export function createAgentsHouseAdapter(options) {
84
110
  bytes: part.bytes,
85
111
  };
86
112
  }
113
+ async function namedDocument(entry, path, signal) {
114
+ const answered = await transport.streamed(houseDoorRoute('bootstrap'), { room_ref: entry.authority, prefixes: [`${authorityRoot(entry.handle)}/${path}`] }, signal ?? new AbortController().signal);
115
+ if (answered.room === null)
116
+ return classifyDoor(answered.status, answered.body, entry.locator) ?? UNCERTAIN_READ;
117
+ return rooms.named(entry, answered.room, signal);
118
+ }
87
119
  async function openedRoom(entry, request) {
88
120
  const reusing = unreused.delete(entry.locator) ? undefined : request.held;
89
121
  const files = reusing === undefined
90
122
  ? null
91
123
  : await heldFiles(entry.authority, reusing, declared().max_held_files);
92
- const answered = await transport.streamed(DOOR_BOOTSTRAP, {
124
+ const answered = await transport.streamed(houseDoorRoute('bootstrap'), {
125
+ room_ref: entry.authority,
93
126
  prefixes: [authorityRoot(entry.handle)],
94
127
  ...(files === null ? {} : { held: [files] }),
95
128
  }, request.signal ?? new AbortController().signal);
@@ -97,84 +130,12 @@ export function createAgentsHouseAdapter(options) {
97
130
  return classifyDoor(answered.status, answered.body, entry.locator) ?? UNCERTAIN_READ;
98
131
  return rooms.head(entry, answered.room, request.arriving, request.signal);
99
132
  }
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
133
  function held(rooms) {
148
- const kept = rooms.flatMap((room) => {
134
+ notifications.send(rooms.flatMap((room) => {
149
135
  const entry = tracked.get(room.locator);
150
136
  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;
137
+ return entry === undefined || at === null ? [] : [presented(entry.authority, at)];
138
+ }));
178
139
  }
179
140
  function authorityFor(locator) {
180
141
  return tracked.get(locator);
@@ -193,60 +154,18 @@ export function createAgentsHouseAdapter(options) {
193
154
  return result;
194
155
  return { ...result, at: { locator, roomVersion: roomVersion({ position, logEpoch }) } };
195
156
  }
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
157
  async function uploaded(head, changes, delta, bytes, entry, handed, keep) {
244
158
  const paths = batchPaths(changes);
245
159
  const sha256 = await deltaDigest(delta);
246
160
  if (handed !== undefined && handed.sha256 === sha256) {
247
161
  return { body: { ...head, paths, upload: handed, runtime: notifications.runtime } };
248
162
  }
249
- const minted = await transport.door(DOOR_BATCH_UPLOAD, { ...head, paths, bytes, sha256 });
163
+ const minted = await transport.door(houseDoorRoute('batch-upload'), {
164
+ ...head,
165
+ paths,
166
+ bytes,
167
+ sha256,
168
+ });
250
169
  if (minted.status !== 200) {
251
170
  return {
252
171
  outcome: await stepped(mutationOutcome(minted.status, minted.body, entry.locator, entry.handle)),
@@ -294,11 +213,11 @@ export function createAgentsHouseAdapter(options) {
294
213
  : { body: inline };
295
214
  if ('outcome' in prepared)
296
215
  return prepared.outcome;
297
- const answer = await transport.door(DOOR_BATCH, prepared.body);
216
+ const answer = await transport.door(houseDoorRoute('batch'), prepared.body);
298
217
  const stagedFiles = await staged(answer, request);
299
218
  if (stagedFiles === false)
300
219
  return UNCERTAIN;
301
- const settled = stagedFiles === null ? answer : await transport.door(DOOR_BATCH, prepared.body);
220
+ const settled = stagedFiles === null ? answer : await transport.door(houseDoorRoute('batch'), prepared.body);
302
221
  if (stagedFiles === true && (await staged(settled, request)) !== null)
303
222
  return UNCERTAIN;
304
223
  return stepped(mutationOutcome(settled.status, settled.body, entry.locator, entry.handle, into === undefined
@@ -366,7 +285,7 @@ export function createAgentsHouseAdapter(options) {
366
285
  const entry = authorityFor(request.locator);
367
286
  if (entry === undefined)
368
287
  return null;
369
- return () => transport.door(DOOR_FILES_GET, {
288
+ return () => transport.door(houseDoorRoute('files/get'), {
370
289
  room_ref: entry.authority,
371
290
  path: request.path,
372
291
  revision: request.revision,
@@ -375,71 +294,20 @@ export function createAgentsHouseAdapter(options) {
375
294
  return {
376
295
  roomTypes: HOUSE_ROOM_TYPES,
377
296
  nameableRoomTypes: HOUSE_NAMEABLE_ROOM_TYPES,
297
+ typedPaths: HOUSE_TYPED_PATHS,
378
298
  async authorize() {
379
299
  return options.authorize();
380
300
  },
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
301
  async bootstrap(_authorization, request) {
422
302
  const entry = authorityFor(request.locator);
423
303
  if (entry === undefined)
424
304
  return { kind: 'room-not-readable', locator: request.locator };
305
+ if (request.path !== undefined)
306
+ return namedDocument(entry, request.path, request.signal);
425
307
  return request.pageToken === undefined
426
308
  ? openedRoom(entry, request)
427
309
  : streamedPage(entry, request.pageToken, request.held);
428
310
  },
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
311
  async mutate(_authorization, request, keep) {
444
312
  const entry = authorityFor(request.locator);
445
313
  if (entry === undefined)
@@ -455,22 +323,21 @@ export function createAgentsHouseAdapter(options) {
455
323
  : houseMove(batch, entry.handle, into.handle);
456
324
  if (mapped.kind === 'unmapped')
457
325
  return rejectedMapping(mapped);
458
- const head = operationHead(batch);
326
+ const head = operationHead(batch, entry.authority);
459
327
  const delta = deltaBody(mapped.changes);
460
328
  const bytes = deltaBytes(delta);
461
329
  const handed = request.upload;
462
330
  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
331
  const outcome = await answer(handed);
465
332
  if (handed === undefined || !lapsedGrant(outcome))
466
- return settle(outcome);
467
- return settle(await answer(undefined));
333
+ return outcome;
334
+ return answer(undefined);
468
335
  },
469
336
  async history(_authorization, request) {
470
337
  const entry = authorityFor(request.locator);
471
338
  if (entry === undefined)
472
339
  return { kind: 'room-not-readable', locator: request.locator };
473
- const answer = await transport.door(DOOR_REVISIONS, revisionBody({
340
+ const answer = await transport.door(houseDoorRoute('revisions'), revisionBody({
474
341
  path: request.path,
475
342
  handle: entry.handle,
476
343
  ...(request.revision === undefined ? {} : { revision: request.revision }),
@@ -497,7 +364,7 @@ export function createAgentsHouseAdapter(options) {
497
364
  const entry = authorityFor(request.locator);
498
365
  if (entry === undefined)
499
366
  return { kind: 'room-not-readable', locator: request.locator };
500
- const declared = await transport.door(DOOR_FILES_ATTACH, {
367
+ const declared = await transport.door(houseDoorRoute('files/attach'), {
501
368
  room_ref: entry.authority,
502
369
  name: request.name,
503
370
  bytes: request.byteLength,
@@ -531,18 +398,12 @@ export function createAgentsHouseAdapter(options) {
531
398
  async action(_authorization, request) {
532
399
  return withAt(await houseAction(transport, request));
533
400
  },
401
+ search(_authorization, request) {
402
+ return houseSearch(transport, [...tracked.values()], request);
403
+ },
534
404
  roomStream: {
535
405
  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
- },
406
+ observe: notifications.observe,
546
407
  },
547
408
  conversations: notifications.conversations,
548
409
  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;
@@ -40,6 +39,11 @@ export type HouseDiscoveryDocument = {
40
39
  authorities: readonly HouseAuthority[];
41
40
  actions: readonly string[];
42
41
  };
42
+ export type HouseAuthorityChange = {
43
+ member: Member;
44
+ authorities: readonly HouseAuthority[];
45
+ left: readonly string[];
46
+ };
43
47
  export type TrackedAuthority = LogPosition & {
44
48
  locator: string;
45
49
  authority: string;
@@ -56,14 +60,24 @@ export type HouseSiteDiscovery = {
56
60
  bounds: HouseBounds;
57
61
  authorities: readonly HouseSiteAuthority[];
58
62
  };
63
+ type RoomOwn = 'room_ref' | 'room_handle' | 'name' | 'position';
64
+ type Folded<A extends Record<RoomOwn, unknown>> = {
65
+ readonly shapes: readonly Omit<A, RoomOwn>[];
66
+ readonly rooms: readonly (Pick<A, RoomOwn> & {
67
+ readonly shape: number;
68
+ })[];
69
+ };
70
+ export declare function foldedAuthorities<A extends Record<RoomOwn, unknown>>(authorities: readonly A[]): Folded<A>;
59
71
  export declare function parseDiscovery(body: unknown): HouseDiscoveryDocument | null;
72
+ export declare function parseAuthorityChange(body: unknown): HouseAuthorityChange | null;
60
73
  export declare function parseSiteDiscovery(body: unknown): HouseSiteDiscovery | null;
61
74
  export declare function siteTracked(document: HouseSiteDiscovery): TrackedAuthority[];
62
- export declare function trackedFrom(document: HouseDiscoveryDocument): TrackedAuthority[];
75
+ export declare function trackedFrom(document: Pick<HouseDiscoveryDocument, 'authorities'>): TrackedAuthority[];
63
76
  export declare function providerLimits(bounds: HouseBounds): readonly ProviderLimit[];
64
77
  export declare function declaredRetention(bounds: HouseBounds): Retention;
65
- export declare function capabilities(actions: HouseDiscoveryDocument['actions'], rooms: readonly Pick<TrackedAuthority, 'authority' | 'handle'>[]): readonly Capability[];
78
+ export declare function capabilities(actions: HouseDiscoveryDocument['actions']): readonly Capability[];
66
79
  export declare function siteCapabilities(): readonly Capability[];
67
80
  export declare function discoveredRoom(authority: HouseAuthority): DiscoveredRoom;
68
81
  export declare function mapDiscovery(document: Pick<HouseDiscoveryDocument, 'bounds'>, rooms: readonly DiscoveredRoom[], declared: readonly Capability[]): Discovery;
82
+ export {};
69
83
  //# sourceMappingURL=discovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,SAAS,EACT,MAAM,EACN,aAAa,EACb,SAAS,EACV,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3E,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAU,CAAC;AAI1D,MAAM,MAAM,WAAW,GAAG;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB,EAAE,MAAM,CAAC;IACjC,2BAA2B,EAAE,MAAM,CAAC;IACpC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1D,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IACzC,kBAAkB,EAAE,UAAU,GAAG,aAAa,CAAC;IAC/C,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,KAAK,EAAE,gBAAgB,CAAC;IACxB,UAAU,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC5C,CAAC;AA0GF,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,sBAAsB,GAAG,IAAI,CAsB3E;AAmBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI,CAa3E;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,kBAAkB,GAAG,gBAAgB,EAAE,CAU5E;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,sBAAsB,GAAG,gBAAgB,EAAE,CAUhF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,aAAa,EAAE,CAa5E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAMhE;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,sBAAsB,CAAC,SAAS,CAAC,EAC1C,KAAK,EAAE,SAAS,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,QAAQ,CAAC,EAAE,GAC/D,SAAS,UAAU,EAAE,CASvB;AAED,wBAAgB,gBAAgB,IAAI,SAAS,UAAU,EAAE,CAOxD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,cAAc,GAAG,cAAc,CAqBxE;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,IAAI,CAAC,sBAAsB,EAAE,QAAQ,CAAC,EAChD,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAC9B,SAAS,CAQX"}
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',
@@ -111,6 +110,47 @@ function parseAuthority(value) {
111
110
  ...at,
112
111
  };
113
112
  }
113
+ function parseAuthorities(value) {
114
+ if (!Array.isArray(value))
115
+ return null;
116
+ const authorities = [];
117
+ for (const entry of value) {
118
+ const authority = parseAuthority(entry);
119
+ if (authority === null)
120
+ return null;
121
+ authorities.push(authority);
122
+ }
123
+ return authorities;
124
+ }
125
+ export function foldedAuthorities(authorities) {
126
+ const shapes = [];
127
+ const known = new Map();
128
+ const rooms = authorities.map(({ room_ref, room_handle, name, position, ...shape }) => {
129
+ const key = JSON.stringify(shape);
130
+ let held = known.get(key);
131
+ if (held === undefined) {
132
+ held = shapes.push(shape) - 1;
133
+ known.set(key, held);
134
+ }
135
+ return { room_ref, room_handle, name, position, shape: held };
136
+ });
137
+ return { shapes, rooms };
138
+ }
139
+ function unfolded(shapes, rooms) {
140
+ if (!Array.isArray(shapes) || !Array.isArray(rooms))
141
+ return null;
142
+ const authorities = [];
143
+ for (const room of rooms) {
144
+ if (typeof room !== 'object' || room === null)
145
+ return null;
146
+ const { shape, ...own } = room;
147
+ const held = typeof shape === 'number' ? shapes[shape] : undefined;
148
+ if (typeof held !== 'object' || held === null)
149
+ return null;
150
+ authorities.push({ ...held, ...own });
151
+ }
152
+ return authorities;
153
+ }
114
154
  export function parseDiscovery(body) {
115
155
  if (typeof body !== 'object' || body === null)
116
156
  return null;
@@ -126,16 +166,19 @@ export function parseDiscovery(body) {
126
166
  new Set(actions).size !== actions.length ||
127
167
  actions.some((name) => name.length === 0))
128
168
  return null;
129
- if (!Array.isArray(held.authorities))
169
+ const authorities = parseAuthorities(unfolded(held.shapes, held.rooms));
170
+ return authorities === null ? null : { member, bounds, authorities, actions };
171
+ }
172
+ export function parseAuthorityChange(body) {
173
+ if (typeof body !== 'object' || body === null)
130
174
  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 };
175
+ const held = body;
176
+ const member = parseMember(held.member);
177
+ const authorities = parseAuthorities(held.authorities);
178
+ const left = stringList(held.left);
179
+ if (member === null || authorities === null || left === null)
180
+ return null;
181
+ return { member, authorities, left };
139
182
  }
140
183
  function parseSiteAuthority(value) {
141
184
  if (typeof value !== 'object' || value === null)
@@ -220,21 +263,14 @@ export function declaredRetention(bounds) {
220
263
  refreshHorizon: bounds.change_retention_seconds,
221
264
  };
222
265
  }
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
- ];
266
+ export function capabilities(actions) {
267
+ return [{ name: PROVIDER_ACTIONS, actions: declaredActions(actions) }];
232
268
  }
233
269
  export function siteCapabilities() {
234
270
  return [
235
271
  {
236
272
  name: PROVIDER_ACTIONS,
237
- actions: [{ name: SITE_SUBMIT, inputShape: {}, resultKind: 'house' }],
273
+ actions: [{ name: SITE_SUBMISSION, inputShape: {}, resultKind: 'house' }],
238
274
  },
239
275
  ];
240
276
  }
@@ -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"}