@agentshouse/mdruntime-adapter 0.1.0-cb42b23b5d2fb → 0.1.0-cb6436097e8a2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/actions.d.ts CHANGED
@@ -24,6 +24,7 @@ export type AppInputs = {
24
24
  readonly 'conversation.interrupt': ConversationControl;
25
25
  readonly 'conversation.kill': ConversationControl;
26
26
  readonly 'conversation.send': ConversationControl & {
27
+ readonly operation_id: string;
27
28
  readonly text?: string;
28
29
  readonly files?: readonly SentFile[];
29
30
  };
@@ -32,9 +33,28 @@ export type AppAnswers = {
32
33
  readonly 'conversation.history': ConversationHistories;
33
34
  };
34
35
  export type AppAnswerAdditions = {
36
+ readonly 'conversation.create': {
37
+ readonly conversation: string;
38
+ };
35
39
  readonly 'conversation.send': {
36
40
  readonly turn: string;
37
41
  };
42
+ readonly 'record.list': {
43
+ readonly attachments: readonly {
44
+ readonly referrer: {
45
+ readonly room_ref: string;
46
+ readonly record: string;
47
+ };
48
+ }[];
49
+ readonly records: readonly {
50
+ readonly attachments: readonly {
51
+ readonly referrer: {
52
+ readonly room_ref: string;
53
+ readonly record: string;
54
+ };
55
+ }[];
56
+ }[];
57
+ };
38
58
  };
39
59
  export declare const HOUSE_APP_ACTS: Readonly<Record<string, string>>;
40
60
  export declare const SITE_SUBMIT = "submit";
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAE1B,KAAK,0BAA0B,EAC/B,KAAK,eAAe,EACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAQtE,KAAK,QAAQ,GAAG;IAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,KAAK,mBAAmB,GAAG,QAAQ,GAAG;IAAE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAExE,KAAK,QAAQ,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,qBAAqB,EAAE,mBAAmB,GAAG;QACpD,QAAQ,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;SAAE,CAAC;KAClF,CAAC;IACF,QAAQ,CAAC,qBAAqB,EAAE,QAAQ,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,QAAQ,CAAC,qBAAqB,EAAE,mBAAmB,CAAC;IACpD,QAAQ,CAAC,sBAAsB,EAAE,0BAA0B,CAAC;IAC5D,QAAQ,CAAC,wBAAwB,EAAE,mBAAmB,CAAC;IACvD,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAClD,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,GAAG;QAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;KACtC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,sBAAsB,EAAE,qBAAqB,CAAC;CACxD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,mBAAmB,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD,CAAC;AAwEF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE3D,CAAC;AAEF,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE5D,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAKhF,CAAC;AAMJ,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAE3E;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,iBAAiB,EAAE,CAMvF;AAED,wBAAgB,WAAW,CACzB,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAQvB;AAwED,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAOjF;AAkLD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAiBtE"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
package/dist/actions.js CHANGED
@@ -122,7 +122,12 @@ async function createAction(transport, route, input, name) {
122
122
  return outcome;
123
123
  const held = record(outcome.result);
124
124
  const conversation = text(held, 'conversation_id');
125
- return conversation === undefined ? outcome : { ...outcome, result: { ...held, conversation } };
125
+ return conversation === undefined
126
+ ? outcome
127
+ : {
128
+ ...outcome,
129
+ result: { ...held, conversation },
130
+ };
126
131
  }
127
132
  function withTurn(body) {
128
133
  const held = record(body);
@@ -147,7 +152,10 @@ function referredRecord(view, roomRef) {
147
152
  const held = record(view);
148
153
  if (roomRef === undefined || typeof held.record !== 'string' || !Array.isArray(held.attachments))
149
154
  return view;
150
- const referrer = { room_ref: roomRef, record: held.record };
155
+ const referrer = {
156
+ room_ref: roomRef,
157
+ record: held.record,
158
+ };
151
159
  return {
152
160
  ...held,
153
161
  attachments: held.attachments.map((attachment) => ({ ...record(attachment), referrer })),
@@ -206,12 +214,13 @@ function sendFiles(input) {
206
214
  }
207
215
  function sendBody(input) {
208
216
  const files = sendFiles(input);
209
- if (files === null)
217
+ const operation = text(input, 'operation_id');
218
+ if (files === null || operation === undefined)
210
219
  return null;
211
220
  const textValue = text(input, 'text');
212
221
  return {
213
222
  conversation_id: text(input, 'conversation'),
214
- operation_id: operationId(input),
223
+ operation_id: operation,
215
224
  ...(textValue !== undefined && textValue.length > 0 ? { text: textValue } : {}),
216
225
  ...(files.length === 0 ? {} : { files }),
217
226
  };
@@ -224,9 +233,6 @@ async function fileBytes(file) {
224
233
  return null;
225
234
  return new Uint8Array(await blob.arrayBuffer());
226
235
  }
227
- function delivered(answer, name) {
228
- return answer.status === 200 ? null : actionOutcome(answer, name);
229
- }
230
236
  function uploadGrant(entry) {
231
237
  if (!('upload' in record(entry)))
232
238
  return 'absent';
@@ -237,36 +243,28 @@ function uploadGrant(entry) {
237
243
  return null;
238
244
  return { method: 'POST', operation: upload.operation, url: upload.url };
239
245
  }
240
- async function uploadFiles(transport, input, result, name) {
246
+ async function uploadFiles(transport, input, result) {
241
247
  const sent = record(result).files;
242
- if (!Array.isArray(sent) || sent.length === 0)
243
- return null;
248
+ if (!Array.isArray(sent))
249
+ return true;
244
250
  const files = Array.isArray(record(input).files) ? record(input).files : [];
245
251
  for (const [index, entry] of sent.entries()) {
246
252
  const grant = uploadGrant(entry);
247
253
  if (grant === 'absent')
248
254
  continue;
249
- if (grant === null)
250
- return malformed();
251
255
  const bytes = index < files.length ? await fileBytes(files[index]) : null;
252
- if (bytes === null) {
253
- return {
254
- kind: 'rejected',
255
- code: 'conversation_file_descriptor_required',
256
- fields: {},
257
- retryable: false,
258
- };
259
- }
260
- const failed = delivered(await transport.transfer({
256
+ if (grant === null || bytes === null)
257
+ return false;
258
+ const answer = await transport.transfer({
261
259
  act: 'conversation_file_upload',
262
260
  url: grant.url,
263
261
  body: bytes,
264
262
  operation: grant.operation,
265
- }), name);
266
- if (failed !== null)
267
- return failed;
263
+ });
264
+ if (answer.status !== 200)
265
+ return false;
268
266
  }
269
- return null;
267
+ return true;
270
268
  }
271
269
  async function sendAction(transport, route, input, name) {
272
270
  const body = sendBody(input);
@@ -275,9 +273,9 @@ async function sendAction(transport, route, input, name) {
275
273
  const outcome = actionOutcome(await transport.door(route, body), name);
276
274
  if (outcome.kind !== 'action')
277
275
  return outcome;
278
- const uploaded = await uploadFiles(transport, input, outcome.result, name);
279
- if (uploaded !== null)
280
- return uploaded;
276
+ if (!(await uploadFiles(transport, input, outcome.result))) {
277
+ return { kind: 'transport-uncertainty' };
278
+ }
281
279
  return { ...outcome, result: withTurn(outcome.result) };
282
280
  }
283
281
  function historyCursor(value) {
package/dist/adapter.d.ts CHANGED
@@ -5,6 +5,7 @@ export type AgentsHouseAdapterOptions = {
5
5
  authorize(): Promise<Authorization>;
6
6
  } | {
7
7
  site: HouseSiteTransport;
8
+ snapshot?: boolean;
8
9
  };
9
10
  export declare function createAgentsHouseAdapter(options: AgentsHouseAdapterOptions): Adapter;
10
11
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,OAAO,EACP,aAAa,EAgBd,MAAM,wBAAwB,CAAC;AAuChC,OAAO,EASL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AAyBxB,MAAM,MAAM,yBAAyB,GACjC;IACE,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;CACrC,GACD;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAwBjC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CA8cpF"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKV,OAAO,EACP,aAAa,EAiBd,MAAM,wBAAwB,CAAC;AA4ChC,OAAO,EASL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AAyBxB,MAAM,MAAM,yBAAyB,GACjC;IACE,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;CACrC,GACD;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAsErD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CA0hBpF"}
package/dist/adapter.js CHANGED
@@ -2,7 +2,8 @@ import { DISCOVER_PREFIXES, capabilities, discoveredRoom, mapDiscovery, parseDis
2
2
  import { partModels, streamedModels, viewModels } from './model.js';
3
3
  import { gathered, gatheredEach, selections } from './gather.js';
4
4
  import { createSiteAdapter } from './site.js';
5
- import { bootstrapOf, contentPrefixes, matchesScope, parseEnumeration, parseEnvelope, parseGrant, refreshFrom, viewOf, } from './read.js';
5
+ import { bootstrapOf, contentPrefixes, matchesScope, parseEnumeration, parseEnvelope, parseGrant, refreshFrom, viewOf, wholeView, } from './read.js';
6
+ import { sha256Hex } from './digest.js';
6
7
  import { acceptedHanded, enumeratedHanded, heldHanded, scopeHanded, streamedHanded, } from './handed.js';
7
8
  import { houseAction } from './actions.js';
8
9
  import { classifyDoor, classifyRead, discoveryFailure, doorRefusal } from './refusal.js';
@@ -16,9 +17,36 @@ const UNCERTAIN_READ = { kind: 'transport-uncertainty' };
16
17
  function lapsedGrant(outcome) {
17
18
  return outcome.kind === 'rejected' && outcome.code === 'upload_unavailable';
18
19
  }
20
+ function heldFiles(authority, held, after, budget) {
21
+ if (held === undefined || budget === 0)
22
+ return null;
23
+ const paths = Object.keys(held.revisions)
24
+ .filter((path) => held.documents[path] !== undefined && (after === null || path > after))
25
+ .sort();
26
+ if (paths.length === 0)
27
+ return null;
28
+ const files = paths.slice(0, budget).map((path) => ({ path, revision: held.revisions[path] }));
29
+ return { room: authority, through: paths.length > budget ? files.at(-1).path : null, files };
30
+ }
31
+ async function reused(scope, held) {
32
+ const sent = new Set(scope.contents.map((entry) => entry.path));
33
+ const contents = [...scope.contents];
34
+ for (const file of scope.files) {
35
+ if (file.binary !== undefined || sent.has(file.path))
36
+ continue;
37
+ const content = held?.documents[file.path];
38
+ if (content === undefined ||
39
+ held?.revisions[file.path] !== file.revision ||
40
+ (await sha256Hex(content)) !== file.sha256) {
41
+ return null;
42
+ }
43
+ contents.push({ path: file.path, content });
44
+ }
45
+ return { ...scope, contents };
46
+ }
19
47
  export function createAgentsHouseAdapter(options) {
20
48
  if ('site' in options)
21
- return createSiteAdapter(options.site);
49
+ return createSiteAdapter(options.site, options.snapshot === true);
22
50
  const transport = options.transport;
23
51
  const notifications = houseNotifications(transport, 'credential');
24
52
  const tracked = new Map();
@@ -29,10 +57,20 @@ export function createAgentsHouseAdapter(options) {
29
57
  throw new Error('no Discovery declared the bounds');
30
58
  return bounds;
31
59
  }
32
- async function bootstrappedRoom(envelope, scope, entry, continued) {
33
- if (scope === undefined)
60
+ async function bootstrappedRoom(envelope, sent, asked, continued) {
61
+ const { entry } = asked;
62
+ if (sent === undefined)
34
63
  return { kind: 'room-not-readable', locator: entry.locator };
35
- const next = envelope.next?.room === entry.authority ? envelope.next.path : null;
64
+ const scope = await reused(sent, asked.held);
65
+ if (scope === null) {
66
+ return asked.held === undefined
67
+ ? UNCERTAIN_READ
68
+ : continued === null
69
+ ? bootstrapTogether({ entry, held: undefined })
70
+ : continuedBootstrap({ entry, held: undefined }, continued);
71
+ }
72
+ const cursor = envelope.next?.room === entry.authority ? envelope.next : undefined;
73
+ const next = cursor?.path ?? null;
36
74
  if (continued === null && next === null)
37
75
  handed.set(entry.locator, scopeHanded(scope));
38
76
  else
@@ -43,17 +81,40 @@ export function createAgentsHouseAdapter(options) {
43
81
  ...entry.schemas.filter((schema) => scope.files.some((file) => file.path === schema)),
44
82
  ];
45
83
  const models = await partModels(scope, entry, new Set(seen), next === null);
46
- const continuation = next === null ? null : { after: next, seen };
84
+ const continuation = next === null
85
+ ? null
86
+ : { after: next, seen, ...(cursor?.cut === undefined ? {} : { cut: cursor.cut }) };
47
87
  return {
48
88
  ...bootstrapOf(scope),
49
89
  ...(models === undefined ? {} : { models }),
50
90
  ...(continuation === null ? {} : { pageToken: JSON.stringify(continuation) }),
51
91
  };
52
92
  }
93
+ async function enumeratedPage(ask, page) {
94
+ const answer = await transport.door(DOOR_ENUMERATE, {
95
+ prefixes: contentPrefixes(ask.entry),
96
+ positions: [
97
+ {
98
+ ...presented(ask.entry.authority, { position: page.after, logEpoch: ask.from.logEpoch }),
99
+ page: { through: page.through, read: page.read },
100
+ },
101
+ ],
102
+ });
103
+ const failure = classifyRead(answer.status, answer.body, ask.entry.locator);
104
+ if (failure !== null)
105
+ return failure;
106
+ const enumeration = parseEnumeration(answer.body, 'credential');
107
+ if (enumeration === null)
108
+ return UNCERTAIN_READ;
109
+ return (viewOf(enumeration, ask.entry) ?? { kind: 'room-not-readable', locator: ask.entry.locator });
110
+ }
53
111
  async function enumeratedRoom(enumeration, ask) {
54
- const view = viewOf(enumeration, ask.entry);
55
- if (view === undefined)
112
+ const first = viewOf(enumeration, ask.entry);
113
+ if (first === undefined)
56
114
  return { kind: 'room-not-readable', locator: ask.entry.locator };
115
+ const view = await wholeView(first, (page) => enumeratedPage(ask, page));
116
+ if ('kind' in view)
117
+ return view;
57
118
  notifications.reach(ask.entry.authority, view);
58
119
  const answer = refreshFrom(view, ask.fromRoomVersion);
59
120
  if (answer.kind !== 'net-advancement')
@@ -73,7 +134,7 @@ export function createAgentsHouseAdapter(options) {
73
134
  const models = await streamedModels(advanced.schemas, entry, 'credential');
74
135
  return models === undefined ? advanced.page : { ...advanced.page, models };
75
136
  }
76
- function held(rooms) {
137
+ function held(rooms, demand) {
77
138
  const kept = rooms.flatMap((room) => {
78
139
  const entry = tracked.get(room.locator);
79
140
  const at = logPosition(room.roomVersion);
@@ -83,7 +144,15 @@ export function createAgentsHouseAdapter(options) {
83
144
  notifications.reach(entry.authority, at);
84
145
  return [presented(entry.authority, at)];
85
146
  });
86
- notifications.send(kept);
147
+ notifications.send(kept, demand === null
148
+ ? null
149
+ : {
150
+ rooms: demand.rooms.flatMap((locator) => {
151
+ const entry = tracked.get(locator);
152
+ return entry === undefined ? [] : [entry.authority];
153
+ }),
154
+ conversations: demand.conversations,
155
+ });
87
156
  }
88
157
  function adopted(entry, outcome) {
89
158
  if (outcome.kind !== 'accepted')
@@ -118,13 +187,19 @@ export function createAgentsHouseAdapter(options) {
118
187
  function weight(entry) {
119
188
  return contentPrefixes(entry).length;
120
189
  }
121
- async function bootstrapped(entries, answer) {
122
- let open = entries.map((entry, ask) => ({ entry, ask }));
190
+ function holding(asks, after) {
191
+ const budget = Math.floor(declared().max_held_files / Math.max(1, asks.filter((ask) => ask.held !== undefined).length));
192
+ return asks.flatMap((ask) => heldFiles(ask.entry.authority, ask.held, after, budget) ?? []);
193
+ }
194
+ async function bootstrapped(asks, answer) {
195
+ let open = asks.map((asked, ask) => ({ entry: asked.entry, asked, ask }));
123
196
  while (open.length > 0) {
124
197
  const unreached = [];
125
198
  for (const part of selections(open, ({ entry }) => weight(entry), declared().max_prefixes)) {
199
+ const held = holding(part.map(({ asked }) => asked), null);
126
200
  const answered = await transport.door(DOOR_BOOTSTRAP, {
127
201
  prefixes: part.flatMap(({ entry }) => contentPrefixes(entry)),
202
+ ...(held.length === 0 ? {} : { held }),
128
203
  });
129
204
  const classified = part.map(({ entry }) => classifyDoor(answered.status, answered.body, entry.locator));
130
205
  const envelope = classified[0] === null ? parseEnvelope(answered.body) : null;
@@ -143,71 +218,79 @@ export function createAgentsHouseAdapter(options) {
143
218
  unreached.push(asked);
144
219
  continue;
145
220
  }
146
- answer(asked.ask, await bootstrappedRoom(envelope, scope, asked.entry, null));
221
+ answer(asked.ask, await bootstrappedRoom(envelope, scope, asked.asked, null));
147
222
  }
148
223
  }
149
224
  open = unreached;
150
225
  }
151
226
  }
152
- async function continuedBootstrap(entry, continued) {
153
- const after = { room: entry.authority, path: continued.after };
227
+ async function continuedBootstrap(asked, continued) {
228
+ const { entry } = asked;
229
+ const after = {
230
+ room: entry.authority,
231
+ path: continued.after,
232
+ ...(continued.cut === undefined ? {} : { cut: continued.cut }),
233
+ };
234
+ const held = holding([asked], continued.after);
154
235
  const answered = await transport.door(DOOR_BOOTSTRAP, {
155
236
  prefixes: contentPrefixes(entry),
156
237
  after,
238
+ ...(held.length === 0 ? {} : { held }),
157
239
  });
158
- const failure = classifyDoor(answered.status, answered.body, entry.locator);
240
+ const failure = classifyRead(answered.status, answered.body, entry.locator);
159
241
  if (failure !== null)
160
242
  return failure;
161
243
  const envelope = parseEnvelope(answered.body);
162
244
  if (envelope === null)
163
245
  return UNCERTAIN_READ;
164
246
  const scope = envelope.scopes.find((candidate) => matchesScope(candidate, entry));
165
- return bootstrappedRoom(envelope, scope, entry, continued);
247
+ return bootstrappedRoom(envelope, scope, asked, continued);
166
248
  }
167
249
  function layered(asks) {
168
250
  const depths = new Map();
169
251
  const layers = [];
170
252
  for (const ask of asks) {
171
- const depth = depths.get(ask.entry.authority) ?? 0;
172
- depths.set(ask.entry.authority, depth + 1);
253
+ const depth = depths.get(ask.ask.entry.authority) ?? 0;
254
+ depths.set(ask.ask.entry.authority, depth + 1);
173
255
  (layers[depth] ??= []).push(ask);
174
256
  }
175
257
  return layers;
176
258
  }
177
259
  async function enumerated(asks) {
178
- const answers = new Map();
179
- const parts = layered(asks).flatMap((layer) => selections(layer, (ask) => weight(ask.entry), declared().max_prefixes));
260
+ const answers = [];
261
+ const parts = layered(asks.map((ask, index) => ({ ask, index }))).flatMap((layer) => selections(layer, ({ ask }) => weight(ask.entry), declared().max_prefixes));
180
262
  for (const part of parts) {
181
263
  let open = [...part];
182
264
  while (open.length > 0) {
183
265
  const answer = await transport.door(DOOR_ENUMERATE, {
184
- prefixes: open.flatMap((ask) => contentPrefixes(ask.entry)),
185
- positions: open.map((ask) => presented(ask.entry.authority, ask.from)),
266
+ prefixes: open.flatMap(({ ask }) => contentPrefixes(ask.entry)),
267
+ positions: open.map(({ ask }) => presented(ask.entry.authority, ask.from)),
186
268
  });
187
- const classified = open.map((ask) => classifyRead(answer.status, answer.body, ask.entry.locator));
269
+ const classified = open.map(({ ask }) => classifyRead(answer.status, answer.body, ask.entry.locator));
188
270
  if (classified[0]?.kind === 'beyond-horizon') {
189
271
  const named = doorRefusal(answer.body)?.fields.authority;
190
- const expired = open.filter((ask) => ask.entry.authority === named);
272
+ const expired = open.filter(({ ask }) => ask.entry.authority === named);
191
273
  const answered = expired.length === 0 ? UNCERTAIN_READ : { kind: 'beyond-horizon' };
192
274
  const gone = expired.length === 0 ? open : expired;
193
275
  for (const ask of gone)
194
- answers.set(ask, answered);
276
+ answers[ask.index] = answered;
195
277
  open = open.filter((ask) => !gone.includes(ask));
196
278
  continue;
197
279
  }
198
280
  const enumeration = classified[0] === null ? parseEnumeration(answer.body, 'credential') : null;
199
- for (const [index, ask] of open.entries()) {
200
- const failure = classified[index];
281
+ for (const [answerIndex, { ask, index }] of open.entries()) {
282
+ const failure = classified[answerIndex];
201
283
  if (failure !== null && failure !== undefined) {
202
- answers.set(ask, failure);
284
+ answers[index] = failure;
203
285
  continue;
204
286
  }
205
- answers.set(ask, enumeration === null ? UNCERTAIN_READ : await enumeratedRoom(enumeration, ask));
287
+ answers[index] =
288
+ enumeration === null ? UNCERTAIN_READ : await enumeratedRoom(enumeration, ask);
206
289
  }
207
290
  open = [];
208
291
  }
209
292
  }
210
- return asks.map((ask) => answers.get(ask) ?? UNCERTAIN_READ);
293
+ return answers;
211
294
  }
212
295
  const bootstrapTogether = gatheredEach(bootstrapped);
213
296
  const enumerateTogether = gathered(enumerated);
@@ -327,10 +410,11 @@ export function createAgentsHouseAdapter(options) {
327
410
  const entry = authorityFor(request.locator);
328
411
  if (entry === undefined)
329
412
  return { kind: 'room-not-readable', locator: request.locator };
413
+ const asked = { entry, held: request.held };
330
414
  if (request.pageToken !== undefined) {
331
- return continuedBootstrap(entry, JSON.parse(request.pageToken));
415
+ return continuedBootstrap(asked, JSON.parse(request.pageToken));
332
416
  }
333
- return bootstrapTogether(entry);
417
+ return bootstrapTogether(asked);
334
418
  },
335
419
  async refresh(_authorization, request) {
336
420
  const entry = authorityFor(request.locator);
@@ -418,7 +502,16 @@ export function createAgentsHouseAdapter(options) {
418
502
  async action(_authorization, request) {
419
503
  return withAt(await houseAction(transport, request));
420
504
  },
421
- roomStream: { hold: held, reopen: notifications.reopen, observe: notifications.observe },
505
+ roomStream: {
506
+ hold: held,
507
+ reopen: notifications.reopen,
508
+ observe: notifications.observe,
509
+ published(locator, roomVersion) {
510
+ const at = logPosition(roomVersion);
511
+ if (at !== null)
512
+ notifications.published(locator, at);
513
+ },
514
+ },
422
515
  conversations: notifications.conversations,
423
516
  serviceMode: notifications.serviceMode,
424
517
  };
@@ -13,6 +13,7 @@ export type HouseBounds = {
13
13
  max_inline_body_bytes: number;
14
14
  max_upload_bytes: number;
15
15
  max_prefixes: number;
16
+ max_held_files: number;
16
17
  change_retention_seconds: number;
17
18
  operation_retention_seconds: number;
18
19
  };
@@ -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
@@ -13,6 +13,7 @@ const BOUND_KEYS = [
13
13
  'max_inline_body_bytes',
14
14
  'max_upload_bytes',
15
15
  'max_prefixes',
16
+ 'max_held_files',
16
17
  'change_retention_seconds',
17
18
  'operation_retention_seconds',
18
19
  ];
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { createAgentsHouseAdapter, type AgentsHouseAdapterOptions } from './adapter.js';
2
2
  export { HOUSE_APP_ACTS, HOUSE_APP_BATCHES, HOUSE_SITE_ACTS } from './actions.js';
3
- export type { HouseByteAct, HouseByteTransfer, HouseBytesAnswer, HouseDoorAnswer, HouseHeldRoom, HouseOpening, HouseStream, HouseStreamEntry, HouseStreamFrame, HouseSiteTransport, HouseTransport, } from './transport.js';
3
+ export type { HouseByteAct, HouseByteTransfer, HouseBytesAnswer, HouseDemand, HouseDoorAnswer, HouseHeldRoom, HouseOpening, HouseStream, HouseStreamEntry, HouseStreamFrame, HouseSiteTransport, HouseTransport, } from './transport.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,KAAK,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAClF,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,KAAK,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAClF,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,aAAa,EACb,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC"}
package/dist/model.d.ts CHANGED
@@ -3,7 +3,6 @@ import type { TrackedAuthority } from './discovery.js';
3
3
  import { type HouseScope, type HouseView } from './read.js';
4
4
  import type { HouseMode, HouseStreamEntry } from './transport.js';
5
5
  export declare function partModels(scope: HouseScope, tracked: TrackedAuthority, seen: ReadonlySet<string>, final: boolean): Promise<RoomModels | undefined>;
6
- export declare function scopeModels(scope: HouseScope, tracked: TrackedAuthority): Promise<RoomModels | undefined>;
7
6
  export declare function viewModels(view: HouseView, tracked: TrackedAuthority): Promise<RoomModels | undefined>;
8
7
  export declare function streamedModels(schemas: ReadonlyMap<string, HouseStreamEntry>, tracked: TrackedAuthority, mode: HouseMode): Promise<RoomModels | undefined>;
9
8
  //# sourceMappingURL=model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAA0C,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACpG,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAoClE,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EACzB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAKjC;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEjC;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAcjC;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAC9C,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAWjC"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAA0C,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACpG,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAoClE,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EACzB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAKjC;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAcjC;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAC9C,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAWjC"}
package/dist/model.js CHANGED
@@ -33,9 +33,6 @@ export function partModels(scope, tracked, seen, final) {
33
33
  return final && !seen.has(schema) ? ABSENT_SCHEMA : undefined;
34
34
  });
35
35
  }
36
- export function scopeModels(scope, tracked) {
37
- return partModels(scope, tracked, new Set(), true);
38
- }
39
36
  export function viewModels(view, tracked) {
40
37
  return modelsOf(tracked, (schema) => {
41
38
  const change = view.changes.find((candidate) => candidate.path === schema);
package/dist/read.d.ts CHANGED
@@ -1,12 +1,16 @@
1
- import type { BinaryFile, BootstrapPage, RefreshResult } from '@agentshouse/mdruntime';
1
+ import type { AdapterFailure, BinaryFile, BootstrapPage, RefreshResult } from '@agentshouse/mdruntime';
2
2
  import type { TrackedAuthority } from './discovery.js';
3
3
  import type { HouseMode } from './transport.js';
4
4
  import { type LogPosition } from './version.js';
5
5
  export type HeadChange = BootstrapPage['changes'][string];
6
+ export declare function identities(revisions: Readonly<Record<string, string>>): {
7
+ fileIds?: Record<string, string>;
8
+ };
6
9
  export type HouseManifestFile = {
7
10
  path: string;
8
11
  revision: string | undefined;
9
12
  version: string;
13
+ sha256?: string;
10
14
  head?: HeadChange;
11
15
  binary?: BinaryFile;
12
16
  };
@@ -19,9 +23,14 @@ export type HouseScope = LogPosition & {
19
23
  files: readonly HouseManifestFile[];
20
24
  contents: readonly HouseContent[];
21
25
  };
26
+ export type HouseCut = {
27
+ position: string;
28
+ log_epoch: string;
29
+ };
22
30
  export type HouseCursor = {
23
31
  room: string;
24
32
  path: string | null;
33
+ cut?: HouseCut;
25
34
  };
26
35
  export type HouseEnvelope = {
27
36
  scopes: readonly HouseScope[];
@@ -51,9 +60,18 @@ export type HouseChange = {
51
60
  version: string;
52
61
  head?: HeadChange;
53
62
  };
63
+ export type HousePage = {
64
+ after: string;
65
+ through: string;
66
+ read: number;
67
+ };
54
68
  export type HouseView = LogPosition & {
55
69
  authority: string;
56
70
  changes: readonly HouseChange[];
71
+ next?: HousePage;
72
+ };
73
+ type PageFailure = AdapterFailure | {
74
+ kind: 'beyond-horizon';
57
75
  };
58
76
  export type HouseEnumeration = {
59
77
  authorities: readonly HouseView[];
@@ -69,7 +87,10 @@ export declare function headChange(held: {
69
87
  export declare function binaryFileOf(held: Readonly<Record<string, unknown>>): BinaryFile | undefined | null;
70
88
  export declare function parseEnvelope(body: unknown): HouseEnvelope | null;
71
89
  export declare function parseSiteBootstrap(body: unknown): HouseScope | null;
90
+ export declare function siteBootstrapNext(body: unknown): string | null;
91
+ export declare function siteBootstrapOffset(body: unknown): number | null;
72
92
  export declare function parseEnumeration(body: unknown, mode: HouseMode): HouseEnumeration | null;
93
+ export declare function wholeView(first: HouseView, more: (page: HousePage) => Promise<HouseView | PageFailure>): Promise<HouseView | PageFailure>;
73
94
  export declare function advancedScope(scope: HouseScope, view: HouseView): HouseScope;
74
95
  export declare function matchesScope(scope: HouseScope, tracked: TrackedAuthority): boolean;
75
96
  export declare function bootstrapOf(scope: HouseScope): BootstrapPage;
@@ -81,4 +102,5 @@ export type HouseSchema = {
81
102
  export declare function schemaOf(scope: HouseScope, schema: string): HouseSchema | null;
82
103
  export declare function viewOf(enumeration: HouseEnumeration, tracked: TrackedAuthority): HouseView | undefined;
83
104
  export declare function refreshFrom(view: HouseView, fromRoomVersion: string): RefreshResult;
105
+ export {};
84
106
  //# sourceMappingURL=read.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":"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"}