@agentshouse/mdruntime-adapter 0.1.0-cfd03209dcd82 → 0.1.0-cfded86738bb2

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/AGENTS.md +294 -276
  2. package/dist/actions.d.ts +16 -5
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +92 -141
  5. package/dist/adapter.d.ts +1 -0
  6. package/dist/adapter.d.ts.map +1 -1
  7. package/dist/adapter.js +307 -138
  8. package/dist/discovery.d.ts +5 -3
  9. package/dist/discovery.d.ts.map +1 -1
  10. package/dist/discovery.js +29 -10
  11. package/dist/gather.d.ts +1 -1
  12. package/dist/gather.d.ts.map +1 -1
  13. package/dist/gather.js +4 -14
  14. package/dist/index.d.ts +3 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -0
  17. package/dist/model.d.ts +0 -1
  18. package/dist/model.d.ts.map +1 -1
  19. package/dist/model.js +0 -3
  20. package/dist/part.d.ts +15 -0
  21. package/dist/part.d.ts.map +1 -0
  22. package/dist/part.js +82 -0
  23. package/dist/read.d.ts +65 -18
  24. package/dist/read.d.ts.map +1 -1
  25. package/dist/read.js +302 -122
  26. package/dist/refusal.d.ts.map +1 -1
  27. package/dist/refusal.js +2 -1
  28. package/dist/room-types.d.ts +6 -0
  29. package/dist/room-types.d.ts.map +1 -0
  30. package/dist/room-types.js +66 -0
  31. package/dist/site.d.ts +1 -1
  32. package/dist/site.d.ts.map +1 -1
  33. package/dist/site.js +149 -82
  34. package/dist/stream.d.ts +5 -4
  35. package/dist/stream.d.ts.map +1 -1
  36. package/dist/stream.js +349 -43
  37. package/dist/transport.d.ts +58 -13
  38. package/dist/transport.d.ts.map +1 -1
  39. package/dist/transport.js +1 -1
  40. package/dist/upload.d.ts +12 -0
  41. package/dist/upload.d.ts.map +1 -0
  42. package/dist/upload.js +52 -0
  43. package/dist/version.d.ts +1 -0
  44. package/dist/version.d.ts.map +1 -1
  45. package/dist/version.js +1 -1
  46. package/dist/write.d.ts +12 -1
  47. package/dist/write.d.ts.map +1 -1
  48. package/dist/write.js +98 -57
  49. package/package.json +2 -2
  50. package/dist/handed.d.ts +0 -15
  51. package/dist/handed.d.ts.map +0 -1
  52. package/dist/handed.js +0 -38
  53. package/dist/referrer.d.ts +0 -7
  54. package/dist/referrer.d.ts.map +0 -1
  55. package/dist/referrer.js +0 -35
package/dist/stream.js CHANGED
@@ -1,5 +1,7 @@
1
+ import { ROW_WEIGHT, } from '@agentshouse/mdruntime';
1
2
  import { acceptedMessage } from './actions.js';
2
- import { binaryFileOf, headChange } from './read.js';
3
+ import { sha256Hex } from './digest.js';
4
+ import { answered, answering, binaryFileOf, folded, forgotten, headChange, revised, } from './read.js';
3
5
  import { roomVersion } from './version.js';
4
6
  const HELD_FRAMES_MAX = 256;
5
7
  function turnOperation(frame) {
@@ -14,6 +16,7 @@ function listedConversation(listed) {
14
16
  created: listed.created_at,
15
17
  finished: listed.finished_at,
16
18
  outcome: listed.outcome,
19
+ waiting: listed.waiting,
17
20
  };
18
21
  }
19
22
  function position(value) {
@@ -21,9 +24,78 @@ function position(value) {
21
24
  return null;
22
25
  return BigInt(value);
23
26
  }
27
+ function assembled(entries) {
28
+ const whole = [];
29
+ let open = null;
30
+ for (const entry of entries) {
31
+ if (entry.kind === 'piece') {
32
+ if (open === null || open.entry.path !== entry.path || entry.text === undefined)
33
+ return null;
34
+ open.texts.push(entry.text);
35
+ }
36
+ else {
37
+ if (open !== null)
38
+ return null;
39
+ if (entry.continued !== true) {
40
+ whole.push(entry);
41
+ continue;
42
+ }
43
+ if (entry.text === undefined)
44
+ return null;
45
+ open = { entry, texts: [entry.text] };
46
+ }
47
+ if (entry.continued === true)
48
+ continue;
49
+ const { continued: _continued, ...head } = open.entry;
50
+ whole.push({ ...head, text: open.texts.join('') });
51
+ open = null;
52
+ }
53
+ return open === null ? whole : null;
54
+ }
55
+ async function verified(entries) {
56
+ try {
57
+ for (const entry of entries) {
58
+ if (entry.text === undefined || entry.sha256 === undefined)
59
+ continue;
60
+ if ((await sha256Hex(entry.text)) !== entry.sha256)
61
+ return false;
62
+ }
63
+ return true;
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ function resumed(kept, frame) {
70
+ const last = frame.entries.at(-1);
71
+ const point = { parts: frame.index + 1, from: frame.from, target: frame.target };
72
+ if (last?.continued !== true)
73
+ return { ...point, handled: frame.handled, piece: null };
74
+ const text = last.text?.length ?? 0;
75
+ if (last.kind !== 'piece') {
76
+ return last.sha256 === undefined
77
+ ? kept.resume
78
+ : { ...point, handled: frame.handled, piece: { sha256: last.sha256, offset: text } };
79
+ }
80
+ const piece = kept.resume?.piece ?? null;
81
+ if (piece === null)
82
+ return kept.resume;
83
+ const pieces = frame.entries.reduce((sum, entry) => sum + (entry.kind === 'piece' ? (entry.text?.length ?? 0) : 0), 0);
84
+ return {
85
+ ...point,
86
+ handled: frame.handled,
87
+ piece: { sha256: piece.sha256, offset: piece.offset + pieces },
88
+ };
89
+ }
24
90
  export function houseNotifications(transport, mode) {
25
91
  const stream = transport.stream;
26
92
  const lines = new Map();
93
+ const kept = new Map();
94
+ let receipts = null;
95
+ let loaded = Promise.resolve();
96
+ let acknowledging = null;
97
+ let receiving = Promise.resolve();
98
+ let verifying = 0;
27
99
  const locators = new Map();
28
100
  const observers = new Set();
29
101
  const conversationObservers = new Set();
@@ -41,7 +113,10 @@ export function houseNotifications(transport, mode) {
41
113
  event.kind === 'questions' ||
42
114
  event.kind === 'process' ||
43
115
  event.kind === 'commands' ||
44
- event.kind === 'options') {
116
+ event.kind === 'options' ||
117
+ event.kind === 'starting' ||
118
+ event.kind === 'link' ||
119
+ event.kind === 'deliveries') {
45
120
  live.add(event.conversation);
46
121
  }
47
122
  for (const observer of conversationObservers)
@@ -49,6 +124,7 @@ export function houseNotifications(transport, mode) {
49
124
  }
50
125
  function reopened(next) {
51
126
  opening = next;
127
+ acknowledging = next;
52
128
  const gapped = new Set([...replicated, ...live]);
53
129
  live.clear();
54
130
  for (const conversation of gapped)
@@ -86,6 +162,18 @@ export function houseNotifications(transport, mode) {
86
162
  emitConversation({ kind: 'options', conversation, options: structuredClone(frame.options) });
87
163
  return;
88
164
  }
165
+ if (frame.type === 'starting') {
166
+ emitConversation({ kind: 'starting', conversation, step: frame.step });
167
+ return;
168
+ }
169
+ if (frame.type === 'link') {
170
+ emitConversation({ kind: 'link', conversation, connected: frame.connected });
171
+ return;
172
+ }
173
+ if (frame.type === 'deliveries') {
174
+ emitConversation({ kind: 'deliveries', conversation, unknown: [...frame.unknown] });
175
+ return;
176
+ }
89
177
  if (frame.type === 'interactions') {
90
178
  emitConversation({
91
179
  kind: 'questions',
@@ -110,7 +198,162 @@ export function houseNotifications(transport, mode) {
110
198
  if (line !== undefined)
111
199
  lines.set(authority, { ...line, frames: [] });
112
200
  }
113
- function receive(frame) {
201
+ async function forget(carries) {
202
+ const held = carries.filter((carry) => kept.delete(carry));
203
+ if (held.length > 0)
204
+ await receipts?.drop(held).catch(() => { });
205
+ }
206
+ async function lost(authority, carry) {
207
+ interrupt(authority);
208
+ await forget([carry]);
209
+ }
210
+ async function stage(frame, via) {
211
+ await loaded;
212
+ const port = receipts;
213
+ if (port === null)
214
+ return;
215
+ const held = kept.get(frame.carry);
216
+ if (held === undefined && frame.index !== 0) {
217
+ interrupt(frame.authority);
218
+ return;
219
+ }
220
+ if (held !== undefined &&
221
+ (held.fenced !== null || frame.index > held.parts || frame.index < (held.resume?.parts ?? 0))) {
222
+ await lost(frame.authority, frame.carry);
223
+ return;
224
+ }
225
+ if (held === undefined) {
226
+ await forget([...kept.values()]
227
+ .filter((other) => other.authority === frame.authority && other.fenced === null)
228
+ .map((other) => other.carry));
229
+ }
230
+ const start = held ?? {
231
+ authority: frame.authority,
232
+ carry: frame.carry,
233
+ logEpoch: lines.get(frame.authority)?.logEpoch ?? null,
234
+ after: frame.after,
235
+ parts: 0,
236
+ resume: null,
237
+ fenced: null,
238
+ };
239
+ const next = { ...start, parts: frame.index + 1, resume: resumed(start, frame) };
240
+ const part = { entries: frame.entries };
241
+ try {
242
+ await port.keep(frame.carry, next, { index: frame.index, value: part });
243
+ }
244
+ catch {
245
+ await lost(frame.authority, frame.carry);
246
+ return;
247
+ }
248
+ kept.set(frame.carry, next);
249
+ via?.received(frame.authority, frame.carry, frame.index);
250
+ }
251
+ async function keptEntries(carry, parts) {
252
+ if (parts === 0)
253
+ return [];
254
+ if (receipts === null)
255
+ return null;
256
+ const read = (await receipts.parts(carry, parts));
257
+ if (read.length !== parts)
258
+ return null;
259
+ const entries = assembled(read.flatMap((part) => part.entries));
260
+ return entries !== null && (await verified(entries)) ? entries : null;
261
+ }
262
+ async function carried(frame) {
263
+ await loaded;
264
+ const held = kept.get(frame.carry);
265
+ if (frame.parts > 0 && held?.parts !== frame.parts) {
266
+ await lost(frame.authority, frame.carry);
267
+ return;
268
+ }
269
+ const entries = await keptEntries(frame.carry, frame.parts).catch(() => null);
270
+ if (entries === null) {
271
+ await lost(frame.authority, frame.carry);
272
+ return;
273
+ }
274
+ const fenced = {
275
+ ...(held ?? {
276
+ authority: frame.authority,
277
+ carry: frame.carry,
278
+ logEpoch: frame.log_epoch,
279
+ after: frame.after,
280
+ parts: 0,
281
+ resume: null,
282
+ }),
283
+ after: frame.after,
284
+ fenced: { position: frame.position, logEpoch: frame.log_epoch },
285
+ };
286
+ try {
287
+ await receipts?.keep(frame.carry, fenced);
288
+ }
289
+ catch {
290
+ await lost(frame.authority, frame.carry);
291
+ return;
292
+ }
293
+ kept.set(frame.carry, fenced);
294
+ publish(frame, entries);
295
+ }
296
+ async function load(port) {
297
+ try {
298
+ for (const { key, head } of await port.heads())
299
+ kept.set(key, head);
300
+ }
301
+ catch {
302
+ kept.clear();
303
+ }
304
+ }
305
+ async function restored(room) {
306
+ const line = lines.get(room.authority);
307
+ let at = room.position;
308
+ const chain = [];
309
+ for (;;) {
310
+ const next = [...kept.values()].find((carry) => carry.authority === room.authority &&
311
+ carry.after === at &&
312
+ carry.fenced?.logEpoch === room.log_epoch);
313
+ if (next?.fenced == null)
314
+ break;
315
+ const entries = await keptEntries(next.carry, next.parts).catch(() => null);
316
+ if (entries === null)
317
+ break;
318
+ chain.push({ carry: next, entries });
319
+ at = next.fenced.position;
320
+ }
321
+ const partial = [...kept.values()].find((carry) => carry.authority === room.authority &&
322
+ carry.fenced === null &&
323
+ carry.logEpoch === room.log_epoch &&
324
+ carry.after === at &&
325
+ carry.resume !== null &&
326
+ carry.resume.parts > 0);
327
+ const stale = [...kept.values()].filter((carry) => carry.authority === room.authority &&
328
+ carry !== partial &&
329
+ !chain.some((link) => link.carry === carry));
330
+ await forget(stale.map((carry) => carry.carry));
331
+ if (line !== undefined && line.logEpoch === room.log_epoch && chain.length > 0) {
332
+ const frames = chain.map(({ carry, entries }) => ({
333
+ after: BigInt(carry.after),
334
+ position: BigInt(carry.fenced.position),
335
+ entries,
336
+ }));
337
+ lines.set(room.authority, { ...line, frames: [...line.frames, ...frames] });
338
+ }
339
+ return {
340
+ ...room,
341
+ position: at,
342
+ ...(partial?.resume == null
343
+ ? {}
344
+ : {
345
+ carry: {
346
+ id: partial.carry,
347
+ parts: partial.resume.parts,
348
+ from: partial.resume.from,
349
+ target: partial.resume.target,
350
+ handled: partial.resume.handled,
351
+ ...(partial.resume.piece === null ? {} : { piece: partial.resume.piece }),
352
+ },
353
+ }),
354
+ };
355
+ }
356
+ function handle(frame, via) {
114
357
  if (frame.type === 'signal') {
115
358
  const mode = frame.service_mode;
116
359
  if (mode !== 'open' && mode !== 'write-halted')
@@ -126,6 +369,10 @@ export function houseNotifications(transport, mode) {
126
369
  });
127
370
  return;
128
371
  }
372
+ if (frame.type === 'authority_changed') {
373
+ emit({ kind: 'authority-changed', scope: { authorities: frame.rooms } });
374
+ return;
375
+ }
129
376
  if (frame.type === 'conversations') {
130
377
  emitConversation({ kind: 'list', entries: frame.conversations.map(listedConversation) });
131
378
  return;
@@ -142,13 +389,20 @@ export function houseNotifications(transport, mode) {
142
389
  frame.type === 'process' ||
143
390
  frame.type === 'commands' ||
144
391
  frame.type === 'options' ||
392
+ frame.type === 'starting' ||
393
+ frame.type === 'link' ||
394
+ frame.type === 'deliveries' ||
145
395
  frame.type === 'interactions' ||
146
396
  frame.type === 'message') {
147
397
  converse(frame);
148
398
  return;
149
399
  }
150
- if (frame.type !== 'entries')
151
- return;
400
+ if (frame.type === 'part')
401
+ return stage(frame, via);
402
+ if (frame.type === 'carried')
403
+ return carried(frame);
404
+ }
405
+ function publish(frame, entries) {
152
406
  const at = position(frame.position);
153
407
  const after = position(frame.after);
154
408
  if (at === null || after === null || after >= at) {
@@ -162,7 +416,7 @@ export function houseNotifications(transport, mode) {
162
416
  const last = line.frames.at(-1);
163
417
  if (last !== undefined && at <= last.position)
164
418
  return;
165
- const held = { after, position: at, entries: frame.entries };
419
+ const held = { after, position: at, entries };
166
420
  const next = last !== undefined && after <= last.position ? [...line.frames, held] : [held];
167
421
  lines.set(frame.authority, { ...line, frames: next.length > HELD_FRAMES_MAX ? [] : next });
168
422
  }
@@ -171,11 +425,30 @@ export function houseNotifications(transport, mode) {
171
425
  }
172
426
  announce(frame.authority, { position: frame.position, logEpoch: frame.log_epoch });
173
427
  }
174
- stream.observe(receive);
428
+ stream.observe((frame) => {
429
+ const via = acknowledging;
430
+ if (verifying === 0) {
431
+ const handled = handle(frame, via);
432
+ if (handled === undefined)
433
+ return;
434
+ verifying += 1;
435
+ receiving = handled.finally(() => {
436
+ verifying -= 1;
437
+ });
438
+ return;
439
+ }
440
+ verifying += 1;
441
+ receiving = receiving
442
+ .then(() => handle(frame, via))
443
+ .finally(() => {
444
+ verifying -= 1;
445
+ });
446
+ });
175
447
  stream.opened(reopened);
176
- stream.closed((revoked) => {
448
+ stream.closed(({ revoked, lost }) => {
177
449
  opening = null;
178
- emit({ kind: 'closed', revoked });
450
+ acknowledging = null;
451
+ emit({ kind: 'closed', revoked, lost });
179
452
  });
180
453
  return {
181
454
  runtime,
@@ -198,8 +471,12 @@ export function houseNotifications(transport, mode) {
198
471
  };
199
472
  },
200
473
  },
201
- observe(notify) {
474
+ observe(notify, port) {
202
475
  observers.add(notify);
476
+ if (receipts === null) {
477
+ receipts = port;
478
+ loaded = load(port);
479
+ }
203
480
  if (opening !== null) {
204
481
  queueMicrotask(() => {
205
482
  if (observers.has(notify))
@@ -220,7 +497,30 @@ export function houseNotifications(transport, mode) {
220
497
  }
221
498
  const current = opening;
222
499
  opening = null;
223
- current?.hold(rooms, runtime);
500
+ if (current === null)
501
+ return;
502
+ void loaded
503
+ .then(() => Promise.all(rooms.map(restored)))
504
+ .then((presented) => {
505
+ current.hold(presented, runtime);
506
+ for (const [index, room] of presented.entries()) {
507
+ if (room.position === rooms[index].position)
508
+ continue;
509
+ announce(room.authority, { position: room.position, logEpoch: room.log_epoch });
510
+ }
511
+ });
512
+ },
513
+ published(locator, at) {
514
+ const authority = [...locators].find(([, held]) => held.includes(locator))?.[0];
515
+ const reached = position(at.position);
516
+ if (authority === undefined || reached === null)
517
+ return;
518
+ void forget([...kept.values()]
519
+ .filter((carry) => carry.authority === authority &&
520
+ carry.fenced !== null &&
521
+ carry.fenced.logEpoch === at.logEpoch &&
522
+ BigInt(carry.fenced.position) <= reached)
523
+ .map((carry) => carry.carry));
224
524
  },
225
525
  reopen() {
226
526
  const current = opening;
@@ -239,6 +539,9 @@ export function houseNotifications(transport, mode) {
239
539
  if (!locators.has(authority))
240
540
  lines.delete(authority);
241
541
  }
542
+ void loaded.then(() => forget([...kept.values()]
543
+ .filter((carry) => !locators.has(carry.authority))
544
+ .map((carry) => carry.carry)));
242
545
  },
243
546
  reach(authority, at) {
244
547
  const line = lines.get(authority);
@@ -253,7 +556,18 @@ export function houseNotifications(transport, mode) {
253
556
  held,
254
557
  });
255
558
  },
256
- advance(tracked, from, holds) {
559
+ edited(tracked, from) {
560
+ const line = lines.get(tracked.authority);
561
+ const start = position(from.position);
562
+ if (line === undefined || start === null || line.logEpoch !== from.logEpoch)
563
+ return [];
564
+ return [
565
+ ...new Set(line.frames
566
+ .filter((frame) => frame.position > start)
567
+ .flatMap((frame) => frame.entries.flatMap((entry) => entry.kind === 'edited' && entry.revision !== undefined ? [entry.path] : []))),
568
+ ];
569
+ },
570
+ *advance(tracked, from, holds) {
257
571
  const line = lines.get(tracked.authority);
258
572
  const start = position(from.position);
259
573
  if (line === undefined || start === null || line.logEpoch !== from.logEpoch)
@@ -262,36 +576,26 @@ export function houseNotifications(transport, mode) {
262
576
  const first = pending[0];
263
577
  if (first === undefined || first.after > start)
264
578
  return null;
265
- const documents = {};
266
- const revisions = {};
267
- const changes = {};
268
- const binaryFiles = {};
269
- const removals = [];
270
- const applied = [];
579
+ const answer = answering();
271
580
  const schemas = new Map();
272
- const forget = (path) => {
273
- delete documents[path];
274
- delete revisions[path];
275
- delete changes[path];
276
- delete binaryFiles[path];
277
- const removed = removals.indexOf(path);
278
- if (removed !== -1)
279
- removals.splice(removed, 1);
280
- };
281
581
  for (const frame of pending) {
282
582
  for (const entry of frame.entries) {
583
+ yield ROW_WEIGHT + (entry.text?.length ?? 0);
584
+ if (entry.kind === 'folder') {
585
+ folded(answer, entry.path, entry.removed === true);
586
+ continue;
587
+ }
283
588
  if (entry.kind === 'edited' &&
284
589
  entry.revision !== undefined &&
285
590
  holds?.(entry.path, entry.revision) === true) {
286
- forget(entry.path);
591
+ forgotten(answer, entry.path);
287
592
  continue;
288
593
  }
289
- applied.push(entry);
290
594
  if (tracked.schemas.includes(entry.path))
291
595
  schemas.set(entry.path, entry);
292
596
  if (entry.kind === 'removed') {
293
- forget(entry.path);
294
- removals.push(entry.path);
597
+ forgotten(answer, entry.path);
598
+ answer.removals.add(entry.path);
295
599
  continue;
296
600
  }
297
601
  const binary = binaryFileOf(entry);
@@ -302,31 +606,33 @@ export function houseNotifications(transport, mode) {
302
606
  const head = headChange(entry);
303
607
  if (head === null)
304
608
  return null;
305
- forget(entry.path);
609
+ forgotten(answer, entry.path);
306
610
  if (binary === undefined)
307
- documents[entry.path] = entry.text;
611
+ answer.documents.set(entry.path, entry.text);
308
612
  else
309
- binaryFiles[entry.path] = binary;
613
+ answer.binaryFiles.set(entry.path, binary);
310
614
  const revision = entry.revision ?? binary?.sha256;
311
615
  if (revision !== undefined)
312
- revisions[entry.path] = revision;
616
+ revised(answer, entry.path, revision);
313
617
  if (head !== undefined)
314
- changes[entry.path] = head;
618
+ answer.changes.set(entry.path, head);
315
619
  }
316
620
  }
317
621
  const last = pending.at(-1);
318
- lines.set(tracked.authority, { ...line, frames: pending, held: last.position });
622
+ const current = lines.get(tracked.authority);
623
+ if (current?.logEpoch === line.logEpoch) {
624
+ lines.set(tracked.authority, {
625
+ ...current,
626
+ frames: current.frames.filter((frame) => frame.position > start),
627
+ held: current.held !== null && current.held > last.position ? current.held : last.position,
628
+ });
629
+ }
319
630
  return {
320
631
  page: {
321
632
  kind: 'net-advancement',
322
633
  roomVersion: roomVersion({ position: last.position.toString(), logEpoch: line.logEpoch }),
323
- documents,
324
- revisions,
325
- changes,
326
- binaryFiles,
327
- removals: removals.sort(),
634
+ ...(yield* answered(answer)),
328
635
  },
329
- entries: applied,
330
636
  schemas,
331
637
  };
332
638
  },
@@ -15,27 +15,26 @@ export type HouseDoorAnswer = {
15
15
  body: unknown;
16
16
  };
17
17
  export declare const DOOR_FILES_GET = "/door/files/get";
18
+ export declare const DOOR_FILES_FINISH = "/door/files/finish";
18
19
  export declare const SITE_FILES = "/_house/files/";
19
- export declare const SITE_FILE_RECORD = "record";
20
- export type HouseByteAct = 'authored_batch_upload' | 'conversation_file_upload' | 'binary_stage';
21
- export type HouseByteBody = string | ArrayBuffer | Uint8Array | Blob;
20
+ export type HouseByteAct = 'authored_batch_upload';
22
21
  export type HouseBytesAnswer = {
23
22
  status: number;
24
- blob: Blob | null;
23
+ body: ReadableStream<Uint8Array> | null;
24
+ mediaType: string;
25
25
  };
26
26
  export type HouseByteTransfer = {
27
27
  act: HouseByteAct;
28
28
  url: string;
29
- body: HouseByteBody;
30
- operation?: string;
29
+ body: string;
31
30
  };
32
31
  export type HouseStreamEntry = {
33
32
  path: string;
34
- kind: 'edited' | 'removed';
33
+ kind: 'edited' | 'removed' | 'piece' | 'folder';
34
+ removed?: true;
35
35
  revision?: string;
36
36
  sha256?: string;
37
37
  text?: string;
38
- file?: string;
39
38
  bytes?: number;
40
39
  media_type?: string;
41
40
  author?: {
@@ -46,6 +45,7 @@ export type HouseStreamEntry = {
46
45
  name: string;
47
46
  };
48
47
  created_at?: string;
48
+ continued?: true;
49
49
  };
50
50
  type LiveFact<K extends ConversationEvent['kind']> = Extract<ConversationEvent, {
51
51
  kind: K;
@@ -57,17 +57,32 @@ export type HouseListedConversation = {
57
57
  created_at: string;
58
58
  finished_at: string | null;
59
59
  outcome: string | null;
60
+ waiting: boolean;
60
61
  };
61
62
  export type HouseStreamFrame = {
62
- type: 'entries';
63
+ type: 'part';
63
64
  authority: string;
65
+ carry: string;
66
+ index: number;
67
+ after: string;
68
+ from: string;
69
+ target: string;
70
+ handled: number;
71
+ entries: readonly HouseStreamEntry[];
72
+ } | {
73
+ type: 'carried';
74
+ authority: string;
75
+ carry: string;
76
+ parts: number;
64
77
  after: string;
65
78
  position: string;
66
79
  log_epoch: string;
67
- entries: readonly HouseStreamEntry[];
68
80
  } | {
69
81
  type: 'opening';
70
82
  expired: readonly string[];
83
+ } | {
84
+ type: 'authority_changed';
85
+ rooms: readonly string[];
71
86
  } | ({
72
87
  type: 'turn';
73
88
  conversation_id: string;
@@ -80,6 +95,10 @@ export type HouseStreamFrame = {
80
95
  type: 'interactions';
81
96
  conversation_id: string;
82
97
  interactions: readonly unknown[];
98
+ } | {
99
+ type: 'deliveries';
100
+ conversation_id: string;
101
+ unknown: readonly string[];
83
102
  } | {
84
103
  type: 'process';
85
104
  conversation_id: string;
@@ -92,6 +111,14 @@ export type HouseStreamFrame = {
92
111
  type: 'options';
93
112
  conversation_id: string;
94
113
  options: LiveFact<'options'>['options'];
114
+ } | {
115
+ type: 'starting';
116
+ conversation_id: string;
117
+ step: string | null;
118
+ } | {
119
+ type: 'link';
120
+ conversation_id: string;
121
+ connected: boolean;
95
122
  } | {
96
123
  type: 'conversations';
97
124
  conversations: readonly HouseListedConversation[];
@@ -105,31 +132,49 @@ export type HouseStreamFrame = {
105
132
  type: 'signal';
106
133
  service_mode: string;
107
134
  };
135
+ export type HouseHeldCarry = {
136
+ id: string;
137
+ parts: number;
138
+ from: string;
139
+ target: string;
140
+ handled: number;
141
+ piece?: {
142
+ sha256: string;
143
+ offset: number;
144
+ };
145
+ };
108
146
  export type HouseHeldRoom = {
109
147
  authority: string;
110
148
  position: string;
111
149
  log_epoch: string;
150
+ carry?: HouseHeldCarry;
112
151
  };
113
152
  export type HouseOpening = {
114
153
  hold(rooms: readonly HouseHeldRoom[], runtime: string): void;
154
+ received(authority: string, carry: string, index: number): void;
115
155
  close(): void;
116
156
  };
157
+ export type HouseClosing = {
158
+ revoked: boolean;
159
+ lost: boolean;
160
+ };
117
161
  export type HouseStream = {
118
162
  observe(receive: (frame: HouseStreamFrame) => void): () => void;
119
163
  opened(notify: (opening: HouseOpening) => void): () => void;
120
- closed(notify: (revoked: boolean) => void): () => void;
164
+ closed(notify: (closing: HouseClosing) => void): () => void;
121
165
  };
122
166
  export type HouseDoor = {
123
- door(route: string, body: unknown): Promise<HouseDoorAnswer>;
167
+ door(route: string, body: unknown, arriving?: (bytes: number) => void): Promise<HouseDoorAnswer>;
124
168
  stream: HouseStream;
125
169
  };
126
170
  export type HouseTransport = HouseDoor & {
127
171
  transfer(request: HouseByteTransfer): Promise<HouseDoorAnswer>;
172
+ put(url: string, body: Blob): Promise<number>;
128
173
  download(url: string): Promise<HouseBytesAnswer>;
129
174
  };
130
175
  export type HouseSiteTransport = HouseDoor & {
131
176
  online(): boolean;
132
- read(route: string): Promise<HouseDoorAnswer>;
177
+ read(route: string, arriving?: (bytes: number) => void): Promise<HouseDoorAnswer>;
133
178
  download(route: string): Promise<HouseBytesAnswer>;
134
179
  };
135
180
  export {};