@semiont/core 0.5.22 → 0.5.24

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/dist/index.js CHANGED
@@ -1,65 +1,8 @@
1
- import { Subject, Observable, merge, TimeoutError, throwError, firstValueFrom } from 'rxjs';
1
+ export { createTomlConfigLoader, loadTomlConfig } from './chunk-XQTWEBJ5.js';
2
+ import { BUS_OPERATIONS } from './chunk-4JTZMWZB.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-4JTZMWZB.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) {
@@ -369,274 +312,6 @@ function isEventRelatedToAnnotation(event, annotationUri2) {
369
312
  function isStoredEvent(event) {
370
313
  return event && typeof event.id === "string" && typeof event.timestamp === "string" && typeof event.type === "string" && typeof event.metadata === "object" && typeof event.metadata.sequenceNumber === "number";
371
314
  }
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
315
  function burstBuffer(options) {
641
316
  const { burstWindowMs, maxBatchSize, idleTimeoutMs } = options;
642
317
  return (source) => new Observable((subscriber) => {
@@ -781,8 +456,21 @@ function findBodyItem(body, identity) {
781
456
  }
782
457
 
783
458
  // src/id-generation.ts
459
+ function v4Bytes() {
460
+ const bytes = crypto.getRandomValues(new Uint8Array(16));
461
+ bytes[6] = bytes[6] & 15 | 64;
462
+ bytes[8] = bytes[8] & 63 | 128;
463
+ return bytes;
464
+ }
465
+ function hex(bytes) {
466
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
467
+ }
784
468
  function generateUuid() {
785
- return crypto.randomUUID().replace(/-/g, "");
469
+ return hex(v4Bytes());
470
+ }
471
+ function uuidV4() {
472
+ const h = hex(v4Bytes());
473
+ return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;
786
474
  }
787
475
 
788
476
  // src/annotation-assembly.ts
@@ -1172,7 +860,7 @@ var BusRequestError = class extends SemiontError {
1172
860
  }
1173
861
  };
1174
862
  async function busRequest(bus, operation, payload, timeoutMs = 3e4) {
1175
- const correlationId = crypto.randomUUID();
863
+ const correlationId = uuidV4();
1176
864
  const fullPayload = { ...payload, correlationId };
1177
865
  const { result: resultChannel, failure: failureChannel } = BUS_OPERATIONS[operation];
1178
866
  const result$ = merge(
@@ -1223,18 +911,69 @@ async function busRequest(bus, operation, payload, timeoutMs = 3e4) {
1223
911
  })
1224
912
  );
1225
913
  const resultPromise = firstValueFrom(result$);
1226
- try {
1227
- await bus.emit(operation, fullPayload);
1228
- } catch (emitError) {
914
+ const closedBeforeEmit = () => {
1229
915
  resultPromise.catch(() => {
1230
916
  });
1231
- throw emitError;
917
+ return new BusRequestError(`Bus closed before emit on ${operation}`, "bus.closed", {
918
+ channel: operation,
919
+ correlationId
920
+ });
921
+ };
922
+ let currentState;
923
+ bus.state$.subscribe((s) => {
924
+ currentState = s;
925
+ }).unsubscribe();
926
+ if (currentState === "closed") {
927
+ throw closedBeforeEmit();
928
+ }
929
+ let emitAllowed = currentState === "open";
930
+ if (!emitAllowed) {
931
+ const gate = firstValueFrom(
932
+ bus.state$.pipe(
933
+ filter((s) => s === "open" || s === "closed"),
934
+ take(1),
935
+ // `state$` completed without ever attaching: treat as closed.
936
+ defaultIfEmpty("closed")
937
+ )
938
+ );
939
+ const outcome = await Promise.race([
940
+ gate,
941
+ // Either settlement of the reply machinery means "stop waiting, never
942
+ // emit": its timeout rejecting `bus.timeout` at `timeoutMs` (the same
943
+ // moment it would fire today — D4), or its streams completing into the
944
+ // `bus.closed` default above. The shared tail below carries it.
945
+ resultPromise.then(
946
+ () => "settled",
947
+ () => "settled"
948
+ )
949
+ ]);
950
+ if (outcome === "closed") {
951
+ throw closedBeforeEmit();
952
+ }
953
+ emitAllowed = outcome === "open";
954
+ }
955
+ let releaseTracking;
956
+ if (emitAllowed) {
957
+ releaseTracking = bus.trackReply?.(correlationId);
958
+ try {
959
+ await bus.emit(operation, fullPayload);
960
+ } catch (emitError) {
961
+ releaseTracking?.();
962
+ releaseTracking = void 0;
963
+ resultPromise.catch(() => {
964
+ });
965
+ throw emitError;
966
+ }
1232
967
  }
1233
- const result = await resultPromise;
1234
- if (!result.ok) {
1235
- throw result.error;
968
+ try {
969
+ const result = await resultPromise;
970
+ if (!result.ok) {
971
+ throw result.error;
972
+ }
973
+ return result.response;
974
+ } finally {
975
+ releaseTracking?.();
1236
976
  }
1237
- return result.response;
1238
977
  }
1239
978
 
1240
979
  // src/fuzzy-anchor.ts
@@ -2061,292 +1800,6 @@ function didToAgent(did) {
2061
1800
  name: decodeURIComponent(encoded)
2062
1801
  };
2063
1802
  }
2064
- function deepMerge(base, override) {
2065
- const result = { ...base };
2066
- for (const key of Object.keys(override)) {
2067
- const b = base[key];
2068
- const o = override[key];
2069
- if (o !== void 0 && o !== null && typeof o === "object" && !Array.isArray(o) && b !== void 0 && b !== null && typeof b === "object" && !Array.isArray(b)) {
2070
- result[key] = deepMerge(b, o);
2071
- } else if (o !== void 0) {
2072
- result[key] = o;
2073
- }
2074
- }
2075
- return result;
2076
- }
2077
- function resolveEnvVars(obj, env) {
2078
- if (typeof obj === "string") {
2079
- return obj.replace(/\$\{([^}]+)\}/g, (match, expr) => {
2080
- const sepIdx = expr.indexOf(":-");
2081
- const varName = sepIdx >= 0 ? expr.slice(0, sepIdx) : expr;
2082
- const defaultValue = sepIdx >= 0 ? expr.slice(sepIdx + 2) : void 0;
2083
- const value = env[varName];
2084
- if (value !== void 0) return value;
2085
- if (defaultValue !== void 0) return defaultValue;
2086
- throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);
2087
- });
2088
- }
2089
- if (Array.isArray(obj)) {
2090
- return obj.map((item) => resolveEnvVars(item, env));
2091
- }
2092
- if (obj !== null && typeof obj === "object") {
2093
- const resolved = {};
2094
- for (const key in obj) {
2095
- resolved[key] = resolveEnvVars(obj[key], env);
2096
- }
2097
- return resolved;
2098
- }
2099
- return obj;
2100
- }
2101
- function requirePlatform(value, serviceName) {
2102
- if (!value) {
2103
- throw new Error(`platform is required for service '${serviceName}' \u2014 add 'platform = "posix"|"container"|"external"' to its config section`);
2104
- }
2105
- return value;
2106
- }
2107
- function loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env) {
2108
- const projectConfigContent = projectRoot ? reader.readIfExists(`${projectRoot}/.semiont/config`) : null;
2109
- const projectConfig = projectConfigContent ? parse(projectConfigContent) : void 0;
2110
- const projectName = projectConfig?.project?.name ?? "semiont-project";
2111
- const projectVersion = projectConfig?.project?.version;
2112
- const projectSite = projectConfig?.site;
2113
- const globalContent = reader.readIfExists(globalConfigPath);
2114
- const raw = globalContent ? parse(globalContent) : {};
2115
- const resolvedEnvironment = environment ?? env.SEMIONT_ENV ?? raw.defaults?.environment;
2116
- if (!resolvedEnvironment) {
2117
- throw new Error(
2118
- "No environment selected: pass one explicitly, set SEMIONT_ENV, or declare `[defaults] environment` in ~/.semiontconfig."
2119
- );
2120
- }
2121
- const projectHasSection = projectConfig?.environments != null && resolvedEnvironment in projectConfig.environments;
2122
- const globalHasSection = raw.environments != null && resolvedEnvironment in raw.environments;
2123
- if (!projectHasSection && !globalHasSection) {
2124
- throw new Error(
2125
- `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.`
2126
- );
2127
- }
2128
- const projectEnvSection = projectConfig?.environments?.[resolvedEnvironment] ?? {};
2129
- const userEnvSection = raw.environments?.[resolvedEnvironment] ?? {};
2130
- const envSection = deepMerge(
2131
- projectEnvSection,
2132
- userEnvSection
2133
- );
2134
- const resolved = resolveEnvVars(envSection, env);
2135
- const flatInference = resolved.inference;
2136
- const makeMeaningSection = resolved["make-meaning"];
2137
- const workersSection = resolved.workers ?? {};
2138
- const actorsSection = resolved.actors ?? {};
2139
- const defaultWorkerInference = workersSection["default"]?.inference;
2140
- const defaultMakeMeaningInference = makeMeaningSection?.default?.inference;
2141
- function mergeWithFlatInference(specific) {
2142
- if (!flatInference) return specific;
2143
- const providerDefaults = {};
2144
- if (specific.type === "anthropic") {
2145
- const a = flatInference.anthropic;
2146
- if (a) {
2147
- providerDefaults.apiKey = a.apiKey;
2148
- providerDefaults.endpoint = a.endpoint;
2149
- } else {
2150
- if (!flatInference.type) {
2151
- throw new Error(
2152
- `[environments.${resolvedEnvironment}.inference] is missing 'type'. Add type = "anthropic" or use [inference.anthropic] sub-section.`
2153
- );
2154
- }
2155
- providerDefaults.apiKey = flatInference.apiKey;
2156
- providerDefaults.endpoint = flatInference.endpoint;
2157
- }
2158
- } else if (specific.type === "ollama") {
2159
- const o = flatInference.ollama;
2160
- if (o) {
2161
- providerDefaults.baseURL = o.baseURL;
2162
- } else {
2163
- if (!flatInference.type) {
2164
- throw new Error(
2165
- `[environments.${resolvedEnvironment}.inference] is missing 'type'. Add type = "ollama" or use [inference.ollama] sub-section.`
2166
- );
2167
- }
2168
- providerDefaults.baseURL = flatInference.baseURL;
2169
- }
2170
- }
2171
- return {
2172
- maxTokens: flatInference.maxTokens,
2173
- ...providerDefaults,
2174
- ...specific
2175
- };
2176
- }
2177
- function resolveActorInference(fromMakeMeaning, fromActors) {
2178
- const base = fromMakeMeaning ?? fromActors ?? defaultMakeMeaningInference;
2179
- if (!base) return void 0;
2180
- return mergeWithFlatInference(base);
2181
- }
2182
- const actors = {};
2183
- const gathererInference = resolveActorInference(
2184
- makeMeaningSection?.actors?.gatherer?.inference,
2185
- actorsSection["gatherer"]?.inference
2186
- );
2187
- if (gathererInference) actors.gatherer = gathererInference;
2188
- const matcherInference = resolveActorInference(
2189
- makeMeaningSection?.actors?.matcher?.inference,
2190
- actorsSection["matcher"]?.inference
2191
- );
2192
- if (matcherInference) actors.matcher = matcherInference;
2193
- const workers = {};
2194
- const workerTypes = ["reference-annotation", "highlight-annotation", "assessment-annotation", "comment-annotation", "tag-annotation", "generation"];
2195
- if (defaultWorkerInference) {
2196
- workers.default = mergeWithFlatInference(defaultWorkerInference);
2197
- }
2198
- for (const wt of workerTypes) {
2199
- const specific = workersSection[wt]?.inference;
2200
- if (specific) {
2201
- workers[wt] = mergeWithFlatInference(specific);
2202
- }
2203
- }
2204
- const backend = resolved.backend;
2205
- const site = resolved.site ?? projectSite;
2206
- const inferenceSection = resolved.inference;
2207
- let inferenceProviders;
2208
- if (inferenceSection) {
2209
- inferenceProviders = {};
2210
- if (inferenceSection.anthropic) {
2211
- const a = inferenceSection.anthropic;
2212
- inferenceProviders.anthropic = {
2213
- platform: requirePlatform(a.platform, "inference.anthropic"),
2214
- endpoint: a.endpoint ?? "https://api.anthropic.com",
2215
- apiKey: a.apiKey ?? ""
2216
- };
2217
- } else if (inferenceSection.type === "anthropic") {
2218
- inferenceProviders.anthropic = {
2219
- platform: requirePlatform(inferenceSection.platform, "inference"),
2220
- endpoint: inferenceSection.endpoint ?? "https://api.anthropic.com",
2221
- apiKey: inferenceSection.apiKey ?? ""
2222
- };
2223
- }
2224
- if (inferenceSection.ollama) {
2225
- const o = inferenceSection.ollama;
2226
- inferenceProviders.ollama = {
2227
- platform: { type: requirePlatform(o.platform, "inference.ollama") },
2228
- baseURL: o.baseURL,
2229
- port: o.baseURL ? void 0 : o.port ?? 11434
2230
- };
2231
- } else if (inferenceSection.type === "ollama") {
2232
- inferenceProviders.ollama = {
2233
- platform: { type: requirePlatform(inferenceSection.platform, "inference") },
2234
- baseURL: inferenceSection.baseURL,
2235
- port: inferenceSection.baseURL ? void 0 : 11434
2236
- };
2237
- }
2238
- }
2239
- const topLevelWorkers = {};
2240
- for (const [name, w] of Object.entries(workersSection)) {
2241
- if (w.inference) {
2242
- topLevelWorkers[name] = { inference: { type: w.inference.type, model: w.inference.model } };
2243
- }
2244
- }
2245
- const topLevelActors = {};
2246
- for (const [name, a] of Object.entries(actorsSection)) {
2247
- if (a.inference) {
2248
- topLevelActors[name] = { inference: { type: a.inference.type, model: a.inference.model } };
2249
- }
2250
- }
2251
- if (makeMeaningSection?.actors?.gatherer?.inference) {
2252
- topLevelActors["gatherer"] = { inference: { type: makeMeaningSection.actors.gatherer.inference.type, model: makeMeaningSection.actors.gatherer.inference.model } };
2253
- }
2254
- if (makeMeaningSection?.actors?.matcher?.inference) {
2255
- topLevelActors["matcher"] = { inference: { type: makeMeaningSection.actors.matcher.inference.type, model: makeMeaningSection.actors.matcher.inference.model } };
2256
- }
2257
- const frontend = resolved.frontend;
2258
- const services = {};
2259
- if (backend) {
2260
- services.backend = {
2261
- platform: { type: requirePlatform(backend.platform, "backend") },
2262
- port: backend.port ?? 4e3,
2263
- publicURL: backend.publicURL ?? `http://localhost:${backend.port ?? 4e3}`
2264
- };
2265
- }
2266
- if (frontend) {
2267
- services.frontend = {
2268
- platform: { type: requirePlatform(frontend.platform, "frontend") },
2269
- port: frontend.port ?? 3e3,
2270
- siteName: site?.siteName ?? "Semiont",
2271
- publicURL: frontend.publicURL
2272
- };
2273
- }
2274
- if (resolved.graph) {
2275
- services.graph = {
2276
- ...resolved.graph,
2277
- platform: { type: requirePlatform(resolved.graph.platform, "graph") },
2278
- type: resolved.graph.type ?? "neo4j"
2279
- };
2280
- } else if (makeMeaningSection?.graph) {
2281
- services.graph = makeMeaningSection.graph;
2282
- }
2283
- if (resolved.database) {
2284
- services.database = {
2285
- platform: { type: requirePlatform(resolved.database.platform, "database") },
2286
- type: "postgres",
2287
- image: resolved.database.image,
2288
- host: resolved.database.host ?? "localhost",
2289
- port: resolved.database.port ?? 5432,
2290
- name: resolved.database.name,
2291
- user: resolved.database.user,
2292
- password: resolved.database.password
2293
- };
2294
- }
2295
- if (resolved.vectors) {
2296
- services.vectors = {
2297
- platform: { type: "external" },
2298
- type: resolved.vectors.type ?? "qdrant",
2299
- host: resolved.vectors.host,
2300
- port: resolved.vectors.port ?? 6333
2301
- };
2302
- }
2303
- const embeddingSource = resolved.embedding ?? resolved.vectors?.embedding;
2304
- if (embeddingSource) {
2305
- services.embedding = {
2306
- platform: { type: "external" },
2307
- type: embeddingSource.type,
2308
- model: embeddingSource.model,
2309
- apiKey: embeddingSource.apiKey,
2310
- baseURL: embeddingSource.baseURL,
2311
- endpoint: embeddingSource.endpoint,
2312
- chunking: resolved.embedding?.chunking ?? resolved.vectors?.chunking ? {
2313
- chunkSize: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.chunkSize ?? 512,
2314
- overlap: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.overlap ?? 64
2315
- } : void 0
2316
- };
2317
- }
2318
- const config = {
2319
- services,
2320
- ...inferenceProviders ? { inference: inferenceProviders } : {},
2321
- ...Object.keys(topLevelWorkers).length > 0 ? { workers: topLevelWorkers } : {},
2322
- ...Object.keys(topLevelActors).length > 0 ? { actors: topLevelActors } : {},
2323
- site: site ? {
2324
- domain: site.domain ?? "localhost",
2325
- siteName: site.siteName,
2326
- adminEmail: site.adminEmail,
2327
- oauthAllowedDomains: site.oauthAllowedDomains
2328
- } : void 0,
2329
- logLevel: resolved.logLevel,
2330
- _metadata: {
2331
- environment: resolvedEnvironment,
2332
- projectRoot,
2333
- projectName,
2334
- projectVersion,
2335
- ...Object.keys(actors).length > 0 ? { actors } : {},
2336
- ...Object.keys(workers).length > 0 ? { workers } : {},
2337
- // Always set — the loader is the ONE home of this default (D5).
2338
- // Consuming code (make-meaning's gather path) receives a required
2339
- // value and defaults nothing.
2340
- gather: { settleTimeoutMs: makeMeaningSection?.gather?.settleTimeoutMs ?? 15e3 }
2341
- }
2342
- };
2343
- return config;
2344
- }
2345
- function createTomlConfigLoader(reader, globalConfigPath, env) {
2346
- return (projectRoot, environment) => {
2347
- return loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env);
2348
- };
2349
- }
2350
1803
 
2351
1804
  // src/config/environment-validator.ts
2352
1805
  function isValidEnvironment(value, availableEnvironments) {
@@ -2472,6 +1925,6 @@ async function retryWithBackoff(fn, isRetryable, policy, onRetry) {
2472
1925
  // src/discovery.ts
2473
1926
  var DISCOVERY_URL_PATH = "/discovery/kbs.json";
2474
1927
 
2475
- export { AUTHORABLE_MEDIA_TYPES, BRIDGED_CHANNELS, BusRequestError, CHANNEL_SCHEMAS, CONTEXT_FULL_WEIGHT, CONTEXT_PARTIAL_WEIGHT, ConfigurationError, ConflictError, DISCOVERY_URL_PATH, EMBEDDABLE_MEDIA_TYPES, EventBus, JWTTokenSchema, LOCALES, MEDIA_TYPES, NotFoundError, PERSISTED_EVENT_TYPES, POSITION_WEIGHT_MAX, POSITION_WINDOW, RESOURCE_BROADCAST_TYPES, STARTUP_FETCH_RETRY, ScopedEventBus, ScriptError, SemiontError, UnauthorizedError, ValidationError, accessToken, agentToDid, anchorAnnotation, annotationId, annotationUri, applyBodyOperations, assembleAnnotation, authCode, baseMediaType, baseUrl, buildContentCache, burstBuffer, busLog, busLogEnabled, busRequest, capabilitiesOf, cloneToken, createCircleSvg, createFragmentSelector, createPolygonSvg, createRectangleSvg, createTomlConfigLoader, decodeRepresentation, decodeWithCharset, deriveViews, didToAgent, email, entityType, errField, extensionForMediaType, extractBoundingBox, extractCharset, extractContext, findBestTextMatch, findBodyItem, 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, getStorageUri, getSvgSelector, getTargetSelector, getTargetSource, getTextPositionSelector, getTextQuoteSelector, googleCredential, 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, isTransientFetchError, isUndefined, isValidEmail, isValidPlatformType, jobId, kbDid, loadTomlConfig, mcpToken, mediaTypeForExtension, normalizeCoordinates, normalizeText, parseEnvironment, parseFragmentSelector, parseSvgSelector, reconcileSelector, refreshToken, resourceAnnotationUri, resourceId, resourceUri, retryWithBackoff, scaleSvgToNative, searchQuery, serializePerKey, setBusLogTraceIdProvider, softwareToAgent, textExtractionOf, userDID, userId, userToAgent, userToDid, validateData, validateEnvironment, validateSvgMarkup, verifyPosition };
1928
+ export { AUTHORABLE_MEDIA_TYPES, BusRequestError, CHANNEL_SCHEMAS, CONTEXT_FULL_WEIGHT, CONTEXT_PARTIAL_WEIGHT, ConfigurationError, ConflictError, DISCOVERY_URL_PATH, EMBEDDABLE_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, annotationId, applyBodyOperations, assembleAnnotation, baseMediaType, buildContentCache, burstBuffer, busRequest, capabilitiesOf, createCircleSvg, createFragmentSelector, createPolygonSvg, createRectangleSvg, decodeRepresentation, decodeWithCharset, deriveViews, didToAgent, errField, extensionForMediaType, extractBoundingBox, extractCharset, extractContext, findBestTextMatch, findBodyItem, 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, 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, isTransientFetchError, isUndefined, isValidEmail, isValidPlatformType, kbDid, mediaTypeForExtension, normalizeCoordinates, normalizeText, parseEnvironment, parseFragmentSelector, parseSvgSelector, reconcileSelector, resourceId, retryWithBackoff, scaleSvgToNative, serializePerKey, softwareToAgent, textExtractionOf, userId, userToAgent, userToDid, uuidV4, validateData, validateEnvironment, validateSvgMarkup, verifyPosition };
2476
1929
  //# sourceMappingURL=index.js.map
2477
1930
  //# sourceMappingURL=index.js.map