@agentshouse/mdruntime-adapter 0.1.0-cd673d02b6e50 → 0.1.0-cd7e4bb187177
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 +58 -212
- 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 +2397 -1
- package/dist/house-model.d.ts.map +1 -1
- package/dist/house-model.js +1321 -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.d.ts.map +1 -1
- package/dist/room-types.js +1 -0
- 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 +149 -422
- package/dist/transport.d.ts +34 -33
- 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/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/adapter.js
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { stepped } from '@agentshouse/mdruntime';
|
|
2
|
-
import {
|
|
3
|
-
import { streamedModels, viewModels } from './model.js';
|
|
4
|
-
import { gathered, selections } from './gather.js';
|
|
2
|
+
import { capabilities, discoveredRoom, mapDiscovery, parseAuthorityChange, parseDiscovery, trackedFrom, } from './discovery.js';
|
|
5
3
|
import { createSiteAdapter } from './site.js';
|
|
6
|
-
import { authorityRoot, bootstrapping,
|
|
4
|
+
import { authorityRoot, bootstrapping, parseFileAddress, parseGrant, } from './read.js';
|
|
7
5
|
import { roomStreams } from './room-stream.js';
|
|
8
6
|
import { sha256Hex } from './digest.js';
|
|
9
7
|
import { finishedUpload, houseUpload } from './upload.js';
|
|
10
8
|
import { houseAction } from './actions.js';
|
|
11
|
-
import { classifyDoor,
|
|
12
|
-
import { houseNotifications } from './stream.js';
|
|
13
|
-
import {
|
|
9
|
+
import { classifyDoor, doorRefusal } from './refusal.js';
|
|
10
|
+
import { houseNotifications, } from './stream.js';
|
|
11
|
+
import { houseDoorRoute, } from './transport.js';
|
|
14
12
|
import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, houseMove, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable, } from './write.js';
|
|
15
13
|
import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
|
|
16
|
-
import { followsVersion, logPosition, presented, reachedVersion, roomVersion
|
|
14
|
+
import { followsVersion, logPosition, presented, reachedVersion, roomVersion } from './version.js';
|
|
17
15
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
18
16
|
const UNCERTAIN_READ = { kind: 'transport-uncertainty' };
|
|
19
17
|
const OCTET_STREAM = 'application/octet-stream';
|
|
@@ -51,18 +49,49 @@ export function createAgentsHouseAdapter(options) {
|
|
|
51
49
|
if ('site' in options)
|
|
52
50
|
return createSiteAdapter(options.site, options.snapshot === true);
|
|
53
51
|
const transport = options.transport;
|
|
54
|
-
const notifications = houseNotifications(transport, 'credential'
|
|
52
|
+
const notifications = houseNotifications(transport, 'credential', {
|
|
53
|
+
opened: async (frame) => (frame === null ? null : opened(frame)),
|
|
54
|
+
changed,
|
|
55
|
+
});
|
|
55
56
|
const tracked = new Map();
|
|
56
|
-
const handed = new Map();
|
|
57
57
|
const rooms = roomStreams('credential');
|
|
58
58
|
const unreused = new Set();
|
|
59
|
-
let heldRevisions;
|
|
60
59
|
let bounds;
|
|
61
60
|
function declared() {
|
|
62
61
|
if (bounds === undefined)
|
|
63
62
|
throw new Error('no Discovery declared the bounds');
|
|
64
63
|
return bounds;
|
|
65
64
|
}
|
|
65
|
+
function opened(frame) {
|
|
66
|
+
const document = parseDiscovery(frame);
|
|
67
|
+
if (document === null)
|
|
68
|
+
return null;
|
|
69
|
+
bounds = document.bounds;
|
|
70
|
+
tracked.clear();
|
|
71
|
+
for (const entry of trackedFrom(document))
|
|
72
|
+
tracked.set(entry.locator, entry);
|
|
73
|
+
notifications.track([...tracked.values()]);
|
|
74
|
+
return {
|
|
75
|
+
...mapDiscovery(document, document.authorities.map((authority) => discoveredRoom(authority)), capabilities(document.actions)),
|
|
76
|
+
member: document.member,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function changed(frame) {
|
|
80
|
+
const change = parseAuthorityChange(frame);
|
|
81
|
+
if (change === null)
|
|
82
|
+
return null;
|
|
83
|
+
for (const locator of change.left)
|
|
84
|
+
tracked.delete(locator);
|
|
85
|
+
for (const entry of trackedFrom(change))
|
|
86
|
+
tracked.set(entry.locator, entry);
|
|
87
|
+
notifications.track([...tracked.values()]);
|
|
88
|
+
return {
|
|
89
|
+
kind: 'authority-changed',
|
|
90
|
+
rooms: change.authorities.map((authority) => discoveredRoom(authority)),
|
|
91
|
+
left: change.left,
|
|
92
|
+
member: change.member,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
66
95
|
async function streamedPage(entry, token, held) {
|
|
67
96
|
const part = await rooms.part(entry, token);
|
|
68
97
|
if ('kind' in part)
|
|
@@ -72,11 +101,6 @@ export function createAgentsHouseAdapter(options) {
|
|
|
72
101
|
unreused.add(entry.locator);
|
|
73
102
|
return UNCERTAIN_READ;
|
|
74
103
|
}
|
|
75
|
-
if (part.first && part.ended)
|
|
76
|
-
handed.set(entry.locator, roomVersion(scope));
|
|
77
|
-
else
|
|
78
|
-
handed.delete(entry.locator);
|
|
79
|
-
notifications.reach(entry.authority, scope);
|
|
80
104
|
return {
|
|
81
105
|
...(await stepped(bootstrapping(scope))),
|
|
82
106
|
...(part.models === undefined ? {} : { models: part.models }),
|
|
@@ -89,7 +113,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
89
113
|
const files = reusing === undefined
|
|
90
114
|
? null
|
|
91
115
|
: await heldFiles(entry.authority, reusing, declared().max_held_files);
|
|
92
|
-
const answered = await transport.streamed(
|
|
116
|
+
const answered = await transport.streamed(houseDoorRoute('bootstrap'), {
|
|
93
117
|
prefixes: [authorityRoot(entry.handle)],
|
|
94
118
|
...(files === null ? {} : { held: [files] }),
|
|
95
119
|
}, request.signal ?? new AbortController().signal);
|
|
@@ -97,84 +121,12 @@ export function createAgentsHouseAdapter(options) {
|
|
|
97
121
|
return classifyDoor(answered.status, answered.body, entry.locator) ?? UNCERTAIN_READ;
|
|
98
122
|
return rooms.head(entry, answered.room, request.arriving, request.signal);
|
|
99
123
|
}
|
|
100
|
-
async function enumeratedPage(ask, page) {
|
|
101
|
-
const answer = await transport.door(DOOR_ENUMERATE, {
|
|
102
|
-
prefixes: [authorityRoot(ask.entry.handle)],
|
|
103
|
-
positions: [
|
|
104
|
-
{
|
|
105
|
-
...presented(ask.entry.authority, { position: page.after, logEpoch: ask.from.logEpoch }),
|
|
106
|
-
page: { through: page.through, read: page.read },
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
});
|
|
110
|
-
const failure = classifyRead(answer.status, answer.body, ask.entry.locator);
|
|
111
|
-
if (failure !== null)
|
|
112
|
-
return failure;
|
|
113
|
-
const enumeration = parseEnumeration(answer.body, 'credential');
|
|
114
|
-
if (enumeration === null)
|
|
115
|
-
return UNCERTAIN_READ;
|
|
116
|
-
return (viewOf(enumeration, ask.entry) ?? { kind: 'room-not-readable', locator: ask.entry.locator });
|
|
117
|
-
}
|
|
118
|
-
async function enumeratedRoom(enumeration, ask) {
|
|
119
|
-
const first = viewOf(enumeration, ask.entry);
|
|
120
|
-
if (first === undefined)
|
|
121
|
-
return { kind: 'room-not-readable', locator: ask.entry.locator };
|
|
122
|
-
const view = await wholeView(first, (page) => enumeratedPage(ask, page));
|
|
123
|
-
if ('kind' in view)
|
|
124
|
-
return view;
|
|
125
|
-
notifications.reach(ask.entry.authority, view);
|
|
126
|
-
const answer = await refreshFrom(view, ask.fromRoomVersion);
|
|
127
|
-
if (answer.kind !== 'net-advancement')
|
|
128
|
-
return answer;
|
|
129
|
-
handed.set(ask.entry.locator, roomVersion(view));
|
|
130
|
-
const models = await viewModels(view, ask.entry);
|
|
131
|
-
return models === undefined ? answer : { ...answer, models };
|
|
132
|
-
}
|
|
133
|
-
async function streamed(entry, request, from) {
|
|
134
|
-
if (handed.get(entry.locator) !== request.fromRoomVersion)
|
|
135
|
-
return null;
|
|
136
|
-
const asked = notifications.edited(entry, from);
|
|
137
|
-
const kept = asked.length === 0 || heldRevisions === undefined
|
|
138
|
-
? new Map()
|
|
139
|
-
: await heldRevisions(entry.locator, asked);
|
|
140
|
-
const advanced = await stepped(notifications.advance(entry, from, (path, revision) => kept.get(path) === revision));
|
|
141
|
-
if (advanced === null)
|
|
142
|
-
return null;
|
|
143
|
-
handed.set(entry.locator, advanced.page.roomVersion);
|
|
144
|
-
const models = await streamedModels(advanced.schemas, entry, 'credential');
|
|
145
|
-
return models === undefined ? advanced.page : { ...advanced.page, models };
|
|
146
|
-
}
|
|
147
124
|
function held(rooms) {
|
|
148
|
-
|
|
125
|
+
notifications.send(rooms.flatMap((room) => {
|
|
149
126
|
const entry = tracked.get(room.locator);
|
|
150
127
|
const at = logPosition(room.roomVersion);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
handed.set(room.locator, room.roomVersion);
|
|
154
|
-
notifications.reach(entry.authority, at);
|
|
155
|
-
return [presented(entry.authority, at)];
|
|
156
|
-
});
|
|
157
|
-
notifications.send(kept);
|
|
158
|
-
}
|
|
159
|
-
async function adoptedMove(entry, into, outcome) {
|
|
160
|
-
if (outcome.kind === 'accepted' && outcome.destination !== undefined) {
|
|
161
|
-
await adopted(into, { kind: 'accepted', ...outcome.destination });
|
|
162
|
-
}
|
|
163
|
-
return adopted(entry, outcome);
|
|
164
|
-
}
|
|
165
|
-
async function adopted(entry, outcome) {
|
|
166
|
-
if (outcome.kind !== 'accepted')
|
|
167
|
-
return outcome;
|
|
168
|
-
const held = handed.get(entry.locator);
|
|
169
|
-
if (held === undefined)
|
|
170
|
-
return outcome;
|
|
171
|
-
const follows = followsVersion(held, outcome.roomVersion);
|
|
172
|
-
if (follows)
|
|
173
|
-
handed.set(entry.locator, outcome.roomVersion);
|
|
174
|
-
const at = logPosition(outcome.roomVersion);
|
|
175
|
-
if (follows && at !== null)
|
|
176
|
-
notifications.reach(entry.authority, at);
|
|
177
|
-
return outcome;
|
|
128
|
+
return entry === undefined || at === null ? [] : [presented(entry.authority, at)];
|
|
129
|
+
}));
|
|
178
130
|
}
|
|
179
131
|
function authorityFor(locator) {
|
|
180
132
|
return tracked.get(locator);
|
|
@@ -193,60 +145,18 @@ export function createAgentsHouseAdapter(options) {
|
|
|
193
145
|
return result;
|
|
194
146
|
return { ...result, at: { locator, roomVersion: roomVersion({ position, logEpoch }) } };
|
|
195
147
|
}
|
|
196
|
-
function layered(asks) {
|
|
197
|
-
const depths = new Map();
|
|
198
|
-
const layers = [];
|
|
199
|
-
for (const ask of asks) {
|
|
200
|
-
const depth = depths.get(ask.ask.entry.authority) ?? 0;
|
|
201
|
-
depths.set(ask.ask.entry.authority, depth + 1);
|
|
202
|
-
(layers[depth] ??= []).push(ask);
|
|
203
|
-
}
|
|
204
|
-
return layers;
|
|
205
|
-
}
|
|
206
|
-
async function enumerated(asks) {
|
|
207
|
-
const answers = [];
|
|
208
|
-
const parts = layered(asks.map((ask, index) => ({ ask, index }))).flatMap((layer) => selections(layer, declared().max_prefixes));
|
|
209
|
-
for (const part of parts) {
|
|
210
|
-
let open = [...part];
|
|
211
|
-
while (open.length > 0) {
|
|
212
|
-
const answer = await transport.door(DOOR_ENUMERATE, {
|
|
213
|
-
prefixes: open.map(({ ask }) => authorityRoot(ask.entry.handle)),
|
|
214
|
-
positions: open.map(({ ask }) => presented(ask.entry.authority, ask.from)),
|
|
215
|
-
});
|
|
216
|
-
const classified = open.map(({ ask }) => classifyRead(answer.status, answer.body, ask.entry.locator));
|
|
217
|
-
if (classified[0]?.kind === 'beyond-horizon') {
|
|
218
|
-
const named = doorRefusal(answer.body)?.fields.authority;
|
|
219
|
-
const expired = open.filter(({ ask }) => ask.entry.authority === named);
|
|
220
|
-
const answered = expired.length === 0 ? UNCERTAIN_READ : { kind: 'beyond-horizon' };
|
|
221
|
-
const gone = expired.length === 0 ? open : expired;
|
|
222
|
-
for (const ask of gone)
|
|
223
|
-
answers[ask.index] = answered;
|
|
224
|
-
open = open.filter((ask) => !gone.includes(ask));
|
|
225
|
-
continue;
|
|
226
|
-
}
|
|
227
|
-
const enumeration = classified[0] === null ? parseEnumeration(answer.body, 'credential') : null;
|
|
228
|
-
for (const [answerIndex, { ask, index }] of open.entries()) {
|
|
229
|
-
const failure = classified[answerIndex];
|
|
230
|
-
if (failure !== null && failure !== undefined) {
|
|
231
|
-
answers[index] = failure;
|
|
232
|
-
continue;
|
|
233
|
-
}
|
|
234
|
-
answers[index] =
|
|
235
|
-
enumeration === null ? UNCERTAIN_READ : await enumeratedRoom(enumeration, ask);
|
|
236
|
-
}
|
|
237
|
-
open = [];
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return answers;
|
|
241
|
-
}
|
|
242
|
-
const enumerateTogether = gathered(enumerated);
|
|
243
148
|
async function uploaded(head, changes, delta, bytes, entry, handed, keep) {
|
|
244
149
|
const paths = batchPaths(changes);
|
|
245
150
|
const sha256 = await deltaDigest(delta);
|
|
246
151
|
if (handed !== undefined && handed.sha256 === sha256) {
|
|
247
152
|
return { body: { ...head, paths, upload: handed, runtime: notifications.runtime } };
|
|
248
153
|
}
|
|
249
|
-
const minted = await transport.door(
|
|
154
|
+
const minted = await transport.door(houseDoorRoute('batch-upload'), {
|
|
155
|
+
...head,
|
|
156
|
+
paths,
|
|
157
|
+
bytes,
|
|
158
|
+
sha256,
|
|
159
|
+
});
|
|
250
160
|
if (minted.status !== 200) {
|
|
251
161
|
return {
|
|
252
162
|
outcome: await stepped(mutationOutcome(minted.status, minted.body, entry.locator, entry.handle)),
|
|
@@ -294,11 +204,11 @@ export function createAgentsHouseAdapter(options) {
|
|
|
294
204
|
: { body: inline };
|
|
295
205
|
if ('outcome' in prepared)
|
|
296
206
|
return prepared.outcome;
|
|
297
|
-
const answer = await transport.door(
|
|
207
|
+
const answer = await transport.door(houseDoorRoute('batch'), prepared.body);
|
|
298
208
|
const stagedFiles = await staged(answer, request);
|
|
299
209
|
if (stagedFiles === false)
|
|
300
210
|
return UNCERTAIN;
|
|
301
|
-
const settled = stagedFiles === null ? answer : await transport.door(
|
|
211
|
+
const settled = stagedFiles === null ? answer : await transport.door(houseDoorRoute('batch'), prepared.body);
|
|
302
212
|
if (stagedFiles === true && (await staged(settled, request)) !== null)
|
|
303
213
|
return UNCERTAIN;
|
|
304
214
|
return stepped(mutationOutcome(settled.status, settled.body, entry.locator, entry.handle, into === undefined
|
|
@@ -366,7 +276,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
366
276
|
const entry = authorityFor(request.locator);
|
|
367
277
|
if (entry === undefined)
|
|
368
278
|
return null;
|
|
369
|
-
return () => transport.door(
|
|
279
|
+
return () => transport.door(houseDoorRoute('files/get'), {
|
|
370
280
|
room_ref: entry.authority,
|
|
371
281
|
path: request.path,
|
|
372
282
|
revision: request.revision,
|
|
@@ -378,46 +288,6 @@ export function createAgentsHouseAdapter(options) {
|
|
|
378
288
|
async authorize() {
|
|
379
289
|
return options.authorize();
|
|
380
290
|
},
|
|
381
|
-
async discover(_authorization, scope) {
|
|
382
|
-
const answer = await transport.door(DOOR_DISCOVER, {
|
|
383
|
-
prefixes: [...DISCOVER_PREFIXES],
|
|
384
|
-
...(scope === undefined ? {} : { rooms: scope.authorities }),
|
|
385
|
-
});
|
|
386
|
-
const failed = discoveryFailure(answer.status, answer.body);
|
|
387
|
-
if (failed !== null)
|
|
388
|
-
return failed;
|
|
389
|
-
const document = parseDiscovery(answer.body);
|
|
390
|
-
if (document === null)
|
|
391
|
-
return { kind: 'transport-uncertainty' };
|
|
392
|
-
bounds = document.bounds;
|
|
393
|
-
const entries = trackedFrom(document);
|
|
394
|
-
const covered = scope === undefined
|
|
395
|
-
? null
|
|
396
|
-
: [
|
|
397
|
-
...new Set([
|
|
398
|
-
...[...tracked.values()]
|
|
399
|
-
.filter((entry) => scope.authorities.includes(entry.authority))
|
|
400
|
-
.map((entry) => entry.locator),
|
|
401
|
-
...entries.map((entry) => entry.locator),
|
|
402
|
-
]),
|
|
403
|
-
];
|
|
404
|
-
if (covered === null)
|
|
405
|
-
tracked.clear();
|
|
406
|
-
else
|
|
407
|
-
for (const locator of covered)
|
|
408
|
-
tracked.delete(locator);
|
|
409
|
-
for (const entry of entries)
|
|
410
|
-
tracked.set(entry.locator, entry);
|
|
411
|
-
for (const locator of handed.keys())
|
|
412
|
-
if (!tracked.has(locator))
|
|
413
|
-
handed.delete(locator);
|
|
414
|
-
notifications.track([...tracked.values()]);
|
|
415
|
-
return {
|
|
416
|
-
...mapDiscovery(document, document.authorities.map((authority) => discoveredRoom(authority)), capabilities(document.actions, [...tracked.values()])),
|
|
417
|
-
member: document.member,
|
|
418
|
-
...(covered === null ? {} : { covered }),
|
|
419
|
-
};
|
|
420
|
-
},
|
|
421
291
|
async bootstrap(_authorization, request) {
|
|
422
292
|
const entry = authorityFor(request.locator);
|
|
423
293
|
if (entry === undefined)
|
|
@@ -426,20 +296,6 @@ export function createAgentsHouseAdapter(options) {
|
|
|
426
296
|
? openedRoom(entry, request)
|
|
427
297
|
: streamedPage(entry, request.pageToken, request.held);
|
|
428
298
|
},
|
|
429
|
-
async refresh(_authorization, request) {
|
|
430
|
-
const entry = authorityFor(request.locator);
|
|
431
|
-
if (entry === undefined)
|
|
432
|
-
return { kind: 'room-not-readable', locator: request.locator };
|
|
433
|
-
if (request.pageToken !== undefined)
|
|
434
|
-
return { kind: 'transport-uncertainty' };
|
|
435
|
-
const from = logPosition(request.fromRoomVersion);
|
|
436
|
-
if (from === null)
|
|
437
|
-
return { kind: 'beyond-horizon' };
|
|
438
|
-
const answered = await streamed(entry, request, from);
|
|
439
|
-
if (answered !== null)
|
|
440
|
-
return answered;
|
|
441
|
-
return enumerateTogether({ entry, from, fromRoomVersion: request.fromRoomVersion });
|
|
442
|
-
},
|
|
443
299
|
async mutate(_authorization, request, keep) {
|
|
444
300
|
const entry = authorityFor(request.locator);
|
|
445
301
|
if (entry === undefined)
|
|
@@ -460,17 +316,16 @@ export function createAgentsHouseAdapter(options) {
|
|
|
460
316
|
const bytes = deltaBytes(delta);
|
|
461
317
|
const handed = request.upload;
|
|
462
318
|
const answer = (upload) => submit(request, head, mapped.changes, delta, bytes, entry, upload, keep, into);
|
|
463
|
-
const settle = (outcome) => into === undefined ? adopted(entry, outcome) : adoptedMove(entry, into, outcome);
|
|
464
319
|
const outcome = await answer(handed);
|
|
465
320
|
if (handed === undefined || !lapsedGrant(outcome))
|
|
466
|
-
return
|
|
467
|
-
return
|
|
321
|
+
return outcome;
|
|
322
|
+
return answer(undefined);
|
|
468
323
|
},
|
|
469
324
|
async history(_authorization, request) {
|
|
470
325
|
const entry = authorityFor(request.locator);
|
|
471
326
|
if (entry === undefined)
|
|
472
327
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
473
|
-
const answer = await transport.door(
|
|
328
|
+
const answer = await transport.door(houseDoorRoute('revisions'), revisionBody({
|
|
474
329
|
path: request.path,
|
|
475
330
|
handle: entry.handle,
|
|
476
331
|
...(request.revision === undefined ? {} : { revision: request.revision }),
|
|
@@ -497,7 +352,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
497
352
|
const entry = authorityFor(request.locator);
|
|
498
353
|
if (entry === undefined)
|
|
499
354
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
500
|
-
const declared = await transport.door(
|
|
355
|
+
const declared = await transport.door(houseDoorRoute('files/attach'), {
|
|
501
356
|
room_ref: entry.authority,
|
|
502
357
|
name: request.name,
|
|
503
358
|
bytes: request.byteLength,
|
|
@@ -533,16 +388,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
533
388
|
},
|
|
534
389
|
roomStream: {
|
|
535
390
|
hold: held,
|
|
536
|
-
|
|
537
|
-
observe(notify, receipts, revisions) {
|
|
538
|
-
heldRevisions = revisions;
|
|
539
|
-
return notifications.observe(notify, receipts);
|
|
540
|
-
},
|
|
541
|
-
published(locator, roomVersion) {
|
|
542
|
-
const at = logPosition(roomVersion);
|
|
543
|
-
if (at !== null)
|
|
544
|
-
notifications.published(locator, at);
|
|
545
|
-
},
|
|
391
|
+
observe: notifications.observe,
|
|
546
392
|
},
|
|
547
393
|
conversations: notifications.conversations,
|
|
548
394
|
serviceMode: notifications.serviceMode,
|
package/dist/discovery.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Capability, DiscoveredRoom, Discovery, Member, ProviderLimit, Retention } from '@agentshouse/mdruntime';
|
|
2
2
|
import { type LogPosition } from './version.js';
|
|
3
3
|
export declare const PROVIDER_ACTIONS = "provider-actions";
|
|
4
|
-
export declare const DISCOVER_PREFIXES: readonly string[];
|
|
5
4
|
export type HouseBounds = {
|
|
6
5
|
max_authored_file_bytes: number;
|
|
7
6
|
max_batch_operations: number;
|
|
@@ -40,6 +39,11 @@ export type HouseDiscoveryDocument = {
|
|
|
40
39
|
authorities: readonly HouseAuthority[];
|
|
41
40
|
actions: readonly string[];
|
|
42
41
|
};
|
|
42
|
+
export type HouseAuthorityChange = {
|
|
43
|
+
member: Member;
|
|
44
|
+
authorities: readonly HouseAuthority[];
|
|
45
|
+
left: readonly string[];
|
|
46
|
+
};
|
|
43
47
|
export type TrackedAuthority = LogPosition & {
|
|
44
48
|
locator: string;
|
|
45
49
|
authority: string;
|
|
@@ -57,12 +61,13 @@ export type HouseSiteDiscovery = {
|
|
|
57
61
|
authorities: readonly HouseSiteAuthority[];
|
|
58
62
|
};
|
|
59
63
|
export declare function parseDiscovery(body: unknown): HouseDiscoveryDocument | null;
|
|
64
|
+
export declare function parseAuthorityChange(body: unknown): HouseAuthorityChange | null;
|
|
60
65
|
export declare function parseSiteDiscovery(body: unknown): HouseSiteDiscovery | null;
|
|
61
66
|
export declare function siteTracked(document: HouseSiteDiscovery): TrackedAuthority[];
|
|
62
|
-
export declare function trackedFrom(document: HouseDiscoveryDocument): TrackedAuthority[];
|
|
67
|
+
export declare function trackedFrom(document: Pick<HouseDiscoveryDocument, 'authorities'>): TrackedAuthority[];
|
|
63
68
|
export declare function providerLimits(bounds: HouseBounds): readonly ProviderLimit[];
|
|
64
69
|
export declare function declaredRetention(bounds: HouseBounds): Retention;
|
|
65
|
-
export declare function capabilities(actions: HouseDiscoveryDocument['actions']
|
|
70
|
+
export declare function capabilities(actions: HouseDiscoveryDocument['actions']): readonly Capability[];
|
|
66
71
|
export declare function siteCapabilities(): readonly Capability[];
|
|
67
72
|
export declare function discoveredRoom(authority: HouseAuthority): DiscoveredRoom;
|
|
68
73
|
export declare function mapDiscovery(document: Pick<HouseDiscoveryDocument, 'bounds'>, rooms: readonly DiscoveredRoom[], declared: readonly Capability[]): Discovery;
|
package/dist/discovery.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,SAAS,EACT,MAAM,EACN,aAAa,EACb,SAAS,EACV,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
package/dist/discovery.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { declaredActions
|
|
1
|
+
import { declaredActions } from './actions.js';
|
|
2
|
+
import { SITE_SUBMISSION } from './transport.js';
|
|
2
3
|
import { readPosition, roomVersion } from './version.js';
|
|
3
4
|
export const PROVIDER_ACTIONS = 'provider-actions';
|
|
4
|
-
export const DISCOVER_PREFIXES = ['/'];
|
|
5
|
-
const PRIVATE_HANDLE = 'private';
|
|
6
5
|
const BOUND_KEYS = [
|
|
7
6
|
'max_authored_file_bytes',
|
|
8
7
|
'max_batch_operations',
|
|
@@ -111,6 +110,18 @@ function parseAuthority(value) {
|
|
|
111
110
|
...at,
|
|
112
111
|
};
|
|
113
112
|
}
|
|
113
|
+
function parseAuthorities(value) {
|
|
114
|
+
if (!Array.isArray(value))
|
|
115
|
+
return null;
|
|
116
|
+
const authorities = [];
|
|
117
|
+
for (const entry of value) {
|
|
118
|
+
const authority = parseAuthority(entry);
|
|
119
|
+
if (authority === null)
|
|
120
|
+
return null;
|
|
121
|
+
authorities.push(authority);
|
|
122
|
+
}
|
|
123
|
+
return authorities;
|
|
124
|
+
}
|
|
114
125
|
export function parseDiscovery(body) {
|
|
115
126
|
if (typeof body !== 'object' || body === null)
|
|
116
127
|
return null;
|
|
@@ -126,16 +137,19 @@ export function parseDiscovery(body) {
|
|
|
126
137
|
new Set(actions).size !== actions.length ||
|
|
127
138
|
actions.some((name) => name.length === 0))
|
|
128
139
|
return null;
|
|
129
|
-
|
|
140
|
+
const authorities = parseAuthorities(held.authorities);
|
|
141
|
+
return authorities === null ? null : { member, bounds, authorities, actions };
|
|
142
|
+
}
|
|
143
|
+
export function parseAuthorityChange(body) {
|
|
144
|
+
if (typeof body !== 'object' || body === null)
|
|
130
145
|
return null;
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
return { member, bounds, authorities, actions };
|
|
146
|
+
const held = body;
|
|
147
|
+
const member = parseMember(held.member);
|
|
148
|
+
const authorities = parseAuthorities(held.authorities);
|
|
149
|
+
const left = stringList(held.left);
|
|
150
|
+
if (member === null || authorities === null || left === null)
|
|
151
|
+
return null;
|
|
152
|
+
return { member, authorities, left };
|
|
139
153
|
}
|
|
140
154
|
function parseSiteAuthority(value) {
|
|
141
155
|
if (typeof value !== 'object' || value === null)
|
|
@@ -220,21 +234,14 @@ export function declaredRetention(bounds) {
|
|
|
220
234
|
refreshHorizon: bounds.change_retention_seconds,
|
|
221
235
|
};
|
|
222
236
|
}
|
|
223
|
-
export function capabilities(actions
|
|
224
|
-
|
|
225
|
-
return [
|
|
226
|
-
{
|
|
227
|
-
name: PROVIDER_ACTIONS,
|
|
228
|
-
actions: declaredActions(actions),
|
|
229
|
-
...(own === undefined ? {} : { conversationAgents: houseConversationAgents(own.authority) }),
|
|
230
|
-
},
|
|
231
|
-
];
|
|
237
|
+
export function capabilities(actions) {
|
|
238
|
+
return [{ name: PROVIDER_ACTIONS, actions: declaredActions(actions) }];
|
|
232
239
|
}
|
|
233
240
|
export function siteCapabilities() {
|
|
234
241
|
return [
|
|
235
242
|
{
|
|
236
243
|
name: PROVIDER_ACTIONS,
|
|
237
|
-
actions: [{ name:
|
|
244
|
+
actions: [{ name: SITE_SUBMISSION, inputShape: {}, resultKind: 'house' }],
|
|
238
245
|
},
|
|
239
246
|
];
|
|
240
247
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AcceptedMessage, ActionResult, ConversationHistoryRequest } from '@agentshouse/mdruntime';
|
|
2
|
+
import { type HouseDoor } from './transport.js';
|
|
3
|
+
export declare const HISTORY_PAGE = 100;
|
|
4
|
+
type HistoryCursor = {
|
|
5
|
+
accepted_at: string;
|
|
6
|
+
message_id: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function cursorPosition(cursor: HistoryCursor): string;
|
|
9
|
+
export declare function acceptedMessage(entry: unknown): AcceptedMessage | null;
|
|
10
|
+
export declare function houseHistory(transport: HouseDoor, request: ConversationHistoryRequest): Promise<ActionResult>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAGZ,0BAA0B,EAC3B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhE,eAAO,MAAM,YAAY,MAAM,CAAC;AAIhC,KAAK,aAAa,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAkBjE,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAE5D;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAUtE;AA8BD,wBAAsB,YAAY,CAChC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,YAAY,CAAC,CAmBvB"}
|
package/dist/history.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { actionOutcome } from './actions.js';
|
|
2
|
+
import { houseDoorRoute } from './transport.js';
|
|
3
|
+
export const HISTORY_PAGE = 100;
|
|
4
|
+
const HISTORY = 'conversations/history';
|
|
5
|
+
function record(value) {
|
|
6
|
+
return typeof value === 'object' && value !== null ? value : {};
|
|
7
|
+
}
|
|
8
|
+
function text(value, name) {
|
|
9
|
+
const held = record(value)[name];
|
|
10
|
+
return typeof held === 'string' ? held : undefined;
|
|
11
|
+
}
|
|
12
|
+
function historyCursor(value) {
|
|
13
|
+
const acceptedAt = text(value, 'accepted_at');
|
|
14
|
+
const messageId = text(value, 'message_id');
|
|
15
|
+
if (acceptedAt === undefined || messageId === undefined)
|
|
16
|
+
return null;
|
|
17
|
+
return { accepted_at: acceptedAt, message_id: messageId };
|
|
18
|
+
}
|
|
19
|
+
export function cursorPosition(cursor) {
|
|
20
|
+
return JSON.stringify({ accepted_at: cursor.accepted_at, message_id: cursor.message_id });
|
|
21
|
+
}
|
|
22
|
+
function positionCursor(value) {
|
|
23
|
+
try {
|
|
24
|
+
return historyCursor(JSON.parse(value));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function acceptedMessage(entry) {
|
|
31
|
+
const cursor = historyCursor(entry);
|
|
32
|
+
if (cursor === null)
|
|
33
|
+
return null;
|
|
34
|
+
return {
|
|
35
|
+
identity: cursor.message_id,
|
|
36
|
+
turn: text(entry, 'turn_id') ?? cursor.message_id,
|
|
37
|
+
position: cursorPosition(cursor),
|
|
38
|
+
text: text(entry, 'text') ?? '',
|
|
39
|
+
message: structuredClone(record(entry)),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function historyPage(entry) {
|
|
43
|
+
const held = record(entry);
|
|
44
|
+
const conversation = text(held, 'conversation_id');
|
|
45
|
+
if (conversation === undefined || !Array.isArray(held.messages))
|
|
46
|
+
return null;
|
|
47
|
+
const messages = [];
|
|
48
|
+
for (const one of held.messages) {
|
|
49
|
+
const message = acceptedMessage(one);
|
|
50
|
+
if (message === null)
|
|
51
|
+
return null;
|
|
52
|
+
messages.push(message);
|
|
53
|
+
}
|
|
54
|
+
const next = held.next === null || held.next === undefined ? undefined : historyCursor(held.next);
|
|
55
|
+
if (next === null)
|
|
56
|
+
return null;
|
|
57
|
+
return { conversation, messages, ...(next === undefined ? {} : { next: cursorPosition(next) }) };
|
|
58
|
+
}
|
|
59
|
+
function historyAsks(request) {
|
|
60
|
+
const asks = [];
|
|
61
|
+
for (const { conversation, after } of request.conversations) {
|
|
62
|
+
const cursor = after === undefined ? undefined : positionCursor(after);
|
|
63
|
+
if (cursor === null)
|
|
64
|
+
return null;
|
|
65
|
+
asks.push({
|
|
66
|
+
conversation_id: conversation,
|
|
67
|
+
...(cursor === undefined ? {} : { after: cursor }),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return asks;
|
|
71
|
+
}
|
|
72
|
+
export async function houseHistory(transport, request) {
|
|
73
|
+
const asks = historyAsks(request);
|
|
74
|
+
if (asks === null)
|
|
75
|
+
return { kind: 'rejected', code: 'invalid_request', fields: {}, retryable: false };
|
|
76
|
+
const outcome = actionOutcome(await transport.door(houseDoorRoute(HISTORY), { conversations: asks, limit: HISTORY_PAGE }), HISTORY);
|
|
77
|
+
if (outcome.kind !== 'action')
|
|
78
|
+
return outcome;
|
|
79
|
+
const answered = record(outcome.result).histories;
|
|
80
|
+
if (!Array.isArray(answered))
|
|
81
|
+
return { kind: 'transport-uncertainty' };
|
|
82
|
+
const histories = [];
|
|
83
|
+
for (const entry of answered) {
|
|
84
|
+
const page = historyPage(entry);
|
|
85
|
+
if (page === null)
|
|
86
|
+
return { kind: 'transport-uncertainty' };
|
|
87
|
+
histories.push(page);
|
|
88
|
+
}
|
|
89
|
+
const result = { histories };
|
|
90
|
+
return { kind: 'action', result };
|
|
91
|
+
}
|