@agentshouse/mdruntime-adapter 0.1.0-cedb8e57837a7 → 0.1.0-cf1ebfb67feeb
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/README.md +2 -2
- package/dist/actions.d.ts +4 -69
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +7 -357
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +204 -411
- package/dist/app-reference.d.ts +2 -0
- package/dist/app-reference.d.ts.map +1 -0
- package/dist/app-reference.js +2 -0
- package/dist/crockford.d.ts +4 -0
- package/dist/crockford.d.ts.map +1 -0
- package/dist/crockford.js +3 -0
- package/dist/discovery.d.ts +21 -13
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +73 -53
- package/dist/history.d.ts +12 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +92 -0
- package/dist/house-model.d.ts +719 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +393 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/model.d.ts +5 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +10 -29
- package/dist/part.d.ts +14 -0
- package/dist/part.d.ts.map +1 -0
- package/dist/part.js +90 -0
- package/dist/read.d.ts +35 -59
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +178 -266
- package/dist/refusal.d.ts +0 -3
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +0 -5
- package/dist/room-stream.d.ts +19 -0
- package/dist/room-stream.d.ts.map +1 -0
- package/dist/room-stream.js +57 -0
- package/dist/room-types.d.ts +7 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +123 -0
- package/dist/search.d.ts +5 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +47 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +83 -193
- package/dist/stream.d.ts +13 -13
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +166 -411
- package/dist/transport.d.ts +54 -40
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +54 -11
- package/dist/upload.d.ts +12 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +63 -0
- package/dist/write.d.ts +6 -1
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +28 -39
- package/package.json +8 -4
- package/AGENTS.md +0 -304
- package/dist/gather.d.ts +0 -4
- package/dist/gather.d.ts.map +0 -1
- package/dist/gather.js +0 -35
- package/dist/handed.d.ts +0 -15
- package/dist/handed.d.ts.map +0 -1
- package/dist/handed.js +0 -45
- package/dist/referrer.d.ts +0 -7
- package/dist/referrer.d.ts.map +0 -1
- package/dist/referrer.js +0 -35
package/dist/stream.js
CHANGED
|
@@ -1,108 +1,95 @@
|
|
|
1
|
-
import { ROW_WEIGHT, } from '@agentshouse/mdruntime';
|
|
2
|
-
import { acceptedMessage } from './
|
|
3
|
-
import {
|
|
4
|
-
import { answered, answering, binaryFileOf, forgotten, headChange, revised } from './read.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
1
|
+
import { ROW_WEIGHT, stepped, } from '@agentshouse/mdruntime';
|
|
2
|
+
import { acceptedMessage, cursorPosition, houseHistory } from './history.js';
|
|
3
|
+
import { streamedModels } from './model.js';
|
|
4
|
+
import { answered, answering, binaryFileOf, folded, forgotten, headChange, revised, } from './read.js';
|
|
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),
|
|
35
|
+
processEnded: listed.process_ended_at,
|
|
20
36
|
};
|
|
21
37
|
}
|
|
22
38
|
function position(value) {
|
|
23
|
-
if (
|
|
39
|
+
if (!DECIMAL.test(value))
|
|
24
40
|
return null;
|
|
25
41
|
return BigInt(value);
|
|
26
42
|
}
|
|
27
|
-
function
|
|
28
|
-
const
|
|
29
|
-
let open = null;
|
|
43
|
+
function* changed(tracked, entries, version, schemas) {
|
|
44
|
+
const answer = answering();
|
|
30
45
|
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] };
|
|
46
|
+
yield ROW_WEIGHT + (entry.text?.length ?? 0);
|
|
47
|
+
if (entry.kind === 'folder') {
|
|
48
|
+
folded(answer, entry.path, entry.removed === true);
|
|
49
|
+
continue;
|
|
46
50
|
}
|
|
47
|
-
if (entry.
|
|
51
|
+
if (entry.path === tracked.schema)
|
|
52
|
+
schemas.set(entry.path, entry);
|
|
53
|
+
forgotten(answer, entry.path);
|
|
54
|
+
if (entry.kind === 'removed') {
|
|
55
|
+
answer.removals.add(entry.path);
|
|
48
56
|
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
57
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
const binary = binaryFileOf(entry);
|
|
59
|
+
if (binary === undefined)
|
|
60
|
+
answer.documents.set(entry.path, entry.text ?? '');
|
|
61
|
+
else if (binary !== null)
|
|
62
|
+
answer.binaryFiles.set(entry.path, binary);
|
|
63
|
+
if (binary === undefined && entry.facts !== undefined)
|
|
64
|
+
answer.facts.set(entry.path, entry.facts);
|
|
65
|
+
const revision = entry.revision ?? binary?.sha256;
|
|
66
|
+
if (revision !== undefined)
|
|
67
|
+
revised(answer, entry.path, revision);
|
|
68
|
+
const head = headChange(entry);
|
|
69
|
+
if (head)
|
|
70
|
+
answer.changes.set(entry.path, head);
|
|
67
71
|
}
|
|
72
|
+
return { kind: 'net-advancement', roomVersion: version, ...(yield* answered(answer)) };
|
|
68
73
|
}
|
|
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
|
-
};
|
|
74
|
+
async function changePage(tracked, entries, version, mode) {
|
|
75
|
+
const schemas = new Map();
|
|
76
|
+
const page = await stepped(changed(tracked, entries, version, schemas));
|
|
77
|
+
const models = await streamedModels(schemas, tracked, mode);
|
|
78
|
+
return models === undefined ? page : { ...page, models };
|
|
89
79
|
}
|
|
90
|
-
export function houseNotifications(transport, mode) {
|
|
80
|
+
export function houseNotifications(transport, mode, discovering) {
|
|
91
81
|
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();
|
|
82
|
+
const staged = new Map();
|
|
83
|
+
let socket = null;
|
|
84
|
+
const tracking = new Map();
|
|
100
85
|
const observers = new Set();
|
|
101
86
|
const conversationObservers = new Set();
|
|
102
87
|
const modeObservers = new Set();
|
|
103
88
|
let replicated = [];
|
|
89
|
+
let listedCursor = null;
|
|
104
90
|
const live = new Set();
|
|
105
91
|
let opening = null;
|
|
92
|
+
let announced = null;
|
|
106
93
|
const runtime = crypto.randomUUID();
|
|
107
94
|
function emit(event) {
|
|
108
95
|
for (const observer of observers)
|
|
@@ -115,6 +102,7 @@ export function houseNotifications(transport, mode) {
|
|
|
115
102
|
event.kind === 'commands' ||
|
|
116
103
|
event.kind === 'options' ||
|
|
117
104
|
event.kind === 'starting' ||
|
|
105
|
+
event.kind === 'subagents' ||
|
|
118
106
|
event.kind === 'link' ||
|
|
119
107
|
event.kind === 'deliveries') {
|
|
120
108
|
live.add(event.conversation);
|
|
@@ -124,12 +112,31 @@ export function houseNotifications(transport, mode) {
|
|
|
124
112
|
}
|
|
125
113
|
function reopened(next) {
|
|
126
114
|
opening = next;
|
|
127
|
-
|
|
115
|
+
announced = null;
|
|
116
|
+
socket = next;
|
|
117
|
+
staged.clear();
|
|
128
118
|
const gapped = new Set([...replicated, ...live]);
|
|
129
119
|
live.clear();
|
|
130
120
|
for (const conversation of gapped)
|
|
131
121
|
emitConversation({ kind: 'gap', conversation });
|
|
132
122
|
emit({ kind: 'opened' });
|
|
123
|
+
if (mode === 'site')
|
|
124
|
+
announce(next, null);
|
|
125
|
+
}
|
|
126
|
+
function announce(via, frame) {
|
|
127
|
+
void discovering.opened(frame).then((discovery) => {
|
|
128
|
+
if (socket !== via)
|
|
129
|
+
return;
|
|
130
|
+
if (discovery === null) {
|
|
131
|
+
via.close();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
announced = { kind: 'discovered', discovery };
|
|
135
|
+
emit(announced);
|
|
136
|
+
}, () => {
|
|
137
|
+
if (socket === via)
|
|
138
|
+
via.close();
|
|
139
|
+
});
|
|
133
140
|
}
|
|
134
141
|
function converse(frame) {
|
|
135
142
|
const conversation = frame.conversation_id;
|
|
@@ -148,6 +155,7 @@ export function houseNotifications(transport, mode) {
|
|
|
148
155
|
return;
|
|
149
156
|
emitConversation({ kind: 'commands', conversation, commands: [] });
|
|
150
157
|
emitConversation({ kind: 'options', conversation, options: [] });
|
|
158
|
+
emitConversation({ kind: 'subagents', conversation, subagents: [] });
|
|
151
159
|
return;
|
|
152
160
|
}
|
|
153
161
|
if (frame.type === 'commands') {
|
|
@@ -166,6 +174,14 @@ export function houseNotifications(transport, mode) {
|
|
|
166
174
|
emitConversation({ kind: 'starting', conversation, step: frame.step });
|
|
167
175
|
return;
|
|
168
176
|
}
|
|
177
|
+
if (frame.type === 'subagents') {
|
|
178
|
+
emitConversation({
|
|
179
|
+
kind: 'subagents',
|
|
180
|
+
conversation,
|
|
181
|
+
subagents: structuredClone(frame.subagents),
|
|
182
|
+
});
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
169
185
|
if (frame.type === 'link') {
|
|
170
186
|
emitConversation({ kind: 'link', conversation, connected: frame.connected });
|
|
171
187
|
return;
|
|
@@ -187,171 +203,30 @@ export function houseNotifications(transport, mode) {
|
|
|
187
203
|
return;
|
|
188
204
|
emitConversation({ kind: 'accepted-message', conversation, message });
|
|
189
205
|
}
|
|
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);
|
|
206
|
+
function stage(frame, via) {
|
|
207
|
+
const held = staged.get(frame.carry);
|
|
208
|
+
if (frame.index !== (held?.parts ?? 0)) {
|
|
209
|
+
staged.delete(frame.carry);
|
|
223
210
|
return;
|
|
224
211
|
}
|
|
225
212
|
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;
|
|
213
|
+
for (const [carry, other] of staged) {
|
|
214
|
+
if (other.authority === frame.authority)
|
|
215
|
+
staged.delete(carry);
|
|
216
|
+
}
|
|
247
217
|
}
|
|
248
|
-
|
|
218
|
+
const next = held ?? { authority: frame.authority, parts: 0, entries: [] };
|
|
219
|
+
next.entries.push(...frame.entries);
|
|
220
|
+
next.parts += 1;
|
|
221
|
+
staged.set(frame.carry, next);
|
|
249
222
|
via?.received(frame.authority, frame.carry, frame.index);
|
|
250
223
|
}
|
|
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);
|
|
224
|
+
function carried(frame) {
|
|
225
|
+
const held = staged.get(frame.carry);
|
|
226
|
+
staged.delete(frame.carry);
|
|
227
|
+
if ((held?.parts ?? 0) !== frame.parts)
|
|
291
228
|
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
|
-
};
|
|
229
|
+
publish(frame, held?.entries ?? []);
|
|
355
230
|
}
|
|
356
231
|
function handle(frame, via) {
|
|
357
232
|
if (frame.type === 'signal') {
|
|
@@ -363,18 +238,31 @@ export function houseNotifications(transport, mode) {
|
|
|
363
238
|
return;
|
|
364
239
|
}
|
|
365
240
|
if (frame.type === 'opening') {
|
|
241
|
+
if (via !== null && mode === 'credential')
|
|
242
|
+
announce(via, frame);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (frame.type === 'caught_up') {
|
|
366
246
|
emit({
|
|
367
|
-
kind: '
|
|
368
|
-
expired: frame.expired.flatMap((authority) =>
|
|
247
|
+
kind: 'caught-up',
|
|
248
|
+
expired: frame.expired.flatMap((authority) => (tracking.get(authority) ?? []).map((tracked) => tracked.locator)),
|
|
369
249
|
});
|
|
370
250
|
return;
|
|
371
251
|
}
|
|
372
252
|
if (frame.type === 'authority_changed') {
|
|
373
|
-
|
|
253
|
+
const change = discovering.changed(frame);
|
|
254
|
+
if (change !== null)
|
|
255
|
+
emit(change);
|
|
374
256
|
return;
|
|
375
257
|
}
|
|
376
258
|
if (frame.type === 'conversations') {
|
|
377
|
-
emitConversation({
|
|
259
|
+
emitConversation({
|
|
260
|
+
kind: 'list',
|
|
261
|
+
entries: frame.conversations.map(listedConversation),
|
|
262
|
+
whole: frame.whole,
|
|
263
|
+
more: frame.more,
|
|
264
|
+
cursor: frame.cursor,
|
|
265
|
+
});
|
|
378
266
|
return;
|
|
379
267
|
}
|
|
380
268
|
if (frame.type === 'conversation') {
|
|
@@ -390,6 +278,7 @@ export function houseNotifications(transport, mode) {
|
|
|
390
278
|
frame.type === 'commands' ||
|
|
391
279
|
frame.type === 'options' ||
|
|
392
280
|
frame.type === 'starting' ||
|
|
281
|
+
frame.type === 'subagents' ||
|
|
393
282
|
frame.type === 'link' ||
|
|
394
283
|
frame.type === 'deliveries' ||
|
|
395
284
|
frame.type === 'interactions' ||
|
|
@@ -398,57 +287,35 @@ export function houseNotifications(transport, mode) {
|
|
|
398
287
|
return;
|
|
399
288
|
}
|
|
400
289
|
if (frame.type === 'part')
|
|
401
|
-
|
|
402
|
-
if (frame.type === 'carried')
|
|
403
|
-
|
|
290
|
+
stage(frame, via);
|
|
291
|
+
else if (frame.type === 'carried')
|
|
292
|
+
carried(frame);
|
|
404
293
|
}
|
|
405
294
|
function publish(frame, entries) {
|
|
406
295
|
const at = position(frame.position);
|
|
407
296
|
const after = position(frame.after);
|
|
408
|
-
if (at === null || after === null || after >= at)
|
|
409
|
-
interrupt(frame.authority);
|
|
297
|
+
if (at === null || after === null || after >= at)
|
|
410
298
|
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;
|
|
299
|
+
const from = roomVersion({ position: frame.after, logEpoch: frame.log_epoch });
|
|
300
|
+
const version = roomVersion({ position: frame.position, logEpoch: frame.log_epoch });
|
|
301
|
+
for (const tracked of tracking.get(frame.authority) ?? []) {
|
|
302
|
+
emit({
|
|
303
|
+
kind: 'room-change',
|
|
304
|
+
locator: tracked.locator,
|
|
305
|
+
from,
|
|
306
|
+
roomVersion: version,
|
|
307
|
+
read: () => changePage(tracked, entries, version, mode),
|
|
437
308
|
});
|
|
438
|
-
return;
|
|
439
309
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
.then(() => handle(frame, via))
|
|
443
|
-
.finally(() => {
|
|
444
|
-
verifying -= 1;
|
|
445
|
-
});
|
|
446
|
-
});
|
|
310
|
+
}
|
|
311
|
+
stream.observe((frame) => handle(frame, socket));
|
|
447
312
|
stream.opened(reopened);
|
|
448
|
-
stream.closed(({ revoked, lost }) => {
|
|
313
|
+
stream.closed(({ revoked, lost, authorityChanged }) => {
|
|
449
314
|
opening = null;
|
|
450
|
-
|
|
451
|
-
|
|
315
|
+
announced = null;
|
|
316
|
+
socket = null;
|
|
317
|
+
staged.clear();
|
|
318
|
+
emit({ kind: 'closed', revoked, lost, authorityChanged });
|
|
452
319
|
});
|
|
453
320
|
return {
|
|
454
321
|
runtime,
|
|
@@ -464,23 +331,30 @@ export function houseNotifications(transport, mode) {
|
|
|
464
331
|
replicate(next) {
|
|
465
332
|
replicated = [...next];
|
|
466
333
|
},
|
|
334
|
+
hold(cursor) {
|
|
335
|
+
listedCursor = cursor;
|
|
336
|
+
},
|
|
467
337
|
observe(notify) {
|
|
468
338
|
conversationObservers.add(notify);
|
|
469
339
|
return () => {
|
|
470
340
|
conversationObservers.delete(notify);
|
|
471
341
|
};
|
|
472
342
|
},
|
|
343
|
+
...(mode === 'credential'
|
|
344
|
+
? {
|
|
345
|
+
agents: () => houseAgents(transport),
|
|
346
|
+
history: (request) => houseHistory(transport, request),
|
|
347
|
+
}
|
|
348
|
+
: {}),
|
|
473
349
|
},
|
|
474
|
-
observe(notify
|
|
350
|
+
observe(notify) {
|
|
475
351
|
observers.add(notify);
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
loaded = load(port);
|
|
479
|
-
}
|
|
480
|
-
if (opening !== null) {
|
|
352
|
+
const replayed = opening === null ? [] : [{ kind: 'opened' }, announced];
|
|
353
|
+
if (replayed.length > 0) {
|
|
481
354
|
queueMicrotask(() => {
|
|
482
|
-
|
|
483
|
-
|
|
355
|
+
for (const event of replayed)
|
|
356
|
+
if (event !== null && observers.has(notify))
|
|
357
|
+
notify(event);
|
|
484
358
|
});
|
|
485
359
|
}
|
|
486
360
|
return () => {
|
|
@@ -488,138 +362,19 @@ export function houseNotifications(transport, mode) {
|
|
|
488
362
|
};
|
|
489
363
|
},
|
|
490
364
|
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
365
|
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();
|
|
366
|
+
announced = null;
|
|
367
|
+
socket?.hold(rooms, runtime, listedCursor);
|
|
529
368
|
},
|
|
530
369
|
track(entries) {
|
|
531
|
-
|
|
370
|
+
tracking.clear();
|
|
532
371
|
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
|
-
}
|
|
372
|
+
tracking.set(entry.authority, [...(tracking.get(entry.authority) ?? []), entry]);
|
|
537
373
|
}
|
|
538
|
-
for (const
|
|
539
|
-
if (!
|
|
540
|
-
|
|
374
|
+
for (const [carry, held] of staged) {
|
|
375
|
+
if (!tracking.has(held.authority))
|
|
376
|
+
staged.delete(carry);
|
|
541
377
|
}
|
|
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
|
-
*advance(tracked, from, holds) {
|
|
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 null;
|
|
564
|
-
const pending = line.frames.filter((frame) => frame.position > start);
|
|
565
|
-
const first = pending[0];
|
|
566
|
-
if (first === undefined || first.after > start)
|
|
567
|
-
return null;
|
|
568
|
-
const answer = answering();
|
|
569
|
-
const schemas = new Map();
|
|
570
|
-
for (const frame of pending) {
|
|
571
|
-
for (const entry of frame.entries) {
|
|
572
|
-
yield ROW_WEIGHT + (entry.text?.length ?? 0);
|
|
573
|
-
if (entry.kind === 'edited' &&
|
|
574
|
-
entry.revision !== undefined &&
|
|
575
|
-
holds?.(entry.path, entry.revision) === true) {
|
|
576
|
-
forgotten(answer, entry.path);
|
|
577
|
-
continue;
|
|
578
|
-
}
|
|
579
|
-
if (tracked.schemas.includes(entry.path))
|
|
580
|
-
schemas.set(entry.path, entry);
|
|
581
|
-
if (entry.kind === 'removed') {
|
|
582
|
-
forgotten(answer, entry.path);
|
|
583
|
-
answer.removals.add(entry.path);
|
|
584
|
-
continue;
|
|
585
|
-
}
|
|
586
|
-
const binary = binaryFileOf(entry);
|
|
587
|
-
if (binary === null || (binary === undefined && entry.text === undefined))
|
|
588
|
-
return null;
|
|
589
|
-
if (mode === 'credential' && entry.revision === undefined)
|
|
590
|
-
return null;
|
|
591
|
-
const head = headChange(entry);
|
|
592
|
-
if (head === null)
|
|
593
|
-
return null;
|
|
594
|
-
forgotten(answer, entry.path);
|
|
595
|
-
if (binary === undefined)
|
|
596
|
-
answer.documents.set(entry.path, entry.text);
|
|
597
|
-
else
|
|
598
|
-
answer.binaryFiles.set(entry.path, binary);
|
|
599
|
-
const revision = entry.revision ?? binary?.sha256;
|
|
600
|
-
if (revision !== undefined)
|
|
601
|
-
revised(answer, entry.path, revision);
|
|
602
|
-
if (head !== undefined)
|
|
603
|
-
answer.changes.set(entry.path, head);
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
const last = pending.at(-1);
|
|
607
|
-
const current = lines.get(tracked.authority);
|
|
608
|
-
if (current?.logEpoch === line.logEpoch) {
|
|
609
|
-
lines.set(tracked.authority, {
|
|
610
|
-
...current,
|
|
611
|
-
frames: current.frames.filter((frame) => frame.position > start),
|
|
612
|
-
held: current.held !== null && current.held > last.position ? current.held : last.position,
|
|
613
|
-
});
|
|
614
|
-
}
|
|
615
|
-
return {
|
|
616
|
-
page: {
|
|
617
|
-
kind: 'net-advancement',
|
|
618
|
-
roomVersion: roomVersion({ position: last.position.toString(), logEpoch: line.logEpoch }),
|
|
619
|
-
...(yield* answered(answer)),
|
|
620
|
-
},
|
|
621
|
-
schemas,
|
|
622
|
-
};
|
|
623
378
|
},
|
|
624
379
|
};
|
|
625
380
|
}
|