@agentshouse/mdruntime-adapter 0.1.0-cedb8e57837a7 → 0.1.0-cf1ebfb67feeb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/actions.d.ts +4 -69
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +7 -357
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +204 -411
- package/dist/app-reference.d.ts +2 -0
- package/dist/app-reference.d.ts.map +1 -0
- package/dist/app-reference.js +2 -0
- package/dist/crockford.d.ts +4 -0
- package/dist/crockford.d.ts.map +1 -0
- package/dist/crockford.js +3 -0
- package/dist/discovery.d.ts +21 -13
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +73 -53
- package/dist/history.d.ts +12 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +92 -0
- package/dist/house-model.d.ts +719 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +393 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/model.d.ts +5 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +10 -29
- package/dist/part.d.ts +14 -0
- package/dist/part.d.ts.map +1 -0
- package/dist/part.js +90 -0
- package/dist/read.d.ts +35 -59
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +178 -266
- package/dist/refusal.d.ts +0 -3
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +0 -5
- package/dist/room-stream.d.ts +19 -0
- package/dist/room-stream.d.ts.map +1 -0
- package/dist/room-stream.js +57 -0
- package/dist/room-types.d.ts +7 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +123 -0
- package/dist/search.d.ts +5 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +47 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +83 -193
- package/dist/stream.d.ts +13 -13
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +166 -411
- package/dist/transport.d.ts +54 -40
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +54 -11
- package/dist/upload.d.ts +12 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +63 -0
- package/dist/write.d.ts +6 -1
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +28 -39
- package/package.json +8 -4
- package/AGENTS.md +0 -304
- package/dist/gather.d.ts +0 -4
- package/dist/gather.d.ts.map +0 -1
- package/dist/gather.js +0 -35
- package/dist/handed.d.ts +0 -15
- package/dist/handed.d.ts.map +0 -1
- package/dist/handed.js +0 -45
- package/dist/referrer.d.ts +0 -7
- package/dist/referrer.d.ts.map +0 -1
- package/dist/referrer.js +0 -35
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { manifestedModels, partModels } from './model.js';
|
|
2
|
+
import { roomFrames } from './part.js';
|
|
3
|
+
import { housePart, manifested, roomHead } from './read.js';
|
|
4
|
+
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
5
|
+
export function roomStreams(mode) {
|
|
6
|
+
const open = new Map();
|
|
7
|
+
let opened = 0;
|
|
8
|
+
async function head(entry, room, arriving, signal) {
|
|
9
|
+
const frames = roomFrames(room, arriving, signal);
|
|
10
|
+
const first = await frames();
|
|
11
|
+
if (first.kind !== 'frame')
|
|
12
|
+
return UNCERTAIN;
|
|
13
|
+
const held = await roomHead(first.payload, mode);
|
|
14
|
+
if (held === null || held.anchor !== entry.authority)
|
|
15
|
+
return UNCERTAIN;
|
|
16
|
+
const { models, seen } = await manifestedModels(held, entry);
|
|
17
|
+
opened += 1;
|
|
18
|
+
const id = String(opened);
|
|
19
|
+
open.set(id, { entry, head: held, frames, next: 1, seen });
|
|
20
|
+
signal?.addEventListener('abort', () => open.delete(id), { once: true });
|
|
21
|
+
return { ...manifested(held, `${id}:1`, models), bytes: first.bytes };
|
|
22
|
+
}
|
|
23
|
+
async function part(entry, token) {
|
|
24
|
+
const [id = '', at = ''] = token.split(':');
|
|
25
|
+
const room = open.get(id);
|
|
26
|
+
if (room === undefined || room.entry.locator !== entry.locator || String(room.next) !== at)
|
|
27
|
+
return UNCERTAIN;
|
|
28
|
+
const frame = await room.frames();
|
|
29
|
+
if (frame.kind !== 'frame') {
|
|
30
|
+
open.delete(id);
|
|
31
|
+
return UNCERTAIN;
|
|
32
|
+
}
|
|
33
|
+
const read = await housePart(room.head, frame.payload, mode);
|
|
34
|
+
if ('kind' in read) {
|
|
35
|
+
open.delete(id);
|
|
36
|
+
return read;
|
|
37
|
+
}
|
|
38
|
+
const { scope, ended } = read;
|
|
39
|
+
const first = room.next === 1;
|
|
40
|
+
room.next += 1;
|
|
41
|
+
room.seen = [
|
|
42
|
+
...room.seen,
|
|
43
|
+
...(scope.files.some((file) => file.path === entry.schema) ? [entry.schema] : []),
|
|
44
|
+
];
|
|
45
|
+
if (ended)
|
|
46
|
+
open.delete(id);
|
|
47
|
+
return {
|
|
48
|
+
scope,
|
|
49
|
+
first,
|
|
50
|
+
ended,
|
|
51
|
+
models: await partModels(scope, entry, new Set(room.seen), ended),
|
|
52
|
+
pageToken: ended ? undefined : `${id}:${room.next}`,
|
|
53
|
+
bytes: frame.bytes,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return { head, part };
|
|
57
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const INBOX_CHANNEL_KINDS: readonly ['telegram-bot', 'telegram-business', 'whatsapp', 'messenger', 'instagram', 'viber', 'tiktok'];
|
|
2
|
+
export type InboxChannelKind = (typeof INBOX_CHANNEL_KINDS)[number];
|
|
3
|
+
export declare const CHAT_TYPE = "chat";
|
|
4
|
+
export declare const CHAT_MESSAGE_TYPE = "chat-message";
|
|
5
|
+
export declare const HOUSE_NAMEABLE_ROOM_TYPES: string[];
|
|
6
|
+
export declare const HOUSE_ROOM_TYPES: string;
|
|
7
|
+
//# sourceMappingURL=room-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"room-types.d.ts","sourceRoot":"","sources":["../src/room-types.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,YAC9B,cAAc,EACd,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,WAAW,EACX,OAAO,EACP,QAAQ,CACA,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,SAAS,SAAS,CAAC;AAEhC,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,eAAO,MAAM,yBAAyB,UAAiC,CAAC;AAyBxE,eAAO,MAAM,gBAAgB,QA2FjB,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { APP_REFERENCE_PATTERN } from './app-reference.js';
|
|
2
|
+
import { HOUSE_MODEL_TYPES } from './house-model.js';
|
|
3
|
+
export const INBOX_CHANNEL_KINDS = [
|
|
4
|
+
'telegram-bot',
|
|
5
|
+
'telegram-business',
|
|
6
|
+
'whatsapp',
|
|
7
|
+
'messenger',
|
|
8
|
+
'instagram',
|
|
9
|
+
'viber',
|
|
10
|
+
'tiktok',
|
|
11
|
+
];
|
|
12
|
+
export const CHAT_TYPE = 'chat';
|
|
13
|
+
export const CHAT_MESSAGE_TYPE = 'chat-message';
|
|
14
|
+
export const HOUSE_NAMEABLE_ROOM_TYPES = [CHAT_TYPE, CHAT_MESSAGE_TYPE];
|
|
15
|
+
const WAYFINDING_MAP_TYPE = 'wayfinding-map';
|
|
16
|
+
const WAYFINDING_TICKET_TYPE = 'wayfinding-ticket';
|
|
17
|
+
const WAYFINDING_MAP_SECTIONS = [
|
|
18
|
+
'Destination',
|
|
19
|
+
'Notes',
|
|
20
|
+
'Decisions so far',
|
|
21
|
+
'Not yet specified',
|
|
22
|
+
'Out of scope',
|
|
23
|
+
];
|
|
24
|
+
const IDENTITY = "{ type: string, pattern: '^\\S+$' }";
|
|
25
|
+
const AGENT = [' agent: { type: string, format: uuid }', ' name: { type: string }'];
|
|
26
|
+
const ASSIGNEE = [
|
|
27
|
+
' type: object',
|
|
28
|
+
' properties:',
|
|
29
|
+
' user: { type: string, format: uuid }',
|
|
30
|
+
...AGENT,
|
|
31
|
+
];
|
|
32
|
+
export const HOUSE_ROOM_TYPES = [
|
|
33
|
+
`${CHAT_TYPE}:`,
|
|
34
|
+
' properties:',
|
|
35
|
+
' inbox: { type: string, format: uuid }',
|
|
36
|
+
` channel: { enum: [${INBOX_CHANNEL_KINDS.join(', ')}] }`,
|
|
37
|
+
` chat: ${IDENTITY}`,
|
|
38
|
+
' customer:',
|
|
39
|
+
' type: object',
|
|
40
|
+
' properties:',
|
|
41
|
+
' name: { type: string }',
|
|
42
|
+
` username: ${IDENTITY}`,
|
|
43
|
+
` phone: ${IDENTITY}`,
|
|
44
|
+
' assignee:',
|
|
45
|
+
...ASSIGNEE,
|
|
46
|
+
' return_to:',
|
|
47
|
+
' type: object',
|
|
48
|
+
' properties:',
|
|
49
|
+
...AGENT,
|
|
50
|
+
' required: [chat, customer]',
|
|
51
|
+
`${CHAT_MESSAGE_TYPE}:`,
|
|
52
|
+
' properties:',
|
|
53
|
+
' direction: { enum: [in, out] }',
|
|
54
|
+
' sender:',
|
|
55
|
+
' type: object',
|
|
56
|
+
' properties:',
|
|
57
|
+
' name: { type: string }',
|
|
58
|
+
` username: ${IDENTITY}`,
|
|
59
|
+
' sent_at: { type: string, format: date-time }',
|
|
60
|
+
` channel_message: ${IDENTITY}`,
|
|
61
|
+
' labelled: { const: true }',
|
|
62
|
+
' reactions:',
|
|
63
|
+
' type: array',
|
|
64
|
+
' items:',
|
|
65
|
+
' type: object',
|
|
66
|
+
' properties:',
|
|
67
|
+
' reaction: { type: string, minLength: 1 }',
|
|
68
|
+
' sender:',
|
|
69
|
+
' type: object',
|
|
70
|
+
' properties:',
|
|
71
|
+
` id: ${IDENTITY}`,
|
|
72
|
+
' name: { type: string }',
|
|
73
|
+
` username: ${IDENTITY}`,
|
|
74
|
+
' count: { type: integer, minimum: 1 }',
|
|
75
|
+
' required: [reaction]',
|
|
76
|
+
` post: ${IDENTITY}`,
|
|
77
|
+
' assignee:',
|
|
78
|
+
...ASSIGNEE,
|
|
79
|
+
' sent_outside: { const: true }',
|
|
80
|
+
' template:',
|
|
81
|
+
' type: object',
|
|
82
|
+
' properties:',
|
|
83
|
+
' name: { type: string, minLength: 1 }',
|
|
84
|
+
' language: { type: string, minLength: 1 }',
|
|
85
|
+
' required: [name, language]',
|
|
86
|
+
' values:',
|
|
87
|
+
' type: object',
|
|
88
|
+
' additionalProperties: { type: string }',
|
|
89
|
+
' withheld: { const: true }',
|
|
90
|
+
' required: [direction]',
|
|
91
|
+
' if: { properties: { direction: { const: in } } }',
|
|
92
|
+
' then: { required: [sent_at] }',
|
|
93
|
+
`${WAYFINDING_MAP_TYPE}:`,
|
|
94
|
+
' properties:',
|
|
95
|
+
' title: { type: string }',
|
|
96
|
+
' required: [title]',
|
|
97
|
+
' sections:',
|
|
98
|
+
...WAYFINDING_MAP_SECTIONS.map((name) => ` ${name}: { kind: text, required: true }`),
|
|
99
|
+
`${WAYFINDING_TICKET_TYPE}:`,
|
|
100
|
+
' properties:',
|
|
101
|
+
' title: { type: string }',
|
|
102
|
+
' kind: { enum: [research, prototype, grilling, task] }',
|
|
103
|
+
' status: { enum: [open, in-progress, done, out-of-scope] }',
|
|
104
|
+
` map: { type: string, reference: ${WAYFINDING_MAP_TYPE} }`,
|
|
105
|
+
` blocked_by: { type: array, items: { type: string, reference: ${WAYFINDING_TICKET_TYPE} } }`,
|
|
106
|
+
' assignee:',
|
|
107
|
+
...ASSIGNEE,
|
|
108
|
+
' conversation: { type: string, format: uuid }',
|
|
109
|
+
` app: { type: string, pattern: '${APP_REFERENCE_PATTERN.source}' }`,
|
|
110
|
+
' required: [title, kind, status, map, blocked_by]',
|
|
111
|
+
' sections:',
|
|
112
|
+
' Question: { kind: text }',
|
|
113
|
+
' Answer: { kind: text }',
|
|
114
|
+
' allOf:',
|
|
115
|
+
' - if: { properties: { status: { enum: [in-progress, done, out-of-scope] } }, required: [status] }',
|
|
116
|
+
' then: { required: [assignee] }',
|
|
117
|
+
' else: { properties: { assignee: false } }',
|
|
118
|
+
' - if: { properties: { assignee: { required: [agent] } }, required: [assignee] }',
|
|
119
|
+
' else: { properties: { conversation: false } }',
|
|
120
|
+
' - if: { properties: { status: { enum: [done, out-of-scope] } }, required: [status] }',
|
|
121
|
+
' then: { sections: { Answer: { kind: text, required: true } } }',
|
|
122
|
+
HOUSE_MODEL_TYPES,
|
|
123
|
+
].join('\n');
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SearchAnswer, SearchAsk } from '@agentshouse/mdruntime';
|
|
2
|
+
import type { TrackedAuthority } from './discovery.js';
|
|
3
|
+
import { type HouseTransport } from './transport.js';
|
|
4
|
+
export declare function houseSearch(transport: Pick<HouseTransport, 'door'>, tracked: readonly TrackedAuthority[], request: SearchAsk): Promise<SearchAnswer>;
|
|
5
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAa,MAAM,wBAAwB,CAAC;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAsBrE,wBAAsB,WAAW,CAC/B,SAAS,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,EACvC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,YAAY,CAAC,CAoBvB"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { doorRefusal } from './refusal.js';
|
|
2
|
+
import { houseDoorRoute } from './transport.js';
|
|
3
|
+
const ROOMS = '/rooms/';
|
|
4
|
+
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
5
|
+
function hitOf(file, locators) {
|
|
6
|
+
if (typeof file !== 'object' || file === null)
|
|
7
|
+
return null;
|
|
8
|
+
const { path, line, snippet } = file;
|
|
9
|
+
if (typeof path !== 'string' || !path.startsWith(ROOMS))
|
|
10
|
+
return null;
|
|
11
|
+
const slash = path.indexOf('/', ROOMS.length);
|
|
12
|
+
if (slash < 0)
|
|
13
|
+
return null;
|
|
14
|
+
const room = locators.get(path.slice(ROOMS.length, slash));
|
|
15
|
+
if (room === undefined)
|
|
16
|
+
return null;
|
|
17
|
+
return {
|
|
18
|
+
room,
|
|
19
|
+
path: path.slice(slash + 1),
|
|
20
|
+
...(typeof line === 'number' ? { line } : {}),
|
|
21
|
+
...(typeof snippet === 'string' ? { snippet } : {}),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export async function houseSearch(transport, tracked, request) {
|
|
25
|
+
const named = request.rooms === null
|
|
26
|
+
? null
|
|
27
|
+
: tracked.filter((entry) => request.rooms.includes(entry.locator));
|
|
28
|
+
if (named !== null && named.length === 0)
|
|
29
|
+
return { kind: 'found', documents: [] };
|
|
30
|
+
const answer = await transport.door(houseDoorRoute('search'), {
|
|
31
|
+
query: request.text,
|
|
32
|
+
...(named === null ? {} : { paths: named.map((entry) => `${ROOMS}${entry.handle}`) }),
|
|
33
|
+
});
|
|
34
|
+
if (answer.status === 401)
|
|
35
|
+
return { kind: 'revoked-authorization' };
|
|
36
|
+
const refusal = doorRefusal(answer.body);
|
|
37
|
+
if (refusal !== null)
|
|
38
|
+
return { kind: 'rejected', ...refusal };
|
|
39
|
+
const files = answer.body?.files;
|
|
40
|
+
if (answer.status !== 200 || !Array.isArray(files))
|
|
41
|
+
return UNCERTAIN;
|
|
42
|
+
const locators = new Map(tracked.map((entry) => [entry.handle, entry.locator]));
|
|
43
|
+
return {
|
|
44
|
+
kind: 'found',
|
|
45
|
+
documents: files.flatMap((file) => hitOf(file, locators) ?? []),
|
|
46
|
+
};
|
|
47
|
+
}
|
package/dist/site.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,
|
|
1
|
+
{"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAQR,MAAM,wBAAwB,CAAC;AAgBhC,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAuBxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAuK1F"}
|
package/dist/site.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { stepped } from '@agentshouse/mdruntime';
|
|
2
|
-
import { actionOutcome
|
|
2
|
+
import { actionOutcome } from './actions.js';
|
|
3
3
|
import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked, } from './discovery.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { bootstrapping } from './read.js';
|
|
5
|
+
import { roomStreams } from './room-stream.js';
|
|
6
|
+
import { classifyDoor, discoveryFailure } from './refusal.js';
|
|
7
|
+
import { HOUSE_TYPED_PATHS } from './house-model.js';
|
|
8
|
+
import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
|
|
8
9
|
import { houseNotifications } from './stream.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
|
|
10
|
+
import { houseSiteRoute, SITE_DOOR_SUBMIT, SITE_FILES, SITE_SUBMISSION, } from './transport.js';
|
|
11
|
+
import { followsVersion, logPosition, presented, reachedVersion, roomVersion } from './version.js';
|
|
12
12
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
13
13
|
function unfound() {
|
|
14
14
|
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
@@ -24,192 +24,98 @@ function siteRoom(tracked) {
|
|
|
24
24
|
providerOwnedPaths: [],
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
-
function settled(refused) {
|
|
28
|
-
return refused.kind === 'beyond-horizon' ? UNCERTAIN : refused;
|
|
29
|
-
}
|
|
30
27
|
export function createSiteAdapter(transport, snapshot = false) {
|
|
31
|
-
const notifications = houseNotifications(transport, 'site'
|
|
28
|
+
const notifications = houseNotifications(transport, 'site', {
|
|
29
|
+
opened: async () => {
|
|
30
|
+
const found = await discovered();
|
|
31
|
+
return found.kind === 'discovery' ? found : null;
|
|
32
|
+
},
|
|
33
|
+
changed: () => null,
|
|
34
|
+
});
|
|
32
35
|
const tracked = new Map();
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return named === null || !tracked.has(named.locator) ? null : named;
|
|
36
|
-
}
|
|
36
|
+
const read = new Map();
|
|
37
|
+
const rooms = roomStreams('site');
|
|
37
38
|
function fileRoute(request) {
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
return { kind: '
|
|
41
|
-
}
|
|
42
|
-
if (request.fileRef === undefined)
|
|
43
|
-
return unfound();
|
|
44
|
-
const { room_ref, path, record } = named.referrer;
|
|
45
|
-
return `${SITE_FILES}${room_ref}/${encodeURIComponent(request.fileRef)}/${path === undefined
|
|
46
|
-
? `${SITE_FILE_RECORD}/${encodeURIComponent(record)}`
|
|
47
|
-
: encodeURIComponent(path)}`;
|
|
39
|
+
const entry = tracked.get(request.locator);
|
|
40
|
+
if (entry === undefined)
|
|
41
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
42
|
+
return `${SITE_FILES}${entry.authority}/${encodeURIComponent(request.revision)}/${encodeURIComponent(request.path)}`;
|
|
48
43
|
}
|
|
49
|
-
async function
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
});
|
|
60
|
-
const classified = classifyRead(answer.status, answer.body, entry.locator);
|
|
61
|
-
if (classified !== null)
|
|
62
|
-
return classified;
|
|
63
|
-
const found = parseEnumeration(answer.body, 'site');
|
|
64
|
-
if (found === null)
|
|
65
|
-
return UNCERTAIN;
|
|
66
|
-
return viewOf(found, entry) ?? { kind: 'room-not-readable', locator: entry.locator };
|
|
44
|
+
async function openedRoom(entry, arriving, signal) {
|
|
45
|
+
const cut = read.get(entry.locator);
|
|
46
|
+
const answered = await transport.streamed(`${houseSiteRoute('bootstrap')}/${entry.authority}${cut === undefined ? '' : `?expired=${cut}`}`, signal ?? new AbortController().signal);
|
|
47
|
+
if (answered.room === null)
|
|
48
|
+
return classifyDoor(answered.status, answered.body, entry.locator) ?? UNCERTAIN;
|
|
49
|
+
const head = await rooms.head(entry, answered.room, arriving, signal);
|
|
50
|
+
const at = head.kind === 'bootstrap' ? logPosition(head.roomVersion) : null;
|
|
51
|
+
if (at !== null)
|
|
52
|
+
read.set(entry.locator, at.position);
|
|
53
|
+
return head;
|
|
67
54
|
}
|
|
68
|
-
async function
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
async function bootstrapPart(entry, after, offset) {
|
|
73
|
-
const query = [
|
|
74
|
-
...(after === null ? [] : [`after=${encodeURIComponent(after)}`]),
|
|
75
|
-
...(offset === null ? [] : [`offset=${offset}`]),
|
|
76
|
-
];
|
|
77
|
-
const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}${query.length === 0 ? '' : `?${query.join('&')}`}`);
|
|
78
|
-
const classified = classifyDoor(answer.status, answer.body, entry.locator);
|
|
79
|
-
if (classified !== null)
|
|
80
|
-
return { failure: classified };
|
|
81
|
-
const scope = await stepped(parseSiteBootstrap(answer.body));
|
|
82
|
-
return scope === null ? { failure: UNCERTAIN } : { body: answer.body, scope };
|
|
83
|
-
}
|
|
84
|
-
async function assembled(entry, scope, path, offset) {
|
|
85
|
-
const opened = scope.contents.at(-1);
|
|
86
|
-
if (opened === undefined || opened.path !== path || opened.content.length !== offset) {
|
|
87
|
-
return UNCERTAIN;
|
|
88
|
-
}
|
|
89
|
-
let text = opened.content;
|
|
90
|
-
for (;;) {
|
|
91
|
-
const part = await bootstrapPart(entry, path, text.length);
|
|
92
|
-
if ('failure' in part)
|
|
93
|
-
return part.failure;
|
|
94
|
-
const [piece] = part.scope.contents;
|
|
95
|
-
if (piece === undefined ||
|
|
96
|
-
part.scope.contents.length !== 1 ||
|
|
97
|
-
piece.path !== path ||
|
|
98
|
-
piece.content.length === 0) {
|
|
99
|
-
return UNCERTAIN;
|
|
100
|
-
}
|
|
101
|
-
text += piece.content;
|
|
102
|
-
const more = siteBootstrapOffset(part.body);
|
|
103
|
-
if (more === null)
|
|
104
|
-
break;
|
|
105
|
-
if (more !== text.length)
|
|
106
|
-
return UNCERTAIN;
|
|
107
|
-
}
|
|
108
|
-
const file = scope.files.find((held) => held.path === path);
|
|
109
|
-
if (file === undefined || (await sha256Hex(text)) !== file.version)
|
|
110
|
-
return UNCERTAIN;
|
|
111
|
-
return { ...scope, contents: [...scope.contents.slice(0, -1), { path, content: text }] };
|
|
112
|
-
}
|
|
113
|
-
async function caughtUp(entry, after) {
|
|
114
|
-
const part = await bootstrapPart(entry, after, null);
|
|
115
|
-
if ('failure' in part)
|
|
55
|
+
async function streamedPage(entry, token) {
|
|
56
|
+
const part = await rooms.part(entry, token);
|
|
57
|
+
if ('kind' in part)
|
|
116
58
|
return part;
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
const { scope } = part;
|
|
126
|
-
if (after !== null || next !== null || roomVersion(scope) === roomVersion(entry)) {
|
|
127
|
-
return { scope, next };
|
|
128
|
-
}
|
|
129
|
-
const view = await enumeration(entry, scope);
|
|
130
|
-
if ('kind' in view)
|
|
131
|
-
return { failure: settled(view) };
|
|
132
|
-
return { scope: await stepped(advancedScope(scope, view)), next: null };
|
|
59
|
+
const { folders: _folders, ...page } = await stepped(bootstrapping(part.scope));
|
|
60
|
+
return {
|
|
61
|
+
...page,
|
|
62
|
+
...(part.models === undefined ? {} : { models: part.models }),
|
|
63
|
+
...(part.pageToken === undefined ? {} : { pageToken: part.pageToken }),
|
|
64
|
+
bytes: part.bytes,
|
|
65
|
+
};
|
|
133
66
|
}
|
|
134
|
-
async function
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
notifications.
|
|
147
|
-
|
|
148
|
-
if (answer.kind !== 'net-advancement')
|
|
149
|
-
return answer;
|
|
150
|
-
const models = await viewModels(view, entry);
|
|
151
|
-
return models === undefined ? answer : { ...answer, models };
|
|
67
|
+
async function discovered() {
|
|
68
|
+
const answer = await transport.read(houseSiteRoute('discover'));
|
|
69
|
+
const failed = discoveryFailure(answer.status, answer.body);
|
|
70
|
+
if (failed !== null)
|
|
71
|
+
return failed;
|
|
72
|
+
const document = parseSiteDiscovery(answer.body);
|
|
73
|
+
if (document === null)
|
|
74
|
+
return UNCERTAIN;
|
|
75
|
+
const entries = siteTracked(document);
|
|
76
|
+
tracked.clear();
|
|
77
|
+
for (const entry of entries)
|
|
78
|
+
tracked.set(entry.locator, entry);
|
|
79
|
+
notifications.track(entries);
|
|
80
|
+
return mapDiscovery(document, entries.map(siteRoom), siteCapabilities());
|
|
152
81
|
}
|
|
153
82
|
return {
|
|
154
83
|
localSaves: true,
|
|
155
|
-
|
|
84
|
+
roomTypes: HOUSE_ROOM_TYPES,
|
|
85
|
+
nameableRoomTypes: HOUSE_NAMEABLE_ROOM_TYPES,
|
|
86
|
+
typedPaths: HOUSE_TYPED_PATHS,
|
|
156
87
|
async authorize() {
|
|
157
88
|
return {};
|
|
158
89
|
},
|
|
159
|
-
async discover() {
|
|
160
|
-
const answer = await transport.read(SITE_DOOR_DISCOVER);
|
|
161
|
-
const failed = discoveryFailure(answer.status, answer.body);
|
|
162
|
-
if (failed !== null)
|
|
163
|
-
return failed;
|
|
164
|
-
const document = parseSiteDiscovery(answer.body);
|
|
165
|
-
if (document === null)
|
|
166
|
-
return UNCERTAIN;
|
|
167
|
-
const entries = siteTracked(document);
|
|
168
|
-
tracked.clear();
|
|
169
|
-
for (const entry of entries)
|
|
170
|
-
tracked.set(entry.locator, entry);
|
|
171
|
-
notifications.track(entries);
|
|
172
|
-
return mapDiscovery(document, entries.map(siteRoom), siteCapabilities());
|
|
173
|
-
},
|
|
174
90
|
async bootstrap(_authorization, request) {
|
|
175
91
|
const entry = tracked.get(request.locator);
|
|
176
92
|
if (entry === undefined)
|
|
177
93
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
178
|
-
|
|
179
|
-
?
|
|
180
|
-
:
|
|
181
|
-
const held = await caughtUp(entry, continued?.after ?? null);
|
|
182
|
-
if ('failure' in held)
|
|
183
|
-
return held.failure;
|
|
184
|
-
notifications.reach(entry.authority, held.scope);
|
|
185
|
-
const seen = [
|
|
186
|
-
...(continued?.seen ?? []),
|
|
187
|
-
...entry.schemas.filter((schema) => held.scope.files.some((file) => file.path === schema)),
|
|
188
|
-
];
|
|
189
|
-
const models = await partModels(held.scope, entry, new Set(seen), held.next === null);
|
|
190
|
-
const continuation = held.next === null ? null : { after: held.next, seen };
|
|
191
|
-
return {
|
|
192
|
-
...(await stepped(bootstrapping(held.scope))),
|
|
193
|
-
...(models === undefined ? {} : { models }),
|
|
194
|
-
...(continuation === null ? {} : { pageToken: JSON.stringify(continuation) }),
|
|
195
|
-
};
|
|
94
|
+
return request.pageToken === undefined
|
|
95
|
+
? openedRoom(entry, request.arriving, request.signal)
|
|
96
|
+
: streamedPage(entry, request.pageToken);
|
|
196
97
|
},
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
98
|
+
...(snapshot
|
|
99
|
+
? {
|
|
100
|
+
discover: discovered,
|
|
101
|
+
async refresh(_authorization, request) {
|
|
102
|
+
const entry = tracked.get(request.locator);
|
|
103
|
+
if (entry === undefined)
|
|
104
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
105
|
+
if (request.pageToken !== undefined)
|
|
106
|
+
return UNCERTAIN;
|
|
107
|
+
return request.fromRoomVersion === roomVersion(entry)
|
|
108
|
+
? { kind: 'still-current' }
|
|
109
|
+
: { kind: 'beyond-horizon' };
|
|
110
|
+
},
|
|
207
111
|
}
|
|
208
|
-
|
|
209
|
-
},
|
|
112
|
+
: {}),
|
|
210
113
|
async mutate() {
|
|
211
114
|
return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {}, retryable: false };
|
|
212
115
|
},
|
|
116
|
+
async attach() {
|
|
117
|
+
return { kind: 'rejected', code: 'write-grant', fields: {}, retryable: false };
|
|
118
|
+
},
|
|
213
119
|
async history() {
|
|
214
120
|
return { kind: 'no-history' };
|
|
215
121
|
},
|
|
@@ -220,8 +126,8 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
220
126
|
const read = await transport.download(route);
|
|
221
127
|
if (read.status === 404)
|
|
222
128
|
return unfound();
|
|
223
|
-
return read.status === 200 && read.
|
|
224
|
-
? { kind: 'binary',
|
|
129
|
+
return read.status === 200 && read.body !== null
|
|
130
|
+
? { kind: 'binary', body: read.body, mediaType: read.mediaType }
|
|
225
131
|
: UNCERTAIN;
|
|
226
132
|
},
|
|
227
133
|
async link(_authorization, request) {
|
|
@@ -234,13 +140,6 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
234
140
|
name: request.path.slice(request.path.lastIndexOf('/') + 1),
|
|
235
141
|
};
|
|
236
142
|
},
|
|
237
|
-
referrerScope(referrer) {
|
|
238
|
-
const named = published(referrer);
|
|
239
|
-
if (named === null)
|
|
240
|
-
return null;
|
|
241
|
-
const { path } = named.referrer;
|
|
242
|
-
return { kind: 'room', locator: named.locator, ...(path === undefined ? {} : { path }) };
|
|
243
|
-
},
|
|
244
143
|
reached(locator, version, target) {
|
|
245
144
|
return reachedVersion(version, target, tracked.get(locator)?.logEpoch);
|
|
246
145
|
},
|
|
@@ -248,7 +147,7 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
248
147
|
return followsVersion(version, next);
|
|
249
148
|
},
|
|
250
149
|
async action(_authorization, request) {
|
|
251
|
-
if (request.name !==
|
|
150
|
+
if (request.name !== SITE_SUBMISSION) {
|
|
252
151
|
return {
|
|
253
152
|
kind: 'rejected',
|
|
254
153
|
code: 'action-unimplemented',
|
|
@@ -258,7 +157,7 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
258
157
|
}
|
|
259
158
|
if (!transport.online())
|
|
260
159
|
return UNCERTAIN;
|
|
261
|
-
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input),
|
|
160
|
+
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), SITE_SUBMISSION, request.input);
|
|
262
161
|
},
|
|
263
162
|
roomStream: snapshot
|
|
264
163
|
? undefined
|
|
@@ -267,19 +166,10 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
267
166
|
notifications.send(rooms.flatMap((room) => {
|
|
268
167
|
const entry = tracked.get(room.locator);
|
|
269
168
|
const at = logPosition(room.roomVersion);
|
|
270
|
-
|
|
271
|
-
return [];
|
|
272
|
-
notifications.reach(entry.authority, at);
|
|
273
|
-
return [presented(entry.authority, at)];
|
|
169
|
+
return entry === undefined || at === null ? [] : [presented(entry.authority, at)];
|
|
274
170
|
}));
|
|
275
171
|
},
|
|
276
|
-
reopen: notifications.reopen,
|
|
277
172
|
observe: notifications.observe,
|
|
278
|
-
published(locator, roomVersion) {
|
|
279
|
-
const at = logPosition(roomVersion);
|
|
280
|
-
if (at !== null)
|
|
281
|
-
notifications.published(locator, at);
|
|
282
|
-
},
|
|
283
173
|
},
|
|
284
174
|
serviceMode: notifications.serviceMode,
|
|
285
175
|
};
|
package/dist/stream.d.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AuthorityChange, type Discovery, type ConversationStream, type RoomStreamEvent, type ServiceModeSignal } from '@agentshouse/mdruntime';
|
|
2
2
|
import type { TrackedAuthority } from './discovery.js';
|
|
3
|
-
import type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import { type HouseDoor, type HouseHeldRoom, type HouseMode, type HouseStreamFrame } from './transport.js';
|
|
4
|
+
export type HouseOpeningFrame = Extract<HouseStreamFrame, {
|
|
5
|
+
type: 'opening';
|
|
6
|
+
}>;
|
|
7
|
+
export type HouseAuthorityChangedFrame = Extract<HouseStreamFrame, {
|
|
8
|
+
type: 'authority_changed';
|
|
9
|
+
}>;
|
|
10
|
+
export type HouseDiscovering = {
|
|
11
|
+
opened(frame: HouseOpeningFrame | null): Promise<Discovery | null>;
|
|
12
|
+
changed(frame: HouseAuthorityChangedFrame): AuthorityChange | null;
|
|
9
13
|
};
|
|
10
14
|
export type HouseNotifications = {
|
|
11
15
|
runtime: string;
|
|
12
|
-
observe(notify: (event: RoomStreamEvent) => void
|
|
16
|
+
observe(notify: (event: RoomStreamEvent) => void): () => void;
|
|
13
17
|
send(rooms: readonly HouseHeldRoom[]): void;
|
|
14
|
-
published(locator: string, at: LogPosition): void;
|
|
15
|
-
reopen(): void;
|
|
16
18
|
track(authorities: readonly TrackedAuthority[]): void;
|
|
17
|
-
reach(authority: string, at: LogPosition): void;
|
|
18
|
-
advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): Generator<number, StreamedAdvancement | null, void>;
|
|
19
19
|
conversations: ConversationStream;
|
|
20
20
|
serviceMode: ServiceModeSignal;
|
|
21
21
|
};
|
|
22
|
-
export declare function houseNotifications(transport: HouseDoor, mode: HouseMode): HouseNotifications;
|
|
22
|
+
export declare function houseNotifications(transport: HouseDoor, mode: HouseMode, discovering: HouseDiscovering): HouseNotifications;
|
|
23
23
|
//# sourceMappingURL=stream.d.ts.map
|