@agentshouse/mdruntime-adapter 0.1.0-ca218e62303fd → 0.1.0-ca231c2cbedb4

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/README.md +2 -2
  2. package/dist/actions.d.ts +4 -22
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +23 -134
  5. package/dist/adapter.d.ts +1 -0
  6. package/dist/adapter.d.ts.map +1 -1
  7. package/dist/adapter.js +304 -174
  8. package/dist/app-reference.d.ts +2 -0
  9. package/dist/app-reference.d.ts.map +1 -0
  10. package/dist/app-reference.js +2 -0
  11. package/dist/crockford.d.ts +4 -0
  12. package/dist/crockford.d.ts.map +1 -0
  13. package/dist/crockford.js +3 -0
  14. package/dist/discovery.d.ts +6 -10
  15. package/dist/discovery.d.ts.map +1 -1
  16. package/dist/discovery.js +37 -32
  17. package/dist/gather.d.ts +1 -1
  18. package/dist/gather.d.ts.map +1 -1
  19. package/dist/gather.js +4 -14
  20. package/dist/house-model.d.ts +2 -0
  21. package/dist/house-model.d.ts.map +1 -0
  22. package/dist/house-model.js +484 -0
  23. package/dist/index.d.ts +7 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +6 -1
  26. package/dist/model.d.ts +5 -1
  27. package/dist/model.d.ts.map +1 -1
  28. package/dist/model.js +11 -13
  29. package/dist/part.d.ts +15 -0
  30. package/dist/part.d.ts.map +1 -0
  31. package/dist/part.js +82 -0
  32. package/dist/read.d.ts +58 -24
  33. package/dist/read.d.ts.map +1 -1
  34. package/dist/read.js +270 -144
  35. package/dist/room-types.d.ts +7 -0
  36. package/dist/room-types.d.ts.map +1 -0
  37. package/dist/room-types.js +124 -0
  38. package/dist/site.d.ts +1 -1
  39. package/dist/site.d.ts.map +1 -1
  40. package/dist/site.js +126 -125
  41. package/dist/stream.d.ts +3 -3
  42. package/dist/stream.d.ts.map +1 -1
  43. package/dist/stream.js +64 -37
  44. package/dist/transport.d.ts +32 -11
  45. package/dist/transport.d.ts.map +1 -1
  46. package/dist/transport.js +2 -1
  47. package/dist/upload.d.ts +12 -0
  48. package/dist/upload.d.ts.map +1 -0
  49. package/dist/upload.js +63 -0
  50. package/dist/write.d.ts +12 -1
  51. package/dist/write.d.ts.map +1 -1
  52. package/dist/write.js +93 -55
  53. package/package.json +8 -4
  54. package/AGENTS.md +0 -309
  55. package/dist/handed.d.ts +0 -15
  56. package/dist/handed.d.ts.map +0 -1
  57. package/dist/handed.js +0 -38
  58. package/dist/referrer.d.ts +0 -7
  59. package/dist/referrer.d.ts.map +0 -1
  60. package/dist/referrer.js +0 -35
package/dist/read.js CHANGED
@@ -1,13 +1,72 @@
1
+ import { paced, patching, ROW_WEIGHT, stepped, } from '@agentshouse/mdruntime';
2
+ import { checkedPayload, gunzipped, parsePart } from './part.js';
1
3
  import { DECIMAL, readPosition, roomVersion } from './version.js';
4
+ const REVISION_FILE = /^fr_([0-9a-z]+)\.[0-9a-z]+\.[0-9a-z]$/u;
5
+ function fileOf(revision) {
6
+ return REVISION_FILE.exec(revision)?.[1];
7
+ }
8
+ export function answering() {
9
+ return {
10
+ documents: new Map(),
11
+ revisions: new Map(),
12
+ fileIds: new Map(),
13
+ changes: new Map(),
14
+ binaryFiles: new Map(),
15
+ removals: new Set(),
16
+ folders: new Set(),
17
+ folderRemovals: new Set(),
18
+ };
19
+ }
20
+ export function revised(answer, path, revision) {
21
+ answer.revisions.set(path, revision);
22
+ const file = fileOf(revision);
23
+ if (file !== undefined)
24
+ answer.fileIds.set(path, file);
25
+ }
26
+ export function forgotten(answer, path) {
27
+ answer.documents.delete(path);
28
+ answer.revisions.delete(path);
29
+ answer.fileIds.delete(path);
30
+ answer.changes.delete(path);
31
+ answer.binaryFiles.delete(path);
32
+ answer.removals.delete(path);
33
+ }
34
+ export function folded(answer, path, removed) {
35
+ if (removed) {
36
+ answer.folders.delete(path);
37
+ answer.folderRemovals.add(path);
38
+ }
39
+ else {
40
+ answer.folderRemovals.delete(path);
41
+ answer.folders.add(path);
42
+ }
43
+ }
44
+ function* pathsOf(paths) {
45
+ const list = [];
46
+ for (const path of paths) {
47
+ list.push(path);
48
+ yield ROW_WEIGHT;
49
+ }
50
+ return list;
51
+ }
52
+ export function* answered(answer) {
53
+ const removals = yield* pathsOf(answer.removals);
54
+ return {
55
+ documents: yield* patching({}, answer.documents),
56
+ revisions: yield* patching({}, answer.revisions),
57
+ ...(answer.fileIds.size === 0 ? {} : { fileIds: yield* patching({}, answer.fileIds) }),
58
+ changes: yield* patching({}, answer.changes),
59
+ binaryFiles: yield* patching({}, answer.binaryFiles),
60
+ removals,
61
+ ...(answer.folders.size === 0 ? {} : { folders: yield* pathsOf(answer.folders) }),
62
+ ...(answer.folderRemovals.size === 0
63
+ ? {}
64
+ : { folderRemovals: yield* pathsOf(answer.folderRemovals) }),
65
+ };
66
+ }
2
67
  export function authorityRoot(handle) {
3
68
  return `/rooms/${handle}`;
4
69
  }
5
- export function contentPrefixes(tracked) {
6
- return [
7
- authorityRoot(tracked.handle),
8
- ...tracked.schemas.map((schema) => schemaPath(tracked.handle, schema)),
9
- ];
10
- }
11
70
  export function schemaPath(handle, schema) {
12
71
  return `${authorityRoot(handle)}/${schema}`;
13
72
  }
@@ -20,22 +79,37 @@ export function parseGrant(body) {
20
79
  const transfer = body.transfer;
21
80
  if (typeof transfer.url !== 'string')
22
81
  return null;
23
- if (transfer.method === 'GET')
24
- return { method: 'GET', url: transfer.url };
25
82
  if (transfer.method !== 'POST' || typeof transfer.operation !== 'string')
26
83
  return null;
27
- return { method: 'POST', operation: transfer.operation, url: transfer.url };
84
+ return { operation: transfer.operation, url: transfer.url };
85
+ }
86
+ export function parseFileAddress(body) {
87
+ if (typeof body !== 'object' || body === null)
88
+ return null;
89
+ const { download, name, sha256, media_type: mediaType } = body;
90
+ if (typeof download !== 'string' ||
91
+ typeof name !== 'string' ||
92
+ typeof sha256 !== 'string' ||
93
+ typeof mediaType !== 'string') {
94
+ return null;
95
+ }
96
+ return { url: download, name, sha256, mediaType };
28
97
  }
29
98
  function changeAuthor(value) {
30
99
  if (typeof value !== 'object' || value === null)
31
100
  return null;
32
- const { user, site, name } = value;
101
+ const { user, site, inbox, name } = value;
33
102
  if (typeof name !== 'string')
34
103
  return null;
35
- if (typeof user === 'string' && site === undefined)
104
+ const named = [user, site, inbox].filter((id) => id !== undefined);
105
+ if (named.length !== 1)
106
+ return null;
107
+ if (typeof user === 'string')
36
108
  return { kind: 'user', id: user, name };
37
- if (typeof site === 'string' && user === undefined)
109
+ if (typeof site === 'string')
38
110
  return { kind: 'site', id: site, name };
111
+ if (typeof inbox === 'string')
112
+ return { kind: 'inbox', id: inbox, name };
39
113
  return null;
40
114
  }
41
115
  export function headChange(held) {
@@ -52,15 +126,12 @@ function headed(head) {
52
126
  return head === undefined ? {} : { head };
53
127
  }
54
128
  export function binaryFileOf(held) {
55
- if (held.file === undefined)
129
+ if (held.media_type === undefined)
56
130
  return undefined;
57
- const { file, bytes, media_type: mediaType, sha256 } = held;
58
- if (typeof file !== 'string' ||
59
- typeof bytes !== 'number' ||
60
- typeof mediaType !== 'string' ||
61
- typeof sha256 !== 'string')
131
+ const { bytes, media_type: mediaType, sha256 } = held;
132
+ if (typeof bytes !== 'number' || typeof mediaType !== 'string' || typeof sha256 !== 'string')
62
133
  return null;
63
- return { fileRef: file, byteLength: bytes, mediaType, sha256 };
134
+ return { byteLength: bytes, mediaType, sha256 };
64
135
  }
65
136
  function binaried(binary) {
66
137
  return binary === undefined ? {} : { binary };
@@ -97,13 +168,31 @@ function parseFile(value, mode) {
97
168
  ...binaried(binary),
98
169
  };
99
170
  }
100
- function parseScope(value, mode) {
171
+ function parseModels(value, mode) {
172
+ if (!Array.isArray(value))
173
+ return null;
174
+ const files = [];
175
+ const contents = [];
176
+ for (const entry of value) {
177
+ const file = parseFile(entry, mode);
178
+ const { content } = entry;
179
+ if (file === null || typeof content !== 'string')
180
+ return null;
181
+ files.push(file);
182
+ contents.push({ path: file.path, content });
183
+ }
184
+ return { files, contents };
185
+ }
186
+ function parseRoomParts(value, mode) {
101
187
  if (typeof value !== 'object' || value === null)
102
188
  return null;
103
189
  const held = value;
104
190
  if (typeof held.manifest !== 'object' || held.manifest === null)
105
191
  return null;
106
- if (!Array.isArray(held.contents))
192
+ if (!Array.isArray(held.parts))
193
+ return null;
194
+ const models = parseModels(held.models, mode);
195
+ if (models === null)
107
196
  return null;
108
197
  const manifest = held.manifest;
109
198
  if (manifest.scope !== 'room')
@@ -113,77 +202,136 @@ function parseScope(value, mode) {
113
202
  return null;
114
203
  if (typeof manifest.room_handle !== 'string' || manifest.room_handle.length === 0)
115
204
  return null;
116
- if (!Array.isArray(manifest.files))
117
- return null;
118
- const files = [];
119
- for (const entry of manifest.files) {
120
- const file = parseFile(entry, mode);
121
- if (file === null)
205
+ const parts = [];
206
+ for (const entry of held.parts) {
207
+ const part = parsePart(entry);
208
+ if (part === null)
122
209
  return null;
123
- files.push(file);
210
+ parts.push(part);
124
211
  }
125
- const contents = [];
126
- for (const entry of held.contents) {
127
- if (typeof entry !== 'object' || entry === null)
128
- return null;
129
- const content = entry;
130
- if (typeof content.path !== 'string' || typeof content.content !== 'string')
131
- return null;
132
- contents.push({ path: content.path, content: content.content });
133
- }
134
- return { anchor: manifest.anchor, ...at, files, contents };
135
- }
136
- function parseCut(value) {
137
- if (value === undefined)
138
- return undefined;
139
- if (typeof value !== 'object' || value === null)
140
- return null;
141
- const { position, log_epoch: logEpoch } = value;
142
- if (typeof position !== 'string' || typeof logEpoch !== 'string')
143
- return null;
144
- return { position, log_epoch: logEpoch };
145
- }
146
- function parseCursor(value) {
147
- if (typeof value !== 'object' || value === null)
148
- return null;
149
- const { room, path, cut } = value;
150
- if (typeof room !== 'string' || (path !== null && typeof path !== 'string'))
151
- return null;
152
- const parsed = parseCut(cut);
153
- if (parsed === null)
154
- return null;
155
- return { room, path, ...(parsed === undefined ? {} : { cut: parsed }) };
212
+ return { anchor: manifest.anchor, ...at, models, parts };
156
213
  }
157
- export function parseEnvelope(body) {
214
+ export function parseParted(body) {
158
215
  if (typeof body !== 'object' || body === null)
159
216
  return null;
160
217
  if (!('scopes' in body) || !Array.isArray(body.scopes))
161
218
  return null;
162
- const scopes = [];
219
+ const rooms = [];
163
220
  for (const entry of body.scopes) {
164
- const scope = parseScope(entry, 'credential');
165
- if (scope === null)
221
+ const room = parseRoomParts(entry, 'credential');
222
+ if (room === null)
166
223
  return null;
167
- scopes.push(scope);
224
+ rooms.push(room);
168
225
  }
169
226
  if (!('next' in body) || body.next === undefined)
170
- return { scopes };
171
- const next = parseCursor(body.next);
172
- return next === null ? null : { scopes, next };
227
+ return { rooms };
228
+ const next = body.next;
229
+ if (typeof next !== 'object' || next === null || typeof next.room !== 'string')
230
+ return null;
231
+ return { rooms, next: next.room };
232
+ }
233
+ export function parseSiteParted(body) {
234
+ return parseRoomParts(body, 'site');
235
+ }
236
+ export function partInventory(room) {
237
+ return {
238
+ parts: room.parts.length,
239
+ bytes: room.parts.reduce((sum, part) => sum + part.bytes, 0),
240
+ };
241
+ }
242
+ export function manifested(room, inventory, pageToken, models) {
243
+ return {
244
+ kind: 'bootstrap',
245
+ roomVersion: roomVersion(room),
246
+ documents: {},
247
+ revisions: {},
248
+ changes: {},
249
+ binaryFiles: {},
250
+ inventory,
251
+ pageToken,
252
+ ...(models === undefined ? {} : { models }),
253
+ };
254
+ }
255
+ export function modelScope(room) {
256
+ return { ...emptyScope(room), files: room.models.files, contents: room.models.contents };
257
+ }
258
+ export function emptyScope(room) {
259
+ return {
260
+ anchor: room.anchor,
261
+ position: room.position,
262
+ logEpoch: room.logEpoch,
263
+ files: [],
264
+ contents: [],
265
+ };
266
+ }
267
+ function partLine(line, mode, read) {
268
+ let entry;
269
+ try {
270
+ entry = JSON.parse(line);
271
+ }
272
+ catch {
273
+ return false;
274
+ }
275
+ if (folderLine(entry)) {
276
+ read.folders.push(entry.folder);
277
+ return true;
278
+ }
279
+ const file = parseFile(entry, mode);
280
+ if (file === null)
281
+ return false;
282
+ read.files.push(file);
283
+ const { content } = entry;
284
+ if (typeof content === 'string')
285
+ read.contents.push({ path: file.path, content });
286
+ else if (content !== undefined)
287
+ return false;
288
+ return true;
289
+ }
290
+ async function partRead(chunks, mode) {
291
+ const read = { files: [], contents: [], folders: [] };
292
+ const pace = paced();
293
+ const unfinished = [];
294
+ for (let chunk = await chunks.read(); chunk.done !== true; chunk = await chunks.read()) {
295
+ const text = chunk.value;
296
+ let start = 0;
297
+ for (let end = text.indexOf('\n'); end !== -1; end = text.indexOf('\n', start)) {
298
+ const piece = text.slice(start, end);
299
+ const line = unfinished.length === 0 ? piece : unfinished.splice(0).join('') + piece;
300
+ if (!partLine(line, mode, read)) {
301
+ await chunks.cancel();
302
+ return null;
303
+ }
304
+ start = end + 1;
305
+ const due = pace(line.length + ROW_WEIGHT);
306
+ if (due instanceof Promise)
307
+ await due;
308
+ }
309
+ if (start < text.length)
310
+ unfinished.push(text.slice(start));
311
+ }
312
+ return unfinished.length === 0 ? read : null;
173
313
  }
174
- export function parseSiteBootstrap(body) {
175
- return parseScope(body, 'site');
314
+ function folderLine(entry) {
315
+ if (typeof entry !== 'object' || entry === null || !('folder' in entry))
316
+ return false;
317
+ return typeof entry.folder === 'string' && Object.keys(entry).length === 1;
176
318
  }
177
- export function siteBootstrapNext(body) {
178
- if (typeof body !== 'object' || body === null || !('next' in body))
319
+ export async function housePart(room, frame, listed, mode) {
320
+ const payload = await checkedPayload(frame, listed);
321
+ if (payload === null)
179
322
  return null;
180
- return typeof body.next === 'string' && body.next.length > 0 ? body.next : null;
323
+ const read = await partRead(gunzipped(payload).getReader(), mode).catch(() => null);
324
+ return read === null ? { kind: 'transport-uncertainty' } : { ...emptyScope(room), ...read };
181
325
  }
182
- export function siteBootstrapOffset(body) {
183
- if (typeof body !== 'object' || body === null || !('offset' in body))
326
+ function folderChange(value) {
327
+ if (typeof value !== 'object' || value === null)
184
328
  return null;
185
- return Number.isSafeInteger(body.offset) && body.offset > 0
186
- ? body.offset
329
+ const { path, folder, removed, ...rest } = value;
330
+ return typeof path === 'string' &&
331
+ folder === true &&
332
+ (removed === undefined || removed === true) &&
333
+ Object.keys(rest).length === 0
334
+ ? { path, removed: removed === true }
187
335
  : null;
188
336
  }
189
337
  function parseChange(value, mode) {
@@ -242,7 +390,13 @@ export function parseEnumeration(body, mode) {
242
390
  if (!Array.isArray(held.changes))
243
391
  return null;
244
392
  const changes = [];
393
+ const folders = [];
245
394
  for (const change of held.changes) {
395
+ const folder = folderChange(change);
396
+ if (folder !== null) {
397
+ folders.push(folder);
398
+ continue;
399
+ }
246
400
  const mapped = parseChange(change, mode);
247
401
  if (mapped === null)
248
402
  return null;
@@ -255,6 +409,7 @@ export function parseEnumeration(body, mode) {
255
409
  authority: held.authority,
256
410
  ...at,
257
411
  changes,
412
+ ...(folders.length === 0 ? {} : { folders }),
258
413
  ...(next === undefined ? {} : { next }),
259
414
  });
260
415
  }
@@ -278,6 +433,7 @@ function advances(asked, next) {
278
433
  }
279
434
  export async function wholeView(first, more) {
280
435
  const changes = new Map(first.changes.map((change) => [change.path, change]));
436
+ const folders = new Map((first.folders ?? []).map((folder) => [folder.path, folder]));
281
437
  let view = first;
282
438
  while (view.next !== undefined) {
283
439
  const asked = view.next;
@@ -293,6 +449,10 @@ export async function wholeView(first, more) {
293
449
  changes.delete(change.path);
294
450
  changes.set(change.path, change);
295
451
  }
452
+ for (const folder of page.folders ?? []) {
453
+ folders.delete(folder.path);
454
+ folders.set(folder.path, folder);
455
+ }
296
456
  view = page;
297
457
  }
298
458
  return {
@@ -300,62 +460,32 @@ export async function wholeView(first, more) {
300
460
  position: view.position,
301
461
  logEpoch: first.logEpoch,
302
462
  changes: [...changes.values()],
463
+ ...(folders.size === 0 ? {} : { folders: [...folders.values()] }),
303
464
  };
304
465
  }
305
- export function advancedScope(scope, view) {
306
- const files = new Map(scope.files.map((file) => [file.path, file]));
307
- const contents = new Map(scope.contents.map((entry) => [entry.path, entry.content]));
308
- for (const change of view.changes) {
309
- files.delete(change.path);
310
- contents.delete(change.path);
311
- if ('removed' in change)
312
- continue;
313
- files.set(change.path, {
314
- path: change.path,
315
- revision: change.revision,
316
- version: change.version,
317
- ...headed(change.head),
318
- ...('binary' in change ? { binary: change.binary } : {}),
319
- });
320
- if ('content' in change)
321
- contents.set(change.path, change.content);
466
+ export function* bootstrapping(scope) {
467
+ const contents = new Map();
468
+ for (const entry of scope.contents) {
469
+ contents.set(entry.path, entry.content);
470
+ yield ROW_WEIGHT;
322
471
  }
323
- return {
324
- ...scope,
325
- position: view.position,
326
- logEpoch: view.logEpoch,
327
- files: [...files.values()],
328
- contents: [...contents].map(([path, content]) => ({ path, content })),
329
- };
330
- }
331
- export function matchesScope(scope, tracked) {
332
- return scope.anchor === tracked.authority;
333
- }
334
- export function bootstrapOf(scope) {
335
- const contents = new Map(scope.contents.map((entry) => [entry.path, entry.content]));
336
- const documents = {};
337
- const revisions = {};
338
- const changes = {};
339
- const binaryFiles = {};
472
+ const answer = answering();
340
473
  for (const file of scope.files) {
341
- if (file.revision !== undefined)
342
- revisions[file.path] = file.revision;
474
+ yield ROW_WEIGHT;
343
475
  if (file.head !== undefined)
344
- changes[file.path] = file.head;
476
+ answer.changes.set(file.path, file.head);
345
477
  const content = contents.get(file.path);
346
478
  if (file.binary !== undefined)
347
- binaryFiles[file.path] = file.binary;
479
+ answer.binaryFiles.set(file.path, file.binary);
348
480
  else if (content !== undefined)
349
- documents[file.path] = content;
481
+ answer.documents.set(file.path, content);
482
+ if (file.revision !== undefined)
483
+ revised(answer, file.path, file.revision);
350
484
  }
351
- return {
352
- kind: 'bootstrap',
353
- roomVersion: roomVersion(scope),
354
- documents,
355
- revisions,
356
- changes,
357
- binaryFiles,
358
- };
485
+ for (const folder of scope.folders ?? [])
486
+ folded(answer, folder, false);
487
+ const { removals: _removals, folderRemovals: _folderRemovals, ...page } = yield* answered(answer);
488
+ return { kind: 'bootstrap', roomVersion: roomVersion(scope), ...page };
359
489
  }
360
490
  export function schemaOf(scope, schema) {
361
491
  const file = scope.files.find((entry) => entry.path === schema);
@@ -369,35 +499,31 @@ export function schemaOf(scope, schema) {
369
499
  export function viewOf(enumeration, tracked) {
370
500
  return enumeration.authorities.find((entry) => entry.authority === tracked.authority);
371
501
  }
372
- export function refreshFrom(view, fromRoomVersion) {
502
+ function* refreshing(view, fromRoomVersion) {
373
503
  if (roomVersion(view) === fromRoomVersion)
374
504
  return { kind: 'still-current' };
375
- const documents = {};
376
- const revisions = {};
377
- const changes = {};
378
- const binaryFiles = {};
379
- const removals = [];
505
+ const answer = answering();
380
506
  for (const change of view.changes) {
507
+ yield ROW_WEIGHT;
381
508
  if ('removed' in change) {
382
- removals.push(change.path);
509
+ answer.removals.add(change.path);
383
510
  continue;
384
511
  }
385
512
  if ('content' in change)
386
- documents[change.path] = change.content;
513
+ answer.documents.set(change.path, change.content);
387
514
  else
388
- binaryFiles[change.path] = change.binary;
389
- if (change.revision !== undefined)
390
- revisions[change.path] = change.revision;
515
+ answer.binaryFiles.set(change.path, change.binary);
391
516
  if (change.head !== undefined)
392
- changes[change.path] = change.head;
517
+ answer.changes.set(change.path, change.head);
518
+ if (change.revision !== undefined)
519
+ revised(answer, change.path, change.revision);
393
520
  }
394
- return {
395
- kind: 'net-advancement',
396
- roomVersion: roomVersion(view),
397
- documents,
398
- revisions,
399
- changes,
400
- binaryFiles,
401
- removals: removals.sort(),
402
- };
521
+ for (const folder of view.folders ?? []) {
522
+ yield ROW_WEIGHT;
523
+ folded(answer, folder.path, folder.removed);
524
+ }
525
+ return { kind: 'net-advancement', roomVersion: roomVersion(view), ...(yield* answered(answer)) };
526
+ }
527
+ export async function refreshFrom(view, fromRoomVersion) {
528
+ return stepped(refreshing(view, fromRoomVersion));
403
529
  }
@@ -0,0 +1,7 @@
1
+ export declare const INBOX_CHANNEL_KINDS: readonly ['telegram-bot', 'whatsapp', 'messenger', 'instagram', 'viber', 'tiktok'];
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_NAMEABLE_ROOM_TYPES: string[];
6
+ export declare const HOUSE_ROOM_TYPES: string;
7
+ //# 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":"AAGA,eAAO,MAAM,mBAAmB,YAC9B,cAAc,EACd,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,eAAe,eAAe,CAAC;AAE5C,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD,eAAO,MAAM,yBAAyB,UAAwC,CAAC;AAyB/E,eAAO,MAAM,gBAAgB,QA6FjB,CAAC"}
@@ -0,0 +1,124 @@
1
+ import { APP_REFERENCE_PATTERN } from './app-reference.js';
2
+ import { HOUSE_MODEL_TYPES } from './house-model.js';
3
+ export const INBOX_CHANNEL_KINDS = [
4
+ 'telegram-bot',
5
+ 'whatsapp',
6
+ 'messenger',
7
+ 'instagram',
8
+ 'viber',
9
+ 'tiktok',
10
+ ];
11
+ export const INBOX_CHAT_TYPE = 'inbox-chat';
12
+ export const INBOX_MESSAGE_TYPE = 'inbox-message';
13
+ export const HOUSE_NAMEABLE_ROOM_TYPES = [INBOX_CHAT_TYPE, INBOX_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
+ `${INBOX_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
+ ' conversation: { type: string, format: uuid }',
50
+ ' required: [inbox, channel, chat, customer]',
51
+ `${INBOX_MESSAGE_TYPE}:`,
52
+ ' properties:',
53
+ ' direction: { enum: [in, out] }',
54
+ ' sender:',
55
+ ' type: object',
56
+ ' properties:',
57
+ ' name: { type: string }',
58
+ ` username: ${IDENTITY}`,
59
+ ' sent_at: { type: string, format: date-time }',
60
+ ` channel_message: ${IDENTITY}`,
61
+ ' state: { enum: [sending, sent, failed] }',
62
+ ' reason: { type: string }',
63
+ ' reactions:',
64
+ ' type: array',
65
+ ' items:',
66
+ ' type: object',
67
+ ' properties:',
68
+ ' reaction: { type: string, minLength: 1 }',
69
+ ' sender:',
70
+ ' type: object',
71
+ ' properties:',
72
+ ` id: ${IDENTITY}`,
73
+ ' name: { type: string }',
74
+ ` username: ${IDENTITY}`,
75
+ ' count: { type: integer, minimum: 1 }',
76
+ ' required: [reaction]',
77
+ ` post: ${IDENTITY}`,
78
+ ' assignee:',
79
+ ...ASSIGNEE,
80
+ ' sent_outside: { const: true }',
81
+ ' template:',
82
+ ' type: object',
83
+ ' properties:',
84
+ ' name: { type: string, minLength: 1 }',
85
+ ' language: { type: string, minLength: 1 }',
86
+ ' required: [name, language]',
87
+ ' values:',
88
+ ' type: object',
89
+ ' additionalProperties: { type: string }',
90
+ ' withheld: { const: true }',
91
+ ' required: [direction]',
92
+ ' if: { properties: { direction: { const: in } } }',
93
+ ' then: { required: [sent_at] }',
94
+ `${WAYFINDING_MAP_TYPE}:`,
95
+ ' properties:',
96
+ ' title: { type: string }',
97
+ ' required: [title]',
98
+ ' sections:',
99
+ ...WAYFINDING_MAP_SECTIONS.map((name) => ` ${name}: { kind: text, required: true }`),
100
+ `${WAYFINDING_TICKET_TYPE}:`,
101
+ ' properties:',
102
+ ' title: { type: string }',
103
+ ' kind: { enum: [research, prototype, grilling, task] }',
104
+ ' status: { enum: [open, in-progress, done, out-of-scope] }',
105
+ ` map: { type: string, reference: ${WAYFINDING_MAP_TYPE} }`,
106
+ ` blocked_by: { type: array, items: { type: string, reference: ${WAYFINDING_TICKET_TYPE} } }`,
107
+ ' assignee:',
108
+ ...ASSIGNEE,
109
+ ' conversation: { type: string, format: uuid }',
110
+ ` app: { type: string, pattern: '${APP_REFERENCE_PATTERN.source}' }`,
111
+ ' required: [title, kind, status, map, blocked_by]',
112
+ ' sections:',
113
+ ' Question: { kind: text }',
114
+ ' Answer: { kind: text }',
115
+ ' allOf:',
116
+ ' - if: { properties: { status: { enum: [in-progress, done, out-of-scope] } }, required: [status] }',
117
+ ' then: { required: [assignee] }',
118
+ ' else: { properties: { assignee: false } }',
119
+ ' - if: { properties: { assignee: { required: [agent] } }, required: [assignee] }',
120
+ ' else: { properties: { conversation: false } }',
121
+ ' - if: { properties: { status: { enum: [done, out-of-scope] } }, required: [status] }',
122
+ ' then: { sections: { Answer: { kind: text, required: true } } }',
123
+ HOUSE_MODEL_TYPES,
124
+ ].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