@agentshouse/mdruntime-adapter 0.1.0-ce3ced044cab5 → 0.1.0-ce3f1a73f440b
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 +1 -46
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +1 -223
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +60 -213
- package/dist/discovery.d.ts +8 -3
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +29 -22
- package/dist/history.d.ts +12 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +91 -0
- package/dist/house-model.d.ts +954 -1
- package/dist/house-model.d.ts.map +1 -1
- package/dist/house-model.js +521 -486
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/model.d.ts +1 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -17
- package/dist/read.d.ts +1 -44
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +2 -173
- package/dist/refusal.d.ts +0 -3
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +0 -5
- package/dist/room-types.js +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +44 -90
- package/dist/stream.d.ts +13 -14
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +160 -423
- package/dist/transport.d.ts +38 -34
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +53 -12
- package/dist/upload.d.ts.map +1 -1
- package/dist/upload.js +2 -2
- package/dist/write.d.ts +2 -1
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +7 -17
- package/package.json +2 -2
- package/dist/gather.d.ts +0 -3
- package/dist/gather.d.ts.map +0 -1
- package/dist/gather.js +0 -35
package/dist/stream.js
CHANGED
|
@@ -1,108 +1,92 @@
|
|
|
1
|
-
import { ROW_WEIGHT, } from '@agentshouse/mdruntime';
|
|
2
|
-
import { acceptedMessage } from './
|
|
3
|
-
import {
|
|
1
|
+
import { ROW_WEIGHT, stepped, } from '@agentshouse/mdruntime';
|
|
2
|
+
import { acceptedMessage, cursorPosition, houseHistory } from './history.js';
|
|
3
|
+
import { streamedModels } from './model.js';
|
|
4
4
|
import { answered, answering, binaryFileOf, folded, forgotten, headChange, revised, } from './read.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import { houseDoorRoute, } from './transport.js';
|
|
6
|
+
import { DECIMAL, roomVersion } from './version.js';
|
|
7
7
|
function turnOperation(frame) {
|
|
8
8
|
const { type: _type, conversation_id: _conversation, turn_id: _turn, ...operation } = frame;
|
|
9
9
|
return structuredClone(operation);
|
|
10
10
|
}
|
|
11
|
+
async function houseAgents(transport) {
|
|
12
|
+
const answer = await transport.door(houseDoorRoute('agents/read'), {});
|
|
13
|
+
const agents = answer.status === 200 ? answer.body?.agents : null;
|
|
14
|
+
if (!Array.isArray(agents))
|
|
15
|
+
return null;
|
|
16
|
+
return agents.flatMap((one) => {
|
|
17
|
+
const { id, name, retired_at: retired } = (one ?? {});
|
|
18
|
+
return typeof id === 'string' && typeof name === 'string'
|
|
19
|
+
? [{ agent: id, name, retired: retired !== null && retired !== undefined }]
|
|
20
|
+
: [];
|
|
21
|
+
});
|
|
22
|
+
}
|
|
11
23
|
function listedConversation(listed) {
|
|
12
24
|
return {
|
|
13
25
|
conversation: listed.conversation_id,
|
|
14
26
|
agent: listed.agent_id,
|
|
27
|
+
agentName: listed.agent_name,
|
|
28
|
+
agentRetired: listed.agent_retired,
|
|
15
29
|
name: listed.name,
|
|
16
30
|
created: listed.created_at,
|
|
17
31
|
finished: listed.finished_at,
|
|
18
32
|
outcome: listed.outcome,
|
|
19
33
|
waiting: listed.waiting,
|
|
34
|
+
newest: listed.newest === null ? null : cursorPosition(listed.newest),
|
|
20
35
|
};
|
|
21
36
|
}
|
|
22
37
|
function position(value) {
|
|
23
|
-
if (
|
|
38
|
+
if (!DECIMAL.test(value))
|
|
24
39
|
return null;
|
|
25
40
|
return BigInt(value);
|
|
26
41
|
}
|
|
27
|
-
function
|
|
28
|
-
const
|
|
29
|
-
let open = null;
|
|
42
|
+
function* changed(tracked, entries, version, schemas) {
|
|
43
|
+
const answer = answering();
|
|
30
44
|
for (const entry of entries) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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] };
|
|
45
|
+
yield ROW_WEIGHT + (entry.text?.length ?? 0);
|
|
46
|
+
if (entry.kind === 'folder') {
|
|
47
|
+
folded(answer, entry.path, entry.removed === true);
|
|
48
|
+
continue;
|
|
46
49
|
}
|
|
47
|
-
if (entry.
|
|
50
|
+
if (entry.path === tracked.schema)
|
|
51
|
+
schemas.set(entry.path, entry);
|
|
52
|
+
forgotten(answer, entry.path);
|
|
53
|
+
if (entry.kind === 'removed') {
|
|
54
|
+
answer.removals.add(entry.path);
|
|
48
55
|
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
56
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
const binary = binaryFileOf(entry);
|
|
58
|
+
if (binary === undefined)
|
|
59
|
+
answer.documents.set(entry.path, entry.text ?? '');
|
|
60
|
+
else if (binary !== null)
|
|
61
|
+
answer.binaryFiles.set(entry.path, binary);
|
|
62
|
+
const revision = entry.revision ?? binary?.sha256;
|
|
63
|
+
if (revision !== undefined)
|
|
64
|
+
revised(answer, entry.path, revision);
|
|
65
|
+
const head = headChange(entry);
|
|
66
|
+
if (head)
|
|
67
|
+
answer.changes.set(entry.path, head);
|
|
67
68
|
}
|
|
69
|
+
return { kind: 'net-advancement', roomVersion: version, ...(yield* answered(answer)) };
|
|
68
70
|
}
|
|
69
|
-
function
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
};
|
|
71
|
+
async function changePage(tracked, entries, version, mode) {
|
|
72
|
+
const schemas = new Map();
|
|
73
|
+
const page = await stepped(changed(tracked, entries, version, schemas));
|
|
74
|
+
const models = await streamedModels(schemas, tracked, mode);
|
|
75
|
+
return models === undefined ? page : { ...page, models };
|
|
89
76
|
}
|
|
90
|
-
export function houseNotifications(transport, mode) {
|
|
77
|
+
export function houseNotifications(transport, mode, discovering) {
|
|
91
78
|
const stream = transport.stream;
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let loaded = Promise.resolve();
|
|
96
|
-
let acknowledging = null;
|
|
97
|
-
let receiving = Promise.resolve();
|
|
98
|
-
let verifying = 0;
|
|
99
|
-
const locators = new Map();
|
|
79
|
+
const staged = new Map();
|
|
80
|
+
let socket = null;
|
|
81
|
+
const tracking = new Map();
|
|
100
82
|
const observers = new Set();
|
|
101
83
|
const conversationObservers = new Set();
|
|
102
84
|
const modeObservers = new Set();
|
|
103
85
|
let replicated = [];
|
|
86
|
+
let listedCursor = null;
|
|
104
87
|
const live = new Set();
|
|
105
88
|
let opening = null;
|
|
89
|
+
let announced = null;
|
|
106
90
|
const runtime = crypto.randomUUID();
|
|
107
91
|
function emit(event) {
|
|
108
92
|
for (const observer of observers)
|
|
@@ -115,6 +99,7 @@ export function houseNotifications(transport, mode) {
|
|
|
115
99
|
event.kind === 'commands' ||
|
|
116
100
|
event.kind === 'options' ||
|
|
117
101
|
event.kind === 'starting' ||
|
|
102
|
+
event.kind === 'subagents' ||
|
|
118
103
|
event.kind === 'link' ||
|
|
119
104
|
event.kind === 'deliveries') {
|
|
120
105
|
live.add(event.conversation);
|
|
@@ -124,12 +109,31 @@ export function houseNotifications(transport, mode) {
|
|
|
124
109
|
}
|
|
125
110
|
function reopened(next) {
|
|
126
111
|
opening = next;
|
|
127
|
-
|
|
112
|
+
announced = null;
|
|
113
|
+
socket = next;
|
|
114
|
+
staged.clear();
|
|
128
115
|
const gapped = new Set([...replicated, ...live]);
|
|
129
116
|
live.clear();
|
|
130
117
|
for (const conversation of gapped)
|
|
131
118
|
emitConversation({ kind: 'gap', conversation });
|
|
132
119
|
emit({ kind: 'opened' });
|
|
120
|
+
if (mode === 'site')
|
|
121
|
+
announce(next, null);
|
|
122
|
+
}
|
|
123
|
+
function announce(via, frame) {
|
|
124
|
+
void discovering.opened(frame).then((discovery) => {
|
|
125
|
+
if (socket !== via)
|
|
126
|
+
return;
|
|
127
|
+
if (discovery === null) {
|
|
128
|
+
via.close();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
announced = { kind: 'discovered', discovery };
|
|
132
|
+
emit(announced);
|
|
133
|
+
}, () => {
|
|
134
|
+
if (socket === via)
|
|
135
|
+
via.close();
|
|
136
|
+
});
|
|
133
137
|
}
|
|
134
138
|
function converse(frame) {
|
|
135
139
|
const conversation = frame.conversation_id;
|
|
@@ -148,6 +152,7 @@ export function houseNotifications(transport, mode) {
|
|
|
148
152
|
return;
|
|
149
153
|
emitConversation({ kind: 'commands', conversation, commands: [] });
|
|
150
154
|
emitConversation({ kind: 'options', conversation, options: [] });
|
|
155
|
+
emitConversation({ kind: 'subagents', conversation, subagents: [] });
|
|
151
156
|
return;
|
|
152
157
|
}
|
|
153
158
|
if (frame.type === 'commands') {
|
|
@@ -166,6 +171,14 @@ export function houseNotifications(transport, mode) {
|
|
|
166
171
|
emitConversation({ kind: 'starting', conversation, step: frame.step });
|
|
167
172
|
return;
|
|
168
173
|
}
|
|
174
|
+
if (frame.type === 'subagents') {
|
|
175
|
+
emitConversation({
|
|
176
|
+
kind: 'subagents',
|
|
177
|
+
conversation,
|
|
178
|
+
subagents: structuredClone(frame.subagents),
|
|
179
|
+
});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
169
182
|
if (frame.type === 'link') {
|
|
170
183
|
emitConversation({ kind: 'link', conversation, connected: frame.connected });
|
|
171
184
|
return;
|
|
@@ -187,171 +200,30 @@ export function houseNotifications(transport, mode) {
|
|
|
187
200
|
return;
|
|
188
201
|
emitConversation({ kind: 'accepted-message', conversation, message });
|
|
189
202
|
}
|
|
190
|
-
function
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
function interrupt(authority) {
|
|
197
|
-
const line = lines.get(authority);
|
|
198
|
-
if (line !== undefined)
|
|
199
|
-
lines.set(authority, { ...line, frames: [] });
|
|
200
|
-
}
|
|
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);
|
|
203
|
+
function stage(frame, via) {
|
|
204
|
+
const held = staged.get(frame.carry);
|
|
205
|
+
if (frame.index !== (held?.parts ?? 0)) {
|
|
206
|
+
staged.delete(frame.carry);
|
|
223
207
|
return;
|
|
224
208
|
}
|
|
225
209
|
if (held === undefined) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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;
|
|
210
|
+
for (const [carry, other] of staged) {
|
|
211
|
+
if (other.authority === frame.authority)
|
|
212
|
+
staged.delete(carry);
|
|
213
|
+
}
|
|
247
214
|
}
|
|
248
|
-
|
|
215
|
+
const next = held ?? { authority: frame.authority, parts: 0, entries: [] };
|
|
216
|
+
next.entries.push(...frame.entries);
|
|
217
|
+
next.parts += 1;
|
|
218
|
+
staged.set(frame.carry, next);
|
|
249
219
|
via?.received(frame.authority, frame.carry, frame.index);
|
|
250
220
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if (
|
|
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);
|
|
221
|
+
function carried(frame) {
|
|
222
|
+
const held = staged.get(frame.carry);
|
|
223
|
+
staged.delete(frame.carry);
|
|
224
|
+
if ((held?.parts ?? 0) !== frame.parts)
|
|
291
225
|
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
|
-
};
|
|
226
|
+
publish(frame, held?.entries ?? []);
|
|
355
227
|
}
|
|
356
228
|
function handle(frame, via) {
|
|
357
229
|
if (frame.type === 'signal') {
|
|
@@ -363,18 +235,31 @@ export function houseNotifications(transport, mode) {
|
|
|
363
235
|
return;
|
|
364
236
|
}
|
|
365
237
|
if (frame.type === 'opening') {
|
|
238
|
+
if (via !== null && mode === 'credential')
|
|
239
|
+
announce(via, frame);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (frame.type === 'caught_up') {
|
|
366
243
|
emit({
|
|
367
|
-
kind: '
|
|
368
|
-
expired: frame.expired.flatMap((authority) =>
|
|
244
|
+
kind: 'caught-up',
|
|
245
|
+
expired: frame.expired.flatMap((authority) => (tracking.get(authority) ?? []).map((tracked) => tracked.locator)),
|
|
369
246
|
});
|
|
370
247
|
return;
|
|
371
248
|
}
|
|
372
249
|
if (frame.type === 'authority_changed') {
|
|
373
|
-
|
|
250
|
+
const change = discovering.changed(frame);
|
|
251
|
+
if (change !== null)
|
|
252
|
+
emit(change);
|
|
374
253
|
return;
|
|
375
254
|
}
|
|
376
255
|
if (frame.type === 'conversations') {
|
|
377
|
-
emitConversation({
|
|
256
|
+
emitConversation({
|
|
257
|
+
kind: 'list',
|
|
258
|
+
entries: frame.conversations.map(listedConversation),
|
|
259
|
+
whole: frame.whole,
|
|
260
|
+
more: frame.more,
|
|
261
|
+
cursor: frame.cursor,
|
|
262
|
+
});
|
|
378
263
|
return;
|
|
379
264
|
}
|
|
380
265
|
if (frame.type === 'conversation') {
|
|
@@ -390,6 +275,7 @@ export function houseNotifications(transport, mode) {
|
|
|
390
275
|
frame.type === 'commands' ||
|
|
391
276
|
frame.type === 'options' ||
|
|
392
277
|
frame.type === 'starting' ||
|
|
278
|
+
frame.type === 'subagents' ||
|
|
393
279
|
frame.type === 'link' ||
|
|
394
280
|
frame.type === 'deliveries' ||
|
|
395
281
|
frame.type === 'interactions' ||
|
|
@@ -398,56 +284,34 @@ export function houseNotifications(transport, mode) {
|
|
|
398
284
|
return;
|
|
399
285
|
}
|
|
400
286
|
if (frame.type === 'part')
|
|
401
|
-
|
|
402
|
-
if (frame.type === 'carried')
|
|
403
|
-
|
|
287
|
+
stage(frame, via);
|
|
288
|
+
else if (frame.type === 'carried')
|
|
289
|
+
carried(frame);
|
|
404
290
|
}
|
|
405
291
|
function publish(frame, entries) {
|
|
406
292
|
const at = position(frame.position);
|
|
407
293
|
const after = position(frame.after);
|
|
408
|
-
if (at === null || after === null || after >= at)
|
|
409
|
-
interrupt(frame.authority);
|
|
294
|
+
if (at === null || after === null || after >= at)
|
|
410
295
|
return;
|
|
411
|
-
}
|
|
412
|
-
const
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
const next = last !== undefined && after <= last.position ? [...line.frames, held] : [held];
|
|
421
|
-
lines.set(frame.authority, { ...line, frames: next.length > HELD_FRAMES_MAX ? [] : next });
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
interrupt(frame.authority);
|
|
425
|
-
}
|
|
426
|
-
announce(frame.authority, { position: frame.position, logEpoch: frame.log_epoch });
|
|
427
|
-
}
|
|
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;
|
|
296
|
+
const from = roomVersion({ position: frame.after, logEpoch: frame.log_epoch });
|
|
297
|
+
const version = roomVersion({ position: frame.position, logEpoch: frame.log_epoch });
|
|
298
|
+
for (const tracked of tracking.get(frame.authority) ?? []) {
|
|
299
|
+
emit({
|
|
300
|
+
kind: 'room-change',
|
|
301
|
+
locator: tracked.locator,
|
|
302
|
+
from,
|
|
303
|
+
roomVersion: version,
|
|
304
|
+
read: () => changePage(tracked, entries, version, mode),
|
|
437
305
|
});
|
|
438
|
-
return;
|
|
439
306
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
.then(() => handle(frame, via))
|
|
443
|
-
.finally(() => {
|
|
444
|
-
verifying -= 1;
|
|
445
|
-
});
|
|
446
|
-
});
|
|
307
|
+
}
|
|
308
|
+
stream.observe((frame) => handle(frame, socket));
|
|
447
309
|
stream.opened(reopened);
|
|
448
310
|
stream.closed(({ revoked, lost }) => {
|
|
449
311
|
opening = null;
|
|
450
|
-
|
|
312
|
+
announced = null;
|
|
313
|
+
socket = null;
|
|
314
|
+
staged.clear();
|
|
451
315
|
emit({ kind: 'closed', revoked, lost });
|
|
452
316
|
});
|
|
453
317
|
return {
|
|
@@ -464,23 +328,30 @@ export function houseNotifications(transport, mode) {
|
|
|
464
328
|
replicate(next) {
|
|
465
329
|
replicated = [...next];
|
|
466
330
|
},
|
|
331
|
+
hold(cursor) {
|
|
332
|
+
listedCursor = cursor;
|
|
333
|
+
},
|
|
467
334
|
observe(notify) {
|
|
468
335
|
conversationObservers.add(notify);
|
|
469
336
|
return () => {
|
|
470
337
|
conversationObservers.delete(notify);
|
|
471
338
|
};
|
|
472
339
|
},
|
|
340
|
+
...(mode === 'credential'
|
|
341
|
+
? {
|
|
342
|
+
agents: () => houseAgents(transport),
|
|
343
|
+
history: (request) => houseHistory(transport, request),
|
|
344
|
+
}
|
|
345
|
+
: {}),
|
|
473
346
|
},
|
|
474
|
-
observe(notify
|
|
347
|
+
observe(notify) {
|
|
475
348
|
observers.add(notify);
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
loaded = load(port);
|
|
479
|
-
}
|
|
480
|
-
if (opening !== null) {
|
|
349
|
+
const replayed = opening === null ? [] : [{ kind: 'opened' }, announced];
|
|
350
|
+
if (replayed.length > 0) {
|
|
481
351
|
queueMicrotask(() => {
|
|
482
|
-
|
|
483
|
-
|
|
352
|
+
for (const event of replayed)
|
|
353
|
+
if (event !== null && observers.has(notify))
|
|
354
|
+
notify(event);
|
|
484
355
|
});
|
|
485
356
|
}
|
|
486
357
|
return () => {
|
|
@@ -488,153 +359,19 @@ export function houseNotifications(transport, mode) {
|
|
|
488
359
|
};
|
|
489
360
|
},
|
|
490
361
|
send(rooms) {
|
|
491
|
-
for (const room of rooms) {
|
|
492
|
-
const line = lines.get(room.authority);
|
|
493
|
-
const held = position(room.position);
|
|
494
|
-
if (line === undefined || held === null || line.logEpoch !== room.log_epoch)
|
|
495
|
-
continue;
|
|
496
|
-
lines.set(room.authority, { ...line, frames: [], held });
|
|
497
|
-
}
|
|
498
|
-
const current = opening;
|
|
499
362
|
opening = null;
|
|
500
|
-
|
|
501
|
-
|
|
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));
|
|
524
|
-
},
|
|
525
|
-
reopen() {
|
|
526
|
-
const current = opening;
|
|
527
|
-
opening = null;
|
|
528
|
-
current?.close();
|
|
363
|
+
announced = null;
|
|
364
|
+
socket?.hold(rooms, runtime, listedCursor);
|
|
529
365
|
},
|
|
530
366
|
track(entries) {
|
|
531
|
-
|
|
367
|
+
tracking.clear();
|
|
532
368
|
for (const entry of entries) {
|
|
533
|
-
|
|
534
|
-
if (lines.get(entry.authority)?.logEpoch !== entry.logEpoch) {
|
|
535
|
-
lines.set(entry.authority, { logEpoch: entry.logEpoch, frames: [], held: null });
|
|
536
|
-
}
|
|
369
|
+
tracking.set(entry.authority, [...(tracking.get(entry.authority) ?? []), entry]);
|
|
537
370
|
}
|
|
538
|
-
for (const
|
|
539
|
-
if (!
|
|
540
|
-
|
|
371
|
+
for (const [carry, held] of staged) {
|
|
372
|
+
if (!tracking.has(held.authority))
|
|
373
|
+
staged.delete(carry);
|
|
541
374
|
}
|
|
542
|
-
void loaded.then(() => forget([...kept.values()]
|
|
543
|
-
.filter((carry) => !locators.has(carry.authority))
|
|
544
|
-
.map((carry) => carry.carry)));
|
|
545
|
-
},
|
|
546
|
-
reach(authority, at) {
|
|
547
|
-
const line = lines.get(authority);
|
|
548
|
-
const held = position(at.position);
|
|
549
|
-
if (line === undefined || held === null || line.logEpoch !== at.logEpoch)
|
|
550
|
-
return;
|
|
551
|
-
if (line.held !== null && held <= line.held)
|
|
552
|
-
return;
|
|
553
|
-
lines.set(authority, {
|
|
554
|
-
...line,
|
|
555
|
-
frames: line.frames.filter((frame) => frame.position > held),
|
|
556
|
-
held,
|
|
557
|
-
});
|
|
558
|
-
},
|
|
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) {
|
|
571
|
-
const line = lines.get(tracked.authority);
|
|
572
|
-
const start = position(from.position);
|
|
573
|
-
if (line === undefined || start === null || line.logEpoch !== from.logEpoch)
|
|
574
|
-
return null;
|
|
575
|
-
const pending = line.frames.filter((frame) => frame.position > start);
|
|
576
|
-
const first = pending[0];
|
|
577
|
-
if (first === undefined || first.after > start)
|
|
578
|
-
return null;
|
|
579
|
-
const answer = answering();
|
|
580
|
-
const schemas = new Map();
|
|
581
|
-
for (const frame of pending) {
|
|
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
|
-
}
|
|
588
|
-
if (entry.kind === 'edited' &&
|
|
589
|
-
entry.revision !== undefined &&
|
|
590
|
-
holds?.(entry.path, entry.revision) === true) {
|
|
591
|
-
forgotten(answer, entry.path);
|
|
592
|
-
continue;
|
|
593
|
-
}
|
|
594
|
-
if (entry.path === tracked.schema)
|
|
595
|
-
schemas.set(entry.path, entry);
|
|
596
|
-
if (entry.kind === 'removed') {
|
|
597
|
-
forgotten(answer, entry.path);
|
|
598
|
-
answer.removals.add(entry.path);
|
|
599
|
-
continue;
|
|
600
|
-
}
|
|
601
|
-
const binary = binaryFileOf(entry);
|
|
602
|
-
if (binary === null || (binary === undefined && entry.text === undefined))
|
|
603
|
-
return null;
|
|
604
|
-
if (mode === 'credential' && entry.revision === undefined)
|
|
605
|
-
return null;
|
|
606
|
-
const head = headChange(entry);
|
|
607
|
-
if (head === null)
|
|
608
|
-
return null;
|
|
609
|
-
forgotten(answer, entry.path);
|
|
610
|
-
if (binary === undefined)
|
|
611
|
-
answer.documents.set(entry.path, entry.text);
|
|
612
|
-
else
|
|
613
|
-
answer.binaryFiles.set(entry.path, binary);
|
|
614
|
-
const revision = entry.revision ?? binary?.sha256;
|
|
615
|
-
if (revision !== undefined)
|
|
616
|
-
revised(answer, entry.path, revision);
|
|
617
|
-
if (head !== undefined)
|
|
618
|
-
answer.changes.set(entry.path, head);
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
const last = pending.at(-1);
|
|
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
|
-
}
|
|
630
|
-
return {
|
|
631
|
-
page: {
|
|
632
|
-
kind: 'net-advancement',
|
|
633
|
-
roomVersion: roomVersion({ position: last.position.toString(), logEpoch: line.logEpoch }),
|
|
634
|
-
...(yield* answered(answer)),
|
|
635
|
-
},
|
|
636
|
-
schemas,
|
|
637
|
-
};
|
|
638
375
|
},
|
|
639
376
|
};
|
|
640
377
|
}
|