@agentshouse/mdruntime-adapter 0.1.0-cd23c45caa798 → 0.1.0-cd519a0f878dc
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 +3 -16
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +23 -53
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +124 -132
- 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 +3 -8
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +11 -24
- package/dist/house-model.d.ts +2 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +441 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/model.d.ts +5 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +11 -13
- package/dist/part.d.ts +4 -2
- package/dist/part.d.ts.map +1 -1
- package/dist/part.js +15 -13
- package/dist/read.d.ts +28 -7
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +172 -95
- package/dist/room-types.d.ts +7 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +124 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +45 -55
- package/dist/stream.d.ts +1 -0
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +17 -2
- package/dist/transport.d.ts +10 -10
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +1 -1
- 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.map +1 -1
- package/dist/write.js +13 -17
- package/package.json +8 -4
- package/AGENTS.md +0 -304
- 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 -33
package/README.md
CHANGED
|
@@ -24,8 +24,8 @@ host.attach(port, 'my-app');
|
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
App code never imports this package; it reaches the Runtime only through the
|
|
27
|
-
client its host hands it. The rules an App's agent follows are
|
|
28
|
-
|
|
27
|
+
client its host hands it. The rules an App's agent follows are the `apps/` pages
|
|
28
|
+
of House's Guide, which House's `open_guide` opens.
|
|
29
29
|
|
|
30
30
|
## License
|
|
31
31
|
|
package/dist/actions.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type AcceptedMessage, type ActionDeclaration, type ActionRequest, type ActionResult, type ConversationAgents, type ConversationHistories, type ConversationHistoryRequest, type FileDeclaration } from '@agentshouse/mdruntime';
|
|
2
2
|
import type { HouseDoorAnswer, HouseTransport } from './transport.js';
|
|
3
|
+
export declare const HISTORY_PAGE = 100;
|
|
4
|
+
export declare const TRIGGER_ROOMS = 100;
|
|
3
5
|
type Operated = {
|
|
4
6
|
readonly operation_id?: string;
|
|
5
7
|
};
|
|
@@ -19,6 +21,7 @@ export type AppInputs = {
|
|
|
19
21
|
};
|
|
20
22
|
readonly 'conversation.create': Operated & {
|
|
21
23
|
readonly agent_id: string;
|
|
24
|
+
readonly replaces?: string;
|
|
22
25
|
};
|
|
23
26
|
readonly 'conversation.delete': ConversationControl;
|
|
24
27
|
readonly 'conversation.history': ConversationHistoryRequest;
|
|
@@ -45,22 +48,6 @@ export type AppAnswerAdditions = {
|
|
|
45
48
|
readonly 'conversation.send': {
|
|
46
49
|
readonly turn: string;
|
|
47
50
|
};
|
|
48
|
-
readonly 'record.list': {
|
|
49
|
-
readonly attachments: readonly {
|
|
50
|
-
readonly referrer: {
|
|
51
|
-
readonly room_ref: string;
|
|
52
|
-
readonly record: string;
|
|
53
|
-
};
|
|
54
|
-
}[];
|
|
55
|
-
readonly records: readonly {
|
|
56
|
-
readonly attachments: readonly {
|
|
57
|
-
readonly referrer: {
|
|
58
|
-
readonly room_ref: string;
|
|
59
|
-
readonly record: string;
|
|
60
|
-
};
|
|
61
|
-
}[];
|
|
62
|
-
}[];
|
|
63
|
-
};
|
|
64
51
|
};
|
|
65
52
|
export declare const HOUSE_APP_ACTS: Readonly<Record<string, string>>;
|
|
66
53
|
export declare const SITE_SUBMIT = "submit";
|
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
package/dist/actions.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { changeBatchIdentity, } from '@agentshouse/mdruntime';
|
|
1
|
+
import { changeBatchIdentity, HISTORY_CONVERSATIONS, } from '@agentshouse/mdruntime';
|
|
2
2
|
import { doorRefusal } from './refusal.js';
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const TRIGGER_ROOMS = 100;
|
|
3
|
+
import { finishedUpload, houseUpload } from './upload.js';
|
|
4
|
+
export const HISTORY_PAGE = 100;
|
|
5
|
+
export const TRIGGER_ROOMS = 100;
|
|
6
6
|
const OCTET_STREAM = 'application/octet-stream';
|
|
7
7
|
function mapped(door, input = (given) => given) {
|
|
8
8
|
return {
|
|
@@ -37,10 +37,13 @@ const APP_ACTS = {
|
|
|
37
37
|
'feature.list': mapped('apps/features/read'),
|
|
38
38
|
'holder.list': mapped('apps/holders'),
|
|
39
39
|
'holder.ring': mapped('apps/ring'),
|
|
40
|
+
'inboxChat.assign': mapped('chats/assign'),
|
|
41
|
+
'inboxChat.return': mapped('chats/return'),
|
|
42
|
+
'inboxChat.takeControl': mapped('chats/take-control'),
|
|
40
43
|
'member.list': mapped('rooms/members'),
|
|
41
44
|
'message.send': mapped('apps/messages/send'),
|
|
42
45
|
'processing.read': mapped('rooms/settings/processing/read'),
|
|
43
|
-
'record.list':
|
|
46
|
+
'record.list': mapped('records/read'),
|
|
44
47
|
'relay.read': mapped('apps/relay'),
|
|
45
48
|
'routine.list': mapped('routines/access'),
|
|
46
49
|
'routineAccess.list': mapped('routines/granted'),
|
|
@@ -106,7 +109,12 @@ function unimplemented(name) {
|
|
|
106
109
|
return { kind: 'rejected', code: 'action-unimplemented', fields: { name }, retryable: false };
|
|
107
110
|
}
|
|
108
111
|
function createBody(input) {
|
|
109
|
-
|
|
112
|
+
const replaces = text(input, 'replaces');
|
|
113
|
+
return {
|
|
114
|
+
agent_id: text(input, 'agent_id'),
|
|
115
|
+
operation_id: operationId(input),
|
|
116
|
+
...(replaces === undefined ? {} : { replaces }),
|
|
117
|
+
};
|
|
110
118
|
}
|
|
111
119
|
function controlBody(input) {
|
|
112
120
|
return { conversation_id: text(input, 'conversation'), operation_id: operationId(input) };
|
|
@@ -154,32 +162,6 @@ export function actionOutcome(answer, name) {
|
|
|
154
162
|
return { kind: 'transport-uncertainty' };
|
|
155
163
|
return { kind: 'action', result: answer.body };
|
|
156
164
|
}
|
|
157
|
-
function referredRecord(view, roomRef) {
|
|
158
|
-
const held = record(view);
|
|
159
|
-
if (roomRef === undefined || typeof held.record !== 'string' || !Array.isArray(held.attachments))
|
|
160
|
-
return view;
|
|
161
|
-
const referrer = {
|
|
162
|
-
room_ref: roomRef,
|
|
163
|
-
record: held.record,
|
|
164
|
-
};
|
|
165
|
-
return {
|
|
166
|
-
...held,
|
|
167
|
-
attachments: held.attachments.map((attachment) => ({ ...record(attachment), referrer })),
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
async function recordsAction(transport, route, input, name) {
|
|
171
|
-
const outcome = actionOutcome(await transport.door(route, input), name);
|
|
172
|
-
if (outcome.kind !== 'action')
|
|
173
|
-
return outcome;
|
|
174
|
-
const roomRef = text(input, 'room_ref');
|
|
175
|
-
const read = record(outcome.result);
|
|
176
|
-
return {
|
|
177
|
-
...outcome,
|
|
178
|
-
result: Array.isArray(read.records)
|
|
179
|
-
? { ...read, records: read.records.map((view) => referredRecord(view, roomRef)) }
|
|
180
|
-
: referredRecord(outcome.result, roomRef),
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
165
|
async function carry(transport, route, name, input) {
|
|
184
166
|
return actionOutcome(await transport.door(route, input), name);
|
|
185
167
|
}
|
|
@@ -217,14 +199,6 @@ function attachBody(input) {
|
|
|
217
199
|
media_type: mediaType !== undefined && mediaType.length > 0 ? mediaType : OCTET_STREAM,
|
|
218
200
|
};
|
|
219
201
|
}
|
|
220
|
-
function uploadGrant(answer) {
|
|
221
|
-
const upload = record(record(answer).upload);
|
|
222
|
-
if (upload.method !== 'POST')
|
|
223
|
-
return null;
|
|
224
|
-
if (typeof upload.operation !== 'string' || typeof upload.url !== 'string')
|
|
225
|
-
return null;
|
|
226
|
-
return { operation: upload.operation, url: upload.url };
|
|
227
|
-
}
|
|
228
202
|
async function attachAction(transport, route, input, name) {
|
|
229
203
|
const body = attachBody(input);
|
|
230
204
|
const blob = record(input).blob;
|
|
@@ -233,20 +207,16 @@ async function attachAction(transport, route, input, name) {
|
|
|
233
207
|
const outcome = actionOutcome(await transport.door(route, body), name);
|
|
234
208
|
if (outcome.kind !== 'action')
|
|
235
209
|
return outcome;
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
210
|
+
const upload = houseUpload(record(outcome.result).upload);
|
|
211
|
+
if (upload === null)
|
|
238
212
|
return { kind: 'transport-uncertainty' };
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
const refusal = doorRefusal(sent.body);
|
|
247
|
-
return refusal === null ? { kind: 'transport-uncertainty' } : { kind: 'rejected', ...refusal };
|
|
248
|
-
}
|
|
249
|
-
const path = text(sent.body, 'path');
|
|
213
|
+
const finished = await finishedUpload(transport, upload, blob);
|
|
214
|
+
if (finished === null)
|
|
215
|
+
return { kind: 'transport-uncertainty' };
|
|
216
|
+
const settled = actionOutcome(finished, name);
|
|
217
|
+
if (settled.kind !== 'action')
|
|
218
|
+
return settled;
|
|
219
|
+
const path = text(settled.result, 'path');
|
|
250
220
|
if (path === undefined)
|
|
251
221
|
return { kind: 'transport-uncertainty' };
|
|
252
222
|
const result = { path };
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,OAAO,EACP,aAAa,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,OAAO,EACP,aAAa,EAkBd,MAAM,wBAAwB,CAAC;AA0ChC,OAAO,EASL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AA0BxB,MAAM,MAAM,yBAAyB,GACjC;IACE,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;CACrC,GACD;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AA8ErD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAmoBpF"}
|
package/dist/adapter.js
CHANGED
|
@@ -1,60 +1,48 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { stepped } from '@agentshouse/mdruntime';
|
|
2
2
|
import { DISCOVER_PREFIXES, capabilities, discoveredRoom, mapDiscovery, parseDiscovery, trackedFrom, } from './discovery.js';
|
|
3
|
-
import { partModels, streamedModels, viewModels } from './model.js';
|
|
3
|
+
import { manifestedModels, partModels, streamedModels, viewModels } from './model.js';
|
|
4
4
|
import { gathered, gatheredEach, selections } from './gather.js';
|
|
5
5
|
import { createSiteAdapter } from './site.js';
|
|
6
|
-
import { authorityRoot, bootstrapping, emptyScope, housePart, parseEnumeration, parseGrant, parseParted, refreshFrom, viewOf, wholeView, } from './read.js';
|
|
7
|
-
import { PART_ATTEMPTS, unverifiedPart } from './part.js';
|
|
6
|
+
import { authorityRoot, bootstrapping, emptyScope, housePart, manifested, parseEnumeration, parseFileAddress, parseGrant, parseParted, partInventory, refreshFrom, viewOf, wholeView, } from './read.js';
|
|
7
|
+
import { PART_ATTEMPTS, partArrival, partFrame, unverifiedPart } from './part.js';
|
|
8
8
|
import { sha256Hex } from './digest.js';
|
|
9
|
-
import {
|
|
9
|
+
import { finishedUpload, houseUpload } from './upload.js';
|
|
10
10
|
import { houseAction } from './actions.js';
|
|
11
11
|
import { classifyDoor, classifyRead, discoveryFailure, doorRefusal } from './refusal.js';
|
|
12
12
|
import { houseNotifications } from './stream.js';
|
|
13
13
|
import { DOOR_BATCH, DOOR_BATCH_UPLOAD, DOOR_BOOTSTRAP, DOOR_DISCOVER, DOOR_ENUMERATE, DOOR_FILES_GET, DOOR_REVISIONS, } from './transport.js';
|
|
14
14
|
import { batchPaths, deltaBody, deltaBytes, deltaDigest, historyOutcome, houseChanges, houseMove, mutationOutcome, operationHead, rejectedMapping, revisionBody, uploadable, } from './write.js';
|
|
15
|
-
import {
|
|
15
|
+
import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
|
|
16
16
|
import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
|
|
17
17
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
18
18
|
const UNCERTAIN_READ = { kind: 'transport-uncertainty' };
|
|
19
|
+
const EXPIRED_ADDRESS = 403;
|
|
19
20
|
function lapsedGrant(outcome) {
|
|
20
21
|
return outcome.kind === 'rejected' && outcome.code === 'upload_unavailable';
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
return known;
|
|
27
|
-
const sorted = await stepped(sortedKeys(held.documents));
|
|
28
|
-
heldPaths.set(held.documents, sorted);
|
|
29
|
-
return sorted;
|
|
30
|
-
}
|
|
31
|
-
function heldFiles(authority, held, paths, bound) {
|
|
32
|
-
const files = [];
|
|
33
|
-
let through = null;
|
|
34
|
-
for (let at = 0; at < paths.length && through === null; at += 1) {
|
|
35
|
-
const revision = held.revisions[paths[at]];
|
|
36
|
-
if (revision === undefined)
|
|
37
|
-
continue;
|
|
38
|
-
if (files.length === bound)
|
|
39
|
-
through = files.at(-1).path;
|
|
40
|
-
else
|
|
41
|
-
files.push({ path: paths[at], revision });
|
|
42
|
-
}
|
|
23
|
+
async function heldFiles(authority, held, bound) {
|
|
24
|
+
const listed = await held.files(null, bound + 1);
|
|
25
|
+
const files = listed.slice(0, bound);
|
|
26
|
+
const through = listed.length > bound ? (files.at(-1)?.path ?? null) : null;
|
|
43
27
|
return files.length === 0 ? null : { room: authority, through, files };
|
|
44
28
|
}
|
|
45
29
|
async function reused(scope, held) {
|
|
46
30
|
const sent = new Set(scope.contents.map((entry) => entry.path));
|
|
47
31
|
const contents = [...scope.contents];
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
32
|
+
const asked = scope.files.filter((file) => file.binary === undefined && !sent.has(file.path));
|
|
33
|
+
if (asked.length === 0)
|
|
34
|
+
return scope;
|
|
35
|
+
if (held === undefined)
|
|
36
|
+
return null;
|
|
37
|
+
const kept = await held.contents(asked.map(({ path }) => path));
|
|
38
|
+
for (const file of asked) {
|
|
39
|
+
const found = kept.get(file.path);
|
|
40
|
+
if (found === undefined ||
|
|
41
|
+
found.revision !== file.revision ||
|
|
42
|
+
(await sha256Hex(found.content)) !== file.sha256) {
|
|
55
43
|
return null;
|
|
56
44
|
}
|
|
57
|
-
contents.push({ path: file.path, content });
|
|
45
|
+
contents.push({ path: file.path, content: found.content });
|
|
58
46
|
}
|
|
59
47
|
return { ...scope, contents };
|
|
60
48
|
}
|
|
@@ -65,51 +53,56 @@ export function createAgentsHouseAdapter(options) {
|
|
|
65
53
|
const notifications = houseNotifications(transport, 'credential');
|
|
66
54
|
const tracked = new Map();
|
|
67
55
|
const handed = new Map();
|
|
56
|
+
let heldRevisions;
|
|
68
57
|
let bounds;
|
|
69
58
|
function declared() {
|
|
70
59
|
if (bounds === undefined)
|
|
71
60
|
throw new Error('no Discovery declared the bounds');
|
|
72
61
|
return bounds;
|
|
73
62
|
}
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
63
|
+
async function fetchedPart(entry, continued, listed, received, arriving) {
|
|
64
|
+
if (received !== undefined) {
|
|
65
|
+
const kept = new Uint8Array(received);
|
|
66
|
+
const held = await housePart(continued.room, kept, listed, 'credential');
|
|
67
|
+
if (held !== null)
|
|
68
|
+
return 'kind' in held ? held : { scope: held, frame: kept };
|
|
80
69
|
}
|
|
81
|
-
return next.then((room) => {
|
|
82
|
-
if (handed.get(locator) === held)
|
|
83
|
-
handed.set(locator, room);
|
|
84
|
-
else
|
|
85
|
-
handed.delete(locator);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
async function fetchedPart(entry, continued, listed) {
|
|
89
70
|
for (let attempt = 0; attempt < PART_ATTEMPTS; attempt += 1) {
|
|
90
71
|
const answered = await transport.door(DOOR_BOOTSTRAP, {
|
|
91
72
|
prefixes: [authorityRoot(entry.handle)],
|
|
92
73
|
part: listed.part,
|
|
93
74
|
...(continued.held === undefined ? {} : { held: [continued.held] }),
|
|
94
|
-
});
|
|
75
|
+
}, partArrival(listed, arriving));
|
|
95
76
|
const failure = classifyRead(answered.status, answered.body, entry.locator);
|
|
96
77
|
if (failure !== null)
|
|
97
78
|
return failure;
|
|
98
|
-
const
|
|
79
|
+
const frame = partFrame(answered.body);
|
|
80
|
+
if (frame === null)
|
|
81
|
+
continue;
|
|
82
|
+
const scope = await housePart(continued.room, frame, listed, 'credential');
|
|
99
83
|
if (scope !== null)
|
|
100
|
-
return scope;
|
|
84
|
+
return 'kind' in scope ? scope : { scope, frame };
|
|
101
85
|
}
|
|
102
86
|
return unverifiedPart(entry.locator);
|
|
103
87
|
}
|
|
104
|
-
async function
|
|
88
|
+
async function manifestPage(asked, continued) {
|
|
89
|
+
const inventory = partInventory(continued.room);
|
|
90
|
+
if (inventory.parts === 0) {
|
|
91
|
+
const page = await partPage(asked, continued, undefined, undefined);
|
|
92
|
+
return page.kind === 'bootstrap' ? { ...page, inventory } : page;
|
|
93
|
+
}
|
|
94
|
+
const { models, seen } = await manifestedModels(continued.room, asked.entry);
|
|
95
|
+
return manifested(continued.room, inventory, JSON.stringify({ ...continued, seen }), models);
|
|
96
|
+
}
|
|
97
|
+
async function partPage(asked, continued, received, arriving) {
|
|
105
98
|
const { entry } = asked;
|
|
106
99
|
const listed = continued.room.parts[continued.next];
|
|
107
100
|
const sent = listed === undefined
|
|
108
|
-
? emptyScope(continued.room)
|
|
109
|
-
: await fetchedPart(entry, continued, listed);
|
|
101
|
+
? { scope: emptyScope(continued.room), frame: null }
|
|
102
|
+
: await fetchedPart(entry, continued, listed, received, arriving);
|
|
110
103
|
if ('kind' in sent)
|
|
111
104
|
return sent;
|
|
112
|
-
const scope = await reused(sent, asked.held);
|
|
105
|
+
const scope = await reused(sent.scope, asked.held);
|
|
113
106
|
if (scope === null) {
|
|
114
107
|
return asked.held === undefined
|
|
115
108
|
? UNCERTAIN_READ
|
|
@@ -118,19 +111,20 @@ export function createAgentsHouseAdapter(options) {
|
|
|
118
111
|
const next = continued.next + 1;
|
|
119
112
|
const more = next < continued.room.parts.length;
|
|
120
113
|
if (continued.next === 0 && !more)
|
|
121
|
-
|
|
114
|
+
handed.set(entry.locator, roomVersion(scope));
|
|
122
115
|
else
|
|
123
116
|
handed.delete(entry.locator);
|
|
124
117
|
notifications.reach(entry.authority, scope);
|
|
125
118
|
const seen = [
|
|
126
119
|
...continued.seen,
|
|
127
|
-
...
|
|
120
|
+
...(scope.files.some((file) => file.path === entry.schema) ? [entry.schema] : []),
|
|
128
121
|
];
|
|
129
122
|
const models = await partModels(scope, entry, new Set(seen), !more);
|
|
130
123
|
return {
|
|
131
124
|
...(await stepped(bootstrapping(scope))),
|
|
132
125
|
...(models === undefined ? {} : { models }),
|
|
133
126
|
...(more ? { pageToken: JSON.stringify({ ...continued, next, seen }) } : {}),
|
|
127
|
+
...(sent.frame === null ? {} : { received: sent.frame }),
|
|
134
128
|
};
|
|
135
129
|
}
|
|
136
130
|
async function enumeratedPage(ask, page) {
|
|
@@ -162,18 +156,21 @@ export function createAgentsHouseAdapter(options) {
|
|
|
162
156
|
const answer = await refreshFrom(view, ask.fromRoomVersion);
|
|
163
157
|
if (answer.kind !== 'net-advancement')
|
|
164
158
|
return answer;
|
|
165
|
-
|
|
159
|
+
handed.set(ask.entry.locator, roomVersion(view));
|
|
166
160
|
const models = await viewModels(view, ask.entry);
|
|
167
161
|
return models === undefined ? answer : { ...answer, models };
|
|
168
162
|
}
|
|
169
163
|
async function streamed(entry, request, from) {
|
|
170
|
-
|
|
171
|
-
if (held?.roomVersion !== request.fromRoomVersion)
|
|
164
|
+
if (handed.get(entry.locator) !== request.fromRoomVersion)
|
|
172
165
|
return null;
|
|
173
|
-
const
|
|
166
|
+
const asked = notifications.edited(entry, from);
|
|
167
|
+
const kept = asked.length === 0 || heldRevisions === undefined
|
|
168
|
+
? new Map()
|
|
169
|
+
: await heldRevisions(entry.locator, asked);
|
|
170
|
+
const advanced = await stepped(notifications.advance(entry, from, (path, revision) => kept.get(path) === revision));
|
|
174
171
|
if (advanced === null)
|
|
175
172
|
return null;
|
|
176
|
-
|
|
173
|
+
handed.set(entry.locator, advanced.page.roomVersion);
|
|
177
174
|
const models = await streamedModels(advanced.schemas, entry, 'credential');
|
|
178
175
|
return models === undefined ? advanced.page : { ...advanced.page, models };
|
|
179
176
|
}
|
|
@@ -183,7 +180,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
183
180
|
const at = logPosition(room.roomVersion);
|
|
184
181
|
if (entry === undefined || at === null)
|
|
185
182
|
return [];
|
|
186
|
-
handed.set(room.locator,
|
|
183
|
+
handed.set(room.locator, room.roomVersion);
|
|
187
184
|
notifications.reach(entry.authority, at);
|
|
188
185
|
return [presented(entry.authority, at)];
|
|
189
186
|
});
|
|
@@ -201,8 +198,9 @@ export function createAgentsHouseAdapter(options) {
|
|
|
201
198
|
const held = handed.get(entry.locator);
|
|
202
199
|
if (held === undefined)
|
|
203
200
|
return outcome;
|
|
204
|
-
const follows = followsVersion(held
|
|
205
|
-
|
|
201
|
+
const follows = followsVersion(held, outcome.roomVersion);
|
|
202
|
+
if (follows)
|
|
203
|
+
handed.set(entry.locator, outcome.roomVersion);
|
|
206
204
|
const at = logPosition(outcome.roomVersion);
|
|
207
205
|
if (follows && at !== null)
|
|
208
206
|
notifications.reach(entry.authority, at);
|
|
@@ -231,8 +229,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
231
229
|
for (const ask of asks) {
|
|
232
230
|
if (ask.held === undefined || bound === 0)
|
|
233
231
|
continue;
|
|
234
|
-
const
|
|
235
|
-
const files = heldFiles(ask.entry.authority, ask.held, paths, bound);
|
|
232
|
+
const files = await heldFiles(ask.entry.authority, ask.held, bound);
|
|
236
233
|
if (files !== null)
|
|
237
234
|
held.push(files);
|
|
238
235
|
}
|
|
@@ -270,7 +267,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
270
267
|
continue;
|
|
271
268
|
}
|
|
272
269
|
const kept = held.find((files) => files.room === asked.entry.authority);
|
|
273
|
-
answer(asked.ask, await
|
|
270
|
+
answer(asked.ask, await manifestPage(asked.asked, {
|
|
274
271
|
room,
|
|
275
272
|
next: 0,
|
|
276
273
|
seen: [],
|
|
@@ -342,7 +339,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
342
339
|
};
|
|
343
340
|
}
|
|
344
341
|
const grant = parseGrant(minted.body);
|
|
345
|
-
if (grant === null
|
|
342
|
+
if (grant === null)
|
|
346
343
|
return { outcome: UNCERTAIN };
|
|
347
344
|
const delivered = await transport.transfer({
|
|
348
345
|
act: 'authored_batch_upload',
|
|
@@ -352,36 +349,31 @@ export function createAgentsHouseAdapter(options) {
|
|
|
352
349
|
if (delivered.status !== 200)
|
|
353
350
|
return { outcome: UNCERTAIN };
|
|
354
351
|
const holding = parseGrant(delivered.body);
|
|
355
|
-
if (holding === null
|
|
352
|
+
if (holding === null)
|
|
356
353
|
return { outcome: UNCERTAIN };
|
|
357
354
|
const upload = { url: holding.url, operation: holding.operation, bytes, sha256 };
|
|
358
355
|
await keep(upload);
|
|
359
356
|
return { body: { ...head, paths, upload, runtime: notifications.runtime } };
|
|
360
357
|
}
|
|
361
|
-
async function staged(answer, batch) {
|
|
358
|
+
async function staged(answer, { changeBatch: batch, file }) {
|
|
362
359
|
const refusal = doorRefusal(answer.body);
|
|
363
360
|
if (refusal?.code !== 'files_unstaged')
|
|
364
361
|
return null;
|
|
365
|
-
const
|
|
366
|
-
if (!Array.isArray(
|
|
362
|
+
const uploads = refusal.fields.upload;
|
|
363
|
+
if (!Array.isArray(uploads))
|
|
367
364
|
return false;
|
|
368
|
-
for (const
|
|
369
|
-
const
|
|
370
|
-
const change = batch.changes.find((held) => held.kind === 'binary' && held.sha256 === sha256);
|
|
371
|
-
if (
|
|
365
|
+
for (const named of uploads) {
|
|
366
|
+
const upload = houseUpload(named);
|
|
367
|
+
const change = batch.changes.find((held) => held.kind === 'binary' && held.sha256 === named.sha256);
|
|
368
|
+
if (upload === null || change === undefined)
|
|
372
369
|
return false;
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
url,
|
|
376
|
-
body: change.blob,
|
|
377
|
-
operation,
|
|
378
|
-
});
|
|
379
|
-
if (delivered.status !== 200)
|
|
370
|
+
const finished = await finishedUpload(transport, upload, await file(change.localId));
|
|
371
|
+
if (finished?.body?.staged !== true)
|
|
380
372
|
return false;
|
|
381
373
|
}
|
|
382
374
|
return true;
|
|
383
375
|
}
|
|
384
|
-
async function submit(
|
|
376
|
+
async function submit(request, head, changes, delta, bytes, entry, handed, keep, into) {
|
|
385
377
|
const inline = { ...head, changes, runtime: notifications.runtime };
|
|
386
378
|
const prepared = uploadable(inline, bytes, declared())
|
|
387
379
|
? await uploaded(head, changes, delta, bytes, entry, handed, keep)
|
|
@@ -389,11 +381,11 @@ export function createAgentsHouseAdapter(options) {
|
|
|
389
381
|
if ('outcome' in prepared)
|
|
390
382
|
return prepared.outcome;
|
|
391
383
|
const answer = await transport.door(DOOR_BATCH, prepared.body);
|
|
392
|
-
const stagedFiles = await staged(answer,
|
|
384
|
+
const stagedFiles = await staged(answer, request);
|
|
393
385
|
if (stagedFiles === false)
|
|
394
386
|
return UNCERTAIN;
|
|
395
387
|
const settled = stagedFiles === null ? answer : await transport.door(DOOR_BATCH, prepared.body);
|
|
396
|
-
if (stagedFiles === true && (await staged(settled,
|
|
388
|
+
if (stagedFiles === true && (await staged(settled, request)) !== null)
|
|
397
389
|
return UNCERTAIN;
|
|
398
390
|
return stepped(mutationOutcome(settled.status, settled.body, entry.locator, entry.handle, into === undefined
|
|
399
391
|
? undefined
|
|
@@ -402,7 +394,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
402
394
|
destination: { authority: into.authority, handle: into.handle },
|
|
403
395
|
}));
|
|
404
396
|
}
|
|
405
|
-
function
|
|
397
|
+
function addressed(answer, locator) {
|
|
406
398
|
const failure = classifyDoor(answer.status, answer.body, locator);
|
|
407
399
|
if (failure !== null) {
|
|
408
400
|
return failure.kind === 'scoped-refusal'
|
|
@@ -414,33 +406,48 @@ export function createAgentsHouseAdapter(options) {
|
|
|
414
406
|
}
|
|
415
407
|
: failure;
|
|
416
408
|
}
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return
|
|
409
|
+
const address = parseFileAddress(answer.body);
|
|
410
|
+
return address === null ? UNCERTAIN_READ : { kind: 'address', ...address };
|
|
411
|
+
}
|
|
412
|
+
function linked(answer, locator) {
|
|
413
|
+
const address = addressed(answer, locator);
|
|
414
|
+
return address.kind === 'address'
|
|
415
|
+
? { kind: 'link', url: address.url, name: address.name }
|
|
416
|
+
: address;
|
|
423
417
|
}
|
|
424
|
-
async function downloaded(
|
|
425
|
-
|
|
426
|
-
if (
|
|
427
|
-
return
|
|
428
|
-
|
|
429
|
-
if (read.status
|
|
418
|
+
async function downloaded(ask, locator) {
|
|
419
|
+
let address = addressed(await ask(), locator);
|
|
420
|
+
if (address.kind !== 'address')
|
|
421
|
+
return address;
|
|
422
|
+
let read = await transport.download(address.url);
|
|
423
|
+
if (read.status === EXPIRED_ADDRESS) {
|
|
424
|
+
address = addressed(await ask(), locator);
|
|
425
|
+
if (address.kind !== 'address')
|
|
426
|
+
return address;
|
|
427
|
+
read = await transport.download(address.url);
|
|
428
|
+
}
|
|
429
|
+
if (read.status !== 200 || read.body === null)
|
|
430
430
|
return UNCERTAIN_READ;
|
|
431
|
-
return {
|
|
431
|
+
return {
|
|
432
|
+
kind: 'binary',
|
|
433
|
+
body: read.body,
|
|
434
|
+
mediaType: address.mediaType,
|
|
435
|
+
sha256: address.sha256,
|
|
436
|
+
};
|
|
432
437
|
}
|
|
433
|
-
function
|
|
438
|
+
function pathAddress(request) {
|
|
434
439
|
const entry = authorityFor(request.locator);
|
|
435
440
|
if (entry === undefined)
|
|
436
441
|
return null;
|
|
437
|
-
return transport.door(DOOR_FILES_GET, {
|
|
442
|
+
return () => transport.door(DOOR_FILES_GET, {
|
|
438
443
|
room_ref: entry.authority,
|
|
439
444
|
path: request.path,
|
|
440
445
|
revision: request.revision,
|
|
441
446
|
});
|
|
442
447
|
}
|
|
443
448
|
return {
|
|
449
|
+
roomTypes: HOUSE_ROOM_TYPES,
|
|
450
|
+
nameableRoomTypes: HOUSE_NAMEABLE_ROOM_TYPES,
|
|
444
451
|
async authorize() {
|
|
445
452
|
return options.authorize();
|
|
446
453
|
},
|
|
@@ -490,7 +497,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
490
497
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
491
498
|
const asked = { entry, held: request.held };
|
|
492
499
|
if (request.pageToken !== undefined) {
|
|
493
|
-
return partPage(asked, JSON.parse(request.pageToken));
|
|
500
|
+
return partPage(asked, JSON.parse(request.pageToken), request.received, request.arriving);
|
|
494
501
|
}
|
|
495
502
|
return bootstrapTogether(asked);
|
|
496
503
|
},
|
|
@@ -527,7 +534,7 @@ export function createAgentsHouseAdapter(options) {
|
|
|
527
534
|
const delta = deltaBody(mapped.changes);
|
|
528
535
|
const bytes = deltaBytes(delta);
|
|
529
536
|
const handed = request.upload;
|
|
530
|
-
const answer = (upload) => submit(
|
|
537
|
+
const answer = (upload) => submit(request, head, mapped.changes, delta, bytes, entry, upload, keep, into);
|
|
531
538
|
const settle = (outcome) => into === undefined ? adopted(entry, outcome) : adoptedMove(entry, into, outcome);
|
|
532
539
|
const outcome = await answer(handed);
|
|
533
540
|
if (handed === undefined || !lapsedGrant(outcome))
|
|
@@ -550,34 +557,16 @@ export function createAgentsHouseAdapter(options) {
|
|
|
550
557
|
});
|
|
551
558
|
},
|
|
552
559
|
async binary(_authorization, request) {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
return downloaded(await asked, request.locator);
|
|
558
|
-
}
|
|
559
|
-
const referrer = houseReferrer(request.referrer, tracked);
|
|
560
|
-
if (referrer === null) {
|
|
561
|
-
return { kind: 'rejected', code: 'referrer_unknown', fields: {}, retryable: false };
|
|
562
|
-
}
|
|
563
|
-
const answer = await transport.door(DOOR_FILES_GET, {
|
|
564
|
-
file: request.fileRef,
|
|
565
|
-
referrer: referrer.referrer,
|
|
566
|
-
});
|
|
567
|
-
return downloaded(answer, referrer.locator);
|
|
560
|
+
const ask = pathAddress(request);
|
|
561
|
+
if (ask === null)
|
|
562
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
563
|
+
return downloaded(ask, request.locator);
|
|
568
564
|
},
|
|
569
565
|
async link(_authorization, request) {
|
|
570
|
-
const
|
|
571
|
-
if (
|
|
566
|
+
const ask = pathAddress(request);
|
|
567
|
+
if (ask === null)
|
|
572
568
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
573
|
-
return
|
|
574
|
-
},
|
|
575
|
-
referrerScope(referrer) {
|
|
576
|
-
const held = houseReferrer(referrer, tracked);
|
|
577
|
-
if (held === null)
|
|
578
|
-
return null;
|
|
579
|
-
const { path } = held.referrer;
|
|
580
|
-
return { locator: held.locator, ...(path === undefined ? {} : { path }) };
|
|
569
|
+
return linked(await ask(), request.locator);
|
|
581
570
|
},
|
|
582
571
|
reached(locator, version, target) {
|
|
583
572
|
return reachedVersion(version, target, authorityFor(locator)?.logEpoch);
|
|
@@ -591,7 +580,10 @@ export function createAgentsHouseAdapter(options) {
|
|
|
591
580
|
roomStream: {
|
|
592
581
|
hold: held,
|
|
593
582
|
reopen: notifications.reopen,
|
|
594
|
-
observe
|
|
583
|
+
observe(notify, receipts, revisions) {
|
|
584
|
+
heldRevisions = revisions;
|
|
585
|
+
return notifications.observe(notify, receipts);
|
|
586
|
+
},
|
|
595
587
|
published(locator, roomVersion) {
|
|
596
588
|
const at = logPosition(roomVersion);
|
|
597
589
|
if (at !== null)
|