@agentshouse/mdruntime-adapter 0.1.0-cec9e6243b0a4 → 0.1.0-ceda07a375a48
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 +122 -22
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +24 -137
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +204 -201
- 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 +36 -32
- 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 +2935 -0
- package/dist/house-model.d.ts.map +1 -0
- package/dist/house-model.js +1613 -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 +53 -27
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +262 -158
- 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 +47 -112
- package/dist/stream.d.ts +3 -3
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +65 -39
- package/dist/transport.d.ts +31 -8
- 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 +100 -55
- package/package.json +8 -4
- package/AGENTS.md +0 -299
- 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
package/dist/discovery.d.ts
CHANGED
|
@@ -16,25 +16,22 @@ export type HouseBounds = {
|
|
|
16
16
|
max_held_files: number;
|
|
17
17
|
change_retention_seconds: number;
|
|
18
18
|
operation_retention_seconds: number;
|
|
19
|
+
max_move_documents?: number;
|
|
19
20
|
};
|
|
20
21
|
export type HouseOperations = {
|
|
21
|
-
read: readonly string[];
|
|
22
|
-
sync: readonly string[];
|
|
23
22
|
write: readonly string[];
|
|
24
23
|
delete: readonly string[];
|
|
25
24
|
};
|
|
26
|
-
export type
|
|
27
|
-
root: string;
|
|
28
|
-
paths: readonly string[];
|
|
29
|
-
};
|
|
25
|
+
export type HouseAccessLevel = 'search' | 'open' | 'keep';
|
|
30
26
|
export type HouseAuthority = LogPosition & {
|
|
31
27
|
roomRef: string;
|
|
32
28
|
roomHandle: string;
|
|
33
29
|
name: string;
|
|
34
30
|
schema: string;
|
|
35
|
-
|
|
31
|
+
typedSelection: readonly string[] | null;
|
|
36
32
|
managedReplication: 'admitted' | 'unavailable';
|
|
37
33
|
protectedPaths: readonly string[];
|
|
34
|
+
level: HouseAccessLevel;
|
|
38
35
|
operations: HouseOperations;
|
|
39
36
|
};
|
|
40
37
|
export type HouseDiscoveryDocument = {
|
|
@@ -48,8 +45,7 @@ export type TrackedAuthority = LogPosition & {
|
|
|
48
45
|
authority: string;
|
|
49
46
|
handle: string;
|
|
50
47
|
schema: string;
|
|
51
|
-
|
|
52
|
-
schemas: readonly string[];
|
|
48
|
+
typedSelection: readonly string[] | null;
|
|
53
49
|
};
|
|
54
50
|
export type HouseSiteAuthority = LogPosition & {
|
|
55
51
|
roomRef: string;
|
|
@@ -66,7 +62,7 @@ export declare function siteTracked(document: HouseSiteDiscovery): TrackedAuthor
|
|
|
66
62
|
export declare function trackedFrom(document: HouseDiscoveryDocument): TrackedAuthority[];
|
|
67
63
|
export declare function providerLimits(bounds: HouseBounds): readonly ProviderLimit[];
|
|
68
64
|
export declare function declaredRetention(bounds: HouseBounds): Retention;
|
|
69
|
-
export declare function capabilities(actions: HouseDiscoveryDocument['actions'], rooms: readonly Pick<TrackedAuthority, 'authority' | '
|
|
65
|
+
export declare function capabilities(actions: HouseDiscoveryDocument['actions'], rooms: readonly Pick<TrackedAuthority, 'authority' | 'handle'>[]): readonly Capability[];
|
|
70
66
|
export declare function siteCapabilities(): readonly Capability[];
|
|
71
67
|
export declare function discoveredRoom(authority: HouseAuthority): DiscoveredRoom;
|
|
72
68
|
export declare function mapDiscovery(document: Pick<HouseDiscoveryDocument, 'bounds'>, rooms: readonly DiscoveredRoom[], declared: readonly Capability[]): Discovery;
|
package/dist/discovery.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,SAAS,EACT,MAAM,EACN,aAAa,EACb,SAAS,EACV,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3E,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
package/dist/discovery.js
CHANGED
|
@@ -2,6 +2,7 @@ import { declaredActions, houseConversationAgents, SITE_SUBMIT } from './actions
|
|
|
2
2
|
import { readPosition, roomVersion } from './version.js';
|
|
3
3
|
export const PROVIDER_ACTIONS = 'provider-actions';
|
|
4
4
|
export const DISCOVER_PREFIXES = ['/'];
|
|
5
|
+
const PRIVATE_HANDLE = 'private';
|
|
5
6
|
const BOUND_KEYS = [
|
|
6
7
|
'max_authored_file_bytes',
|
|
7
8
|
'max_batch_operations',
|
|
@@ -17,7 +18,8 @@ const BOUND_KEYS = [
|
|
|
17
18
|
'change_retention_seconds',
|
|
18
19
|
'operation_retention_seconds',
|
|
19
20
|
];
|
|
20
|
-
const OPERATION_KEYS = ['
|
|
21
|
+
const OPERATION_KEYS = ['write', 'delete'];
|
|
22
|
+
const ACCESS_LEVELS = ['search', 'open', 'keep'];
|
|
21
23
|
function stringList(value) {
|
|
22
24
|
if (!Array.isArray(value))
|
|
23
25
|
return null;
|
|
@@ -34,18 +36,18 @@ function parseBounds(value) {
|
|
|
34
36
|
return null;
|
|
35
37
|
bounds[key] = amount;
|
|
36
38
|
}
|
|
39
|
+
const moves = held.max_move_documents;
|
|
40
|
+
if (moves !== undefined) {
|
|
41
|
+
if (typeof moves !== 'number' || !Number.isFinite(moves))
|
|
42
|
+
return null;
|
|
43
|
+
bounds.max_move_documents = moves;
|
|
44
|
+
}
|
|
37
45
|
return bounds;
|
|
38
46
|
}
|
|
39
|
-
function
|
|
47
|
+
function parseTypedSelection(value) {
|
|
40
48
|
if (value === undefined)
|
|
41
49
|
return null;
|
|
42
|
-
|
|
43
|
-
return undefined;
|
|
44
|
-
const held = value;
|
|
45
|
-
const paths = stringList(held.paths);
|
|
46
|
-
if (typeof held.root !== 'string' || held.root.length === 0 || paths === null)
|
|
47
|
-
return undefined;
|
|
48
|
-
return { root: held.root, paths };
|
|
50
|
+
return stringList(value) ?? undefined;
|
|
49
51
|
}
|
|
50
52
|
function parseMember(value) {
|
|
51
53
|
if (typeof value !== 'object' || value === null)
|
|
@@ -82,10 +84,15 @@ function parseAuthority(value) {
|
|
|
82
84
|
return null;
|
|
83
85
|
}
|
|
84
86
|
const at = readPosition(held);
|
|
85
|
-
const
|
|
87
|
+
const typedSelection = parseTypedSelection(held.typed_selection);
|
|
86
88
|
const protectedPaths = stringList(held.protected_paths);
|
|
87
89
|
const operations = parseOperations(held.operations);
|
|
88
|
-
|
|
90
|
+
const level = ACCESS_LEVELS.find((one) => one === held.level);
|
|
91
|
+
if (at === null ||
|
|
92
|
+
typedSelection === undefined ||
|
|
93
|
+
protectedPaths === null ||
|
|
94
|
+
level === undefined ||
|
|
95
|
+
operations === null)
|
|
89
96
|
return null;
|
|
90
97
|
if (typeof held.room_ref !== 'string' || held.room_ref.length === 0)
|
|
91
98
|
return null;
|
|
@@ -96,9 +103,10 @@ function parseAuthority(value) {
|
|
|
96
103
|
roomHandle: held.room_handle,
|
|
97
104
|
name: held.name,
|
|
98
105
|
schema: held.model_root,
|
|
99
|
-
|
|
106
|
+
typedSelection,
|
|
100
107
|
managedReplication: held.managed_replication,
|
|
101
108
|
protectedPaths,
|
|
109
|
+
level,
|
|
102
110
|
operations,
|
|
103
111
|
...at,
|
|
104
112
|
};
|
|
@@ -175,25 +183,18 @@ export function siteTracked(document) {
|
|
|
175
183
|
authority: authority.roomRef,
|
|
176
184
|
handle: authority.roomHandle,
|
|
177
185
|
schema: authority.schema,
|
|
178
|
-
|
|
179
|
-
schemas: [authority.schema],
|
|
186
|
+
typedSelection: null,
|
|
180
187
|
position: authority.position,
|
|
181
188
|
logEpoch: authority.logEpoch,
|
|
182
189
|
}));
|
|
183
190
|
}
|
|
184
|
-
function schemasOf(authority) {
|
|
185
|
-
return authority.houseModel === null
|
|
186
|
-
? [authority.schema]
|
|
187
|
-
: [authority.schema, authority.houseModel.root];
|
|
188
|
-
}
|
|
189
191
|
export function trackedFrom(document) {
|
|
190
192
|
return document.authorities.map((authority) => ({
|
|
191
193
|
locator: authority.roomRef,
|
|
192
194
|
authority: authority.roomRef,
|
|
193
195
|
handle: authority.roomHandle,
|
|
194
196
|
schema: authority.schema,
|
|
195
|
-
|
|
196
|
-
schemas: schemasOf(authority),
|
|
197
|
+
typedSelection: authority.typedSelection,
|
|
197
198
|
position: authority.position,
|
|
198
199
|
logEpoch: authority.logEpoch,
|
|
199
200
|
}));
|
|
@@ -205,8 +206,11 @@ export function providerLimits(bounds) {
|
|
|
205
206
|
{ name: 'change-documents', value: bounds.max_batch_documents },
|
|
206
207
|
{ name: 'path-length', value: bounds.max_path_length },
|
|
207
208
|
{ name: 'path-depth', value: bounds.max_path_depth },
|
|
209
|
+
...(bounds.max_move_documents === undefined
|
|
210
|
+
? []
|
|
211
|
+
: [{ name: 'move-documents', value: bounds.max_move_documents }]),
|
|
208
212
|
{ name: 'write-rate' },
|
|
209
|
-
{ name: '
|
|
213
|
+
{ name: 'storage-limit' },
|
|
210
214
|
];
|
|
211
215
|
}
|
|
212
216
|
export function declaredRetention(bounds) {
|
|
@@ -217,14 +221,12 @@ export function declaredRetention(bounds) {
|
|
|
217
221
|
};
|
|
218
222
|
}
|
|
219
223
|
export function capabilities(actions, rooms) {
|
|
220
|
-
const
|
|
224
|
+
const own = rooms.find((room) => room.handle === PRIVATE_HANDLE);
|
|
221
225
|
return [
|
|
222
226
|
{
|
|
223
227
|
name: PROVIDER_ACTIONS,
|
|
224
228
|
actions: declaredActions(actions),
|
|
225
|
-
...(
|
|
226
|
-
? {}
|
|
227
|
-
: { conversationAgents: houseConversationAgents(house.authority) }),
|
|
229
|
+
...(own === undefined ? {} : { conversationAgents: houseConversationAgents(own.authority) }),
|
|
228
230
|
},
|
|
229
231
|
];
|
|
230
232
|
}
|
|
@@ -244,16 +246,18 @@ export function discoveredRoom(authority) {
|
|
|
244
246
|
handle: authority.roomHandle,
|
|
245
247
|
roomVersion: roomVersion(authority),
|
|
246
248
|
operations: {
|
|
247
|
-
read: [...authority.operations.read],
|
|
248
|
-
sync: [...authority.operations.sync],
|
|
249
249
|
write: [...authority.operations.write],
|
|
250
250
|
delete: [...authority.operations.delete],
|
|
251
251
|
},
|
|
252
|
-
replica: {
|
|
253
|
-
|
|
252
|
+
replica: {
|
|
253
|
+
selection: locator,
|
|
254
|
+
admission: authority.managedReplication,
|
|
255
|
+
offline: authority.level === 'open' ? 'locked' : 'open',
|
|
256
|
+
},
|
|
257
|
+
...(authority.typedSelection === null
|
|
254
258
|
? {}
|
|
255
|
-
: { typedSelection: { roots: [...authority.
|
|
256
|
-
providerOwnedPaths: [...authority.protectedPaths,
|
|
259
|
+
: { typedSelection: { roots: [...authority.typedSelection] } }),
|
|
260
|
+
providerOwnedPaths: [...authority.protectedPaths, authority.schema],
|
|
257
261
|
};
|
|
258
262
|
}
|
|
259
263
|
export function mapDiscovery(document, rooms, declared) {
|
package/dist/gather.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export declare function gatheredEach<A, R>(send: (asks: readonly A[], answer: (ask: number, result: R) => void) => Promise<void>): (ask: A) => Promise<R>;
|
|
2
1
|
export declare function gathered<A, R>(send: (asks: readonly A[]) => Promise<readonly R[]>): (ask: A) => Promise<R>;
|
|
3
|
-
export declare function selections<T>(items: readonly T[],
|
|
2
|
+
export declare function selections<T>(items: readonly T[], limit: number): readonly (readonly T[])[];
|
|
4
3
|
//# sourceMappingURL=gather.d.ts.map
|
package/dist/gather.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gather.d.ts","sourceRoot":"","sources":["../src/gather.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gather.d.ts","sourceRoot":"","sources":["../src/gather.ts"],"names":[],"mappings":"AAkCA,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAC3B,IAAI,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,GAClD,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAMxB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAO3F"}
|
package/dist/gather.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
function gatheredEach(send) {
|
|
2
2
|
let held = [];
|
|
3
3
|
function flush() {
|
|
4
4
|
const taken = held;
|
|
@@ -25,21 +25,11 @@ export function gathered(send) {
|
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
-
export function selections(items,
|
|
28
|
+
export function selections(items, limit) {
|
|
29
|
+
const size = Math.max(1, limit);
|
|
29
30
|
const parts = [];
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
for (const item of items) {
|
|
33
|
-
const weighed = weight(item);
|
|
34
|
-
if (part.length > 0 && carried + weighed > limit) {
|
|
35
|
-
parts.push(part);
|
|
36
|
-
part = [];
|
|
37
|
-
carried = 0;
|
|
38
|
-
}
|
|
39
|
-
part.push(item);
|
|
40
|
-
carried += weighed;
|
|
31
|
+
for (let start = 0; start < items.length; start += size) {
|
|
32
|
+
parts.push(items.slice(start, start + size));
|
|
41
33
|
}
|
|
42
|
-
if (part.length > 0)
|
|
43
|
-
parts.push(part);
|
|
44
34
|
return parts;
|
|
45
35
|
}
|