@agentshouse/mdruntime-adapter 0.1.0-cd23c45caa798 → 0.1.0-cd24cf2286fd6
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 -72
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +7 -319
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +204 -417
- 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/chunks.d.ts +38 -0
- package/dist/chunks.d.ts.map +1 -0
- package/dist/chunks.js +247 -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 +22 -15
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +75 -56
- 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 +641 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +361 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/model.d.ts +5 -4
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +34 -41
- package/dist/read.d.ts +31 -54
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +82 -300
- 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.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 +82 -185
- package/dist/space-schema.d.ts +7 -0
- package/dist/space-schema.d.ts.map +1 -0
- package/dist/space-schema.js +18 -0
- package/dist/stream.d.ts +16 -14
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +230 -408
- package/dist/transport.d.ts +50 -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/part.d.ts +0 -13
- package/dist/part.d.ts.map +0 -1
- package/dist/part.js +0 -80
- package/dist/referrer.d.ts +0 -7
- package/dist/referrer.d.ts.map +0 -1
- package/dist/referrer.js +0 -33
package/dist/stream.js
CHANGED
|
@@ -1,112 +1,111 @@
|
|
|
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 { keptSpaceSchemas, 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, logPosition, presented, 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
|
-
|
|
46
|
+
yield ROW_WEIGHT + (entry.text?.length ?? 0);
|
|
47
|
+
if (entry.kind === 'folder') {
|
|
48
|
+
folded(answer, entry.path, entry.removed === true);
|
|
49
|
+
continue;
|
|
35
50
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
if (entry.text === undefined)
|
|
44
|
-
return null;
|
|
45
|
-
open = { entry, texts: [entry.text] };
|
|
51
|
+
if (entry.path === tracked.schema)
|
|
52
|
+
schemas.set(entry.path, entry);
|
|
53
|
+
forgotten(answer, entry.path);
|
|
54
|
+
if (entry.space !== undefined) {
|
|
55
|
+
answer.removals.add(entry.path);
|
|
56
|
+
continue;
|
|
46
57
|
}
|
|
47
|
-
if (entry.
|
|
58
|
+
if (entry.kind === 'removed') {
|
|
59
|
+
answer.removals.add(entry.path);
|
|
48
60
|
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
61
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
const binary = binaryFileOf(entry);
|
|
63
|
+
if (binary === undefined)
|
|
64
|
+
answer.documents.set(entry.path, entry.text ?? '');
|
|
65
|
+
else if (binary !== null)
|
|
66
|
+
answer.binaryFiles.set(entry.path, binary);
|
|
67
|
+
if (binary === undefined && entry.facts !== undefined)
|
|
68
|
+
answer.facts.set(entry.path, entry.facts);
|
|
69
|
+
const revision = entry.revision ?? binary?.sha256;
|
|
70
|
+
if (revision !== undefined)
|
|
71
|
+
revised(answer, entry.path, revision);
|
|
72
|
+
const head = headChange(entry);
|
|
73
|
+
if (head)
|
|
74
|
+
answer.changes.set(entry.path, head);
|
|
67
75
|
}
|
|
76
|
+
return { kind: 'net-advancement', roomVersion: version, ...(yield* answered(answer)) };
|
|
68
77
|
}
|
|
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
|
-
};
|
|
78
|
+
async function changePage(tracked, entries, version, mode, spaces, whole) {
|
|
79
|
+
const schemas = new Map();
|
|
80
|
+
const page = await stepped(changed(tracked, entries, version, schemas));
|
|
81
|
+
const models = await streamedModels(schemas, tracked, mode, spaces, whole);
|
|
82
|
+
return models === undefined ? page : { ...page, models };
|
|
89
83
|
}
|
|
90
|
-
export function houseNotifications(transport, mode) {
|
|
84
|
+
export function houseNotifications(transport, mode, discovering, spaces) {
|
|
91
85
|
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();
|
|
86
|
+
const staged = new Map();
|
|
87
|
+
let socket = null;
|
|
88
|
+
const tracking = new Map();
|
|
100
89
|
const observers = new Set();
|
|
90
|
+
const replaying = new Map();
|
|
101
91
|
const conversationObservers = new Set();
|
|
102
92
|
const modeObservers = new Set();
|
|
103
93
|
let replicated = [];
|
|
94
|
+
let listedCursor = null;
|
|
95
|
+
const unanswered = [];
|
|
96
|
+
const heldAtZero = new Set();
|
|
104
97
|
const live = new Set();
|
|
105
98
|
let opening = null;
|
|
99
|
+
let announced = null;
|
|
106
100
|
const runtime = crypto.randomUUID();
|
|
107
101
|
function emit(event) {
|
|
108
|
-
for (const observer of observers)
|
|
109
|
-
observer
|
|
102
|
+
for (const observer of observers) {
|
|
103
|
+
const held = replaying.get(observer);
|
|
104
|
+
if (held === undefined)
|
|
105
|
+
observer(event);
|
|
106
|
+
else
|
|
107
|
+
held.push(event);
|
|
108
|
+
}
|
|
110
109
|
}
|
|
111
110
|
function emitConversation(event) {
|
|
112
111
|
if (event.kind === 'turn' ||
|
|
@@ -115,6 +114,7 @@ export function houseNotifications(transport, mode) {
|
|
|
115
114
|
event.kind === 'commands' ||
|
|
116
115
|
event.kind === 'options' ||
|
|
117
116
|
event.kind === 'starting' ||
|
|
117
|
+
event.kind === 'subagents' ||
|
|
118
118
|
event.kind === 'link' ||
|
|
119
119
|
event.kind === 'deliveries') {
|
|
120
120
|
live.add(event.conversation);
|
|
@@ -124,12 +124,33 @@ export function houseNotifications(transport, mode) {
|
|
|
124
124
|
}
|
|
125
125
|
function reopened(next) {
|
|
126
126
|
opening = next;
|
|
127
|
-
|
|
127
|
+
announced = null;
|
|
128
|
+
socket = next;
|
|
129
|
+
staged.clear();
|
|
130
|
+
unanswered.length = 0;
|
|
131
|
+
heldAtZero.clear();
|
|
128
132
|
const gapped = new Set([...replicated, ...live]);
|
|
129
133
|
live.clear();
|
|
130
134
|
for (const conversation of gapped)
|
|
131
135
|
emitConversation({ kind: 'gap', conversation });
|
|
132
136
|
emit({ kind: 'opened' });
|
|
137
|
+
if (mode === 'site')
|
|
138
|
+
announce(next, null);
|
|
139
|
+
}
|
|
140
|
+
function announce(via, frame) {
|
|
141
|
+
void discovering.opened(frame).then((discovery) => {
|
|
142
|
+
if (socket !== via)
|
|
143
|
+
return;
|
|
144
|
+
if (discovery === null) {
|
|
145
|
+
via.close();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
announced = { kind: 'discovered', discovery };
|
|
149
|
+
emit(announced);
|
|
150
|
+
}, () => {
|
|
151
|
+
if (socket === via)
|
|
152
|
+
via.close();
|
|
153
|
+
});
|
|
133
154
|
}
|
|
134
155
|
function converse(frame) {
|
|
135
156
|
const conversation = frame.conversation_id;
|
|
@@ -148,6 +169,7 @@ export function houseNotifications(transport, mode) {
|
|
|
148
169
|
return;
|
|
149
170
|
emitConversation({ kind: 'commands', conversation, commands: [] });
|
|
150
171
|
emitConversation({ kind: 'options', conversation, options: [] });
|
|
172
|
+
emitConversation({ kind: 'subagents', conversation, subagents: [] });
|
|
151
173
|
return;
|
|
152
174
|
}
|
|
153
175
|
if (frame.type === 'commands') {
|
|
@@ -166,6 +188,14 @@ export function houseNotifications(transport, mode) {
|
|
|
166
188
|
emitConversation({ kind: 'starting', conversation, step: frame.step });
|
|
167
189
|
return;
|
|
168
190
|
}
|
|
191
|
+
if (frame.type === 'subagents') {
|
|
192
|
+
emitConversation({
|
|
193
|
+
kind: 'subagents',
|
|
194
|
+
conversation,
|
|
195
|
+
subagents: structuredClone(frame.subagents),
|
|
196
|
+
});
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
169
199
|
if (frame.type === 'link') {
|
|
170
200
|
emitConversation({ kind: 'link', conversation, connected: frame.connected });
|
|
171
201
|
return;
|
|
@@ -187,171 +217,31 @@ export function houseNotifications(transport, mode) {
|
|
|
187
217
|
return;
|
|
188
218
|
emitConversation({ kind: 'accepted-message', conversation, message });
|
|
189
219
|
}
|
|
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);
|
|
220
|
+
function stage(frame, via) {
|
|
221
|
+
const held = staged.get(frame.carry);
|
|
222
|
+
if (frame.index !== (held?.parts ?? 0)) {
|
|
223
|
+
staged.delete(frame.carry);
|
|
223
224
|
return;
|
|
224
225
|
}
|
|
225
226
|
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;
|
|
227
|
+
for (const [carry, other] of staged) {
|
|
228
|
+
if (other.authority === frame.authority)
|
|
229
|
+
staged.delete(carry);
|
|
230
|
+
}
|
|
247
231
|
}
|
|
248
|
-
|
|
232
|
+
const next = held ?? { authority: frame.authority, parts: 0, entries: [] };
|
|
233
|
+
keptSpaceSchemas(frame.entries, spaces);
|
|
234
|
+
next.entries.push(...frame.entries);
|
|
235
|
+
next.parts += 1;
|
|
236
|
+
staged.set(frame.carry, next);
|
|
249
237
|
via?.received(frame.authority, frame.carry, frame.index);
|
|
250
238
|
}
|
|
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);
|
|
239
|
+
function carried(frame) {
|
|
240
|
+
const held = staged.get(frame.carry);
|
|
241
|
+
staged.delete(frame.carry);
|
|
242
|
+
if ((held?.parts ?? 0) !== frame.parts)
|
|
272
243
|
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
|
-
};
|
|
244
|
+
publish(frame, held?.entries ?? []);
|
|
355
245
|
}
|
|
356
246
|
function handle(frame, via) {
|
|
357
247
|
if (frame.type === 'signal') {
|
|
@@ -363,18 +253,35 @@ export function houseNotifications(transport, mode) {
|
|
|
363
253
|
return;
|
|
364
254
|
}
|
|
365
255
|
if (frame.type === 'opening') {
|
|
256
|
+
if (via !== null && mode === 'credential')
|
|
257
|
+
announce(via, frame);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (frame.type === 'caught_up') {
|
|
261
|
+
discovering.expired?.(frame.expired);
|
|
366
262
|
emit({
|
|
367
|
-
kind: '
|
|
368
|
-
expired:
|
|
263
|
+
kind: 'caught-up',
|
|
264
|
+
expired: [
|
|
265
|
+
...frame.expired.flatMap((authority) => (tracking.get(authority) ?? []).map((tracked) => tracked.locator)),
|
|
266
|
+
...(unanswered.shift() ?? []),
|
|
267
|
+
],
|
|
369
268
|
});
|
|
370
269
|
return;
|
|
371
270
|
}
|
|
372
271
|
if (frame.type === 'authority_changed') {
|
|
373
|
-
|
|
272
|
+
const change = discovering.changed(frame);
|
|
273
|
+
if (change !== null)
|
|
274
|
+
emit(change);
|
|
374
275
|
return;
|
|
375
276
|
}
|
|
376
277
|
if (frame.type === 'conversations') {
|
|
377
|
-
emitConversation({
|
|
278
|
+
emitConversation({
|
|
279
|
+
kind: 'list',
|
|
280
|
+
entries: frame.conversations.map(listedConversation),
|
|
281
|
+
whole: frame.whole,
|
|
282
|
+
more: frame.more,
|
|
283
|
+
cursor: frame.cursor,
|
|
284
|
+
});
|
|
378
285
|
return;
|
|
379
286
|
}
|
|
380
287
|
if (frame.type === 'conversation') {
|
|
@@ -390,6 +297,7 @@ export function houseNotifications(transport, mode) {
|
|
|
390
297
|
frame.type === 'commands' ||
|
|
391
298
|
frame.type === 'options' ||
|
|
392
299
|
frame.type === 'starting' ||
|
|
300
|
+
frame.type === 'subagents' ||
|
|
393
301
|
frame.type === 'link' ||
|
|
394
302
|
frame.type === 'deliveries' ||
|
|
395
303
|
frame.type === 'interactions' ||
|
|
@@ -398,57 +306,39 @@ export function houseNotifications(transport, mode) {
|
|
|
398
306
|
return;
|
|
399
307
|
}
|
|
400
308
|
if (frame.type === 'part')
|
|
401
|
-
|
|
402
|
-
if (frame.type === 'carried')
|
|
403
|
-
|
|
309
|
+
stage(frame, via);
|
|
310
|
+
else if (frame.type === 'carried')
|
|
311
|
+
carried(frame);
|
|
404
312
|
}
|
|
405
313
|
function publish(frame, entries) {
|
|
406
314
|
const at = position(frame.position);
|
|
407
315
|
const after = position(frame.after);
|
|
408
|
-
if (at === null || after === null || after >= at)
|
|
409
|
-
interrupt(frame.authority);
|
|
316
|
+
if (at === null || after === null || after >= at)
|
|
410
317
|
return;
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
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;
|
|
318
|
+
const from = after === 0n && !heldAtZero.has(frame.authority)
|
|
319
|
+
? null
|
|
320
|
+
: roomVersion({ position: frame.after, logEpoch: frame.log_epoch });
|
|
321
|
+
const version = roomVersion({ position: frame.position, logEpoch: frame.log_epoch });
|
|
322
|
+
for (const tracked of tracking.get(frame.authority) ?? []) {
|
|
323
|
+
emit({
|
|
324
|
+
kind: 'room-change',
|
|
325
|
+
locator: tracked.locator,
|
|
326
|
+
from,
|
|
327
|
+
roomVersion: version,
|
|
328
|
+
read: () => changePage(tracked, entries, version, mode, spaces, from === null),
|
|
437
329
|
});
|
|
438
|
-
return;
|
|
439
330
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
.then(() => handle(frame, via))
|
|
443
|
-
.finally(() => {
|
|
444
|
-
verifying -= 1;
|
|
445
|
-
});
|
|
446
|
-
});
|
|
331
|
+
}
|
|
332
|
+
stream.observe((frame) => handle(frame, socket));
|
|
447
333
|
stream.opened(reopened);
|
|
448
|
-
stream.closed(({ revoked, lost }) => {
|
|
334
|
+
stream.closed(({ revoked, lost, authorityChanged }) => {
|
|
449
335
|
opening = null;
|
|
450
|
-
|
|
451
|
-
|
|
336
|
+
announced = null;
|
|
337
|
+
socket = null;
|
|
338
|
+
staged.clear();
|
|
339
|
+
unanswered.length = 0;
|
|
340
|
+
heldAtZero.clear();
|
|
341
|
+
emit({ kind: 'closed', revoked, lost, authorityChanged });
|
|
452
342
|
});
|
|
453
343
|
return {
|
|
454
344
|
runtime,
|
|
@@ -464,23 +354,34 @@ export function houseNotifications(transport, mode) {
|
|
|
464
354
|
replicate(next) {
|
|
465
355
|
replicated = [...next];
|
|
466
356
|
},
|
|
357
|
+
hold(cursor) {
|
|
358
|
+
listedCursor = cursor;
|
|
359
|
+
},
|
|
467
360
|
observe(notify) {
|
|
468
361
|
conversationObservers.add(notify);
|
|
469
362
|
return () => {
|
|
470
363
|
conversationObservers.delete(notify);
|
|
471
364
|
};
|
|
472
365
|
},
|
|
366
|
+
...(mode === 'credential'
|
|
367
|
+
? {
|
|
368
|
+
agents: () => houseAgents(transport),
|
|
369
|
+
history: (request) => houseHistory(transport, request),
|
|
370
|
+
}
|
|
371
|
+
: {}),
|
|
473
372
|
},
|
|
474
|
-
observe(notify
|
|
373
|
+
observe(notify) {
|
|
475
374
|
observers.add(notify);
|
|
476
|
-
if (receipts === null) {
|
|
477
|
-
receipts = port;
|
|
478
|
-
loaded = load(port);
|
|
479
|
-
}
|
|
480
375
|
if (opening !== null) {
|
|
376
|
+
const replayed = [{ kind: 'opened' }];
|
|
377
|
+
if (announced !== null)
|
|
378
|
+
replayed.push(announced);
|
|
379
|
+
replaying.set(notify, replayed);
|
|
481
380
|
queueMicrotask(() => {
|
|
482
|
-
|
|
483
|
-
|
|
381
|
+
replaying.delete(notify);
|
|
382
|
+
for (const event of replayed)
|
|
383
|
+
if (observers.has(notify))
|
|
384
|
+
notify(event);
|
|
484
385
|
});
|
|
485
386
|
}
|
|
486
387
|
return () => {
|
|
@@ -488,138 +389,59 @@ export function houseNotifications(transport, mode) {
|
|
|
488
389
|
};
|
|
489
390
|
},
|
|
490
391
|
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
392
|
opening = null;
|
|
500
|
-
|
|
393
|
+
announced = null;
|
|
394
|
+
if (socket === null)
|
|
501
395
|
return;
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
.
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
if (room.position === rooms[index].position)
|
|
508
|
-
continue;
|
|
509
|
-
announce(room.authority, { position: room.position, logEpoch: room.log_epoch });
|
|
510
|
-
}
|
|
396
|
+
const entries = new Map([...tracking.values()].flat().map((tracked) => [tracked.locator, tracked]));
|
|
397
|
+
const named = rooms.flatMap((room) => {
|
|
398
|
+
const entry = entries.get(room.locator);
|
|
399
|
+
const at = room.roomVersion === null ? null : logPosition(room.roomVersion);
|
|
400
|
+
return entry === undefined || at === null ? [] : [{ entry, at }];
|
|
511
401
|
});
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
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();
|
|
529
|
-
},
|
|
530
|
-
track(entries) {
|
|
531
|
-
locators.clear();
|
|
532
|
-
for (const entry of entries) {
|
|
533
|
-
locators.set(entry.authority, [...(locators.get(entry.authority) ?? []), entry.locator]);
|
|
534
|
-
if (lines.get(entry.authority)?.logEpoch !== entry.logEpoch) {
|
|
535
|
-
lines.set(entry.authority, { logEpoch: entry.logEpoch, frames: [], held: null });
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
for (const authority of lines.keys()) {
|
|
539
|
-
if (!locators.has(authority))
|
|
540
|
-
lines.delete(authority);
|
|
402
|
+
const unheld = rooms.flatMap((room) => {
|
|
403
|
+
const entry = entries.get(room.locator);
|
|
404
|
+
return entry === undefined || room.roomVersion !== null ? [] : [entry];
|
|
405
|
+
});
|
|
406
|
+
for (const { entry, at } of named) {
|
|
407
|
+
if (at.position === '0')
|
|
408
|
+
heldAtZero.add(entry.authority);
|
|
409
|
+
else
|
|
410
|
+
heldAtZero.delete(entry.authority);
|
|
541
411
|
}
|
|
542
|
-
|
|
543
|
-
.
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
if (line.held !== null && held <= line.held)
|
|
412
|
+
for (const entry of unheld)
|
|
413
|
+
heldAtZero.delete(entry.authority);
|
|
414
|
+
const site = mode === 'site';
|
|
415
|
+
unanswered.push(site ? unheld.map((entry) => entry.locator) : []);
|
|
416
|
+
socket.hold([
|
|
417
|
+
...named.map(({ entry, at }) => presented(entry.authority, at)),
|
|
418
|
+
...(site ? [] : unheld).map((entry) => presented(entry.authority, { position: '0', logEpoch: entry.logEpoch })),
|
|
419
|
+
], runtime, listedCursor);
|
|
420
|
+
if (site)
|
|
552
421
|
return;
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
422
|
+
const made = unheld.filter((entry) => entry.position === '0');
|
|
423
|
+
queueMicrotask(() => {
|
|
424
|
+
for (const entry of made) {
|
|
425
|
+
const version = roomVersion(entry);
|
|
426
|
+
emit({
|
|
427
|
+
kind: 'room-change',
|
|
428
|
+
locator: entry.locator,
|
|
429
|
+
from: null,
|
|
430
|
+
roomVersion: version,
|
|
431
|
+
read: () => changePage(entry, [], version, mode, spaces, true),
|
|
432
|
+
});
|
|
433
|
+
}
|
|
557
434
|
});
|
|
558
435
|
},
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
const
|
|
562
|
-
|
|
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
|
-
}
|
|
436
|
+
track(entries) {
|
|
437
|
+
tracking.clear();
|
|
438
|
+
for (const entry of entries) {
|
|
439
|
+
tracking.set(entry.authority, [...(tracking.get(entry.authority) ?? []), entry]);
|
|
605
440
|
}
|
|
606
|
-
const
|
|
607
|
-
|
|
608
|
-
|
|
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
|
-
});
|
|
441
|
+
for (const [carry, held] of staged) {
|
|
442
|
+
if (!tracking.has(held.authority))
|
|
443
|
+
staged.delete(carry);
|
|
614
444
|
}
|
|
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
445
|
},
|
|
624
446
|
};
|
|
625
447
|
}
|