@agentshouse/mdruntime-adapter 0.1.0-ca5b2f7fcb9d1 → 0.1.0-ca632988146a3
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 +11 -23
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +26 -137
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +239 -199
- 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 +6 -10
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +38 -34
- package/dist/gather.d.ts +1 -2
- package/dist/gather.d.ts.map +1 -1
- package/dist/gather.js +5 -15
- package/dist/house-model.d.ts +2 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +491 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -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 +14 -0
- package/dist/part.d.ts.map +1 -0
- package/dist/part.js +90 -0
- package/dist/read.d.ts +54 -25
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +264 -150
- 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 +126 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +66 -114
- package/dist/stream.d.ts +3 -3
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +71 -40
- package/dist/transport.d.ts +39 -9
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +2 -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 +16 -1
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +101 -55
- package/package.json +8 -4
- package/AGENTS.md +0 -296
- package/dist/handed.d.ts +0 -15
- package/dist/handed.d.ts.map +0 -1
- package/dist/handed.js +0 -38
- package/dist/referrer.d.ts +0 -7
- package/dist/referrer.d.ts.map +0 -1
- package/dist/referrer.js +0 -35
|
@@ -0,0 +1,126 @@
|
|
|
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 INBOX_CHAT_TYPE = 'inbox-chat';
|
|
13
|
+
export const INBOX_MESSAGE_TYPE = 'inbox-message';
|
|
14
|
+
export const HOUSE_NAMEABLE_ROOM_TYPES = [INBOX_CHAT_TYPE, INBOX_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
|
+
`${INBOX_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
|
+
' conversation: { type: string, format: uuid }',
|
|
51
|
+
' required: [inbox, channel, chat, customer]',
|
|
52
|
+
`${INBOX_MESSAGE_TYPE}:`,
|
|
53
|
+
' properties:',
|
|
54
|
+
' direction: { enum: [in, out] }',
|
|
55
|
+
' sender:',
|
|
56
|
+
' type: object',
|
|
57
|
+
' properties:',
|
|
58
|
+
' name: { type: string }',
|
|
59
|
+
` username: ${IDENTITY}`,
|
|
60
|
+
' sent_at: { type: string, format: date-time }',
|
|
61
|
+
` channel_message: ${IDENTITY}`,
|
|
62
|
+
' state: { enum: [sending, sent, failed] }',
|
|
63
|
+
' reason: { type: string }',
|
|
64
|
+
' labelled: { const: true }',
|
|
65
|
+
' reactions:',
|
|
66
|
+
' type: array',
|
|
67
|
+
' items:',
|
|
68
|
+
' type: object',
|
|
69
|
+
' properties:',
|
|
70
|
+
' reaction: { type: string, minLength: 1 }',
|
|
71
|
+
' sender:',
|
|
72
|
+
' type: object',
|
|
73
|
+
' properties:',
|
|
74
|
+
` id: ${IDENTITY}`,
|
|
75
|
+
' name: { type: string }',
|
|
76
|
+
` username: ${IDENTITY}`,
|
|
77
|
+
' count: { type: integer, minimum: 1 }',
|
|
78
|
+
' required: [reaction]',
|
|
79
|
+
` post: ${IDENTITY}`,
|
|
80
|
+
' assignee:',
|
|
81
|
+
...ASSIGNEE,
|
|
82
|
+
' sent_outside: { const: true }',
|
|
83
|
+
' template:',
|
|
84
|
+
' type: object',
|
|
85
|
+
' properties:',
|
|
86
|
+
' name: { type: string, minLength: 1 }',
|
|
87
|
+
' language: { type: string, minLength: 1 }',
|
|
88
|
+
' required: [name, language]',
|
|
89
|
+
' values:',
|
|
90
|
+
' type: object',
|
|
91
|
+
' additionalProperties: { type: string }',
|
|
92
|
+
' withheld: { const: true }',
|
|
93
|
+
' required: [direction]',
|
|
94
|
+
' if: { properties: { direction: { const: in } } }',
|
|
95
|
+
' then: { required: [sent_at] }',
|
|
96
|
+
`${WAYFINDING_MAP_TYPE}:`,
|
|
97
|
+
' properties:',
|
|
98
|
+
' title: { type: string }',
|
|
99
|
+
' required: [title]',
|
|
100
|
+
' sections:',
|
|
101
|
+
...WAYFINDING_MAP_SECTIONS.map((name) => ` ${name}: { kind: text, required: true }`),
|
|
102
|
+
`${WAYFINDING_TICKET_TYPE}:`,
|
|
103
|
+
' properties:',
|
|
104
|
+
' title: { type: string }',
|
|
105
|
+
' kind: { enum: [research, prototype, grilling, task] }',
|
|
106
|
+
' status: { enum: [open, in-progress, done, out-of-scope] }',
|
|
107
|
+
` map: { type: string, reference: ${WAYFINDING_MAP_TYPE} }`,
|
|
108
|
+
` blocked_by: { type: array, items: { type: string, reference: ${WAYFINDING_TICKET_TYPE} } }`,
|
|
109
|
+
' assignee:',
|
|
110
|
+
...ASSIGNEE,
|
|
111
|
+
' conversation: { type: string, format: uuid }',
|
|
112
|
+
` app: { type: string, pattern: '${APP_REFERENCE_PATTERN.source}' }`,
|
|
113
|
+
' required: [title, kind, status, map, blocked_by]',
|
|
114
|
+
' sections:',
|
|
115
|
+
' Question: { kind: text }',
|
|
116
|
+
' Answer: { kind: text }',
|
|
117
|
+
' allOf:',
|
|
118
|
+
' - if: { properties: { status: { enum: [in-progress, done, out-of-scope] } }, required: [status] }',
|
|
119
|
+
' then: { required: [assignee] }',
|
|
120
|
+
' else: { properties: { assignee: false } }',
|
|
121
|
+
' - if: { properties: { assignee: { required: [agent] } }, required: [assignee] }',
|
|
122
|
+
' else: { properties: { conversation: false } }',
|
|
123
|
+
' - if: { properties: { status: { enum: [done, out-of-scope] } }, required: [status] }',
|
|
124
|
+
' then: { sections: { Answer: { kind: text, required: true } } }',
|
|
125
|
+
HOUSE_MODEL_TYPES,
|
|
126
|
+
].join('\n');
|
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,EAUR,MAAM,wBAAwB,CAAC;AAwBhC,OAAO,EAML,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAgCxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAqN1F"}
|
package/dist/site.js
CHANGED
|
@@ -1,34 +1,39 @@
|
|
|
1
|
+
import { stepped } from '@agentshouse/mdruntime';
|
|
1
2
|
import { actionOutcome, SITE_SUBMIT } from './actions.js';
|
|
2
3
|
import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked, } from './discovery.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { streamedModels, viewModels } from './model.js';
|
|
5
|
+
import { bootstrapping, parseEnumeration, refreshFrom, viewOf, wholeView, } from './read.js';
|
|
6
|
+
import { roomStreams } from './room-stream.js';
|
|
6
7
|
import { classifyDoor, classifyRead, discoveryFailure } from './refusal.js';
|
|
8
|
+
import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
|
|
7
9
|
import { houseNotifications } from './stream.js';
|
|
8
|
-
import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT,
|
|
9
|
-
import { houseReferrer } from './referrer.js';
|
|
10
|
+
import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, SITE_FILES, } from './transport.js';
|
|
10
11
|
import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
|
|
11
12
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
13
|
+
function unfound() {
|
|
14
|
+
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
15
|
+
}
|
|
12
16
|
function siteRoom(tracked) {
|
|
13
17
|
return {
|
|
14
18
|
name: tracked.handle,
|
|
15
19
|
locator: tracked.locator,
|
|
16
20
|
handle: tracked.handle,
|
|
17
21
|
roomVersion: roomVersion(tracked),
|
|
18
|
-
operations: {
|
|
19
|
-
replica: { selection: tracked.locator, admission: 'admitted' },
|
|
22
|
+
operations: { write: [], delete: [] },
|
|
23
|
+
replica: { selection: tracked.locator, admission: 'admitted', offline: 'open' },
|
|
20
24
|
providerOwnedPaths: [],
|
|
21
25
|
};
|
|
22
26
|
}
|
|
23
|
-
function settled(refused) {
|
|
24
|
-
return refused.kind === 'beyond-horizon' ? UNCERTAIN : refused;
|
|
25
|
-
}
|
|
26
27
|
export function createSiteAdapter(transport, snapshot = false) {
|
|
27
28
|
const notifications = houseNotifications(transport, 'site');
|
|
28
29
|
const tracked = new Map();
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const read = new Map();
|
|
31
|
+
const rooms = roomStreams('site');
|
|
32
|
+
function fileRoute(request) {
|
|
33
|
+
const entry = tracked.get(request.locator);
|
|
34
|
+
if (entry === undefined)
|
|
35
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
36
|
+
return `${SITE_FILES}${entry.authority}/${encodeURIComponent(request.revision)}/${encodeURIComponent(request.path)}`;
|
|
32
37
|
}
|
|
33
38
|
async function enumerated(entry, from, page) {
|
|
34
39
|
const answer = await transport.door(SITE_DOOR_ENUMERATE, {
|
|
@@ -53,73 +58,35 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
53
58
|
const first = await enumerated(entry, from);
|
|
54
59
|
return 'kind' in first ? first : wholeView(first, (page) => enumerated(entry, from, page));
|
|
55
60
|
}
|
|
56
|
-
async function
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return scope === null ? { failure: UNCERTAIN } : { body: answer.body, scope };
|
|
67
|
-
}
|
|
68
|
-
async function assembled(entry, scope, path, offset) {
|
|
69
|
-
const opened = scope.contents.at(-1);
|
|
70
|
-
if (opened === undefined || opened.path !== path || opened.content.length !== offset) {
|
|
71
|
-
return UNCERTAIN;
|
|
72
|
-
}
|
|
73
|
-
let text = opened.content;
|
|
74
|
-
for (;;) {
|
|
75
|
-
const part = await bootstrapPart(entry, path, text.length);
|
|
76
|
-
if ('failure' in part)
|
|
77
|
-
return part.failure;
|
|
78
|
-
const [piece] = part.scope.contents;
|
|
79
|
-
if (piece === undefined ||
|
|
80
|
-
part.scope.contents.length !== 1 ||
|
|
81
|
-
piece.path !== path ||
|
|
82
|
-
piece.content.length === 0) {
|
|
83
|
-
return UNCERTAIN;
|
|
84
|
-
}
|
|
85
|
-
text += piece.content;
|
|
86
|
-
const more = siteBootstrapOffset(part.body);
|
|
87
|
-
if (more === null)
|
|
88
|
-
break;
|
|
89
|
-
if (more !== text.length)
|
|
90
|
-
return UNCERTAIN;
|
|
91
|
-
}
|
|
92
|
-
const file = scope.files.find((held) => held.path === path);
|
|
93
|
-
if (file === undefined || (await sha256Hex(text)) !== file.version)
|
|
94
|
-
return UNCERTAIN;
|
|
95
|
-
return { ...scope, contents: [...scope.contents.slice(0, -1), { path, content: text }] };
|
|
61
|
+
async function openedRoom(entry, arriving, signal) {
|
|
62
|
+
const cut = read.get(entry.locator);
|
|
63
|
+
const answered = await transport.streamed(`${SITE_DOOR_BOOTSTRAP}${entry.authority}${cut === undefined ? '' : `?expired=${cut}`}`, signal ?? new AbortController().signal);
|
|
64
|
+
if (answered.room === null)
|
|
65
|
+
return classifyDoor(answered.status, answered.body, entry.locator) ?? UNCERTAIN;
|
|
66
|
+
const head = await rooms.head(entry, answered.room, arriving, signal);
|
|
67
|
+
const at = head.kind === 'bootstrap' ? logPosition(head.roomVersion) : null;
|
|
68
|
+
if (at !== null)
|
|
69
|
+
read.set(entry.locator, at.position);
|
|
70
|
+
return head;
|
|
96
71
|
}
|
|
97
|
-
async function
|
|
98
|
-
const part = await
|
|
99
|
-
if ('
|
|
72
|
+
async function streamedPage(entry, token) {
|
|
73
|
+
const part = await rooms.part(entry, token);
|
|
74
|
+
if ('kind' in part)
|
|
100
75
|
return part;
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
const { scope } = part;
|
|
110
|
-
if (after !== null || next !== null || roomVersion(scope) === roomVersion(entry)) {
|
|
111
|
-
return { scope, next };
|
|
112
|
-
}
|
|
113
|
-
const view = await enumeration(entry, scope);
|
|
114
|
-
if ('kind' in view)
|
|
115
|
-
return { failure: settled(view) };
|
|
116
|
-
return { scope: advancedScope(scope, view), next: null };
|
|
76
|
+
notifications.reach(entry.authority, part.scope);
|
|
77
|
+
const { folders: _folders, ...page } = await stepped(bootstrapping(part.scope));
|
|
78
|
+
return {
|
|
79
|
+
...page,
|
|
80
|
+
...(part.models === undefined ? {} : { models: part.models }),
|
|
81
|
+
...(part.pageToken === undefined ? {} : { pageToken: part.pageToken }),
|
|
82
|
+
bytes: part.bytes,
|
|
83
|
+
};
|
|
117
84
|
}
|
|
118
85
|
async function refreshed(entry, fromRoomVersion) {
|
|
119
86
|
const from = logPosition(fromRoomVersion);
|
|
120
87
|
if (from === null)
|
|
121
88
|
return { kind: 'beyond-horizon' };
|
|
122
|
-
const streamed = notifications.advance(entry, from);
|
|
89
|
+
const streamed = await stepped(notifications.advance(entry, from));
|
|
123
90
|
if (streamed !== null) {
|
|
124
91
|
const models = await streamedModels(streamed.schemas, entry, 'site');
|
|
125
92
|
return models === undefined ? streamed.page : { ...streamed.page, models };
|
|
@@ -128,7 +95,7 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
128
95
|
if ('kind' in view)
|
|
129
96
|
return view;
|
|
130
97
|
notifications.reach(entry.authority, view);
|
|
131
|
-
const answer = refreshFrom(view, fromRoomVersion);
|
|
98
|
+
const answer = await refreshFrom(view, fromRoomVersion);
|
|
132
99
|
if (answer.kind !== 'net-advancement')
|
|
133
100
|
return answer;
|
|
134
101
|
const models = await viewModels(view, entry);
|
|
@@ -137,6 +104,8 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
137
104
|
return {
|
|
138
105
|
localSaves: true,
|
|
139
106
|
exhaustiveDiscovery: true,
|
|
107
|
+
roomTypes: HOUSE_ROOM_TYPES,
|
|
108
|
+
nameableRoomTypes: HOUSE_NAMEABLE_ROOM_TYPES,
|
|
140
109
|
async authorize() {
|
|
141
110
|
return {};
|
|
142
111
|
},
|
|
@@ -159,24 +128,9 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
159
128
|
const entry = tracked.get(request.locator);
|
|
160
129
|
if (entry === undefined)
|
|
161
130
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
162
|
-
|
|
163
|
-
?
|
|
164
|
-
:
|
|
165
|
-
const held = await caughtUp(entry, continued?.after ?? null);
|
|
166
|
-
if ('failure' in held)
|
|
167
|
-
return held.failure;
|
|
168
|
-
notifications.reach(entry.authority, held.scope);
|
|
169
|
-
const seen = [
|
|
170
|
-
...(continued?.seen ?? []),
|
|
171
|
-
...entry.schemas.filter((schema) => held.scope.files.some((file) => file.path === schema)),
|
|
172
|
-
];
|
|
173
|
-
const models = await partModels(held.scope, entry, new Set(seen), held.next === null);
|
|
174
|
-
const continuation = held.next === null ? null : { after: held.next, seen };
|
|
175
|
-
return {
|
|
176
|
-
...bootstrapOf(held.scope),
|
|
177
|
-
...(models === undefined ? {} : { models }),
|
|
178
|
-
...(continuation === null ? {} : { pageToken: JSON.stringify(continuation) }),
|
|
179
|
-
};
|
|
131
|
+
return request.pageToken === undefined
|
|
132
|
+
? openedRoom(entry, request.arriving, request.signal)
|
|
133
|
+
: streamedPage(entry, request.pageToken);
|
|
180
134
|
},
|
|
181
135
|
async refresh(_authorization, request) {
|
|
182
136
|
const entry = tracked.get(request.locator);
|
|
@@ -194,34 +148,32 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
194
148
|
async mutate() {
|
|
195
149
|
return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {}, retryable: false };
|
|
196
150
|
},
|
|
151
|
+
async attach() {
|
|
152
|
+
return { kind: 'rejected', code: 'write-grant', fields: {}, retryable: false };
|
|
153
|
+
},
|
|
197
154
|
async history() {
|
|
198
155
|
return { kind: 'no-history' };
|
|
199
156
|
},
|
|
200
157
|
async binary(_authorization, request) {
|
|
201
|
-
const
|
|
202
|
-
if (
|
|
203
|
-
return
|
|
204
|
-
|
|
205
|
-
if (
|
|
206
|
-
return
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const read = await transport.download(`${SITE_FILES}${room_ref}/${encodeURIComponent(request.fileRef)}/${path === undefined
|
|
210
|
-
? `${SITE_FILE_RECORD}/${encodeURIComponent(record)}`
|
|
211
|
-
: encodeURIComponent(path)}`);
|
|
212
|
-
if (read.status === 404) {
|
|
213
|
-
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
214
|
-
}
|
|
215
|
-
return read.status === 200 && read.blob !== null
|
|
216
|
-
? { kind: 'binary', blob: read.blob }
|
|
158
|
+
const route = fileRoute(request);
|
|
159
|
+
if (typeof route !== 'string')
|
|
160
|
+
return route;
|
|
161
|
+
const read = await transport.download(route);
|
|
162
|
+
if (read.status === 404)
|
|
163
|
+
return unfound();
|
|
164
|
+
return read.status === 200 && read.body !== null
|
|
165
|
+
? { kind: 'binary', body: read.body, mediaType: read.mediaType }
|
|
217
166
|
: UNCERTAIN;
|
|
218
167
|
},
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
if (
|
|
222
|
-
return
|
|
223
|
-
|
|
224
|
-
|
|
168
|
+
async link(_authorization, request) {
|
|
169
|
+
const route = fileRoute(request);
|
|
170
|
+
if (typeof route !== 'string')
|
|
171
|
+
return route;
|
|
172
|
+
return {
|
|
173
|
+
kind: 'link',
|
|
174
|
+
url: route,
|
|
175
|
+
name: request.path.slice(request.path.lastIndexOf('/') + 1),
|
|
176
|
+
};
|
|
225
177
|
},
|
|
226
178
|
reached(locator, version, target) {
|
|
227
179
|
return reachedVersion(version, target, tracked.get(locator)?.logEpoch);
|
package/dist/stream.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ConversationStream, type RefreshPage, type RoomStreamEvent, type ServiceModeSignal, type StreamReceipts } from '@agentshouse/mdruntime';
|
|
2
2
|
import type { TrackedAuthority } from './discovery.js';
|
|
3
3
|
import type { HouseDoor, HouseHeldRoom, HouseMode, HouseStreamEntry } from './transport.js';
|
|
4
4
|
import { type LogPosition } from './version.js';
|
|
5
5
|
export type HeldRevision = (path: string, revision: string) => boolean;
|
|
6
6
|
export type StreamedAdvancement = {
|
|
7
7
|
page: RefreshPage;
|
|
8
|
-
entries: readonly HouseStreamEntry[];
|
|
9
8
|
schemas: ReadonlyMap<string, HouseStreamEntry>;
|
|
10
9
|
};
|
|
11
10
|
export type HouseNotifications = {
|
|
@@ -16,7 +15,8 @@ export type HouseNotifications = {
|
|
|
16
15
|
reopen(): void;
|
|
17
16
|
track(authorities: readonly TrackedAuthority[]): void;
|
|
18
17
|
reach(authority: string, at: LogPosition): void;
|
|
19
|
-
|
|
18
|
+
edited(tracked: TrackedAuthority, from: LogPosition): readonly string[];
|
|
19
|
+
advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): Generator<number, StreamedAdvancement | null, void>;
|
|
20
20
|
conversations: ConversationStream;
|
|
21
21
|
serviceMode: ServiceModeSignal;
|
|
22
22
|
};
|
package/dist/stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EAEvB,KAAK,WAAW,EAChB,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAUvD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EAEb,SAAS,EAET,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AA0C7D,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI,CAAC;IACxF,IAAI,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IAC5C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAClD,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,MAAM,EAAE,CAAC;IACxE,OAAO,CACL,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,EACjB,KAAK,CAAC,EAAE,YAAY,GACnB,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;IACvD,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAoFF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAkkB5F"}
|
package/dist/stream.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ROW_WEIGHT, } from '@agentshouse/mdruntime';
|
|
2
|
+
import { acceptedMessage, cursorPosition } from './actions.js';
|
|
2
3
|
import { sha256Hex } from './digest.js';
|
|
3
|
-
import { binaryFileOf, headChange } from './read.js';
|
|
4
|
+
import { answered, answering, binaryFileOf, folded, forgotten, headChange, revised, } from './read.js';
|
|
4
5
|
import { roomVersion } from './version.js';
|
|
5
6
|
const HELD_FRAMES_MAX = 256;
|
|
6
7
|
function turnOperation(frame) {
|
|
@@ -15,6 +16,8 @@ function listedConversation(listed) {
|
|
|
15
16
|
created: listed.created_at,
|
|
16
17
|
finished: listed.finished_at,
|
|
17
18
|
outcome: listed.outcome,
|
|
19
|
+
waiting: listed.waiting,
|
|
20
|
+
newest: listed.newest === null ? null : cursorPosition(listed.newest),
|
|
18
21
|
};
|
|
19
22
|
}
|
|
20
23
|
function position(value) {
|
|
@@ -111,7 +114,10 @@ export function houseNotifications(transport, mode) {
|
|
|
111
114
|
event.kind === 'questions' ||
|
|
112
115
|
event.kind === 'process' ||
|
|
113
116
|
event.kind === 'commands' ||
|
|
114
|
-
event.kind === 'options'
|
|
117
|
+
event.kind === 'options' ||
|
|
118
|
+
event.kind === 'starting' ||
|
|
119
|
+
event.kind === 'link' ||
|
|
120
|
+
event.kind === 'deliveries') {
|
|
115
121
|
live.add(event.conversation);
|
|
116
122
|
}
|
|
117
123
|
for (const observer of conversationObservers)
|
|
@@ -157,6 +163,18 @@ export function houseNotifications(transport, mode) {
|
|
|
157
163
|
emitConversation({ kind: 'options', conversation, options: structuredClone(frame.options) });
|
|
158
164
|
return;
|
|
159
165
|
}
|
|
166
|
+
if (frame.type === 'starting') {
|
|
167
|
+
emitConversation({ kind: 'starting', conversation, step: frame.step });
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (frame.type === 'link') {
|
|
171
|
+
emitConversation({ kind: 'link', conversation, connected: frame.connected });
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (frame.type === 'deliveries') {
|
|
175
|
+
emitConversation({ kind: 'deliveries', conversation, unknown: [...frame.unknown] });
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
160
178
|
if (frame.type === 'interactions') {
|
|
161
179
|
emitConversation({
|
|
162
180
|
kind: 'questions',
|
|
@@ -352,6 +370,10 @@ export function houseNotifications(transport, mode) {
|
|
|
352
370
|
});
|
|
353
371
|
return;
|
|
354
372
|
}
|
|
373
|
+
if (frame.type === 'authority_changed') {
|
|
374
|
+
emit({ kind: 'authority-changed', scope: { authorities: frame.rooms } });
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
355
377
|
if (frame.type === 'conversations') {
|
|
356
378
|
emitConversation({ kind: 'list', entries: frame.conversations.map(listedConversation) });
|
|
357
379
|
return;
|
|
@@ -368,15 +390,21 @@ export function houseNotifications(transport, mode) {
|
|
|
368
390
|
frame.type === 'process' ||
|
|
369
391
|
frame.type === 'commands' ||
|
|
370
392
|
frame.type === 'options' ||
|
|
393
|
+
frame.type === 'starting' ||
|
|
394
|
+
frame.type === 'link' ||
|
|
395
|
+
frame.type === 'deliveries' ||
|
|
371
396
|
frame.type === 'interactions' ||
|
|
372
397
|
frame.type === 'message') {
|
|
373
398
|
converse(frame);
|
|
374
399
|
return;
|
|
375
400
|
}
|
|
376
401
|
if (frame.type === 'part')
|
|
377
|
-
return stage(frame, via);
|
|
402
|
+
return ahead(() => stage(frame, via));
|
|
378
403
|
if (frame.type === 'carried')
|
|
379
|
-
return carried(frame);
|
|
404
|
+
return ahead(() => carried(frame));
|
|
405
|
+
}
|
|
406
|
+
function ahead(work) {
|
|
407
|
+
return receipts === null ? work() : receipts.ahead(work);
|
|
380
408
|
}
|
|
381
409
|
function publish(frame, entries) {
|
|
382
410
|
const at = position(frame.position);
|
|
@@ -421,10 +449,10 @@ export function houseNotifications(transport, mode) {
|
|
|
421
449
|
});
|
|
422
450
|
});
|
|
423
451
|
stream.opened(reopened);
|
|
424
|
-
stream.closed((revoked) => {
|
|
452
|
+
stream.closed(({ revoked, lost }) => {
|
|
425
453
|
opening = null;
|
|
426
454
|
acknowledging = null;
|
|
427
|
-
emit({ kind: 'closed', revoked });
|
|
455
|
+
emit({ kind: 'closed', revoked, lost });
|
|
428
456
|
});
|
|
429
457
|
return {
|
|
430
458
|
runtime,
|
|
@@ -532,7 +560,18 @@ export function houseNotifications(transport, mode) {
|
|
|
532
560
|
held,
|
|
533
561
|
});
|
|
534
562
|
},
|
|
535
|
-
|
|
563
|
+
edited(tracked, from) {
|
|
564
|
+
const line = lines.get(tracked.authority);
|
|
565
|
+
const start = position(from.position);
|
|
566
|
+
if (line === undefined || start === null || line.logEpoch !== from.logEpoch)
|
|
567
|
+
return [];
|
|
568
|
+
return [
|
|
569
|
+
...new Set(line.frames
|
|
570
|
+
.filter((frame) => frame.position > start)
|
|
571
|
+
.flatMap((frame) => frame.entries.flatMap((entry) => entry.kind === 'edited' && entry.revision !== undefined ? [entry.path] : []))),
|
|
572
|
+
];
|
|
573
|
+
},
|
|
574
|
+
*advance(tracked, from, holds) {
|
|
536
575
|
const line = lines.get(tracked.authority);
|
|
537
576
|
const start = position(from.position);
|
|
538
577
|
if (line === undefined || start === null || line.logEpoch !== from.logEpoch)
|
|
@@ -541,36 +580,26 @@ export function houseNotifications(transport, mode) {
|
|
|
541
580
|
const first = pending[0];
|
|
542
581
|
if (first === undefined || first.after > start)
|
|
543
582
|
return null;
|
|
544
|
-
const
|
|
545
|
-
const revisions = {};
|
|
546
|
-
const changes = {};
|
|
547
|
-
const binaryFiles = {};
|
|
548
|
-
const removals = [];
|
|
549
|
-
const applied = [];
|
|
583
|
+
const answer = answering();
|
|
550
584
|
const schemas = new Map();
|
|
551
|
-
const forget = (path) => {
|
|
552
|
-
delete documents[path];
|
|
553
|
-
delete revisions[path];
|
|
554
|
-
delete changes[path];
|
|
555
|
-
delete binaryFiles[path];
|
|
556
|
-
const removed = removals.indexOf(path);
|
|
557
|
-
if (removed !== -1)
|
|
558
|
-
removals.splice(removed, 1);
|
|
559
|
-
};
|
|
560
585
|
for (const frame of pending) {
|
|
561
586
|
for (const entry of frame.entries) {
|
|
587
|
+
yield ROW_WEIGHT + (entry.text?.length ?? 0);
|
|
588
|
+
if (entry.kind === 'folder') {
|
|
589
|
+
folded(answer, entry.path, entry.removed === true);
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
562
592
|
if (entry.kind === 'edited' &&
|
|
563
593
|
entry.revision !== undefined &&
|
|
564
594
|
holds?.(entry.path, entry.revision) === true) {
|
|
565
|
-
|
|
595
|
+
forgotten(answer, entry.path);
|
|
566
596
|
continue;
|
|
567
597
|
}
|
|
568
|
-
|
|
569
|
-
if (tracked.schemas.includes(entry.path))
|
|
598
|
+
if (entry.path === tracked.schema)
|
|
570
599
|
schemas.set(entry.path, entry);
|
|
571
600
|
if (entry.kind === 'removed') {
|
|
572
|
-
|
|
573
|
-
removals.
|
|
601
|
+
forgotten(answer, entry.path);
|
|
602
|
+
answer.removals.add(entry.path);
|
|
574
603
|
continue;
|
|
575
604
|
}
|
|
576
605
|
const binary = binaryFileOf(entry);
|
|
@@ -581,31 +610,33 @@ export function houseNotifications(transport, mode) {
|
|
|
581
610
|
const head = headChange(entry);
|
|
582
611
|
if (head === null)
|
|
583
612
|
return null;
|
|
584
|
-
|
|
613
|
+
forgotten(answer, entry.path);
|
|
585
614
|
if (binary === undefined)
|
|
586
|
-
documents
|
|
615
|
+
answer.documents.set(entry.path, entry.text);
|
|
587
616
|
else
|
|
588
|
-
binaryFiles
|
|
617
|
+
answer.binaryFiles.set(entry.path, binary);
|
|
589
618
|
const revision = entry.revision ?? binary?.sha256;
|
|
590
619
|
if (revision !== undefined)
|
|
591
|
-
|
|
620
|
+
revised(answer, entry.path, revision);
|
|
592
621
|
if (head !== undefined)
|
|
593
|
-
changes
|
|
622
|
+
answer.changes.set(entry.path, head);
|
|
594
623
|
}
|
|
595
624
|
}
|
|
596
625
|
const last = pending.at(-1);
|
|
597
|
-
lines.
|
|
626
|
+
const current = lines.get(tracked.authority);
|
|
627
|
+
if (current?.logEpoch === line.logEpoch) {
|
|
628
|
+
lines.set(tracked.authority, {
|
|
629
|
+
...current,
|
|
630
|
+
frames: current.frames.filter((frame) => frame.position > start),
|
|
631
|
+
held: current.held !== null && current.held > last.position ? current.held : last.position,
|
|
632
|
+
});
|
|
633
|
+
}
|
|
598
634
|
return {
|
|
599
635
|
page: {
|
|
600
636
|
kind: 'net-advancement',
|
|
601
637
|
roomVersion: roomVersion({ position: last.position.toString(), logEpoch: line.logEpoch }),
|
|
602
|
-
|
|
603
|
-
revisions,
|
|
604
|
-
changes,
|
|
605
|
-
binaryFiles,
|
|
606
|
-
removals: removals.sort(),
|
|
638
|
+
...(yield* answered(answer)),
|
|
607
639
|
},
|
|
608
|
-
entries: applied,
|
|
609
640
|
schemas,
|
|
610
641
|
};
|
|
611
642
|
},
|