@semiont/make-meaning 0.5.29 → 0.5.31

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.
@@ -1,8 +1,11 @@
1
- import { archivistContentReads, createAnchoredTextStore, EXTRACTORS, calculateChecksum } from '@semiont/content';
2
- import { createTomlConfigLoader, accessToken, baseUrl as baseUrl$1, retryWithBackoff, isTransientFetchError, STARTUP_FETCH_RETRY, burstBuffer, errField, resourceId, textExtractionOf, busRequest, getResourceEntityTypes, chunkText, getTargetSelector, getExactText, annotationId, getPrimaryMediaType, getPrimaryRepresentation } from '@semiont/core';
1
+ import { archivistContentReads, createAnchoredTextStore, derivingExtractorFor, calculateChecksum } from '@semiont/content';
2
+ import { replyChannelsFor, createTomlConfigLoader, accessToken, baseUrl as baseUrl$1, retryWithBackoff, isTransientFetchError, STARTUP_FETCH_RETRY, burstBuffer, errField, resourceId, textSourceOf, decodeRepresentation, busRequest, getResourceEntityTypes, chunkText, getTargetSelector, getExactText, annotationId, getPrimaryMediaType, yieldsGeometryOf, getPrimaryRepresentation } from '@semiont/core';
3
3
  import { registerVectorIndexSizeProvider, withActorSpan } from '@semiont/observability';
4
- import { HttpTransport } from '@semiont/http-transport';
4
+ import '@semiont/ontology';
5
+ import '@semiont/graph';
5
6
  import { createEmbeddingProvider, createVectorStore } from '@semiont/vectors';
7
+ import '@semiont/event-sourcing';
8
+ import { HttpTransport } from '@semiont/http-transport';
6
9
  import { createServer } from 'http';
7
10
  import { existsSync, readFileSync } from 'fs';
8
11
  import { homedir } from 'os';
@@ -10057,8 +10060,8 @@ var Smelter = class _Smelter {
10057
10060
  if (!rid) return;
10058
10061
  const { data, contentType } = await this.content.getBinary(resourceId(rid));
10059
10062
  const bytes = Buffer.from(data);
10060
- const extractor = EXTRACTORS[textExtractionOf(contentType)];
10061
- if (!extractor?.yieldsGeometry) {
10063
+ const extractor = derivingExtractorFor(contentType);
10064
+ if (!extractor) {
10062
10065
  this.logger.info("Re-anchor found no geometry-capable extractor", { resourceId: rid, contentType });
10063
10066
  return;
10064
10067
  }
@@ -10092,41 +10095,38 @@ var Smelter = class _Smelter {
10092
10095
  * null (logged) when the resource doesn't decode as text, is unavailable,
10093
10096
  * or is empty — callers skip it.
10094
10097
  */
10095
- async fetchEmbeddableText(resourceId$1) {
10098
+ async fetchEmbeddableText(resourceId6) {
10096
10099
  try {
10097
- const { data, contentType } = await this.content.getBinary(resourceId(resourceId$1));
10100
+ const { data, contentType } = await this.content.getBinary(resourceId(resourceId6));
10098
10101
  const bytes = Buffer.from(data);
10099
10102
  const checksum = calculateChecksum(bytes);
10100
- const extractor = EXTRACTORS[textExtractionOf(contentType)];
10101
- if (!extractor) {
10102
- this.logger.debug("Skipping resource with no extractor for its media type", { resourceId: resourceId$1, contentType });
10103
+ const extractor = derivingExtractorFor(contentType);
10104
+ if (!extractor && textSourceOf(contentType) === "none") {
10105
+ this.logger.debug("Skipping resource with no way to read its media type", { resourceId: resourceId6, contentType });
10103
10106
  return { kind: "skipped", checksum, reason: "no-extractor" };
10104
10107
  }
10105
- const extracted = await extractor.extract(bytes, contentType, {
10106
- key: checksum,
10107
- store: this.anchoredStore
10108
- });
10108
+ const extracted = extractor ? await extractor.extract(bytes, contentType, { key: checksum, store: this.anchoredStore }) : { kind: "extracted", text: decodeRepresentation(bytes, contentType), method: "text-passthrough" };
10109
10109
  if (extracted.kind === "declined") {
10110
- this.logger.debug("Extractor declined", { resourceId: resourceId$1, contentType, reason: extracted.declined });
10110
+ this.logger.debug("Extractor declined", { resourceId: resourceId6, contentType, reason: extracted.declined });
10111
10111
  return { kind: "skipped", checksum, reason: extracted.declined };
10112
10112
  }
10113
10113
  if (extracted.ocrConfidence && extracted.ocrConfidence.lowConfidenceWords > 0) {
10114
10114
  this.logger.info("OCR read words it was unsure of", {
10115
- resourceId: resourceId$1,
10115
+ resourceId: resourceId6,
10116
10116
  contentType,
10117
10117
  ...extracted.ocrConfidence
10118
10118
  });
10119
10119
  }
10120
10120
  if (extracted.unreadPages?.length) {
10121
10121
  this.logger.info("Partial extraction coverage", {
10122
- resourceId: resourceId$1,
10122
+ resourceId: resourceId6,
10123
10123
  contentType,
10124
10124
  unreadPages: extracted.unreadPages
10125
10125
  });
10126
10126
  }
10127
10127
  return extracted.text.trim() ? { kind: "text", text: extracted.text, checksum, machineRead: extracted.method === "ocr" } : { kind: "skipped", checksum, reason: "empty" };
10128
10128
  } catch (error) {
10129
- this.logger.warn("Content unavailable for embedding", { resourceId: resourceId$1, error: errField(error) });
10129
+ this.logger.warn("Content unavailable for embedding", { resourceId: resourceId6, error: errField(error) });
10130
10130
  return { kind: "unavailable" };
10131
10131
  }
10132
10132
  }
@@ -10136,11 +10136,11 @@ var Smelter = class _Smelter {
10136
10136
  * fold. Best-effort — waiters degrade to their bounded timeout; a signal
10137
10137
  * failure must never fail the embed.
10138
10138
  */
10139
- async emitSettled(resourceId, contentChecksum, outcome, reason) {
10139
+ async emitSettled(resourceId6, contentChecksum, outcome, reason) {
10140
10140
  try {
10141
- await this.bus.emit("smelt:settled", { resourceId, contentChecksum, outcome, ...reason ? { reason } : {} });
10141
+ await this.bus.emit("smelt:settled", { resourceId: resourceId6, contentChecksum, outcome, ...reason ? { reason } : {} });
10142
10142
  } catch (error) {
10143
- this.logger.warn("Failed to emit smelt:settled", { resourceId, outcome, error: errField(error) });
10143
+ this.logger.warn("Failed to emit smelt:settled", { resourceId: resourceId6, outcome, error: errField(error) });
10144
10144
  }
10145
10145
  }
10146
10146
  /**
@@ -10152,11 +10152,11 @@ var Smelter = class _Smelter {
10152
10152
  * propagates to the pipeline's per-resource error handler (reconcile heals),
10153
10153
  * rather than silently stamping `[]` and letting the resource leak into recall.
10154
10154
  */
10155
- async resolveEntityTypes(resourceId) {
10155
+ async resolveEntityTypes(resourceId6) {
10156
10156
  const { resource } = await busRequest(
10157
10157
  this.bus,
10158
10158
  "browse:resource-requested",
10159
- { resourceId }
10159
+ { resourceId: resourceId6 }
10160
10160
  );
10161
10161
  return getResourceEntityTypes(resource);
10162
10162
  }
@@ -10240,11 +10240,11 @@ var Smelter = class _Smelter {
10240
10240
  this.logger.info("Indexed annotation", { annotationId: String(aid) });
10241
10241
  }
10242
10242
  async handleAnnotationRemoved(event) {
10243
- const annotationId$1 = event.payload.annotationId;
10244
- if (!annotationId$1) return;
10245
- const aid = annotationId(annotationId$1);
10243
+ const annotationId3 = event.payload.annotationId;
10244
+ if (!annotationId3) return;
10245
+ const aid = annotationId(annotationId3);
10246
10246
  await this.vectorStore.deleteAnnotationVector(aid);
10247
- this.logger.info("Deleted annotation vector", { annotationId: annotationId$1 });
10247
+ this.logger.info("Deleted annotation vector", { annotationId: annotationId3 });
10248
10248
  }
10249
10249
  /**
10250
10250
  * Batch-embed chunks from multiple yield:created events in a single
@@ -10483,16 +10483,16 @@ var Smelter = class _Smelter {
10483
10483
  * resource (S1/S2).
10484
10484
  */
10485
10485
  async rebuildAnchors(command) {
10486
- const { correlationId, resourceId } = command;
10486
+ const { correlationId, resourceId: resourceId6 } = command;
10487
10487
  try {
10488
10488
  let work;
10489
- if (resourceId) {
10490
- work = [{ type: "smelt:reanchor", resourceId, payload: {} }];
10489
+ if (resourceId6) {
10490
+ work = [{ type: "smelt:reanchor", resourceId: resourceId6, payload: {} }];
10491
10491
  } else {
10492
10492
  const resources = await this.listAllResources();
10493
10493
  work = [...this.classifyEmbeddable(resources)].filter(([, catalog]) => catalog.yieldsGeometry).map(([rid]) => ({ type: "smelt:reanchor", resourceId: rid, payload: {} }));
10494
10494
  }
10495
- this.logger.info("Anchored-text rebuild started", { scoped: resourceId ?? null, resources: work.length });
10495
+ this.logger.info("Anchored-text rebuild started", { scoped: resourceId6 ?? null, resources: work.length });
10496
10496
  const failed = await this.drain(work);
10497
10497
  if (failed > 0) {
10498
10498
  await this.bus.emit("smelt:rebuild-anchors-failed", {
@@ -10502,7 +10502,7 @@ var Smelter = class _Smelter {
10502
10502
  return;
10503
10503
  }
10504
10504
  await this.bus.emit("smelt:rebuild-anchors-ok", correlationId ? { correlationId } : {});
10505
- this.logger.info("Anchored-text rebuild complete", { scoped: resourceId ?? null, resources: work.length });
10505
+ this.logger.info("Anchored-text rebuild complete", { scoped: resourceId6 ?? null, resources: work.length });
10506
10506
  } catch (error) {
10507
10507
  this.logger.error("Anchored-text rebuild failed", { error: errField(error) });
10508
10508
  try {
@@ -10520,22 +10520,24 @@ var Smelter = class _Smelter {
10520
10520
  * representation's checksum (the bytes the smelter would read), the
10521
10521
  * current entity-type set (the discriminator the stamps must carry), and
10522
10522
  * whether the media type's extractor derives geometry (whether an
10523
- * anchored-text artifact should exist). Embeddable an extractor exists
10524
- * for the media type's strategy the same registry the live fetch
10525
- * resolves, and `yieldsGeometry` is declared on the extractor itself, so
10526
- * every gate here and the live fetch's behavior are twins by construction.
10523
+ * anchored-text artifact should exist). Both answers are core's, keyed by the
10524
+ * media type's strategy: embeddable the type has any text-reading strategy
10525
+ * at all, and geometry that strategy derives it. Until READ-VS-EXTRACT P2
10526
+ * embeddability was asked as `EXTRACTORS[strategy] !== null` true, but a
10527
+ * second statement of `strategy !== 'none'`, answered by resolving an
10528
+ * implementation to learn a fact about a media type.
10527
10529
  * Shared by `reconcile()` and the `smelt:rebuild-anchors` planner.
10528
10530
  */
10529
10531
  classifyEmbeddable(resources) {
10530
10532
  const embeddable = /* @__PURE__ */ new Map();
10531
10533
  for (const resource of resources) {
10532
10534
  const mediaType = getPrimaryMediaType(resource);
10533
- const extractor = mediaType ? EXTRACTORS[textExtractionOf(mediaType)] : null;
10534
- if (resource["@id"] && extractor) {
10535
+ const readable = mediaType !== void 0 && textSourceOf(mediaType) !== "none";
10536
+ if (resource["@id"] && mediaType && readable) {
10535
10537
  embeddable.set(resource["@id"], {
10536
10538
  checksum: getPrimaryRepresentation(resource)?.checksum,
10537
10539
  entityTypes: getResourceEntityTypes(resource),
10538
- yieldsGeometry: extractor.yieldsGeometry
10540
+ yieldsGeometry: yieldsGeometryOf(mediaType)
10539
10541
  });
10540
10542
  }
10541
10543
  }
@@ -10555,6 +10557,108 @@ var Smelter = class _Smelter {
10555
10557
  }
10556
10558
  }
10557
10559
  };
10560
+ var MATCHER_CHANNELS = [
10561
+ "match:search-requested"
10562
+ ];
10563
+
10564
+ // src/gatherer.ts
10565
+ var GATHERER_CHANNELS = [
10566
+ "gather:requested",
10567
+ "gather:resource-requested"
10568
+ ];
10569
+ var STOWER_CHANNELS = [
10570
+ "yield:create",
10571
+ "yield:clone-persist",
10572
+ "yield:update",
10573
+ "yield:mv",
10574
+ "mark:create",
10575
+ "mark:commit",
10576
+ "mark:delete",
10577
+ "mark:update-body",
10578
+ "frame:add-entity-type",
10579
+ "frame:add-tag-schema",
10580
+ "mark:archive",
10581
+ "mark:unarchive",
10582
+ "mark:update-entity-types",
10583
+ "job:start",
10584
+ "job:complete",
10585
+ "job:fail"
10586
+ ];
10587
+
10588
+ // src/browser.ts
10589
+ var BROWSER_CHANNELS = [
10590
+ "browse:resource-requested",
10591
+ "browse:anchored-text-requested",
10592
+ "browse:resources-requested",
10593
+ "browse:annotations-requested",
10594
+ "browse:annotation-requested",
10595
+ "browse:events-requested",
10596
+ "browse:annotation-history-requested",
10597
+ "browse:referenced-by-requested",
10598
+ "browse:entity-types-requested",
10599
+ "browse:tag-schemas-requested",
10600
+ "browse:agents-requested",
10601
+ "browse:directory-requested"
10602
+ ];
10603
+
10604
+ // src/clone-token-manager.ts
10605
+ var CLONE_TOKEN_CHANNELS = [
10606
+ "yield:clone-token-requested",
10607
+ "yield:clone-resource-requested",
10608
+ "yield:clone-create"
10609
+ ];
10610
+
10611
+ // src/service-channels.ts
10612
+ var SMELTER_AWAITED_OPERATIONS = [
10613
+ "browse:resource-requested",
10614
+ "browse:annotations-requested",
10615
+ "browse:resources-requested"
10616
+ ];
10617
+ var SMELTER_REPLY_CHANNELS = replyChannelsFor(SMELTER_AWAITED_OPERATIONS);
10618
+ var WEAVER_AWAITED_OPERATIONS = [
10619
+ "browse:resources-requested",
10620
+ "browse:events-requested",
10621
+ "browse:annotations-requested"
10622
+ ];
10623
+ replyChannelsFor(WEAVER_AWAITED_OPERATIONS);
10624
+ var LIBRARIAN_INBOUND_CHANNELS = [
10625
+ ...MATCHER_CHANNELS,
10626
+ ...GATHERER_CHANNELS,
10627
+ "gather:summary-requested",
10628
+ "weave:applied",
10629
+ "smelt:settled"
10630
+ ];
10631
+ replyChannelsFor(LIBRARIAN_INBOUND_CHANNELS);
10632
+ var ARCHIVIST_INBOUND_CHANNELS = [
10633
+ ...STOWER_CHANNELS,
10634
+ ...BROWSER_CHANNELS,
10635
+ ...CLONE_TOKEN_CHANNELS,
10636
+ "mark:create-request",
10637
+ "smelt:settled",
10638
+ // The annotation-context read moved here with the bytes (SINGLE-KB-MOUNT D5).
10639
+ "browse:annotation-context-requested"
10640
+ ];
10641
+ var ARCHIVIST_OUTBOUND_STRAYS = [
10642
+ "mark:body-update-failed",
10643
+ // op keyed 'bind:update-body' (gateway handler re-emits mark:update-body)
10644
+ "yield:move-failed"
10645
+ // yield:mv has no registered operation; failure is direct-subscribed
10646
+ ];
10647
+ [
10648
+ ...ARCHIVIST_OUTBOUND_STRAYS,
10649
+ ...replyChannelsFor(ARCHIVIST_INBOUND_CHANNELS)
10650
+ ];
10651
+ async function runBootPass(pass, run, logger2, onState) {
10652
+ try {
10653
+ const summary = await run();
10654
+ onState?.({ phase: "done", summary });
10655
+ } catch (error) {
10656
+ logger2.error(`Boot pass '${pass}' failed \u2014 continuing with a store that may be behind`, {
10657
+ pass,
10658
+ error: errField(error)
10659
+ });
10660
+ }
10661
+ }
10558
10662
  var configPath = join(homedir(), ".semiontconfig");
10559
10663
  var tomlReader = {
10560
10664
  readIfExists: (p) => existsSync(p) ? readFileSync(p, "utf-8") : null
@@ -10590,7 +10694,7 @@ var chunkingConfig = {
10590
10694
  overlap: embedding.chunking?.overlap ?? 64
10591
10695
  };
10592
10696
  var workerSecret = process.env.SEMIONT_WORKER_SECRET ?? "";
10593
- var healthPort = 9091;
10697
+ var healthPort = 24101;
10594
10698
  var logger = createProcessLogger("smelter");
10595
10699
  async function authenticate() {
10596
10700
  if (!workerSecret) {
@@ -10661,7 +10765,12 @@ async function main() {
10661
10765
  const httpTransport = new HttpTransport({
10662
10766
  baseUrl: baseUrl$1(baseUrl),
10663
10767
  token$: tokenSubject,
10664
- tokenRefresher: refreshToken
10768
+ tokenRefresher: refreshToken,
10769
+ // Only the reply channels this process awaits — not the full bridged
10770
+ // set, whose global reply fan-out is the worker-OOM failure mode. See
10771
+ // SMELTER_AWAITED_OPERATIONS. The domain-event channels are added by
10772
+ // the actor state unit's start() below.
10773
+ channels: SMELTER_REPLY_CHANNELS
10665
10774
  });
10666
10775
  const actorStateUnit = createSmelterActorStateUnit({
10667
10776
  bus: httpTransport.actor
@@ -10715,7 +10824,7 @@ async function main() {
10715
10824
  };
10716
10825
  process.on("SIGTERM", shutdown);
10717
10826
  process.on("SIGINT", shutdown);
10718
- await smelter.reconcile();
10827
+ await runBootPass("reconcile", () => smelter.reconcile(), logger);
10719
10828
  }
10720
10829
  main().catch((error) => {
10721
10830
  logger.error("Fatal", { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : void 0 });