@agentshouse/mdruntime-adapter 0.1.0-alpha.9 → 0.1.0-c9f1e531ad7c8

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.
Files changed (60) hide show
  1. package/AGENTS.md +157 -26
  2. package/README.md +32 -0
  3. package/dist/actions.d.ts +4 -12
  4. package/dist/actions.d.ts.map +1 -1
  5. package/dist/actions.js +239 -332
  6. package/dist/adapter.d.ts.map +1 -1
  7. package/dist/adapter.js +258 -193
  8. package/dist/digest.js +1 -5
  9. package/dist/discovery.d.ts +20 -18
  10. package/dist/discovery.d.ts.map +1 -1
  11. package/dist/discovery.js +182 -210
  12. package/dist/gather.d.ts +3 -0
  13. package/dist/gather.d.ts.map +1 -0
  14. package/dist/gather.js +40 -0
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +0 -2
  18. package/dist/links.d.ts +12 -0
  19. package/dist/links.d.ts.map +1 -0
  20. package/dist/links.js +66 -0
  21. package/dist/map.d.ts +2 -2
  22. package/dist/map.d.ts.map +1 -1
  23. package/dist/map.js +6 -7
  24. package/dist/model.d.ts +2 -2
  25. package/dist/model.d.ts.map +1 -1
  26. package/dist/model.js +21 -39
  27. package/dist/read.d.ts +29 -23
  28. package/dist/read.d.ts.map +1 -1
  29. package/dist/read.js +222 -195
  30. package/dist/refusal.d.ts.map +1 -1
  31. package/dist/refusal.js +30 -51
  32. package/dist/site.d.ts.map +1 -1
  33. package/dist/site.js +110 -124
  34. package/dist/stream.d.ts +11 -5
  35. package/dist/stream.d.ts.map +1 -1
  36. package/dist/stream.js +211 -213
  37. package/dist/transport.d.ts +46 -28
  38. package/dist/transport.d.ts.map +1 -1
  39. package/dist/transport.js +3 -3
  40. package/dist/version.d.ts +1 -0
  41. package/dist/version.d.ts.map +1 -1
  42. package/dist/version.js +23 -18
  43. package/dist/write.d.ts +3 -3
  44. package/dist/write.d.ts.map +1 -1
  45. package/dist/write.js +120 -203
  46. package/package.json +4 -12
  47. package/dist/actions.js.map +0 -1
  48. package/dist/adapter.js.map +0 -1
  49. package/dist/digest.js.map +0 -1
  50. package/dist/discovery.js.map +0 -1
  51. package/dist/index.js.map +0 -1
  52. package/dist/map.js.map +0 -1
  53. package/dist/model.js.map +0 -1
  54. package/dist/read.js.map +0 -1
  55. package/dist/refusal.js.map +0 -1
  56. package/dist/site.js.map +0 -1
  57. package/dist/stream.js.map +0 -1
  58. package/dist/transport.js.map +0 -1
  59. package/dist/version.js.map +0 -1
  60. package/dist/write.js.map +0 -1
package/dist/site.js CHANGED
@@ -1,40 +1,28 @@
1
- import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked } from './discovery.js';
2
- import { MODEL_ABSENT, failedModel, heldModel, modelKey, modelShelf } from './model.js';
3
- import { advancedScope, authorityRoot, bootstrapOf, definitionsOf, parseEnumeration, parseSiteBootstrap, refreshFrom, selectionRoots } from './read.js';
4
- import { classifyDoor, discoveryFailure } from './refusal.js';
1
+ import { actionOutcome } from './actions.js';
2
+ import { UNTYPED_FOLDERS, mapDiscovery, parseSiteDiscovery, siteCapabilities, siteSlots, siteTracked, } from './discovery.js';
3
+ import { MODEL_ABSENT, failedModel, heldModel, modelKey, modelShelf, } from './model.js';
4
+ import { advancedScope, bootstrapOf, parseEnumeration, parseSiteBootstrap, refreshFrom, schemaOf, schemaPath, viewOf, } from './read.js';
5
+ import { classifyDoor, discoveryFailure, doorRefusal } from './refusal.js';
5
6
  import { houseNotifications } from './stream.js';
6
- import { PRIVATE_AUTHORITY, SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE } from './transport.js';
7
- import { logPosition, presented, roomVersion } from './version.js';
8
- const UNCERTAIN = {
9
- kind: 'transport-uncertainty'
10
- };
7
+ import { PRIVATE_LOCATOR, SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, } from './transport.js';
8
+ import { logPosition, presented, reachedVersion, roomVersion, } from './version.js';
9
+ const UNCERTAIN = { kind: 'transport-uncertainty' };
11
10
  function siteRoom(tracked, attachedModel) {
12
- const read = selectionRoots(tracked);
13
11
  return {
14
- name: tracked.slot,
12
+ name: tracked.handle,
15
13
  locator: tracked.locator,
16
- collectionRoot: tracked.collectionRoot,
17
14
  roomVersion: roomVersion(tracked),
18
- operations: {
19
- read: [
20
- ...read
21
- ],
22
- sync: [
23
- ...read
24
- ],
25
- write: [],
26
- delete: []
27
- },
28
- replica: {
29
- selection: tracked.locator,
30
- admission: 'admitted'
31
- },
15
+ operations: { read: [''], sync: [''], write: [], delete: [] },
16
+ replica: { selection: tracked.locator, admission: 'admitted' },
32
17
  attachedModel,
33
- providerOwnedPaths: []
18
+ untypedFolders: [...UNTYPED_FOLDERS],
19
+ providerOwnedPaths: [],
34
20
  };
35
21
  }
36
22
  function settled(refused) {
37
- return refused.kind === 'beyond-horizon' ? UNCERTAIN : refused;
23
+ return refused.kind === 'beyond-horizon' || refused.kind === 'retryable-refusal'
24
+ ? UNCERTAIN
25
+ : refused;
38
26
  }
39
27
  export function createSiteAdapter(transport) {
40
28
  const notifications = houseNotifications(transport, 'site');
@@ -44,92 +32,85 @@ export function createSiteAdapter(transport) {
44
32
  let caught = new Map();
45
33
  async function enumeration(entry, from) {
46
34
  const answer = await transport.door(SITE_DOOR_ENUMERATE, {
47
- positions: [
48
- presented(entry.authority, from)
49
- ]
35
+ positions: [presented(entry.authority, from)],
50
36
  });
37
+ const behind = doorRefusal(answer.body);
38
+ if (behind?.code === 'replica_behind')
39
+ return { kind: 'retryable-refusal', ...behind };
51
40
  const classified = classifyDoor(answer.status, answer.body, entry.locator);
52
- if (classified !== null) return classified;
41
+ if (classified !== null)
42
+ return classified;
53
43
  return parseEnumeration(answer.body, 'site') ?? UNCERTAIN;
54
44
  }
55
45
  async function caughtUp(entry) {
56
46
  const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}`);
57
47
  const classified = classifyDoor(answer.status, answer.body, entry.locator);
58
- if (classified !== null) return {
59
- failure: settled(classified)
60
- };
48
+ if (classified !== null)
49
+ return { failure: settled(classified) };
61
50
  const scope = parseSiteBootstrap(answer.body);
62
- if (scope === null) return {
63
- failure: UNCERTAIN
64
- };
65
- if (roomVersion(scope) === roomVersion(entry)) return {
66
- scope
67
- };
51
+ if (scope === null)
52
+ return { failure: UNCERTAIN };
53
+ if (roomVersion(scope) === roomVersion(entry))
54
+ return { scope };
68
55
  const found = await enumeration(entry, scope);
69
- if ('kind' in found) return {
70
- failure: settled(found)
71
- };
72
- const view = found.authorities.find((held)=>held.authority === entry.authority);
73
- if (view === undefined) return {
74
- failure: {
75
- kind: 'room-not-readable',
76
- locator: entry.locator
77
- }
78
- };
79
- return {
80
- scope: advancedScope(scope, view)
81
- };
56
+ if ('kind' in found)
57
+ return { failure: settled(found) };
58
+ const view = viewOf(found, entry);
59
+ if (view === undefined)
60
+ return { failure: { kind: 'room-not-readable', locator: entry.locator } };
61
+ return { scope: advancedScope(scope, view) };
82
62
  }
83
63
  async function refreshed(entry, fromRoomVersion) {
84
64
  const from = logPosition(fromRoomVersion);
85
- if (from === null) return {
86
- kind: 'beyond-horizon'
87
- };
65
+ if (from === null)
66
+ return { kind: 'beyond-horizon' };
88
67
  const streamed = notifications.advance(entry, from);
89
- if (streamed !== null) return streamed;
68
+ if (streamed !== null)
69
+ return streamed.page;
90
70
  const found = await enumeration(entry, from);
91
- if ('kind' in found) return found;
92
- return refreshFrom(found, entry, fromRoomVersion);
71
+ if ('kind' in found)
72
+ return found;
73
+ const view = viewOf(found, entry);
74
+ if (view === undefined)
75
+ return { kind: 'room-not-readable', locator: entry.locator };
76
+ notifications.hold(entry.authority, view);
77
+ return refreshFrom(view, entry, fromRoomVersion);
93
78
  }
94
79
  async function acquire(entry, held) {
95
- if ('failure' in held) return {
96
- snapshot: failedModel(held.failure),
97
- identity: null
98
- };
99
- const model = await heldModel(definitionsOf(held.scope, entry.modelRoot), `${authorityRoot(entry.handle)}/${entry.modelRoot}`, MODEL_ABSENT);
100
- acquired.set(entry.authority, {
101
- roomVersion: roomVersion(held.scope),
102
- model
103
- });
80
+ if ('failure' in held)
81
+ return { snapshot: failedModel(held.failure), identity: null };
82
+ const model = await heldModel(schemaOf(held.scope, entry.schema), schemaPath(entry.handle, entry.schema), MODEL_ABSENT);
83
+ acquired.set(entry.authority, { roomVersion: roomVersion(held.scope), model });
104
84
  return model;
105
85
  }
106
86
  return {
107
- async authorize () {
87
+ async authorize() {
108
88
  return {};
109
89
  },
110
- async model (_authorization, request) {
90
+ async model(_authorization, request) {
111
91
  return models.answer(request);
112
92
  },
113
- async discover () {
114
- const answer = await transport.door(SITE_DOOR_DISCOVER, {});
115
- const classified = classifyDoor(answer.status, answer.body, PRIVATE_AUTHORITY);
116
- if (classified !== null) return discoveryFailure(classified);
93
+ async discover() {
94
+ const answer = await transport.read(SITE_DOOR_DISCOVER);
95
+ const classified = classifyDoor(answer.status, answer.body, PRIVATE_LOCATOR);
96
+ if (classified !== null)
97
+ return discoveryFailure(classified);
117
98
  const document = parseSiteDiscovery(answer.body);
118
- if (document === null) return UNCERTAIN;
99
+ if (document === null)
100
+ return UNCERTAIN;
119
101
  const entries = siteTracked(document);
120
102
  tracked.clear();
121
- for (const entry of entries)tracked.set(entry.locator, entry);
103
+ for (const entry of entries)
104
+ tracked.set(entry.locator, entry);
122
105
  notifications.track(entries);
123
- const published = new Set(entries.map((entry)=>entry.authority));
124
- for (const authority of [
125
- ...acquired.keys()
126
- ]){
127
- if (!published.has(authority)) acquired.delete(authority);
106
+ const published = new Set(entries.map((entry) => entry.authority));
107
+ for (const authority of [...acquired.keys()]) {
108
+ if (!published.has(authority))
109
+ acquired.delete(authority);
128
110
  }
129
111
  const fresh = new Map();
130
112
  const current = new Map();
131
- for (const entry of entries){
132
- if (current.has(entry.authority)) continue;
113
+ for (const entry of entries) {
133
114
  const kept = acquired.get(entry.authority);
134
115
  if (kept !== undefined && kept.roomVersion === roomVersion(entry)) {
135
116
  current.set(entry.authority, kept.model);
@@ -140,59 +121,64 @@ export function createSiteAdapter(transport) {
140
121
  current.set(entry.authority, await acquire(entry, held));
141
122
  }
142
123
  caught = fresh;
143
- const rooms = entries.map((entry)=>{
124
+ const rooms = entries.map((entry) => {
144
125
  const shelved = models.retain(modelKey(entry.locator, 'collection'), current.get(entry.authority));
145
126
  return siteRoom(entry, shelved?.identity ?? null);
146
127
  });
147
- models.keep(entries.map((entry)=>entry.locator));
148
- return mapDiscovery(document, rooms, siteCapabilities());
128
+ models.keep(entries.map((entry) => entry.locator));
129
+ return { ...mapDiscovery(document, rooms, siteCapabilities()), slots: siteSlots(document) };
149
130
  },
150
- async bootstrap (_authorization, request) {
131
+ async bootstrap(_authorization, request) {
151
132
  const entry = tracked.get(request.locator);
152
- if (entry === undefined) return {
153
- kind: 'room-not-readable',
154
- locator: request.locator
155
- };
156
- if (request.pageToken !== undefined) return UNCERTAIN;
157
- const held = caught.get(entry.authority) ?? await caughtUp(entry);
158
- if ('failure' in held) return held.failure;
133
+ if (entry === undefined)
134
+ return { kind: 'room-not-readable', locator: request.locator };
135
+ if (request.pageToken !== undefined)
136
+ return UNCERTAIN;
137
+ const held = caught.get(entry.authority) ?? (await caughtUp(entry));
138
+ if ('failure' in held)
139
+ return held.failure;
140
+ notifications.hold(entry.authority, held.scope);
159
141
  return bootstrapOf(held.scope, entry);
160
142
  },
161
- async refresh (_authorization, request) {
143
+ async refresh(_authorization, request) {
162
144
  const entry = tracked.get(request.locator);
163
- if (entry === undefined) return {
164
- kind: 'room-not-readable',
165
- locator: request.locator
166
- };
167
- if (request.pageToken !== undefined) return UNCERTAIN;
145
+ if (entry === undefined)
146
+ return { kind: 'room-not-readable', locator: request.locator };
147
+ if (request.pageToken !== undefined)
148
+ return UNCERTAIN;
168
149
  const result = await refreshed(entry, request.fromRoomVersion);
169
- if (result.kind === 'beyond-horizon') caught.delete(entry.authority);
150
+ if (result.kind === 'beyond-horizon')
151
+ caught.delete(entry.authority);
152
+ const answered = result.kind === 'net-advancement'
153
+ ? result.roomVersion
154
+ : result.kind === 'still-current'
155
+ ? request.fromRoomVersion
156
+ : null;
157
+ if (request.minPosition !== undefined &&
158
+ answered !== null &&
159
+ !reachedVersion(answered, request.minPosition, entry.logEpoch)) {
160
+ return { kind: 'retryable-refusal', code: 'replica_behind', fields: {} };
161
+ }
170
162
  return result;
171
163
  },
172
- async mutate () {
173
- return {
174
- kind: 'rejected',
175
- affected: {},
176
- code: 'write-grant',
177
- fields: {}
178
- };
164
+ async mutate() {
165
+ return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {} };
179
166
  },
180
- async history () {
181
- return {
182
- kind: 'no-history'
183
- };
167
+ async history() {
168
+ return { kind: 'no-history' };
184
169
  },
185
- async action (_authorization, request) {
186
- return {
187
- kind: 'rejected',
188
- code: 'action-unimplemented',
189
- fields: {
190
- name: request.name
191
- }
192
- };
170
+ reached(locator, version, target) {
171
+ return reachedVersion(version, target, tracked.get(locator)?.logEpoch);
172
+ },
173
+ async action(_authorization, request) {
174
+ if (request.name !== 'submit') {
175
+ return { kind: 'rejected', code: 'action-unimplemented', fields: { name: request.name } };
176
+ }
177
+ if (!transport.online())
178
+ return UNCERTAIN;
179
+ return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), 'submit');
193
180
  },
194
- roomVersions: notifications
181
+ roomVersions: notifications,
182
+ serviceMode: notifications.serviceMode,
195
183
  };
196
184
  }
197
-
198
- //# sourceMappingURL=site.js.map
package/dist/stream.d.ts CHANGED
@@ -1,12 +1,18 @@
1
- import type { RefreshPage, SelectedRooms, ViewedConversations } from '@agentshouse/mdruntime';
1
+ import type { ConversationStream, RefreshPage, SelectedRooms, ServiceModeSignal } from '@agentshouse/mdruntime';
2
2
  import type { TrackedAuthority } from './discovery.js';
3
- import { type HouseDoor } from './transport.js';
4
- import type { HouseMode } from './transport.js';
3
+ import type { HouseDoor, HouseMode, HouseStreamEntry } from './transport.js';
5
4
  import { type LogPosition } from './version.js';
5
+ export type HeldRevision = (path: string, revision: string) => boolean;
6
+ export type StreamedAdvancement = {
7
+ page: RefreshPage;
8
+ entries: readonly HouseStreamEntry[];
9
+ };
6
10
  export type HouseNotifications = SelectedRooms & {
7
11
  track(authorities: readonly TrackedAuthority[]): void;
8
- advance(tracked: TrackedAuthority, from: LogPosition): RefreshPage | null;
9
- conversations: ViewedConversations;
12
+ hold(authority: string, at: LogPosition): void;
13
+ advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): StreamedAdvancement | null;
14
+ conversations: ConversationStream;
15
+ serviceMode: ServiceModeSignal;
10
16
  };
11
17
  export declare function houseNotifications(transport: HouseDoor, mode: HouseMode): HouseNotifications;
12
18
  //# sourceMappingURL=stream.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,WAAW,EAEX,aAAa,EACb,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAqB,KAAK,SAAS,EAA6B,MAAM,gBAAgB,CAAC;AAC9F,OAAO,KAAK,EAAE,SAAS,EAAsC,MAAM,gBAAgB,CAAC;AACpF,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAc7D,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG;IAC/C,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAAC;IAC1E,aAAa,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAaF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CA+O5F"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EAClB,WAAW,EAEX,aAAa,EAEb,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,gBAAgB,EAAoB,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAgB7D,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,SAAS,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG;IAC/C,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAC/C,OAAO,CACL,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,EACjB,KAAK,CAAC,EAAE,YAAY,GACnB,mBAAmB,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAOF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAuR5F"}