@agentshouse/mdruntime-adapter 0.1.0-cca5d676bc88e → 0.1.0-ccda1a2da11c3
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/AGENTS.md +291 -213
- package/dist/actions.d.ts +69 -2
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +197 -198
- package/dist/adapter.d.ts +1 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +378 -112
- package/dist/discovery.d.ts +7 -6
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +50 -18
- package/dist/gather.d.ts +2 -1
- package/dist/gather.d.ts.map +1 -1
- package/dist/gather.js +15 -20
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/model.d.ts +1 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +21 -7
- package/dist/part.d.ts +13 -0
- package/dist/part.d.ts.map +1 -0
- package/dist/part.js +80 -0
- package/dist/read.d.ts +72 -20
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +353 -155
- package/dist/referrer.d.ts +9 -0
- package/dist/referrer.d.ts.map +1 -0
- package/dist/referrer.js +41 -0
- package/dist/refusal.d.ts +5 -9
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +31 -17
- package/dist/room-types.d.ts +6 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +66 -0
- package/dist/site.d.ts +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +184 -62
- package/dist/stream.d.ts +6 -4
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +360 -42
- package/dist/transport.d.ts +67 -11
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +3 -1
- package/dist/version.d.ts +1 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/write.d.ts +14 -9
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +172 -47
- package/package.json +3 -4
- package/dist/links.d.ts +0 -20
- package/dist/links.d.ts.map +0 -1
- package/dist/links.js +0 -104
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"referrer.d.ts","sourceRoot":"","sources":["../src/referrer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,CAAC;AAgB5F,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC7C,aAAa,GAAG,IAAI,CAoBtB;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC7C,aAAa,GAAG,IAAI,CAOtB"}
|
package/dist/referrer.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
function fields(value) {
|
|
2
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
3
|
+
? value
|
|
4
|
+
: null;
|
|
5
|
+
}
|
|
6
|
+
function named(held, ...keys) {
|
|
7
|
+
const present = Object.keys(held);
|
|
8
|
+
return (present.length === keys.length &&
|
|
9
|
+
keys.every((key) => typeof held[key] === 'string' && held[key] !== ''));
|
|
10
|
+
}
|
|
11
|
+
export function houseReferrer(referrer, tracked) {
|
|
12
|
+
const held = fields(referrer);
|
|
13
|
+
if (held === null)
|
|
14
|
+
return null;
|
|
15
|
+
if (named(held, 'room', 'path')) {
|
|
16
|
+
const entry = tracked.get(held.room);
|
|
17
|
+
if (entry === undefined)
|
|
18
|
+
return null;
|
|
19
|
+
return {
|
|
20
|
+
locator: entry.locator,
|
|
21
|
+
referrer: { room_ref: entry.authority, path: held.path },
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (named(held, 'room_ref', 'record')) {
|
|
25
|
+
const roomRef = held.room_ref;
|
|
26
|
+
const entry = [...tracked.values()].find((candidate) => candidate.authority === roomRef);
|
|
27
|
+
return {
|
|
28
|
+
locator: entry?.locator ?? roomRef,
|
|
29
|
+
referrer: { room_ref: roomRef, record: held.record },
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
export function houseReferrerScope(referrer, tracked) {
|
|
35
|
+
const held = fields(referrer);
|
|
36
|
+
if (held !== null && named(held, 'room', 'path')) {
|
|
37
|
+
return { locator: held.room, path: held.path };
|
|
38
|
+
}
|
|
39
|
+
const found = houseReferrer(referrer, tracked);
|
|
40
|
+
return found === null ? null : { locator: found.locator };
|
|
41
|
+
}
|
package/dist/refusal.d.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import type { AdapterFailure, DiscoverResult, ProviderRefusal, ScopedRefusal } from '@agentshouse/mdruntime';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function scopedRefusal(locator: string, scope: ScopedRefusal['scope'], refusal: DoorRefusal): ScopedRefusal;
|
|
7
|
-
export declare function classifyDoor(status: number, body: unknown, locator: string): AdapterFailure | {
|
|
2
|
+
export declare function doorRefusal(body: unknown): ProviderRefusal | null;
|
|
3
|
+
export declare function scopedRefusal(locator: string, scope: ScopedRefusal['scope'], refusal: ProviderRefusal): ScopedRefusal;
|
|
4
|
+
export declare function classifyDoor(status: number, body: unknown, locator: string): AdapterFailure | null;
|
|
5
|
+
export declare function classifyRead(status: number, body: unknown, locator: string): AdapterFailure | {
|
|
8
6
|
kind: 'beyond-horizon';
|
|
9
7
|
} | null;
|
|
10
|
-
export declare function discoveryFailure(
|
|
11
|
-
kind: 'beyond-horizon';
|
|
12
|
-
}): DiscoverResult;
|
|
8
|
+
export declare function discoveryFailure(status: number, body: unknown): DiscoverResult | null;
|
|
13
9
|
//# sourceMappingURL=refusal.d.ts.map
|
package/dist/refusal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refusal.d.ts","sourceRoot":"","sources":["../src/refusal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,eAAe,EACf,aAAa,EACd,MAAM,wBAAwB,CAAC;AAEhC,
|
|
1
|
+
{"version":3,"file":"refusal.d.ts","sourceRoot":"","sources":["../src/refusal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,eAAe,EACf,aAAa,EACd,MAAM,wBAAwB,CAAC;AAEhC,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAOjE;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,OAAO,EAAE,eAAe,GACvB,aAAa,CAEf;AAqBD,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,GACd,cAAc,GAAG,IAAI,CAMvB;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,GACd,cAAc,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAAG,IAAI,CAGpD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAQrF"}
|
package/dist/refusal.js
CHANGED
|
@@ -6,38 +6,52 @@ export function doorRefusal(body) {
|
|
|
6
6
|
const error = body.error;
|
|
7
7
|
if (typeof error.code !== 'string')
|
|
8
8
|
return null;
|
|
9
|
-
const { code, ...fields } = error;
|
|
10
|
-
return { code, fields, retryable:
|
|
9
|
+
const { code, retryable, ...fields } = error;
|
|
10
|
+
return { code, fields, retryable: retryable === true };
|
|
11
11
|
}
|
|
12
12
|
export function scopedRefusal(locator, scope, refusal) {
|
|
13
|
-
return { kind: 'scoped-refusal', locator, scope,
|
|
13
|
+
return { kind: 'scoped-refusal', locator, scope, ...refusal };
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
function doorFailure(status, body) {
|
|
16
16
|
if (status === 0)
|
|
17
17
|
return { kind: 'transport-uncertainty' };
|
|
18
18
|
const refusal = doorRefusal(body);
|
|
19
19
|
if (status === 401)
|
|
20
20
|
return { kind: 'revoked-authorization' };
|
|
21
|
-
if (refusal?.retryable === true)
|
|
21
|
+
if (refusal?.retryable === true || refusal?.code === 'update_required') {
|
|
22
22
|
return { kind: 'transport-uncertainty' };
|
|
23
|
-
if (refusal !== null && refusal.code === 'position_expired')
|
|
24
|
-
return { kind: 'beyond-horizon' };
|
|
25
|
-
if (status === 404 || refusal?.code === 'room_not_found') {
|
|
26
|
-
return { kind: 'room-not-readable', locator };
|
|
27
23
|
}
|
|
24
|
+
if (status === 404 || refusal?.code === 'room_not_found')
|
|
25
|
+
return { kind: 'room-not-readable' };
|
|
28
26
|
if (status < 400)
|
|
29
27
|
return null;
|
|
30
28
|
if (refusal === null)
|
|
31
29
|
return { kind: 'transport-uncertainty' };
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
return { kind: 'refused', scope: status === 403 ? 'operation' : 'undisclosed', refusal };
|
|
31
|
+
}
|
|
32
|
+
export function classifyDoor(status, body, locator) {
|
|
33
|
+
const failure = doorFailure(status, body);
|
|
34
|
+
if (failure === null)
|
|
35
|
+
return null;
|
|
36
|
+
if (failure.kind === 'room-not-readable')
|
|
37
|
+
return { kind: 'room-not-readable', locator };
|
|
38
|
+
if (failure.kind === 'refused')
|
|
39
|
+
return scopedRefusal(locator, failure.scope, failure.refusal);
|
|
40
|
+
return failure;
|
|
35
41
|
}
|
|
36
|
-
export function
|
|
37
|
-
if (
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
export function classifyRead(status, body, locator) {
|
|
43
|
+
if (doorRefusal(body)?.code === 'expired')
|
|
44
|
+
return { kind: 'beyond-horizon' };
|
|
45
|
+
return classifyDoor(status, body, locator);
|
|
46
|
+
}
|
|
47
|
+
export function discoveryFailure(status, body) {
|
|
48
|
+
const failure = doorFailure(status, body);
|
|
49
|
+
if (failure === null)
|
|
50
|
+
return null;
|
|
51
|
+
if (failure.kind === 'revoked-authorization')
|
|
52
|
+
return failure;
|
|
53
|
+
if (failure.kind === 'refused') {
|
|
54
|
+
return { kind: 'contract-unavailable', ...failure.refusal };
|
|
41
55
|
}
|
|
42
56
|
return { kind: 'transport-uncertainty' };
|
|
43
57
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const INBOX_CHANNEL_KINDS: readonly ['telegram-bot'];
|
|
2
|
+
export type InboxChannelKind = (typeof INBOX_CHANNEL_KINDS)[number];
|
|
3
|
+
export declare const INBOX_CHAT_TYPE = "inbox-chat";
|
|
4
|
+
export declare const INBOX_MESSAGE_TYPE = "inbox-message";
|
|
5
|
+
export declare const HOUSE_ROOM_TYPES: string;
|
|
6
|
+
//# 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":"AAAA,eAAO,MAAM,mBAAmB,YAAI,cAAc,CAAU,CAAC;AAE7D,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,eAAe,eAAe,CAAC;AAE5C,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAalD,eAAO,MAAM,gBAAgB,QAsDjB,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export const INBOX_CHANNEL_KINDS = ['telegram-bot'];
|
|
2
|
+
export const INBOX_CHAT_TYPE = 'inbox-chat';
|
|
3
|
+
export const INBOX_MESSAGE_TYPE = 'inbox-message';
|
|
4
|
+
const IDENTITY = "{ type: string, pattern: '^\\S+$' }";
|
|
5
|
+
const AGENT = [' agent: { type: string, format: uuid }', ' name: { type: string }'];
|
|
6
|
+
const ASSIGNEE = [
|
|
7
|
+
' type: object',
|
|
8
|
+
' properties:',
|
|
9
|
+
' user: { type: string, format: uuid }',
|
|
10
|
+
...AGENT,
|
|
11
|
+
];
|
|
12
|
+
export const HOUSE_ROOM_TYPES = [
|
|
13
|
+
`${INBOX_CHAT_TYPE}:`,
|
|
14
|
+
' properties:',
|
|
15
|
+
' inbox: { type: string, format: uuid }',
|
|
16
|
+
` channel: { enum: [${INBOX_CHANNEL_KINDS.join(', ')}] }`,
|
|
17
|
+
` chat: ${IDENTITY}`,
|
|
18
|
+
' customer:',
|
|
19
|
+
' type: object',
|
|
20
|
+
' properties:',
|
|
21
|
+
' name: { type: string }',
|
|
22
|
+
` username: ${IDENTITY}`,
|
|
23
|
+
` phone: ${IDENTITY}`,
|
|
24
|
+
' assignee:',
|
|
25
|
+
...ASSIGNEE,
|
|
26
|
+
' return_to:',
|
|
27
|
+
' type: object',
|
|
28
|
+
' properties:',
|
|
29
|
+
...AGENT,
|
|
30
|
+
' conversation: { type: string, format: uuid }',
|
|
31
|
+
' required: [inbox, channel, chat, customer]',
|
|
32
|
+
`${INBOX_MESSAGE_TYPE}:`,
|
|
33
|
+
' properties:',
|
|
34
|
+
' direction: { enum: [in, out] }',
|
|
35
|
+
' sender:',
|
|
36
|
+
' type: object',
|
|
37
|
+
' properties:',
|
|
38
|
+
' name: { type: string }',
|
|
39
|
+
` username: ${IDENTITY}`,
|
|
40
|
+
' sent_at: { type: string, format: date-time }',
|
|
41
|
+
` channel_message: ${IDENTITY}`,
|
|
42
|
+
' state: { enum: [sending, sent, failed] }',
|
|
43
|
+
' reason: { type: string }',
|
|
44
|
+
' reactions:',
|
|
45
|
+
' type: array',
|
|
46
|
+
' items:',
|
|
47
|
+
' type: object',
|
|
48
|
+
' properties:',
|
|
49
|
+
' reaction: { type: string, minLength: 1 }',
|
|
50
|
+
' sender:',
|
|
51
|
+
' type: object',
|
|
52
|
+
' properties:',
|
|
53
|
+
` id: ${IDENTITY}`,
|
|
54
|
+
' name: { type: string }',
|
|
55
|
+
` username: ${IDENTITY}`,
|
|
56
|
+
' count: { type: integer, minimum: 1 }',
|
|
57
|
+
' required: [reaction]',
|
|
58
|
+
` post: ${IDENTITY}`,
|
|
59
|
+
' assignee:',
|
|
60
|
+
...ASSIGNEE,
|
|
61
|
+
' sent_outside: { const: true }',
|
|
62
|
+
' required: [direction]',
|
|
63
|
+
' if: { properties: { direction: { const: in } } }',
|
|
64
|
+
' then: { required: [sent_at] }',
|
|
65
|
+
'',
|
|
66
|
+
].join('\n');
|
package/dist/site.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Adapter } from '@agentshouse/mdruntime';
|
|
2
2
|
import { type HouseSiteTransport } from './transport.js';
|
|
3
|
-
export declare function createSiteAdapter(transport: HouseSiteTransport): Adapter;
|
|
3
|
+
export declare function createSiteAdapter(transport: HouseSiteTransport, snapshot?: boolean): Adapter;
|
|
4
4
|
//# sourceMappingURL=site.d.ts.map
|
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;AA8BhC,OAAO,EAOL,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAuCxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAoQ1F"}
|
package/dist/site.js
CHANGED
|
@@ -1,86 +1,144 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { stepped } from '@agentshouse/mdruntime';
|
|
2
|
+
import { actionOutcome, SITE_SUBMIT } from './actions.js';
|
|
2
3
|
import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked, } from './discovery.js';
|
|
3
|
-
import {
|
|
4
|
-
import { advancedScope,
|
|
5
|
-
import {
|
|
4
|
+
import { partModels, streamedModels, viewModels } from './model.js';
|
|
5
|
+
import { advancedScope, bootstrapping, emptyScope, housePart, parseEnumeration, parseSiteParted, refreshFrom, viewOf, wholeView, } from './read.js';
|
|
6
|
+
import { PART_ATTEMPTS, unverifiedPart } from './part.js';
|
|
7
|
+
import { classifyDoor, classifyRead, discoveryFailure } from './refusal.js';
|
|
8
|
+
import { HOUSE_ROOM_TYPES } from './room-types.js';
|
|
6
9
|
import { houseNotifications } from './stream.js';
|
|
7
|
-
import {
|
|
10
|
+
import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, SITE_FILE_RECORD, SITE_FILES, } from './transport.js';
|
|
11
|
+
import { houseReferrer } from './referrer.js';
|
|
8
12
|
import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
|
|
9
13
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
14
|
+
function unfound() {
|
|
15
|
+
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
16
|
+
}
|
|
10
17
|
function siteRoom(tracked) {
|
|
11
18
|
return {
|
|
12
19
|
name: tracked.handle,
|
|
13
20
|
locator: tracked.locator,
|
|
21
|
+
handle: tracked.handle,
|
|
14
22
|
roomVersion: roomVersion(tracked),
|
|
15
|
-
operations: {
|
|
16
|
-
replica: { selection: tracked.locator, admission: 'admitted' },
|
|
23
|
+
operations: { write: [], delete: [] },
|
|
24
|
+
replica: { selection: tracked.locator, admission: 'admitted', offline: 'open' },
|
|
17
25
|
providerOwnedPaths: [],
|
|
18
26
|
};
|
|
19
27
|
}
|
|
20
28
|
function settled(refused) {
|
|
21
29
|
return refused.kind === 'beyond-horizon' ? UNCERTAIN : refused;
|
|
22
30
|
}
|
|
23
|
-
export function createSiteAdapter(transport) {
|
|
31
|
+
export function createSiteAdapter(transport, snapshot = false) {
|
|
24
32
|
const notifications = houseNotifications(transport, 'site');
|
|
25
33
|
const tracked = new Map();
|
|
26
|
-
|
|
34
|
+
const expired = new Map();
|
|
35
|
+
function published(referrer) {
|
|
36
|
+
const named = houseReferrer(referrer, tracked);
|
|
37
|
+
return named === null || !tracked.has(named.locator) ? null : named;
|
|
38
|
+
}
|
|
39
|
+
function fileRoute(request) {
|
|
40
|
+
const named = published(request.kind === 'path' ? { room: request.locator, path: request.path } : request.referrer);
|
|
41
|
+
if (named === null) {
|
|
42
|
+
return { kind: 'rejected', code: 'referrer_unknown', fields: {}, retryable: false };
|
|
43
|
+
}
|
|
44
|
+
if (request.fileRef === undefined)
|
|
45
|
+
return unfound();
|
|
46
|
+
const { room_ref, path, record } = named.referrer;
|
|
47
|
+
return `${SITE_FILES}${room_ref}/${encodeURIComponent(request.fileRef)}/${path === undefined
|
|
48
|
+
? `${SITE_FILE_RECORD}/${encodeURIComponent(record)}`
|
|
49
|
+
: encodeURIComponent(path)}`;
|
|
50
|
+
}
|
|
51
|
+
async function enumerated(entry, from, page) {
|
|
27
52
|
const answer = await transport.door(SITE_DOOR_ENUMERATE, {
|
|
28
|
-
positions: [
|
|
53
|
+
positions: [
|
|
54
|
+
page === undefined
|
|
55
|
+
? presented(entry.authority, from)
|
|
56
|
+
: {
|
|
57
|
+
...presented(entry.authority, { position: page.after, logEpoch: from.logEpoch }),
|
|
58
|
+
page: { through: page.through, read: page.read },
|
|
59
|
+
},
|
|
60
|
+
],
|
|
29
61
|
});
|
|
30
|
-
const classified =
|
|
62
|
+
const classified = classifyRead(answer.status, answer.body, entry.locator);
|
|
31
63
|
if (classified !== null)
|
|
32
64
|
return classified;
|
|
33
|
-
|
|
65
|
+
const found = parseEnumeration(answer.body, 'site');
|
|
66
|
+
if (found === null)
|
|
67
|
+
return UNCERTAIN;
|
|
68
|
+
return viewOf(found, entry) ?? { kind: 'room-not-readable', locator: entry.locator };
|
|
69
|
+
}
|
|
70
|
+
async function enumeration(entry, from) {
|
|
71
|
+
const first = await enumerated(entry, from);
|
|
72
|
+
return 'kind' in first ? first : wholeView(first, (page) => enumerated(entry, from, page));
|
|
34
73
|
}
|
|
35
|
-
async function
|
|
36
|
-
const
|
|
74
|
+
async function partedRoom(entry) {
|
|
75
|
+
const cut = expired.get(entry.locator);
|
|
76
|
+
const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}${cut === undefined ? '' : `?expired=${cut}`}`);
|
|
37
77
|
const classified = classifyDoor(answer.status, answer.body, entry.locator);
|
|
38
78
|
if (classified !== null)
|
|
39
|
-
return
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
79
|
+
return classified;
|
|
80
|
+
const room = parseSiteParted(answer.body);
|
|
81
|
+
return room === null || room.anchor !== entry.authority ? UNCERTAIN : room;
|
|
82
|
+
}
|
|
83
|
+
async function fetchedPart(entry, room, listed) {
|
|
84
|
+
for (let attempt = 0; attempt < PART_ATTEMPTS; attempt += 1) {
|
|
85
|
+
const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}?part=${encodeURIComponent(listed.part)}`);
|
|
86
|
+
const failure = classifyRead(answer.status, answer.body, entry.locator);
|
|
87
|
+
if (failure?.kind === 'beyond-horizon')
|
|
88
|
+
expired.set(entry.locator, room.position);
|
|
89
|
+
if (failure !== null)
|
|
90
|
+
return failure;
|
|
91
|
+
const scope = await housePart(room, answer.body, listed, 'site');
|
|
92
|
+
if (scope !== null)
|
|
93
|
+
return scope;
|
|
94
|
+
}
|
|
95
|
+
return unverifiedPart(entry.locator);
|
|
96
|
+
}
|
|
97
|
+
async function caughtUp(entry, continued) {
|
|
98
|
+
const listed = continued.room.parts[continued.next];
|
|
99
|
+
const scope = listed === undefined
|
|
100
|
+
? emptyScope(continued.room)
|
|
101
|
+
: await fetchedPart(entry, continued.room, listed);
|
|
102
|
+
if ('kind' in scope)
|
|
103
|
+
return scope;
|
|
104
|
+
if (continued.room.parts.length > 1 || roomVersion(scope) === roomVersion(entry))
|
|
105
|
+
return scope;
|
|
106
|
+
const view = await enumeration(entry, scope);
|
|
107
|
+
if ('kind' in view)
|
|
108
|
+
return settled(view);
|
|
109
|
+
return stepped(advancedScope(scope, view));
|
|
52
110
|
}
|
|
53
111
|
async function refreshed(entry, fromRoomVersion) {
|
|
54
112
|
const from = logPosition(fromRoomVersion);
|
|
55
113
|
if (from === null)
|
|
56
114
|
return { kind: 'beyond-horizon' };
|
|
57
|
-
const streamed = notifications.advance(entry, from);
|
|
115
|
+
const streamed = await stepped(notifications.advance(entry, from));
|
|
58
116
|
if (streamed !== null) {
|
|
59
117
|
const models = await streamedModels(streamed.schemas, entry, 'site');
|
|
60
118
|
return models === undefined ? streamed.page : { ...streamed.page, models };
|
|
61
119
|
}
|
|
62
|
-
const
|
|
63
|
-
if ('kind' in
|
|
64
|
-
return
|
|
65
|
-
const view = viewOf(found, entry);
|
|
66
|
-
if (view === undefined)
|
|
67
|
-
return { kind: 'room-not-readable', locator: entry.locator };
|
|
120
|
+
const view = await enumeration(entry, from);
|
|
121
|
+
if ('kind' in view)
|
|
122
|
+
return view;
|
|
68
123
|
notifications.reach(entry.authority, view);
|
|
69
|
-
const answer = refreshFrom(view, fromRoomVersion);
|
|
124
|
+
const answer = await refreshFrom(view, fromRoomVersion);
|
|
70
125
|
if (answer.kind !== 'net-advancement')
|
|
71
126
|
return answer;
|
|
72
127
|
const models = await viewModels(view, entry);
|
|
73
128
|
return models === undefined ? answer : { ...answer, models };
|
|
74
129
|
}
|
|
75
130
|
return {
|
|
131
|
+
localSaves: true,
|
|
132
|
+
exhaustiveDiscovery: true,
|
|
133
|
+
roomTypes: HOUSE_ROOM_TYPES,
|
|
76
134
|
async authorize() {
|
|
77
135
|
return {};
|
|
78
136
|
},
|
|
79
137
|
async discover() {
|
|
80
138
|
const answer = await transport.read(SITE_DOOR_DISCOVER);
|
|
81
|
-
const
|
|
82
|
-
if (
|
|
83
|
-
return
|
|
139
|
+
const failed = discoveryFailure(answer.status, answer.body);
|
|
140
|
+
if (failed !== null)
|
|
141
|
+
return failed;
|
|
84
142
|
const document = parseSiteDiscovery(answer.body);
|
|
85
143
|
if (document === null)
|
|
86
144
|
return UNCERTAIN;
|
|
@@ -95,14 +153,32 @@ export function createSiteAdapter(transport) {
|
|
|
95
153
|
const entry = tracked.get(request.locator);
|
|
96
154
|
if (entry === undefined)
|
|
97
155
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
156
|
+
let continued;
|
|
157
|
+
if (request.pageToken === undefined) {
|
|
158
|
+
const room = await partedRoom(entry);
|
|
159
|
+
if ('kind' in room)
|
|
160
|
+
return room;
|
|
161
|
+
continued = { room, next: 0, seen: [] };
|
|
162
|
+
}
|
|
163
|
+
else
|
|
164
|
+
continued = JSON.parse(request.pageToken);
|
|
165
|
+
const scope = await caughtUp(entry, continued);
|
|
166
|
+
if ('kind' in scope)
|
|
167
|
+
return scope;
|
|
168
|
+
notifications.reach(entry.authority, scope);
|
|
169
|
+
const next = continued.next + 1;
|
|
170
|
+
const more = next < continued.room.parts.length;
|
|
171
|
+
const seen = [
|
|
172
|
+
...continued.seen,
|
|
173
|
+
...entry.schemas.filter((schema) => scope.files.some((file) => file.path === schema)),
|
|
174
|
+
];
|
|
175
|
+
const models = await partModels(scope, entry, new Set(seen), !more);
|
|
176
|
+
const { folders: _folders, ...page } = await stepped(bootstrapping(scope));
|
|
177
|
+
return {
|
|
178
|
+
...page,
|
|
179
|
+
...(models === undefined ? {} : { models }),
|
|
180
|
+
...(more ? { pageToken: JSON.stringify({ ...continued, next, seen }) } : {}),
|
|
181
|
+
};
|
|
106
182
|
},
|
|
107
183
|
async refresh(_authorization, request) {
|
|
108
184
|
const entry = tracked.get(request.locator);
|
|
@@ -110,14 +186,47 @@ export function createSiteAdapter(transport) {
|
|
|
110
186
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
111
187
|
if (request.pageToken !== undefined)
|
|
112
188
|
return UNCERTAIN;
|
|
189
|
+
if (snapshot) {
|
|
190
|
+
return request.fromRoomVersion === roomVersion(entry)
|
|
191
|
+
? { kind: 'still-current' }
|
|
192
|
+
: { kind: 'beyond-horizon' };
|
|
193
|
+
}
|
|
113
194
|
return refreshed(entry, request.fromRoomVersion);
|
|
114
195
|
},
|
|
115
196
|
async mutate() {
|
|
116
|
-
return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {} };
|
|
197
|
+
return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {}, retryable: false };
|
|
117
198
|
},
|
|
118
199
|
async history() {
|
|
119
200
|
return { kind: 'no-history' };
|
|
120
201
|
},
|
|
202
|
+
async binary(_authorization, request) {
|
|
203
|
+
const route = fileRoute(request);
|
|
204
|
+
if (typeof route !== 'string')
|
|
205
|
+
return route;
|
|
206
|
+
const read = await transport.download(route);
|
|
207
|
+
if (read.status === 404)
|
|
208
|
+
return unfound();
|
|
209
|
+
return read.status === 200 && read.body !== null
|
|
210
|
+
? { kind: 'binary', body: read.body, mediaType: read.mediaType }
|
|
211
|
+
: UNCERTAIN;
|
|
212
|
+
},
|
|
213
|
+
async link(_authorization, request) {
|
|
214
|
+
const route = fileRoute(request);
|
|
215
|
+
if (typeof route !== 'string')
|
|
216
|
+
return route;
|
|
217
|
+
return {
|
|
218
|
+
kind: 'link',
|
|
219
|
+
url: route,
|
|
220
|
+
name: request.path.slice(request.path.lastIndexOf('/') + 1),
|
|
221
|
+
};
|
|
222
|
+
},
|
|
223
|
+
referrerScope(referrer) {
|
|
224
|
+
const named = published(referrer);
|
|
225
|
+
if (named === null)
|
|
226
|
+
return null;
|
|
227
|
+
const { path } = named.referrer;
|
|
228
|
+
return { locator: named.locator, ...(path === undefined ? {} : { path }) };
|
|
229
|
+
},
|
|
121
230
|
reached(locator, version, target) {
|
|
122
231
|
return reachedVersion(version, target, tracked.get(locator)?.logEpoch);
|
|
123
232
|
},
|
|
@@ -125,26 +234,39 @@ export function createSiteAdapter(transport) {
|
|
|
125
234
|
return followsVersion(version, next);
|
|
126
235
|
},
|
|
127
236
|
async action(_authorization, request) {
|
|
128
|
-
if (request.name !==
|
|
129
|
-
return {
|
|
237
|
+
if (request.name !== SITE_SUBMIT) {
|
|
238
|
+
return {
|
|
239
|
+
kind: 'rejected',
|
|
240
|
+
code: 'action-unimplemented',
|
|
241
|
+
fields: { name: request.name },
|
|
242
|
+
retryable: false,
|
|
243
|
+
};
|
|
130
244
|
}
|
|
131
245
|
if (!transport.online())
|
|
132
246
|
return UNCERTAIN;
|
|
133
|
-
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input),
|
|
247
|
+
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), SITE_SUBMIT);
|
|
134
248
|
},
|
|
135
|
-
roomStream:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
249
|
+
roomStream: snapshot
|
|
250
|
+
? undefined
|
|
251
|
+
: {
|
|
252
|
+
hold(rooms) {
|
|
253
|
+
notifications.send(rooms.flatMap((room) => {
|
|
254
|
+
const entry = tracked.get(room.locator);
|
|
255
|
+
const at = logPosition(room.roomVersion);
|
|
256
|
+
if (entry === undefined || at === null)
|
|
257
|
+
return [];
|
|
258
|
+
notifications.reach(entry.authority, at);
|
|
259
|
+
return [presented(entry.authority, at)];
|
|
260
|
+
}));
|
|
261
|
+
},
|
|
262
|
+
reopen: notifications.reopen,
|
|
263
|
+
observe: notifications.observe,
|
|
264
|
+
published(locator, roomVersion) {
|
|
265
|
+
const at = logPosition(roomVersion);
|
|
266
|
+
if (at !== null)
|
|
267
|
+
notifications.published(locator, at);
|
|
268
|
+
},
|
|
145
269
|
},
|
|
146
|
-
observe: notifications.observe,
|
|
147
|
-
},
|
|
148
270
|
serviceMode: notifications.serviceMode,
|
|
149
271
|
};
|
|
150
272
|
}
|
package/dist/stream.d.ts
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
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 = {
|
|
12
11
|
runtime: string;
|
|
13
|
-
observe(notify: (event: RoomStreamEvent) => void): () => void;
|
|
12
|
+
observe(notify: (event: RoomStreamEvent) => void, receipts: StreamReceipts): () => void;
|
|
14
13
|
send(rooms: readonly HouseHeldRoom[]): void;
|
|
14
|
+
published(locator: string, at: LogPosition): void;
|
|
15
|
+
reopen(): void;
|
|
15
16
|
track(authorities: readonly TrackedAuthority[]): void;
|
|
16
17
|
reach(authority: string, at: LogPosition): void;
|
|
17
|
-
|
|
18
|
+
edited(tracked: TrackedAuthority, from: LogPosition): readonly string[];
|
|
19
|
+
advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): Generator<number, StreamedAdvancement | null, void>;
|
|
18
20
|
conversations: ConversationStream;
|
|
19
21
|
serviceMode: ServiceModeSignal;
|
|
20
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;AAmFF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CA8jB5F"}
|