@agentshouse/mdruntime-adapter 0.1.0-cf22c8563f9f4 → 0.1.0-cf599f631976d
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 +6 -5
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +25 -322
- package/dist/adapter.d.ts +1 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +278 -206
- 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/chunks.d.ts +38 -0
- package/dist/chunks.d.ts.map +1 -0
- package/dist/chunks.js +247 -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 +25 -15
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +104 -52
- 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 +682 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +396 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/model.d.ts +5 -4
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +40 -33
- package/dist/read.d.ts +63 -42
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +179 -262
- package/dist/refusal.d.ts +3 -8
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +10 -14
- package/dist/room-types.d.ts +5 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +120 -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 +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +120 -105
- package/dist/space-schema.d.ts +7 -0
- package/dist/space-schema.d.ts.map +1 -0
- package/dist/space-schema.js +18 -0
- package/dist/stream.d.ts +15 -12
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +275 -147
- package/dist/transport.d.ts +90 -24
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +55 -9
- package/dist/upload.d.ts +12 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +63 -0
- 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 +20 -10
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +165 -59
- package/package.json +9 -6
- package/AGENTS.md +0 -244
- package/dist/gather.d.ts +0 -3
- package/dist/gather.d.ts.map +0 -1
- package/dist/gather.js +0 -40
- package/dist/links.d.ts +0 -20
- package/dist/links.d.ts.map +0 -1
- package/dist/links.js +0 -104
package/dist/refusal.d.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import type { AdapterFailure, DiscoverResult, ProviderRefusal, ScopedRefusal } from '@agentshouse/mdruntime';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export declare function doorRefusal(body: unknown): DoorRefusal | null;
|
|
6
|
-
export declare function scopedRefusal(locator: string, scope: ScopedRefusal['scope'], refusal: DoorRefusal): ScopedRefusal;
|
|
2
|
+
export declare function doorRefusal(body: unknown): ProviderRefusal | null;
|
|
3
|
+
export declare function resetOf(refusal: ProviderRefusal | null): string | undefined;
|
|
4
|
+
export declare function scopedRefusal(locator: string, scope: ScopedRefusal['scope'], refusal: ProviderRefusal): ScopedRefusal;
|
|
7
5
|
export declare function classifyDoor(status: number, body: unknown, locator: string): AdapterFailure | null;
|
|
8
|
-
export declare function classifyRead(status: number, body: unknown, locator: string): AdapterFailure | {
|
|
9
|
-
kind: 'beyond-horizon';
|
|
10
|
-
} | null;
|
|
11
6
|
export declare function discoveryFailure(status: number, body: unknown): DiscoverResult | null;
|
|
12
7
|
//# 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,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAG3E;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,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAQrF"}
|
package/dist/refusal.js
CHANGED
|
@@ -6,11 +6,15 @@ 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
|
+
}
|
|
12
|
+
export function resetOf(refusal) {
|
|
13
|
+
const reset = refusal?.fields.retry_at;
|
|
14
|
+
return refusal?.retryable === true && typeof reset === 'string' ? reset : undefined;
|
|
11
15
|
}
|
|
12
16
|
export function scopedRefusal(locator, scope, refusal) {
|
|
13
|
-
return { kind: 'scoped-refusal', locator, scope,
|
|
17
|
+
return { kind: 'scoped-refusal', locator, scope, ...refusal };
|
|
14
18
|
}
|
|
15
19
|
function doorFailure(status, body) {
|
|
16
20
|
if (status === 0)
|
|
@@ -18,8 +22,9 @@ function doorFailure(status, body) {
|
|
|
18
22
|
const refusal = doorRefusal(body);
|
|
19
23
|
if (status === 401)
|
|
20
24
|
return { kind: 'revoked-authorization' };
|
|
21
|
-
if (refusal?.retryable === true)
|
|
25
|
+
if (refusal?.retryable === true || refusal?.code === 'update_required') {
|
|
22
26
|
return { kind: 'transport-uncertainty' };
|
|
27
|
+
}
|
|
23
28
|
if (status === 404 || refusal?.code === 'room_not_found')
|
|
24
29
|
return { kind: 'room-not-readable' };
|
|
25
30
|
if (status < 400)
|
|
@@ -38,11 +43,6 @@ export function classifyDoor(status, body, locator) {
|
|
|
38
43
|
return scopedRefusal(locator, failure.scope, failure.refusal);
|
|
39
44
|
return failure;
|
|
40
45
|
}
|
|
41
|
-
export function classifyRead(status, body, locator) {
|
|
42
|
-
if (doorRefusal(body)?.code === 'expired')
|
|
43
|
-
return { kind: 'beyond-horizon' };
|
|
44
|
-
return classifyDoor(status, body, locator);
|
|
45
|
-
}
|
|
46
46
|
export function discoveryFailure(status, body) {
|
|
47
47
|
const failure = doorFailure(status, body);
|
|
48
48
|
if (failure === null)
|
|
@@ -50,11 +50,7 @@ export function discoveryFailure(status, body) {
|
|
|
50
50
|
if (failure.kind === 'revoked-authorization')
|
|
51
51
|
return failure;
|
|
52
52
|
if (failure.kind === 'refused') {
|
|
53
|
-
return {
|
|
54
|
-
kind: 'contract-unavailable',
|
|
55
|
-
code: failure.refusal.code,
|
|
56
|
-
fields: failure.refusal.fields,
|
|
57
|
-
};
|
|
53
|
+
return { kind: 'contract-unavailable', ...failure.refusal };
|
|
58
54
|
}
|
|
59
55
|
return { kind: 'transport-uncertainty' };
|
|
60
56
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
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 HOUSE_NAMEABLE_ROOM_TYPES: string[];
|
|
4
|
+
export declare const HOUSE_ROOM_TYPES: string;
|
|
5
|
+
//# 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":"AAIA,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,yBAAyB,UAAiC,CAAC;AAyBxE,eAAO,MAAM,gBAAgB,QAyFjB,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { CHAT_MESSAGE_TYPE, CHAT_TYPE } from '@agentshouse/mdruntime';
|
|
2
|
+
import { APP_REFERENCE_PATTERN } from './app-reference.js';
|
|
3
|
+
import { HOUSE_MODEL_TYPES } from './house-model.js';
|
|
4
|
+
export const INBOX_CHANNEL_KINDS = [
|
|
5
|
+
'telegram-bot',
|
|
6
|
+
'telegram-business',
|
|
7
|
+
'whatsapp',
|
|
8
|
+
'messenger',
|
|
9
|
+
'instagram',
|
|
10
|
+
'viber',
|
|
11
|
+
'tiktok',
|
|
12
|
+
];
|
|
13
|
+
export const HOUSE_NAMEABLE_ROOM_TYPES = [CHAT_TYPE, CHAT_MESSAGE_TYPE];
|
|
14
|
+
const WAYFINDING_MAP_TYPE = 'wayfinding-map';
|
|
15
|
+
const WAYFINDING_TICKET_TYPE = 'wayfinding-ticket';
|
|
16
|
+
const WAYFINDING_MAP_SECTIONS = [
|
|
17
|
+
'Destination',
|
|
18
|
+
'Notes',
|
|
19
|
+
'Decisions so far',
|
|
20
|
+
'Not yet specified',
|
|
21
|
+
'Out of scope',
|
|
22
|
+
];
|
|
23
|
+
const IDENTITY = "{ type: string, pattern: '^\\S+$' }";
|
|
24
|
+
const AGENT = [' agent: { type: string, format: uuid }', ' name: { type: string }'];
|
|
25
|
+
const ASSIGNEE = [
|
|
26
|
+
' type: object',
|
|
27
|
+
' properties:',
|
|
28
|
+
' user: { type: string, format: uuid }',
|
|
29
|
+
...AGENT,
|
|
30
|
+
];
|
|
31
|
+
export const HOUSE_ROOM_TYPES = [
|
|
32
|
+
`${CHAT_TYPE}:`,
|
|
33
|
+
' properties:',
|
|
34
|
+
' inbox: { type: string, format: uuid }',
|
|
35
|
+
` channel: { enum: [${INBOX_CHANNEL_KINDS.join(', ')}] }`,
|
|
36
|
+
` chat: ${IDENTITY}`,
|
|
37
|
+
' customer:',
|
|
38
|
+
' type: object',
|
|
39
|
+
' properties:',
|
|
40
|
+
' name: { type: string }',
|
|
41
|
+
` username: ${IDENTITY}`,
|
|
42
|
+
` phone: ${IDENTITY}`,
|
|
43
|
+
' assignee:',
|
|
44
|
+
...ASSIGNEE,
|
|
45
|
+
' return_to:',
|
|
46
|
+
' type: object',
|
|
47
|
+
' properties:',
|
|
48
|
+
...AGENT,
|
|
49
|
+
' required: [chat, customer]',
|
|
50
|
+
`${CHAT_MESSAGE_TYPE}:`,
|
|
51
|
+
' properties:',
|
|
52
|
+
' direction: { enum: [in, out] }',
|
|
53
|
+
' sender:',
|
|
54
|
+
...ASSIGNEE,
|
|
55
|
+
` username: ${IDENTITY}`,
|
|
56
|
+
' sent_at: { type: string, format: date-time }',
|
|
57
|
+
` channel_message: ${IDENTITY}`,
|
|
58
|
+
' labelled: { const: true }',
|
|
59
|
+
' reactions:',
|
|
60
|
+
' type: array',
|
|
61
|
+
' items:',
|
|
62
|
+
' type: object',
|
|
63
|
+
' properties:',
|
|
64
|
+
' reaction: { type: string, minLength: 1 }',
|
|
65
|
+
' sender:',
|
|
66
|
+
' type: object',
|
|
67
|
+
' properties:',
|
|
68
|
+
` id: ${IDENTITY}`,
|
|
69
|
+
' name: { type: string }',
|
|
70
|
+
` username: ${IDENTITY}`,
|
|
71
|
+
' count: { type: integer, minimum: 1 }',
|
|
72
|
+
' required: [reaction]',
|
|
73
|
+
` post: ${IDENTITY}`,
|
|
74
|
+
' assignee:',
|
|
75
|
+
...ASSIGNEE,
|
|
76
|
+
' sent_outside: { const: true }',
|
|
77
|
+
' template:',
|
|
78
|
+
' type: object',
|
|
79
|
+
' properties:',
|
|
80
|
+
' name: { type: string, minLength: 1 }',
|
|
81
|
+
' language: { type: string, minLength: 1 }',
|
|
82
|
+
' required: [name, language]',
|
|
83
|
+
' values:',
|
|
84
|
+
' type: object',
|
|
85
|
+
' additionalProperties: { type: string }',
|
|
86
|
+
' withheld: { const: true }',
|
|
87
|
+
' required: [direction]',
|
|
88
|
+
' if: { properties: { direction: { const: in } } }',
|
|
89
|
+
' then: { required: [sent_at] }',
|
|
90
|
+
`${WAYFINDING_MAP_TYPE}:`,
|
|
91
|
+
' properties:',
|
|
92
|
+
' title: { type: string }',
|
|
93
|
+
' required: [title]',
|
|
94
|
+
' sections:',
|
|
95
|
+
...WAYFINDING_MAP_SECTIONS.map((name) => ` ${name}: { kind: text, required: true }`),
|
|
96
|
+
`${WAYFINDING_TICKET_TYPE}:`,
|
|
97
|
+
' properties:',
|
|
98
|
+
' title: { type: string }',
|
|
99
|
+
' kind: { enum: [research, prototype, grilling, task] }',
|
|
100
|
+
' status: { enum: [open, in-progress, done, out-of-scope] }',
|
|
101
|
+
` map: { type: string, reference: ${WAYFINDING_MAP_TYPE} }`,
|
|
102
|
+
` blocked_by: { type: array, items: { type: string, reference: ${WAYFINDING_TICKET_TYPE} } }`,
|
|
103
|
+
' assignee:',
|
|
104
|
+
...ASSIGNEE,
|
|
105
|
+
' conversation: { type: string, format: uuid }',
|
|
106
|
+
` app: { type: string, pattern: '${APP_REFERENCE_PATTERN.source}' }`,
|
|
107
|
+
' required: [title, kind, status, map, blocked_by]',
|
|
108
|
+
' sections:',
|
|
109
|
+
' Question: { kind: text }',
|
|
110
|
+
' Answer: { kind: text }',
|
|
111
|
+
' allOf:',
|
|
112
|
+
' - if: { properties: { status: { enum: [in-progress, done, out-of-scope] } }, required: [status] }',
|
|
113
|
+
' then: { required: [assignee] }',
|
|
114
|
+
' else: { properties: { assignee: false } }',
|
|
115
|
+
' - if: { properties: { assignee: { required: [agent] } }, required: [assignee] }',
|
|
116
|
+
' else: { properties: { conversation: false } }',
|
|
117
|
+
' - if: { properties: { status: { enum: [done, out-of-scope] } }, required: [status] }',
|
|
118
|
+
' then: { sections: { Answer: { kind: text, required: true } } }',
|
|
119
|
+
HOUSE_MODEL_TYPES,
|
|
120
|
+
].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('rooms/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
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,EAQR,MAAM,wBAAwB,CAAC;AAehC,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAuBxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAiK1F"}
|
package/dist/site.js
CHANGED
|
@@ -1,124 +1,141 @@
|
|
|
1
1
|
import { actionOutcome } from './actions.js';
|
|
2
|
+
import { chunkedHead, chunkPart, siteChunkList } from './chunks.js';
|
|
2
3
|
import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked, } from './discovery.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { spaceSchemas } from './space-schema.js';
|
|
5
|
+
import { discoveryFailure } from './refusal.js';
|
|
6
|
+
import { HOUSE_TYPED_PATHS } from './house-model.js';
|
|
7
|
+
import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
|
|
6
8
|
import { houseNotifications } from './stream.js';
|
|
7
|
-
import {
|
|
8
|
-
import { followsVersion,
|
|
9
|
+
import { houseSiteRoute, SITE_DOOR_SUBMIT, SITE_FILES, SITES_SUBMISSIONS_CREATE, } from './transport.js';
|
|
10
|
+
import { followsVersion, reachedVersion, roomVersion } from './version.js';
|
|
9
11
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
12
|
+
function unfound() {
|
|
13
|
+
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
14
|
+
}
|
|
10
15
|
function siteRoom(tracked) {
|
|
11
16
|
return {
|
|
12
17
|
name: tracked.handle,
|
|
13
18
|
locator: tracked.locator,
|
|
14
19
|
handle: tracked.handle,
|
|
15
20
|
roomVersion: roomVersion(tracked),
|
|
16
|
-
operations: {
|
|
17
|
-
replica: { selection: tracked.locator, admission: 'admitted' },
|
|
21
|
+
operations: { write: [], erase: [] },
|
|
22
|
+
replica: { selection: tracked.locator, admission: 'admitted', offline: 'open' },
|
|
18
23
|
providerOwnedPaths: [],
|
|
19
24
|
};
|
|
20
25
|
}
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
export function createSiteAdapter(transport, snapshot = false) {
|
|
27
|
+
const spaces = spaceSchemas();
|
|
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
|
+
}, spaces);
|
|
26
35
|
const tracked = new Map();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return classified;
|
|
34
|
-
return parseEnumeration(answer.body, 'site') ?? UNCERTAIN;
|
|
36
|
+
const chunked = new Map();
|
|
37
|
+
function fileRoute(request) {
|
|
38
|
+
const entry = tracked.get(request.locator);
|
|
39
|
+
if (entry === undefined)
|
|
40
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
41
|
+
return `${SITE_FILES}${entry.authority}/${encodeURIComponent(request.revision)}/${encodeURIComponent(request.path)}`;
|
|
35
42
|
}
|
|
36
|
-
async function
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
return
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return { scope };
|
|
46
|
-
const found = await enumeration(entry, scope);
|
|
47
|
-
if ('kind' in found)
|
|
48
|
-
return { failure: settled(found) };
|
|
49
|
-
const view = viewOf(found, entry);
|
|
50
|
-
if (view === undefined)
|
|
51
|
-
return { failure: { kind: 'room-not-readable', locator: entry.locator } };
|
|
52
|
-
return { scope: advancedScope(scope, view) };
|
|
43
|
+
async function listedRoom(entry) {
|
|
44
|
+
const past = chunked.get(entry.locator)?.position;
|
|
45
|
+
const listed = siteChunkList(await transport.read(`${houseSiteRoute('chunks')}/${entry.authority}${past === undefined ? '' : `?expired=${past}`}`), entry.locator);
|
|
46
|
+
if ('kind' in listed)
|
|
47
|
+
return listed;
|
|
48
|
+
const head = await chunkedHead(listed, entry, spaces);
|
|
49
|
+
if (head.kind === 'bootstrap')
|
|
50
|
+
chunked.set(entry.locator, listed);
|
|
51
|
+
return head;
|
|
53
52
|
}
|
|
54
|
-
async function
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
return
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
53
|
+
async function chunkPage(entry, id, arriving) {
|
|
54
|
+
const room = chunked.get(entry.locator);
|
|
55
|
+
const address = room?.chunks.get(id);
|
|
56
|
+
if (room === undefined || address === undefined)
|
|
57
|
+
return UNCERTAIN;
|
|
58
|
+
const read = await transport.download(address.url);
|
|
59
|
+
if (read.status !== 200)
|
|
60
|
+
return UNCERTAIN;
|
|
61
|
+
return chunkPart(read.body, room, id, arriving);
|
|
62
|
+
}
|
|
63
|
+
async function discovered() {
|
|
64
|
+
const answer = await transport.read(houseSiteRoute('discover'));
|
|
65
|
+
const failed = discoveryFailure(answer.status, answer.body);
|
|
66
|
+
if (failed !== null)
|
|
67
|
+
return failed;
|
|
68
|
+
const document = parseSiteDiscovery(answer.body);
|
|
69
|
+
if (document === null)
|
|
70
|
+
return UNCERTAIN;
|
|
71
|
+
const entries = siteTracked(document);
|
|
72
|
+
tracked.clear();
|
|
73
|
+
for (const entry of entries)
|
|
74
|
+
tracked.set(entry.locator, entry);
|
|
75
|
+
notifications.track(entries);
|
|
76
|
+
return mapDiscovery(document, entries.map(siteRoom), siteCapabilities());
|
|
75
77
|
}
|
|
76
78
|
return {
|
|
79
|
+
localSaves: true,
|
|
80
|
+
roomTypes: HOUSE_ROOM_TYPES,
|
|
81
|
+
nameableRoomTypes: HOUSE_NAMEABLE_ROOM_TYPES,
|
|
82
|
+
typedPaths: HOUSE_TYPED_PATHS,
|
|
77
83
|
async authorize() {
|
|
78
84
|
return {};
|
|
79
85
|
},
|
|
80
|
-
async discover() {
|
|
81
|
-
const answer = await transport.read(SITE_DOOR_DISCOVER);
|
|
82
|
-
const failed = discoveryFailure(answer.status, answer.body);
|
|
83
|
-
if (failed !== null)
|
|
84
|
-
return failed;
|
|
85
|
-
const document = parseSiteDiscovery(answer.body);
|
|
86
|
-
if (document === null)
|
|
87
|
-
return UNCERTAIN;
|
|
88
|
-
const entries = siteTracked(document);
|
|
89
|
-
tracked.clear();
|
|
90
|
-
for (const entry of entries)
|
|
91
|
-
tracked.set(entry.locator, entry);
|
|
92
|
-
notifications.track(entries);
|
|
93
|
-
return mapDiscovery(document, entries.map(siteRoom), siteCapabilities());
|
|
94
|
-
},
|
|
95
86
|
async bootstrap(_authorization, request) {
|
|
96
87
|
const entry = tracked.get(request.locator);
|
|
97
88
|
if (entry === undefined)
|
|
98
89
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if ('failure' in held)
|
|
103
|
-
return held.failure;
|
|
104
|
-
notifications.reach(entry.authority, held.scope);
|
|
105
|
-
const models = await scopeModels(held.scope, entry);
|
|
106
|
-
return { ...bootstrapOf(held.scope), ...(models === undefined ? {} : { models }) };
|
|
107
|
-
},
|
|
108
|
-
async refresh(_authorization, request) {
|
|
109
|
-
const entry = tracked.get(request.locator);
|
|
110
|
-
if (entry === undefined)
|
|
111
|
-
return { kind: 'room-not-readable', locator: request.locator };
|
|
112
|
-
if (request.pageToken !== undefined)
|
|
113
|
-
return UNCERTAIN;
|
|
114
|
-
return refreshed(entry, request.fromRoomVersion);
|
|
90
|
+
return request.pageToken === undefined
|
|
91
|
+
? listedRoom(entry)
|
|
92
|
+
: chunkPage(entry, request.pageToken, request.arriving);
|
|
115
93
|
},
|
|
94
|
+
...(snapshot
|
|
95
|
+
? {
|
|
96
|
+
discover: discovered,
|
|
97
|
+
async refresh(_authorization, request) {
|
|
98
|
+
const entry = tracked.get(request.locator);
|
|
99
|
+
if (entry === undefined)
|
|
100
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
101
|
+
if (request.pageToken !== undefined)
|
|
102
|
+
return UNCERTAIN;
|
|
103
|
+
return request.fromRoomVersion === roomVersion(entry)
|
|
104
|
+
? { kind: 'still-current' }
|
|
105
|
+
: { kind: 'beyond-horizon' };
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
: {}),
|
|
116
109
|
async mutate() {
|
|
117
|
-
return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {} };
|
|
110
|
+
return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {}, retryable: false };
|
|
111
|
+
},
|
|
112
|
+
async attach() {
|
|
113
|
+
return { kind: 'rejected', code: 'write-grant', fields: {}, retryable: false };
|
|
118
114
|
},
|
|
119
115
|
async history() {
|
|
120
116
|
return { kind: 'no-history' };
|
|
121
117
|
},
|
|
118
|
+
async binary(_authorization, request) {
|
|
119
|
+
const route = fileRoute(request);
|
|
120
|
+
if (typeof route !== 'string')
|
|
121
|
+
return route;
|
|
122
|
+
const read = await transport.download(route);
|
|
123
|
+
if (read.status === 404)
|
|
124
|
+
return unfound();
|
|
125
|
+
return read.status === 200 && read.body !== null
|
|
126
|
+
? { kind: 'binary', body: read.body, mediaType: read.mediaType }
|
|
127
|
+
: UNCERTAIN;
|
|
128
|
+
},
|
|
129
|
+
async link(_authorization, request) {
|
|
130
|
+
const route = fileRoute(request);
|
|
131
|
+
if (typeof route !== 'string')
|
|
132
|
+
return route;
|
|
133
|
+
return {
|
|
134
|
+
kind: 'link',
|
|
135
|
+
url: route,
|
|
136
|
+
name: request.path.slice(request.path.lastIndexOf('/') + 1),
|
|
137
|
+
};
|
|
138
|
+
},
|
|
122
139
|
reached(locator, version, target) {
|
|
123
140
|
return reachedVersion(version, target, tracked.get(locator)?.logEpoch);
|
|
124
141
|
},
|
|
@@ -126,26 +143,24 @@ export function createSiteAdapter(transport) {
|
|
|
126
143
|
return followsVersion(version, next);
|
|
127
144
|
},
|
|
128
145
|
async action(_authorization, request) {
|
|
129
|
-
if (request.name !==
|
|
130
|
-
return {
|
|
146
|
+
if (request.name !== SITES_SUBMISSIONS_CREATE) {
|
|
147
|
+
return {
|
|
148
|
+
kind: 'rejected',
|
|
149
|
+
code: 'action-unimplemented',
|
|
150
|
+
fields: { name: request.name },
|
|
151
|
+
retryable: false,
|
|
152
|
+
};
|
|
131
153
|
}
|
|
132
154
|
if (!transport.online())
|
|
133
155
|
return UNCERTAIN;
|
|
134
|
-
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input),
|
|
156
|
+
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), SITES_SUBMISSIONS_CREATE, request.input);
|
|
135
157
|
},
|
|
136
|
-
roomStream:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (entry === undefined || at === null)
|
|
142
|
-
return [];
|
|
143
|
-
notifications.reach(entry.authority, at);
|
|
144
|
-
return [presented(entry.authority, at)];
|
|
145
|
-
}));
|
|
158
|
+
roomStream: snapshot
|
|
159
|
+
? undefined
|
|
160
|
+
: {
|
|
161
|
+
hold: notifications.send,
|
|
162
|
+
observe: notifications.observe,
|
|
146
163
|
},
|
|
147
|
-
observe: notifications.observe,
|
|
148
|
-
},
|
|
149
164
|
serviceMode: notifications.serviceMode,
|
|
150
165
|
};
|
|
151
166
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type SpaceSchemas = {
|
|
2
|
+
held(space: string, revision: string): string | undefined;
|
|
3
|
+
keep(space: string, revision: string, text: string): void;
|
|
4
|
+
};
|
|
5
|
+
export declare function spaceSchemas(): SpaceSchemas;
|
|
6
|
+
export declare function spaceIdentity(space: string): string;
|
|
7
|
+
//# sourceMappingURL=space-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space-schema.d.ts","sourceRoot":"","sources":["../src/space-schema.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3D,CAAC;AAEF,wBAAgB,YAAY,IAAI,YAAY,CAY3C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const HELD_TEXTS = 16;
|
|
2
|
+
export function spaceSchemas() {
|
|
3
|
+
const texts = new Map();
|
|
4
|
+
const key = (space, revision) => `${space} ${revision}`;
|
|
5
|
+
return {
|
|
6
|
+
held: (space, revision) => texts.get(key(space, revision)),
|
|
7
|
+
keep(space, revision, text) {
|
|
8
|
+
const named = key(space, revision);
|
|
9
|
+
texts.delete(named);
|
|
10
|
+
texts.set(named, text);
|
|
11
|
+
if (texts.size > HELD_TEXTS)
|
|
12
|
+
texts.delete(texts.keys().next().value);
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function spaceIdentity(space) {
|
|
17
|
+
return `space:${space}`;
|
|
18
|
+
}
|
package/dist/stream.d.ts
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AuthorityChange, type Discovery, type ConversationStream, type HeldRoom, type RoomStreamEvent, type ServiceModeSignal } from '@agentshouse/mdruntime';
|
|
2
2
|
import type { TrackedAuthority } from './discovery.js';
|
|
3
|
-
import type {
|
|
4
|
-
import { type
|
|
5
|
-
export type
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
import type { SpaceSchemas } from './space-schema.js';
|
|
4
|
+
import { type HouseDoor, type HouseMode, type HouseStreamFrame } from './transport.js';
|
|
5
|
+
export type HouseOpeningFrame = Extract<HouseStreamFrame, {
|
|
6
|
+
type: 'opening';
|
|
7
|
+
}>;
|
|
8
|
+
export type HouseAuthorityChangedFrame = Extract<HouseStreamFrame, {
|
|
9
|
+
type: 'authority_changed';
|
|
10
|
+
}>;
|
|
11
|
+
export type HouseDiscovering = {
|
|
12
|
+
opened(frame: HouseOpeningFrame | null): Promise<Discovery | null>;
|
|
13
|
+
changed(frame: HouseAuthorityChangedFrame): AuthorityChange | null;
|
|
14
|
+
expired?(authorities: readonly string[]): void;
|
|
10
15
|
};
|
|
11
16
|
export type HouseNotifications = {
|
|
12
17
|
runtime: string;
|
|
13
18
|
observe(notify: (event: RoomStreamEvent) => void): () => void;
|
|
14
|
-
send(rooms: readonly
|
|
19
|
+
send(rooms: readonly HeldRoom[]): void;
|
|
15
20
|
track(authorities: readonly TrackedAuthority[]): void;
|
|
16
|
-
reach(authority: string, at: LogPosition): void;
|
|
17
|
-
advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): StreamedAdvancement | null;
|
|
18
21
|
conversations: ConversationStream;
|
|
19
22
|
serviceMode: ServiceModeSignal;
|
|
20
23
|
};
|
|
21
|
-
export declare function houseNotifications(transport: HouseDoor, mode: HouseMode): HouseNotifications;
|
|
24
|
+
export declare function houseNotifications(transport: HouseDoor, mode: HouseMode, discovering: HouseDiscovering, spaces: SpaceSchemas): HouseNotifications;
|
|
22
25
|
//# sourceMappingURL=stream.d.ts.map
|
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,eAAe,EAEpB,KAAK,SAAS,EACd,KAAK,kBAAkB,EAEvB,KAAK,QAAQ,EAGb,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EAEvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAWtD,OAAO,EAEL,KAAK,SAAS,EAEd,KAAK,SAAS,EAGd,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAaxB,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAE/E,MAAM,MAAM,0BAA0B,GAAG,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAAC;AAElG,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACnE,OAAO,CAAC,KAAK,EAAE,0BAA0B,GAAG,eAAe,GAAG,IAAI,CAAC;IACnE,OAAO,CAAC,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,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,GAAG,MAAM,IAAI,CAAC;IAC9D,IAAI,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,IAAI,CAAC;IACvC,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AA6FF,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,SAAS,EACf,WAAW,EAAE,gBAAgB,EAC7B,MAAM,EAAE,YAAY,GACnB,kBAAkB,CA8XpB"}
|