@semiont/core 0.5.23 → 0.5.25
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 +31 -0
- package/dist/chunk-FMFOBVTE.js +334 -0
- package/dist/chunk-FMFOBVTE.js.map +1 -0
- package/dist/chunk-I3ZOWCTH.js +143 -0
- package/dist/chunk-I3ZOWCTH.js.map +1 -0
- package/dist/chunk-XQTWEBJ5.js +293 -0
- package/dist/chunk-XQTWEBJ5.js.map +1 -0
- package/dist/config/node-config-loader.d.ts +44 -11
- package/dist/config/node-config-loader.js +20 -294
- package/dist/config/node-config-loader.js.map +1 -1
- package/dist/index.d.ts +707 -6
- package/dist/index.js +245 -627
- package/dist/index.js.map +1 -1
- package/dist/testing/axioms.d.ts +180 -0
- package/dist/testing/axioms.js +365 -0
- package/dist/testing/axioms.js.map +1 -0
- package/dist/testing.d.ts +16 -178
- package/dist/testing.js +2 -761
- package/dist/testing.js.map +1 -1
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -1,65 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
export { createTomlConfigLoader, loadTomlConfig } from './chunk-XQTWEBJ5.js';
|
|
2
|
+
import { BUS_OPERATIONS } from './chunk-FMFOBVTE.js';
|
|
3
|
+
export { BRIDGED_CHANNELS, BUS_OPERATIONS, EventBus, ScopedEventBus, accessToken, annotationUri, authCode, baseUrl, busLog, busLogEnabled, cloneToken, email, entityType, googleCredential, jobId, mcpToken, refreshToken, resourceAnnotationUri, resourceUri, searchQuery, setBusLogTraceIdProvider, userDID } from './chunk-FMFOBVTE.js';
|
|
4
|
+
import { Observable, merge, TimeoutError, throwError, firstValueFrom } from 'rxjs';
|
|
2
5
|
import { filter, map, take, timeout, catchError, defaultIfEmpty } from 'rxjs/operators';
|
|
3
|
-
import { parse } from 'smol-toml';
|
|
4
|
-
|
|
5
|
-
// src/branded-types.ts
|
|
6
|
-
function email(value) {
|
|
7
|
-
return value;
|
|
8
|
-
}
|
|
9
|
-
function authCode(value) {
|
|
10
|
-
return value;
|
|
11
|
-
}
|
|
12
|
-
function googleCredential(value) {
|
|
13
|
-
return value;
|
|
14
|
-
}
|
|
15
|
-
function accessToken(value) {
|
|
16
|
-
return value;
|
|
17
|
-
}
|
|
18
|
-
function refreshToken(value) {
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
function mcpToken(value) {
|
|
22
|
-
return value;
|
|
23
|
-
}
|
|
24
|
-
function cloneToken(value) {
|
|
25
|
-
return value;
|
|
26
|
-
}
|
|
27
|
-
function jobId(value) {
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
function userDID(value) {
|
|
31
|
-
return value;
|
|
32
|
-
}
|
|
33
|
-
function entityType(value) {
|
|
34
|
-
return value;
|
|
35
|
-
}
|
|
36
|
-
function searchQuery(value) {
|
|
37
|
-
return value;
|
|
38
|
-
}
|
|
39
|
-
function baseUrl(value) {
|
|
40
|
-
return value;
|
|
41
|
-
}
|
|
42
|
-
function resourceUri(uri) {
|
|
43
|
-
if (!uri.startsWith("http://") && !uri.startsWith("https://")) {
|
|
44
|
-
throw new TypeError(`Expected ResourceUri, got: ${uri}`);
|
|
45
|
-
}
|
|
46
|
-
return uri;
|
|
47
|
-
}
|
|
48
|
-
function annotationUri(uri) {
|
|
49
|
-
if (!uri.startsWith("http://") && !uri.startsWith("https://")) {
|
|
50
|
-
throw new TypeError(`Expected AnnotationUri, got: ${uri}`);
|
|
51
|
-
}
|
|
52
|
-
return uri;
|
|
53
|
-
}
|
|
54
|
-
function resourceAnnotationUri(uri) {
|
|
55
|
-
if (!uri.startsWith("http://") && !uri.startsWith("https://")) {
|
|
56
|
-
throw new TypeError(`Expected ResourceAnnotationUri, got: ${uri}`);
|
|
57
|
-
}
|
|
58
|
-
if (!uri.includes("/resources/") || !uri.includes("/annotations/")) {
|
|
59
|
-
throw new TypeError(`Expected nested ResourceAnnotationUri format, got: ${uri}`);
|
|
60
|
-
}
|
|
61
|
-
return uri;
|
|
62
|
-
}
|
|
63
6
|
|
|
64
7
|
// src/identifiers.ts
|
|
65
8
|
function isResourceId(value) {
|
|
@@ -236,6 +179,10 @@ var CHANNEL_SCHEMAS = {
|
|
|
236
179
|
"browse:resource-result": "BrowseResourceResult",
|
|
237
180
|
"browse:resource-failed": null,
|
|
238
181
|
// { correlationId } & CommandError
|
|
182
|
+
"browse:anchored-text-requested": "BrowseAnchoredTextRequest",
|
|
183
|
+
"browse:anchored-text-result": "BrowseAnchoredTextResult",
|
|
184
|
+
"browse:anchored-text-failed": null,
|
|
185
|
+
// { correlationId } & CommandError
|
|
239
186
|
"browse:resources-requested": "BrowseResourcesRequest",
|
|
240
187
|
"browse:resources-result": "BrowseResourcesResult",
|
|
241
188
|
"browse:resources-failed": null,
|
|
@@ -328,12 +275,17 @@ var CHANNEL_SCHEMAS = {
|
|
|
328
275
|
"weave:applied": null,
|
|
329
276
|
// { resourceId; sequenceNumber }
|
|
330
277
|
"smelt:settled": null,
|
|
331
|
-
// { resourceId; contentChecksum; outcome }
|
|
278
|
+
// { resourceId; contentChecksum; outcome; reason? }
|
|
332
279
|
"weave:rebuild": "WeaveRebuildCommand",
|
|
333
280
|
"weave:rebuild-ok": null,
|
|
334
281
|
// { correlationId }
|
|
335
282
|
"weave:rebuild-failed": null,
|
|
336
283
|
// { correlationId; message }
|
|
284
|
+
"smelt:rebuild-anchors": "SmeltRebuildAnchorsCommand",
|
|
285
|
+
"smelt:rebuild-anchors-ok": null,
|
|
286
|
+
// { correlationId }
|
|
287
|
+
"smelt:rebuild-anchors-failed": null,
|
|
288
|
+
// { correlationId; message }
|
|
337
289
|
// ── SSE infrastructure ──────────────────────────────────────────
|
|
338
290
|
"stream-connected": null,
|
|
339
291
|
// Record<string, never>
|
|
@@ -369,274 +321,6 @@ function isEventRelatedToAnnotation(event, annotationUri2) {
|
|
|
369
321
|
function isStoredEvent(event) {
|
|
370
322
|
return event && typeof event.id === "string" && typeof event.timestamp === "string" && typeof event.type === "string" && typeof event.metadata === "object" && typeof event.metadata.sequenceNumber === "number";
|
|
371
323
|
}
|
|
372
|
-
|
|
373
|
-
// src/bus-operations.ts
|
|
374
|
-
var BUS_OPERATIONS = {
|
|
375
|
-
// ── BIND ────────────────────────────────────────────────────────
|
|
376
|
-
"bind:update-body": { result: "bind:body-updated", failure: "bind:body-update-failed" },
|
|
377
|
-
// ── BROWSE (reads) ──────────────────────────────────────────────
|
|
378
|
-
"browse:resource-requested": { result: "browse:resource-result", failure: "browse:resource-failed" },
|
|
379
|
-
"browse:resources-requested": { result: "browse:resources-result", failure: "browse:resources-failed" },
|
|
380
|
-
"browse:annotation-requested": { result: "browse:annotation-result", failure: "browse:annotation-failed" },
|
|
381
|
-
"browse:annotations-requested": { result: "browse:annotations-result", failure: "browse:annotations-failed" },
|
|
382
|
-
"browse:annotation-history-requested": { result: "browse:annotation-history-result", failure: "browse:annotation-history-failed" },
|
|
383
|
-
"browse:events-requested": { result: "browse:events-result", failure: "browse:events-failed" },
|
|
384
|
-
"browse:referenced-by-requested": { result: "browse:referenced-by-result", failure: "browse:referenced-by-failed" },
|
|
385
|
-
"browse:entity-types-requested": { result: "browse:entity-types-result", failure: "browse:entity-types-failed" },
|
|
386
|
-
"browse:tag-schemas-requested": { result: "browse:tag-schemas-result", failure: "browse:tag-schemas-failed" },
|
|
387
|
-
"browse:agents-requested": { result: "browse:agents-result", failure: "browse:agents-failed" },
|
|
388
|
-
"browse:directory-requested": { result: "browse:directory-result", failure: "browse:directory-failed" },
|
|
389
|
-
// dormant — backend handler complete, no client caller yet (annotation-detail capability)
|
|
390
|
-
"browse:annotation-context-requested": { result: "browse:annotation-context-result", failure: "browse:annotation-context-failed" },
|
|
391
|
-
// ── FRAME (KB schema writes) ────────────────────────────────────
|
|
392
|
-
"frame:add-entity-type": { result: "frame:entity-type-add-ok", failure: "frame:entity-type-add-failed" },
|
|
393
|
-
"frame:add-tag-schema": { result: "frame:tag-schema-add-ok", failure: "frame:tag-schema-add-failed" },
|
|
394
|
-
// ── GATHER ──────────────────────────────────────────────────────
|
|
395
|
-
// streaming: take-1 result + failure plus an intermediate progress channel
|
|
396
|
-
"gather:requested": { result: "gather:complete", failure: "gather:failed", progress: "gather:annotation-progress" },
|
|
397
|
-
"gather:resource-requested": { result: "gather:resource-complete", failure: "gather:resource-failed" },
|
|
398
|
-
// dormant — backend handler complete, no client caller yet (annotation summary)
|
|
399
|
-
"gather:summary-requested": { result: "gather:summary-result", failure: "gather:summary-failed" },
|
|
400
|
-
// ── JOB ─────────────────────────────────────────────────────────
|
|
401
|
-
"job:create": { result: "job:created", failure: "job:create-failed" },
|
|
402
|
-
"job:status-requested": { result: "job:status-result", failure: "job:status-failed" },
|
|
403
|
-
"job:cancel-requested": { result: "job:cancel-ok", failure: "job:cancel-failed" },
|
|
404
|
-
// worker-side: the worker claims a queued job (not an SDK call)
|
|
405
|
-
"job:claim": { result: "job:claimed", failure: "job:claim-failed" },
|
|
406
|
-
// ── MARK ────────────────────────────────────────────────────────
|
|
407
|
-
"mark:create-request": { result: "mark:create-ok", failure: "mark:create-failed" },
|
|
408
|
-
"mark:delete": { result: "mark:delete-ok", failure: "mark:delete-failed" },
|
|
409
|
-
"mark:archive": { result: "mark:archive-ok", failure: "mark:archive-failed" },
|
|
410
|
-
"mark:unarchive": { result: "mark:unarchive-ok", failure: "mark:unarchive-failed" },
|
|
411
|
-
"mark:update-entity-types": { result: "mark:update-entity-types-ok", failure: "mark:update-entity-types-failed" },
|
|
412
|
-
// ── MATCH ───────────────────────────────────────────────────────
|
|
413
|
-
// take-1 dressed as an Observable in the SDK; no progress channel
|
|
414
|
-
"match:search-requested": { result: "match:search-results", failure: "match:search-failed" },
|
|
415
|
-
// ── WEAVE ───────────────────────────────────────────────────────
|
|
416
|
-
// Graph-projection rebuild, served by the Weaver (WEAVER-ISOLATION D3)
|
|
417
|
-
"weave:rebuild": { result: "weave:rebuild-ok", failure: "weave:rebuild-failed" },
|
|
418
|
-
// ── YIELD ───────────────────────────────────────────────────────
|
|
419
|
-
// live in-process (resource-operations.ts emits + awaits via race()); the
|
|
420
|
-
// client also .on()-subscribes -ok for cache invalidation
|
|
421
|
-
"yield:create": { result: "yield:create-ok", failure: "yield:create-failed" },
|
|
422
|
-
// dormant — handler in stower exists, no request emitter; client pre-subscribes -ok
|
|
423
|
-
"yield:update": { result: "yield:update-ok", failure: "yield:update-failed" },
|
|
424
|
-
"yield:clone-create": { result: "yield:clone-created", failure: "yield:clone-create-failed" },
|
|
425
|
-
"yield:clone-resource-requested": { result: "yield:clone-resource-result", failure: "yield:clone-resource-failed" },
|
|
426
|
-
"yield:clone-token-requested": { result: "yield:clone-token-generated", failure: "yield:clone-token-failed" }
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
// src/bridged-channels.ts
|
|
430
|
-
var BRIDGED_BROADCASTS = [
|
|
431
|
-
"job:report-progress",
|
|
432
|
-
"job:complete",
|
|
433
|
-
"job:fail",
|
|
434
|
-
"frame:entity-type-added",
|
|
435
|
-
"frame:tag-schema-added",
|
|
436
|
-
"beckon:focus",
|
|
437
|
-
"beckon:sparkle",
|
|
438
|
-
"bus:resume-gap"
|
|
439
|
-
];
|
|
440
|
-
var REGISTRY_REPLIES = Object.keys(BUS_OPERATIONS).flatMap(
|
|
441
|
-
(key) => {
|
|
442
|
-
const op = BUS_OPERATIONS[key];
|
|
443
|
-
return "progress" in op ? [op.result, op.failure, op.progress] : [op.result, op.failure];
|
|
444
|
-
}
|
|
445
|
-
);
|
|
446
|
-
var BRIDGED_CHANNELS = [
|
|
447
|
-
...REGISTRY_REPLIES,
|
|
448
|
-
...BRIDGED_BROADCASTS
|
|
449
|
-
];
|
|
450
|
-
|
|
451
|
-
// src/bus-log.ts
|
|
452
|
-
var NODE_BUS_LOG = typeof process !== "undefined" && !!process.env?.SEMIONT_BUS_LOG;
|
|
453
|
-
var IS_NODE = typeof process !== "undefined" && !!process.versions?.node;
|
|
454
|
-
function busLogEnabled() {
|
|
455
|
-
const g = globalThis;
|
|
456
|
-
if (g.__SEMIONT_BUS_LOG__) return true;
|
|
457
|
-
return NODE_BUS_LOG;
|
|
458
|
-
}
|
|
459
|
-
var traceIdProvider;
|
|
460
|
-
function setBusLogTraceIdProvider(fn) {
|
|
461
|
-
traceIdProvider = fn;
|
|
462
|
-
}
|
|
463
|
-
function busLog(op, channel, payload, scope) {
|
|
464
|
-
if (!busLogEnabled()) return;
|
|
465
|
-
const cidRaw = payload?.correlationId;
|
|
466
|
-
const cid = typeof cidRaw === "string" ? cidRaw.slice(0, 8) : void 0;
|
|
467
|
-
let traceId;
|
|
468
|
-
if (traceIdProvider) {
|
|
469
|
-
try {
|
|
470
|
-
traceId = traceIdProvider();
|
|
471
|
-
} catch {
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
const tag = `[bus ${op}] ${channel}` + (scope ? ` scope=${scope}` : "") + (cid ? ` cid=${cid}` : "") + (traceId ? ` trace=${traceId.slice(0, 8)}` : "");
|
|
475
|
-
console.debug(tag, payload);
|
|
476
|
-
}
|
|
477
|
-
function warnUnobservedRepliesEnabled() {
|
|
478
|
-
return IS_NODE;
|
|
479
|
-
}
|
|
480
|
-
var unobservedReplyWarned = /* @__PURE__ */ new Set();
|
|
481
|
-
function warnIfUnobservedReply(channel, payload, observerCount) {
|
|
482
|
-
if (observerCount > 0) return;
|
|
483
|
-
const cidRaw = payload?.correlationId;
|
|
484
|
-
if (typeof cidRaw !== "string" || cidRaw.length === 0) return;
|
|
485
|
-
if (BRIDGED_CHANNELS.includes(channel)) return;
|
|
486
|
-
if (unobservedReplyWarned.has(channel)) return;
|
|
487
|
-
unobservedReplyWarned.add(channel);
|
|
488
|
-
console.warn(
|
|
489
|
-
`[bus DROP] ${channel} cid=${cidRaw.slice(0, 8)} emitted with 0 subscribers and not in BRIDGED_CHANNELS \u2014 a correlation reply with no forwarder is dropped, so the awaiting client times out (no error). Bridge it by declaring its operation in BUS_OPERATIONS (packages/core/src/bus-operations.ts) \u2014 or, if it is a non-reply broadcast, add it to BRIDGED_BROADCASTS (packages/core/src/bridged-channels.ts) \u2014 so transports subscribe to it.`
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// src/event-bus.ts
|
|
494
|
-
var EventBus = class {
|
|
495
|
-
subjects;
|
|
496
|
-
isDestroyed;
|
|
497
|
-
constructor() {
|
|
498
|
-
this.subjects = /* @__PURE__ */ new Map();
|
|
499
|
-
this.isDestroyed = false;
|
|
500
|
-
}
|
|
501
|
-
/**
|
|
502
|
-
* Get the RxJS Subject for an event
|
|
503
|
-
*
|
|
504
|
-
* Returns a typed Subject that can be used with all RxJS operators.
|
|
505
|
-
* Subjects are created lazily on first access.
|
|
506
|
-
*
|
|
507
|
-
* @param eventName - The event name
|
|
508
|
-
* @returns The RxJS Subject for this event
|
|
509
|
-
*
|
|
510
|
-
* @example
|
|
511
|
-
* ```typescript
|
|
512
|
-
* // Emit
|
|
513
|
-
* eventBus.get('beckon:hover').next({ annotationId: 'ann-1' });
|
|
514
|
-
*
|
|
515
|
-
* // Subscribe
|
|
516
|
-
* const sub = eventBus.get('beckon:hover').subscribe(handleHover);
|
|
517
|
-
*
|
|
518
|
-
* // With operators
|
|
519
|
-
* eventBus.get('beckon:hover')
|
|
520
|
-
* .pipe(debounceTime(100), distinctUntilChanged())
|
|
521
|
-
* .subscribe(handleHover);
|
|
522
|
-
* ```
|
|
523
|
-
*/
|
|
524
|
-
get(eventName) {
|
|
525
|
-
if (this.isDestroyed) {
|
|
526
|
-
throw new Error(`Cannot access event '${String(eventName)}' on destroyed bus`);
|
|
527
|
-
}
|
|
528
|
-
if (!this.subjects.has(eventName)) {
|
|
529
|
-
const subject = new Subject();
|
|
530
|
-
const wantBusLog = busLogEnabled();
|
|
531
|
-
const wantDropCheck = warnUnobservedRepliesEnabled();
|
|
532
|
-
if (wantBusLog || wantDropCheck) {
|
|
533
|
-
const wrapped = subject;
|
|
534
|
-
const originalNext = subject.next.bind(subject);
|
|
535
|
-
subject.next = (value) => {
|
|
536
|
-
if (wantBusLog) busLog("EMIT", String(eventName), value);
|
|
537
|
-
if (wantDropCheck) warnIfUnobservedReply(String(eventName), value, wrapped.observers.length);
|
|
538
|
-
originalNext(value);
|
|
539
|
-
};
|
|
540
|
-
}
|
|
541
|
-
this.subjects.set(eventName, subject);
|
|
542
|
-
}
|
|
543
|
-
return this.subjects.get(eventName);
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Get the RxJS Subject for a domain event type (PersistedEventType).
|
|
547
|
-
*
|
|
548
|
-
* Domain event channels carry `StoredEvent`. This method avoids the need
|
|
549
|
-
* for `as keyof EventMap` casts when subscribing to domain event channels
|
|
550
|
-
* using runtime `PersistedEventType` strings.
|
|
551
|
-
*/
|
|
552
|
-
getDomainEvent(eventType) {
|
|
553
|
-
return this.get(eventType);
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* Destroy the event bus and complete all subjects
|
|
557
|
-
*
|
|
558
|
-
* After calling destroy(), no new events can be emitted or subscribed to.
|
|
559
|
-
* All active subscriptions will be completed.
|
|
560
|
-
*/
|
|
561
|
-
destroy() {
|
|
562
|
-
if (this.isDestroyed) {
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
for (const subject of this.subjects.values()) {
|
|
566
|
-
subject.complete();
|
|
567
|
-
}
|
|
568
|
-
this.subjects.clear();
|
|
569
|
-
this.isDestroyed = true;
|
|
570
|
-
}
|
|
571
|
-
/**
|
|
572
|
-
* Check if the event bus has been destroyed
|
|
573
|
-
*/
|
|
574
|
-
get destroyed() {
|
|
575
|
-
return this.isDestroyed;
|
|
576
|
-
}
|
|
577
|
-
/**
|
|
578
|
-
* Create a resource-scoped event bus
|
|
579
|
-
*
|
|
580
|
-
* Events emitted or subscribed through the scoped bus are isolated to that resource.
|
|
581
|
-
* Internally, events are namespaced but the API remains identical to the parent bus.
|
|
582
|
-
*
|
|
583
|
-
* @param resourceId - Resource identifier to scope events to
|
|
584
|
-
* @returns A scoped event bus for this resource
|
|
585
|
-
*
|
|
586
|
-
* @example
|
|
587
|
-
* ```typescript
|
|
588
|
-
* const eventBus = new EventBus();
|
|
589
|
-
* const resource1 = eventBus.scope('resource-1');
|
|
590
|
-
* const resource2 = eventBus.scope('resource-2');
|
|
591
|
-
*
|
|
592
|
-
* // These are isolated - only resource1 subscribers will fire
|
|
593
|
-
* resource1.get('detection:progress').next({ status: 'started' });
|
|
594
|
-
* ```
|
|
595
|
-
*/
|
|
596
|
-
scope(resourceId2) {
|
|
597
|
-
return new ScopedEventBus(this, resourceId2);
|
|
598
|
-
}
|
|
599
|
-
};
|
|
600
|
-
var ScopedEventBus = class _ScopedEventBus {
|
|
601
|
-
constructor(parent, scopePrefix) {
|
|
602
|
-
this.parent = parent;
|
|
603
|
-
this.scopePrefix = scopePrefix;
|
|
604
|
-
}
|
|
605
|
-
parent;
|
|
606
|
-
scopePrefix;
|
|
607
|
-
/**
|
|
608
|
-
* Get the RxJS Subject for a scoped event
|
|
609
|
-
*
|
|
610
|
-
* Returns the same type as the parent bus, but events are isolated to this scope.
|
|
611
|
-
* Internally uses namespaced keys but preserves type safety.
|
|
612
|
-
*
|
|
613
|
-
* @param event - The event name
|
|
614
|
-
* @returns The RxJS Subject for this scoped event
|
|
615
|
-
*/
|
|
616
|
-
get(event) {
|
|
617
|
-
const scopedKey = `${this.scopePrefix}:${event}`;
|
|
618
|
-
const parentSubjects = this.parent.subjects;
|
|
619
|
-
if (!parentSubjects.has(scopedKey)) {
|
|
620
|
-
parentSubjects.set(scopedKey, new Subject());
|
|
621
|
-
}
|
|
622
|
-
return parentSubjects.get(scopedKey);
|
|
623
|
-
}
|
|
624
|
-
/** Get the RxJS Subject for a domain event type on this scoped bus. */
|
|
625
|
-
getDomainEvent(eventType) {
|
|
626
|
-
return this.get(eventType);
|
|
627
|
-
}
|
|
628
|
-
/**
|
|
629
|
-
* Create a nested scope
|
|
630
|
-
*
|
|
631
|
-
* Allows hierarchical scoping like `resource-1:subsystem-a`
|
|
632
|
-
*
|
|
633
|
-
* @param subScope - Additional scope level
|
|
634
|
-
* @returns A nested scoped event bus
|
|
635
|
-
*/
|
|
636
|
-
scope(subScope) {
|
|
637
|
-
return new _ScopedEventBus(this.parent, `${this.scopePrefix}:${subScope}`);
|
|
638
|
-
}
|
|
639
|
-
};
|
|
640
324
|
function burstBuffer(options) {
|
|
641
325
|
const { burstWindowMs, maxBatchSize, idleTimeoutMs } = options;
|
|
642
326
|
return (source) => new Observable((subscriber) => {
|
|
@@ -781,8 +465,21 @@ function findBodyItem(body, identity) {
|
|
|
781
465
|
}
|
|
782
466
|
|
|
783
467
|
// src/id-generation.ts
|
|
468
|
+
function v4Bytes() {
|
|
469
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
470
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
471
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
472
|
+
return bytes;
|
|
473
|
+
}
|
|
474
|
+
function hex(bytes) {
|
|
475
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
476
|
+
}
|
|
784
477
|
function generateUuid() {
|
|
785
|
-
return
|
|
478
|
+
return hex(v4Bytes());
|
|
479
|
+
}
|
|
480
|
+
function uuidV4() {
|
|
481
|
+
const h = hex(v4Bytes());
|
|
482
|
+
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;
|
|
786
483
|
}
|
|
787
484
|
|
|
788
485
|
// src/annotation-assembly.ts
|
|
@@ -1057,6 +754,136 @@ function getPageFromFragment(fragment) {
|
|
|
1057
754
|
return match ? parseInt(match[1], 10) : null;
|
|
1058
755
|
}
|
|
1059
756
|
|
|
757
|
+
// src/pdf-anchoring.ts
|
|
758
|
+
function isTextRun(item) {
|
|
759
|
+
return typeof item === "object" && item !== null && "str" in item;
|
|
760
|
+
}
|
|
761
|
+
function anchorRuns(runs, page) {
|
|
762
|
+
const items = [];
|
|
763
|
+
let text = "";
|
|
764
|
+
for (const run of runs) {
|
|
765
|
+
if (run.str.trim()) {
|
|
766
|
+
const start = text.length;
|
|
767
|
+
text += run.str;
|
|
768
|
+
const end = text.length;
|
|
769
|
+
const [, , , , x, y] = run.transform;
|
|
770
|
+
items.push({ start, end, page, x, y, width: run.width, height: run.height });
|
|
771
|
+
text += run.hasEOL ? "\n" : " ";
|
|
772
|
+
} else if (run.hasEOL) {
|
|
773
|
+
text += "\n";
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
return { text, items };
|
|
777
|
+
}
|
|
778
|
+
var SAME_LINE_THRESHOLD_PT = 2;
|
|
779
|
+
function locate(anchored, start, end) {
|
|
780
|
+
const overlap = anchored.items.filter(
|
|
781
|
+
(item) => item.start < end && item.end > start
|
|
782
|
+
);
|
|
783
|
+
if (overlap.length === 0) return { rects: [], overlap };
|
|
784
|
+
const pages = groupItemsByPage(overlap);
|
|
785
|
+
const rects = [];
|
|
786
|
+
for (const [page, pageItems] of pages) {
|
|
787
|
+
const lines = groupItemsByLine(pageItems, SAME_LINE_THRESHOLD_PT);
|
|
788
|
+
for (const lineItems of lines) {
|
|
789
|
+
const edges = lineItems.map((i) => {
|
|
790
|
+
const chars = i.end - i.start;
|
|
791
|
+
const left = i.start < start && chars > 0 ? i.x + i.width * ((start - i.start) / chars) : i.x;
|
|
792
|
+
const right2 = i.end > end && chars > 0 ? i.x + i.width * ((end - i.start) / chars) : i.x + i.width;
|
|
793
|
+
return { left, right: right2 };
|
|
794
|
+
});
|
|
795
|
+
const x = Math.min(...edges.map((e) => e.left));
|
|
796
|
+
const right = Math.max(...edges.map((e) => e.right));
|
|
797
|
+
const y = Math.min(...lineItems.map((i) => i.y));
|
|
798
|
+
const top = Math.max(...lineItems.map((i) => i.y + i.height));
|
|
799
|
+
rects.push({ page, x, y, width: right - x, height: top - y });
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
return { rects, overlap };
|
|
803
|
+
}
|
|
804
|
+
function textUnder(anchored, rect) {
|
|
805
|
+
const covered = anchored.items.filter((item) => item.page === rect.page && covers(item, rect)).sort((a, b) => a.start - b.start);
|
|
806
|
+
if (covered.length === 0) return "";
|
|
807
|
+
let quoted = slice(anchored, covered[0]);
|
|
808
|
+
for (let i = 1; i < covered.length; i++) {
|
|
809
|
+
const gap = anchored.text.slice(covered[i - 1].end, covered[i].start);
|
|
810
|
+
quoted += (gap.trim() === "" ? gap : " ") + slice(anchored, covered[i]);
|
|
811
|
+
}
|
|
812
|
+
return quoted.trim();
|
|
813
|
+
}
|
|
814
|
+
var slice = (anchored, item) => anchored.text.slice(item.start, item.end);
|
|
815
|
+
var RUN_COVERAGE_THRESHOLD = 0.5;
|
|
816
|
+
function covers(item, rect) {
|
|
817
|
+
const overlapX = Math.min(item.x + item.width, rect.x + rect.width) - Math.max(item.x, rect.x);
|
|
818
|
+
const overlapY = Math.min(item.y + item.height, rect.y + rect.height) - Math.max(item.y, rect.y);
|
|
819
|
+
if (overlapX <= 0 || overlapY <= 0) return false;
|
|
820
|
+
return overlapX * overlapY >= RUN_COVERAGE_THRESHOLD * item.width * item.height;
|
|
821
|
+
}
|
|
822
|
+
function groupItemsByPage(items) {
|
|
823
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
824
|
+
for (const item of items) {
|
|
825
|
+
const existing = map2.get(item.page);
|
|
826
|
+
if (existing) {
|
|
827
|
+
existing.push(item);
|
|
828
|
+
} else {
|
|
829
|
+
map2.set(item.page, [item]);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
return map2;
|
|
833
|
+
}
|
|
834
|
+
function groupItemsByLine(items, sameLineThreshold) {
|
|
835
|
+
const sorted = [...items].sort((a, b) => b.y - a.y || a.x - b.x);
|
|
836
|
+
const lines = [];
|
|
837
|
+
let currentLine = [];
|
|
838
|
+
for (const item of sorted) {
|
|
839
|
+
if (currentLine.length === 0 || Math.abs(item.y - currentLine[0].y) <= sameLineThreshold) {
|
|
840
|
+
currentLine.push(item);
|
|
841
|
+
} else {
|
|
842
|
+
lines.push(currentLine);
|
|
843
|
+
currentLine = [item];
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
if (currentLine.length > 0) lines.push(currentLine);
|
|
847
|
+
return lines;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// src/pdf-citation-search.ts
|
|
851
|
+
var BREAK_MARKER = "";
|
|
852
|
+
var BREAK_GAP = `(?: ?${BREAK_MARKER} ?)?`;
|
|
853
|
+
var escapeRegExp = (ch) => ch.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
854
|
+
function findClaimSpan(anchored, exact) {
|
|
855
|
+
const needle = exact.replace(/\s+/g, " ").trim();
|
|
856
|
+
if (needle.length === 0) return null;
|
|
857
|
+
let norm = "";
|
|
858
|
+
const map2 = [];
|
|
859
|
+
let pendingWsAt = -1;
|
|
860
|
+
for (let i = 0; i < anchored.text.length; i++) {
|
|
861
|
+
const ch = anchored.text[i];
|
|
862
|
+
if (/\s/.test(ch)) {
|
|
863
|
+
if (norm.length > 0 && pendingWsAt < 0) pendingWsAt = i;
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
if (pendingWsAt >= 0) {
|
|
867
|
+
norm += " ";
|
|
868
|
+
map2.push(pendingWsAt);
|
|
869
|
+
pendingWsAt = -1;
|
|
870
|
+
}
|
|
871
|
+
norm += ch;
|
|
872
|
+
map2.push(i);
|
|
873
|
+
}
|
|
874
|
+
const idx = norm.indexOf(needle);
|
|
875
|
+
if (idx >= 0) {
|
|
876
|
+
return { start: map2[idx], end: map2[idx + needle.length - 1] + 1 };
|
|
877
|
+
}
|
|
878
|
+
const marker = anchored.text.replace(/\n/g, BREAK_MARKER);
|
|
879
|
+
const pattern = [...needle].map(escapeRegExp).join(BREAK_GAP);
|
|
880
|
+
const match = new RegExp(pattern).exec(marker);
|
|
881
|
+
if (match) {
|
|
882
|
+
return { start: match.index, end: match.index + match[0].length };
|
|
883
|
+
}
|
|
884
|
+
return null;
|
|
885
|
+
}
|
|
886
|
+
|
|
1060
887
|
// src/resource-utils.ts
|
|
1061
888
|
function getResourceId(resource) {
|
|
1062
889
|
if (!resource) return void 0;
|
|
@@ -1172,7 +999,7 @@ var BusRequestError = class extends SemiontError {
|
|
|
1172
999
|
}
|
|
1173
1000
|
};
|
|
1174
1001
|
async function busRequest(bus, operation, payload, timeoutMs = 3e4) {
|
|
1175
|
-
const correlationId =
|
|
1002
|
+
const correlationId = uuidV4();
|
|
1176
1003
|
const fullPayload = { ...payload, correlationId };
|
|
1177
1004
|
const { result: resultChannel, failure: failureChannel } = BUS_OPERATIONS[operation];
|
|
1178
1005
|
const result$ = merge(
|
|
@@ -1891,7 +1718,8 @@ var storedBinary = (extension, label) => ({
|
|
|
1891
1718
|
anchoring: "none",
|
|
1892
1719
|
extractText: "none",
|
|
1893
1720
|
authorable: false,
|
|
1894
|
-
uploadable: true
|
|
1721
|
+
uploadable: true,
|
|
1722
|
+
generatable: false
|
|
1895
1723
|
});
|
|
1896
1724
|
var storedText = (extension, label) => ({
|
|
1897
1725
|
...storedBinary(extension, label),
|
|
@@ -1899,13 +1727,15 @@ var storedText = (extension, label) => ({
|
|
|
1899
1727
|
});
|
|
1900
1728
|
var MEDIA_TYPES = {
|
|
1901
1729
|
// Full-capability tier
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
"text/
|
|
1905
|
-
"
|
|
1906
|
-
"
|
|
1907
|
-
"
|
|
1908
|
-
"
|
|
1730
|
+
// `generatable: application/pdf` — the Typst renderer (PDF-GENERATION P3):
|
|
1731
|
+
// the model writes Typst, the worker's pinned binary compiles it.
|
|
1732
|
+
"text/markdown": { extension: ".md", label: "Markdown", render: "text", anchoring: "text-selector", extractText: "decode", authorable: true, uploadable: true, generatable: true },
|
|
1733
|
+
"text/plain": { extension: ".txt", label: "Plain Text", render: "text", anchoring: "text-selector", extractText: "decode", authorable: true, uploadable: true, generatable: true },
|
|
1734
|
+
"text/html": { extension: ".html", label: "HTML", render: "text", anchoring: "text-selector", extractText: "decode", authorable: true, uploadable: true, generatable: false },
|
|
1735
|
+
"application/json": { extension: ".json", label: "JSON", render: "text", anchoring: "text-selector", extractText: "decode", authorable: false, uploadable: true, generatable: false },
|
|
1736
|
+
"image/png": { extension: ".png", label: "PNG image", render: "image", anchoring: "spatial", extractText: "none", authorable: false, uploadable: true, generatable: false },
|
|
1737
|
+
"image/jpeg": { extension: ".jpg", label: "JPEG image", render: "image", anchoring: "spatial", extractText: "none", authorable: false, uploadable: true, generatable: false },
|
|
1738
|
+
"application/pdf": { extension: ".pdf", label: "PDF", render: "pdf", anchoring: "spatial", extractText: "pdf-text-layer", authorable: false, uploadable: true, generatable: true },
|
|
1909
1739
|
// Storage tier — the big tent. Every row is a deliberate admission,
|
|
1910
1740
|
// promotable by editing its row. Text-flavored rows embed (decode).
|
|
1911
1741
|
// Text
|
|
@@ -2019,6 +1849,53 @@ var AUTHORABLE_MEDIA_TYPES = REGISTRY_KEYS.filter(
|
|
|
2019
1849
|
var EMBEDDABLE_MEDIA_TYPES = REGISTRY_KEYS.filter(
|
|
2020
1850
|
(type) => MEDIA_TYPES[type].extractText !== "none"
|
|
2021
1851
|
);
|
|
1852
|
+
var GENERATABLE_MEDIA_TYPES = REGISTRY_KEYS.filter(
|
|
1853
|
+
(type) => MEDIA_TYPES[type].generatable
|
|
1854
|
+
);
|
|
1855
|
+
|
|
1856
|
+
// src/chunking.ts
|
|
1857
|
+
var DEFAULT_CHUNKING_CONFIG = {
|
|
1858
|
+
chunkSize: 512,
|
|
1859
|
+
overlap: 64
|
|
1860
|
+
};
|
|
1861
|
+
function estimateTokens(text) {
|
|
1862
|
+
return Math.ceil(text.length / 4);
|
|
1863
|
+
}
|
|
1864
|
+
function chunkText(text, config = DEFAULT_CHUNKING_CONFIG) {
|
|
1865
|
+
if (text.length === 0) return [];
|
|
1866
|
+
const totalTokens = estimateTokens(text);
|
|
1867
|
+
if (totalTokens <= config.chunkSize) {
|
|
1868
|
+
return [text];
|
|
1869
|
+
}
|
|
1870
|
+
const chunkChars = config.chunkSize * 4;
|
|
1871
|
+
const overlapChars = config.overlap * 4;
|
|
1872
|
+
const chunks = [];
|
|
1873
|
+
let start = 0;
|
|
1874
|
+
while (start < text.length) {
|
|
1875
|
+
let end = Math.min(start + chunkChars, text.length);
|
|
1876
|
+
if (end < text.length) {
|
|
1877
|
+
const paraBreak = text.lastIndexOf("\n\n", end);
|
|
1878
|
+
if (paraBreak > start + chunkChars / 2) {
|
|
1879
|
+
end = paraBreak;
|
|
1880
|
+
} else {
|
|
1881
|
+
const sentenceBreak = text.lastIndexOf(". ", end);
|
|
1882
|
+
if (sentenceBreak > start + chunkChars / 2) {
|
|
1883
|
+
end = sentenceBreak + 1;
|
|
1884
|
+
} else {
|
|
1885
|
+
const wordBreak = text.lastIndexOf(" ", end);
|
|
1886
|
+
if (wordBreak > start + chunkChars / 2) {
|
|
1887
|
+
end = wordBreak;
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
chunks.push(text.slice(start, end).trim());
|
|
1893
|
+
const nextStart = end - overlapChars;
|
|
1894
|
+
start = nextStart > start ? nextStart : end;
|
|
1895
|
+
if (start >= text.length) break;
|
|
1896
|
+
}
|
|
1897
|
+
return chunks.filter((c) => c.length > 0);
|
|
1898
|
+
}
|
|
2022
1899
|
|
|
2023
1900
|
// src/type-guards.ts
|
|
2024
1901
|
function isString(value) {
|
|
@@ -2112,292 +1989,6 @@ function didToAgent(did) {
|
|
|
2112
1989
|
name: decodeURIComponent(encoded)
|
|
2113
1990
|
};
|
|
2114
1991
|
}
|
|
2115
|
-
function deepMerge(base, override) {
|
|
2116
|
-
const result = { ...base };
|
|
2117
|
-
for (const key of Object.keys(override)) {
|
|
2118
|
-
const b = base[key];
|
|
2119
|
-
const o = override[key];
|
|
2120
|
-
if (o !== void 0 && o !== null && typeof o === "object" && !Array.isArray(o) && b !== void 0 && b !== null && typeof b === "object" && !Array.isArray(b)) {
|
|
2121
|
-
result[key] = deepMerge(b, o);
|
|
2122
|
-
} else if (o !== void 0) {
|
|
2123
|
-
result[key] = o;
|
|
2124
|
-
}
|
|
2125
|
-
}
|
|
2126
|
-
return result;
|
|
2127
|
-
}
|
|
2128
|
-
function resolveEnvVars(obj, env) {
|
|
2129
|
-
if (typeof obj === "string") {
|
|
2130
|
-
return obj.replace(/\$\{([^}]+)\}/g, (match, expr) => {
|
|
2131
|
-
const sepIdx = expr.indexOf(":-");
|
|
2132
|
-
const varName = sepIdx >= 0 ? expr.slice(0, sepIdx) : expr;
|
|
2133
|
-
const defaultValue = sepIdx >= 0 ? expr.slice(sepIdx + 2) : void 0;
|
|
2134
|
-
const value = env[varName];
|
|
2135
|
-
if (value !== void 0) return value;
|
|
2136
|
-
if (defaultValue !== void 0) return defaultValue;
|
|
2137
|
-
throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);
|
|
2138
|
-
});
|
|
2139
|
-
}
|
|
2140
|
-
if (Array.isArray(obj)) {
|
|
2141
|
-
return obj.map((item) => resolveEnvVars(item, env));
|
|
2142
|
-
}
|
|
2143
|
-
if (obj !== null && typeof obj === "object") {
|
|
2144
|
-
const resolved = {};
|
|
2145
|
-
for (const key in obj) {
|
|
2146
|
-
resolved[key] = resolveEnvVars(obj[key], env);
|
|
2147
|
-
}
|
|
2148
|
-
return resolved;
|
|
2149
|
-
}
|
|
2150
|
-
return obj;
|
|
2151
|
-
}
|
|
2152
|
-
function requirePlatform(value, serviceName) {
|
|
2153
|
-
if (!value) {
|
|
2154
|
-
throw new Error(`platform is required for service '${serviceName}' \u2014 add 'platform = "posix"|"container"|"external"' to its config section`);
|
|
2155
|
-
}
|
|
2156
|
-
return value;
|
|
2157
|
-
}
|
|
2158
|
-
function loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env) {
|
|
2159
|
-
const projectConfigContent = projectRoot ? reader.readIfExists(`${projectRoot}/.semiont/config`) : null;
|
|
2160
|
-
const projectConfig = projectConfigContent ? parse(projectConfigContent) : void 0;
|
|
2161
|
-
const projectName = projectConfig?.project?.name ?? "semiont-project";
|
|
2162
|
-
const projectVersion = projectConfig?.project?.version;
|
|
2163
|
-
const projectSite = projectConfig?.site;
|
|
2164
|
-
const globalContent = reader.readIfExists(globalConfigPath);
|
|
2165
|
-
const raw = globalContent ? parse(globalContent) : {};
|
|
2166
|
-
const resolvedEnvironment = environment ?? env.SEMIONT_ENV ?? raw.defaults?.environment;
|
|
2167
|
-
if (!resolvedEnvironment) {
|
|
2168
|
-
throw new Error(
|
|
2169
|
-
"No environment selected: pass one explicitly, set SEMIONT_ENV, or declare `[defaults] environment` in ~/.semiontconfig."
|
|
2170
|
-
);
|
|
2171
|
-
}
|
|
2172
|
-
const projectHasSection = projectConfig?.environments != null && resolvedEnvironment in projectConfig.environments;
|
|
2173
|
-
const globalHasSection = raw.environments != null && resolvedEnvironment in raw.environments;
|
|
2174
|
-
if (!projectHasSection && !globalHasSection) {
|
|
2175
|
-
throw new Error(
|
|
2176
|
-
`Environment "${resolvedEnvironment}" is selected but no [environments.${resolvedEnvironment}] section exists in the project (.semiont/config) or global (~/.semiontconfig) config. Declare the section, or select an environment that exists.`
|
|
2177
|
-
);
|
|
2178
|
-
}
|
|
2179
|
-
const projectEnvSection = projectConfig?.environments?.[resolvedEnvironment] ?? {};
|
|
2180
|
-
const userEnvSection = raw.environments?.[resolvedEnvironment] ?? {};
|
|
2181
|
-
const envSection = deepMerge(
|
|
2182
|
-
projectEnvSection,
|
|
2183
|
-
userEnvSection
|
|
2184
|
-
);
|
|
2185
|
-
const resolved = resolveEnvVars(envSection, env);
|
|
2186
|
-
const flatInference = resolved.inference;
|
|
2187
|
-
const makeMeaningSection = resolved["make-meaning"];
|
|
2188
|
-
const workersSection = resolved.workers ?? {};
|
|
2189
|
-
const actorsSection = resolved.actors ?? {};
|
|
2190
|
-
const defaultWorkerInference = workersSection["default"]?.inference;
|
|
2191
|
-
const defaultMakeMeaningInference = makeMeaningSection?.default?.inference;
|
|
2192
|
-
function mergeWithFlatInference(specific) {
|
|
2193
|
-
if (!flatInference) return specific;
|
|
2194
|
-
const providerDefaults = {};
|
|
2195
|
-
if (specific.type === "anthropic") {
|
|
2196
|
-
const a = flatInference.anthropic;
|
|
2197
|
-
if (a) {
|
|
2198
|
-
providerDefaults.apiKey = a.apiKey;
|
|
2199
|
-
providerDefaults.endpoint = a.endpoint;
|
|
2200
|
-
} else {
|
|
2201
|
-
if (!flatInference.type) {
|
|
2202
|
-
throw new Error(
|
|
2203
|
-
`[environments.${resolvedEnvironment}.inference] is missing 'type'. Add type = "anthropic" or use [inference.anthropic] sub-section.`
|
|
2204
|
-
);
|
|
2205
|
-
}
|
|
2206
|
-
providerDefaults.apiKey = flatInference.apiKey;
|
|
2207
|
-
providerDefaults.endpoint = flatInference.endpoint;
|
|
2208
|
-
}
|
|
2209
|
-
} else if (specific.type === "ollama") {
|
|
2210
|
-
const o = flatInference.ollama;
|
|
2211
|
-
if (o) {
|
|
2212
|
-
providerDefaults.baseURL = o.baseURL;
|
|
2213
|
-
} else {
|
|
2214
|
-
if (!flatInference.type) {
|
|
2215
|
-
throw new Error(
|
|
2216
|
-
`[environments.${resolvedEnvironment}.inference] is missing 'type'. Add type = "ollama" or use [inference.ollama] sub-section.`
|
|
2217
|
-
);
|
|
2218
|
-
}
|
|
2219
|
-
providerDefaults.baseURL = flatInference.baseURL;
|
|
2220
|
-
}
|
|
2221
|
-
}
|
|
2222
|
-
return {
|
|
2223
|
-
maxTokens: flatInference.maxTokens,
|
|
2224
|
-
...providerDefaults,
|
|
2225
|
-
...specific
|
|
2226
|
-
};
|
|
2227
|
-
}
|
|
2228
|
-
function resolveActorInference(fromMakeMeaning, fromActors) {
|
|
2229
|
-
const base = fromMakeMeaning ?? fromActors ?? defaultMakeMeaningInference;
|
|
2230
|
-
if (!base) return void 0;
|
|
2231
|
-
return mergeWithFlatInference(base);
|
|
2232
|
-
}
|
|
2233
|
-
const actors = {};
|
|
2234
|
-
const gathererInference = resolveActorInference(
|
|
2235
|
-
makeMeaningSection?.actors?.gatherer?.inference,
|
|
2236
|
-
actorsSection["gatherer"]?.inference
|
|
2237
|
-
);
|
|
2238
|
-
if (gathererInference) actors.gatherer = gathererInference;
|
|
2239
|
-
const matcherInference = resolveActorInference(
|
|
2240
|
-
makeMeaningSection?.actors?.matcher?.inference,
|
|
2241
|
-
actorsSection["matcher"]?.inference
|
|
2242
|
-
);
|
|
2243
|
-
if (matcherInference) actors.matcher = matcherInference;
|
|
2244
|
-
const workers = {};
|
|
2245
|
-
const workerTypes = ["reference-annotation", "highlight-annotation", "assessment-annotation", "comment-annotation", "tag-annotation", "generation"];
|
|
2246
|
-
if (defaultWorkerInference) {
|
|
2247
|
-
workers.default = mergeWithFlatInference(defaultWorkerInference);
|
|
2248
|
-
}
|
|
2249
|
-
for (const wt of workerTypes) {
|
|
2250
|
-
const specific = workersSection[wt]?.inference;
|
|
2251
|
-
if (specific) {
|
|
2252
|
-
workers[wt] = mergeWithFlatInference(specific);
|
|
2253
|
-
}
|
|
2254
|
-
}
|
|
2255
|
-
const backend = resolved.backend;
|
|
2256
|
-
const site = resolved.site ?? projectSite;
|
|
2257
|
-
const inferenceSection = resolved.inference;
|
|
2258
|
-
let inferenceProviders;
|
|
2259
|
-
if (inferenceSection) {
|
|
2260
|
-
inferenceProviders = {};
|
|
2261
|
-
if (inferenceSection.anthropic) {
|
|
2262
|
-
const a = inferenceSection.anthropic;
|
|
2263
|
-
inferenceProviders.anthropic = {
|
|
2264
|
-
platform: requirePlatform(a.platform, "inference.anthropic"),
|
|
2265
|
-
endpoint: a.endpoint ?? "https://api.anthropic.com",
|
|
2266
|
-
apiKey: a.apiKey ?? ""
|
|
2267
|
-
};
|
|
2268
|
-
} else if (inferenceSection.type === "anthropic") {
|
|
2269
|
-
inferenceProviders.anthropic = {
|
|
2270
|
-
platform: requirePlatform(inferenceSection.platform, "inference"),
|
|
2271
|
-
endpoint: inferenceSection.endpoint ?? "https://api.anthropic.com",
|
|
2272
|
-
apiKey: inferenceSection.apiKey ?? ""
|
|
2273
|
-
};
|
|
2274
|
-
}
|
|
2275
|
-
if (inferenceSection.ollama) {
|
|
2276
|
-
const o = inferenceSection.ollama;
|
|
2277
|
-
inferenceProviders.ollama = {
|
|
2278
|
-
platform: { type: requirePlatform(o.platform, "inference.ollama") },
|
|
2279
|
-
baseURL: o.baseURL,
|
|
2280
|
-
port: o.baseURL ? void 0 : o.port ?? 11434
|
|
2281
|
-
};
|
|
2282
|
-
} else if (inferenceSection.type === "ollama") {
|
|
2283
|
-
inferenceProviders.ollama = {
|
|
2284
|
-
platform: { type: requirePlatform(inferenceSection.platform, "inference") },
|
|
2285
|
-
baseURL: inferenceSection.baseURL,
|
|
2286
|
-
port: inferenceSection.baseURL ? void 0 : 11434
|
|
2287
|
-
};
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
const topLevelWorkers = {};
|
|
2291
|
-
for (const [name, w] of Object.entries(workersSection)) {
|
|
2292
|
-
if (w.inference) {
|
|
2293
|
-
topLevelWorkers[name] = { inference: { type: w.inference.type, model: w.inference.model } };
|
|
2294
|
-
}
|
|
2295
|
-
}
|
|
2296
|
-
const topLevelActors = {};
|
|
2297
|
-
for (const [name, a] of Object.entries(actorsSection)) {
|
|
2298
|
-
if (a.inference) {
|
|
2299
|
-
topLevelActors[name] = { inference: { type: a.inference.type, model: a.inference.model } };
|
|
2300
|
-
}
|
|
2301
|
-
}
|
|
2302
|
-
if (makeMeaningSection?.actors?.gatherer?.inference) {
|
|
2303
|
-
topLevelActors["gatherer"] = { inference: { type: makeMeaningSection.actors.gatherer.inference.type, model: makeMeaningSection.actors.gatherer.inference.model } };
|
|
2304
|
-
}
|
|
2305
|
-
if (makeMeaningSection?.actors?.matcher?.inference) {
|
|
2306
|
-
topLevelActors["matcher"] = { inference: { type: makeMeaningSection.actors.matcher.inference.type, model: makeMeaningSection.actors.matcher.inference.model } };
|
|
2307
|
-
}
|
|
2308
|
-
const frontend = resolved.frontend;
|
|
2309
|
-
const services = {};
|
|
2310
|
-
if (backend) {
|
|
2311
|
-
services.backend = {
|
|
2312
|
-
platform: { type: requirePlatform(backend.platform, "backend") },
|
|
2313
|
-
port: backend.port ?? 4e3,
|
|
2314
|
-
publicURL: backend.publicURL ?? `http://localhost:${backend.port ?? 4e3}`
|
|
2315
|
-
};
|
|
2316
|
-
}
|
|
2317
|
-
if (frontend) {
|
|
2318
|
-
services.frontend = {
|
|
2319
|
-
platform: { type: requirePlatform(frontend.platform, "frontend") },
|
|
2320
|
-
port: frontend.port ?? 3e3,
|
|
2321
|
-
siteName: site?.siteName ?? "Semiont",
|
|
2322
|
-
publicURL: frontend.publicURL
|
|
2323
|
-
};
|
|
2324
|
-
}
|
|
2325
|
-
if (resolved.graph) {
|
|
2326
|
-
services.graph = {
|
|
2327
|
-
...resolved.graph,
|
|
2328
|
-
platform: { type: requirePlatform(resolved.graph.platform, "graph") },
|
|
2329
|
-
type: resolved.graph.type ?? "neo4j"
|
|
2330
|
-
};
|
|
2331
|
-
} else if (makeMeaningSection?.graph) {
|
|
2332
|
-
services.graph = makeMeaningSection.graph;
|
|
2333
|
-
}
|
|
2334
|
-
if (resolved.database) {
|
|
2335
|
-
services.database = {
|
|
2336
|
-
platform: { type: requirePlatform(resolved.database.platform, "database") },
|
|
2337
|
-
type: "postgres",
|
|
2338
|
-
image: resolved.database.image,
|
|
2339
|
-
host: resolved.database.host ?? "localhost",
|
|
2340
|
-
port: resolved.database.port ?? 5432,
|
|
2341
|
-
name: resolved.database.name,
|
|
2342
|
-
user: resolved.database.user,
|
|
2343
|
-
password: resolved.database.password
|
|
2344
|
-
};
|
|
2345
|
-
}
|
|
2346
|
-
if (resolved.vectors) {
|
|
2347
|
-
services.vectors = {
|
|
2348
|
-
platform: { type: "external" },
|
|
2349
|
-
type: resolved.vectors.type ?? "qdrant",
|
|
2350
|
-
host: resolved.vectors.host,
|
|
2351
|
-
port: resolved.vectors.port ?? 6333
|
|
2352
|
-
};
|
|
2353
|
-
}
|
|
2354
|
-
const embeddingSource = resolved.embedding ?? resolved.vectors?.embedding;
|
|
2355
|
-
if (embeddingSource) {
|
|
2356
|
-
services.embedding = {
|
|
2357
|
-
platform: { type: "external" },
|
|
2358
|
-
type: embeddingSource.type,
|
|
2359
|
-
model: embeddingSource.model,
|
|
2360
|
-
apiKey: embeddingSource.apiKey,
|
|
2361
|
-
baseURL: embeddingSource.baseURL,
|
|
2362
|
-
endpoint: embeddingSource.endpoint,
|
|
2363
|
-
chunking: resolved.embedding?.chunking ?? resolved.vectors?.chunking ? {
|
|
2364
|
-
chunkSize: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.chunkSize ?? 512,
|
|
2365
|
-
overlap: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.overlap ?? 64
|
|
2366
|
-
} : void 0
|
|
2367
|
-
};
|
|
2368
|
-
}
|
|
2369
|
-
const config = {
|
|
2370
|
-
services,
|
|
2371
|
-
...inferenceProviders ? { inference: inferenceProviders } : {},
|
|
2372
|
-
...Object.keys(topLevelWorkers).length > 0 ? { workers: topLevelWorkers } : {},
|
|
2373
|
-
...Object.keys(topLevelActors).length > 0 ? { actors: topLevelActors } : {},
|
|
2374
|
-
site: site ? {
|
|
2375
|
-
domain: site.domain ?? "localhost",
|
|
2376
|
-
siteName: site.siteName,
|
|
2377
|
-
adminEmail: site.adminEmail,
|
|
2378
|
-
oauthAllowedDomains: site.oauthAllowedDomains
|
|
2379
|
-
} : void 0,
|
|
2380
|
-
logLevel: resolved.logLevel,
|
|
2381
|
-
_metadata: {
|
|
2382
|
-
environment: resolvedEnvironment,
|
|
2383
|
-
projectRoot,
|
|
2384
|
-
projectName,
|
|
2385
|
-
projectVersion,
|
|
2386
|
-
...Object.keys(actors).length > 0 ? { actors } : {},
|
|
2387
|
-
...Object.keys(workers).length > 0 ? { workers } : {},
|
|
2388
|
-
// Always set — the loader is the ONE home of this default (D5).
|
|
2389
|
-
// Consuming code (make-meaning's gather path) receives a required
|
|
2390
|
-
// value and defaults nothing.
|
|
2391
|
-
gather: { settleTimeoutMs: makeMeaningSection?.gather?.settleTimeoutMs ?? 15e3 }
|
|
2392
|
-
}
|
|
2393
|
-
};
|
|
2394
|
-
return config;
|
|
2395
|
-
}
|
|
2396
|
-
function createTomlConfigLoader(reader, globalConfigPath, env) {
|
|
2397
|
-
return (projectRoot, environment) => {
|
|
2398
|
-
return loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env);
|
|
2399
|
-
};
|
|
2400
|
-
}
|
|
2401
1992
|
|
|
2402
1993
|
// src/config/environment-validator.ts
|
|
2403
1994
|
function isValidEnvironment(value, availableEnvironments) {
|
|
@@ -2520,9 +2111,36 @@ async function retryWithBackoff(fn, isRetryable, policy, onRetry) {
|
|
|
2520
2111
|
}
|
|
2521
2112
|
}
|
|
2522
2113
|
|
|
2114
|
+
// src/shard-utils.ts
|
|
2115
|
+
function jumpConsistentHash(key, numBuckets = 65536) {
|
|
2116
|
+
const hash = hashToUint32(key);
|
|
2117
|
+
return hash % numBuckets;
|
|
2118
|
+
}
|
|
2119
|
+
function hashToUint32(str) {
|
|
2120
|
+
let hash = 0;
|
|
2121
|
+
for (let i = 0; i < str.length; i++) {
|
|
2122
|
+
hash = (hash << 5) - hash + str.charCodeAt(i);
|
|
2123
|
+
hash = hash & 4294967295;
|
|
2124
|
+
}
|
|
2125
|
+
return Math.abs(hash);
|
|
2126
|
+
}
|
|
2127
|
+
function shardIdToPath(shardId) {
|
|
2128
|
+
if (shardId < 0 || shardId >= 65536) {
|
|
2129
|
+
throw new Error(`Invalid shard ID: ${shardId}. Must be 0-65535 for 4-hex sharding.`);
|
|
2130
|
+
}
|
|
2131
|
+
const shardHex = shardId.toString(16).padStart(4, "0");
|
|
2132
|
+
const ab = shardHex.substring(0, 2);
|
|
2133
|
+
const cd = shardHex.substring(2, 4);
|
|
2134
|
+
return [ab, cd];
|
|
2135
|
+
}
|
|
2136
|
+
function getShardPath(key, numBuckets = 65536) {
|
|
2137
|
+
const shardId = jumpConsistentHash(key, numBuckets);
|
|
2138
|
+
return shardIdToPath(shardId);
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2523
2141
|
// src/discovery.ts
|
|
2524
2142
|
var DISCOVERY_URL_PATH = "/discovery/kbs.json";
|
|
2525
2143
|
|
|
2526
|
-
export { AUTHORABLE_MEDIA_TYPES,
|
|
2144
|
+
export { AUTHORABLE_MEDIA_TYPES, BusRequestError, CHANNEL_SCHEMAS, CONTEXT_FULL_WEIGHT, CONTEXT_PARTIAL_WEIGHT, ConfigurationError, ConflictError, DEFAULT_CHUNKING_CONFIG, DISCOVERY_URL_PATH, EMBEDDABLE_MEDIA_TYPES, GENERATABLE_MEDIA_TYPES, JWTTokenSchema, LOCALES, MEDIA_TYPES, NotFoundError, PERSISTED_EVENT_TYPES, POSITION_WEIGHT_MAX, POSITION_WINDOW, RESOURCE_BROADCAST_TYPES, STARTUP_FETCH_RETRY, ScriptError, SemiontError, UnauthorizedError, ValidationError, agentToDid, anchorAnnotation, anchorRuns, annotationId, applyBodyOperations, assembleAnnotation, baseMediaType, buildContentCache, burstBuffer, busRequest, capabilitiesOf, chunkText, createCircleSvg, createFragmentSelector, createPolygonSvg, createRectangleSvg, decodeRepresentation, decodeWithCharset, deriveViews, didToAgent, errField, estimateTokens, extensionForMediaType, extractBoundingBox, extractCharset, extractContext, findBestTextMatch, findBodyItem, findClaimSpan, formatLocaleDisplay, generateUuid, getAllLocaleCodes, getAllPlatformTypes, getAnnotationExactText, getAnnotationUriFromEvent, getBodySource, getBodyType, getChecksum, getCommentText, getCreator, getDerivedFrom, getExactText, getFragmentSelector, getLanguage, getLocaleEnglishName, getLocaleInfo, getLocaleNativeName, getNodeEncoding, getPageFromFragment, getPrimaryMediaType, getPrimaryRepresentation, getPrimarySelector, getResourceEntityTypes, getResourceId, getShardPath, getStorageUri, getSvgSelector, getTargetSelector, getTargetSource, getTextPositionSelector, getTextQuoteSelector, hasTargetSelector, isAnnotationId, isArchived, isArray, isAssessment, isBodyResolved, isBoolean, isComment, isDefined, isDraft, isEventRelatedToAnnotation, isFunction, isHighlight, isNull, isNullish, isNumber, isObject, isReference, isResolvedReference, isResourceId, isStoredEvent, isString, isStubReference, isSupportedMediaType, isTag, isTextRun, isTransientFetchError, isUndefined, isValidEmail, isValidPlatformType, jumpConsistentHash, kbDid, locate, mediaTypeForExtension, normalizeCoordinates, normalizeText, parseEnvironment, parseFragmentSelector, parseSvgSelector, reconcileSelector, resourceId, retryWithBackoff, scaleSvgToNative, serializePerKey, softwareToAgent, textExtractionOf, textUnder, userId, userToAgent, userToDid, uuidV4, validateData, validateEnvironment, validateSvgMarkup, verifyPosition };
|
|
2527
2145
|
//# sourceMappingURL=index.js.map
|
|
2528
2146
|
//# sourceMappingURL=index.js.map
|