@semiont/make-meaning 0.5.32 → 0.5.34

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,5 +1,5 @@
1
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';
2
+ import { replyChannelsFor, createTomlConfigLoader, accessToken, withDeadline, baseUrl as baseUrl$1, retryWithBackoff, isTransientFetchError, STARTUP_FETCH_RETRY, burstBuffer, errField, resourceId, textSourceOf, decodeRepresentation, busRequest, getResourceEntityTypes, chunkText, getTargetSelector, getExactText, annotationId, getPrimaryMediaType, yieldsGeometryOf, getPrimaryRepresentation, isPeerUnavailable } from '@semiont/core';
3
3
  import { registerVectorIndexSizeProvider, withActorSpan } from '@semiont/observability';
4
4
  import '@semiont/ontology';
5
5
  import '@semiont/graph';
@@ -11,6 +11,8 @@ import { existsSync, readFileSync } from 'fs';
11
11
  import { homedir } from 'os';
12
12
  import { join } from 'path';
13
13
  import { createProcessLogger } from '@semiont/observability/process-logger';
14
+ import '@semiont/jobs';
15
+ import '@semiont/inference';
14
16
 
15
17
  var __create = Object.create;
16
18
  var __defProp = Object.defineProperty;
@@ -9789,6 +9791,28 @@ function partitionByType(events) {
9789
9791
  if (currentRun.length > 0) runs.push(currentRun);
9790
9792
  return runs;
9791
9793
  }
9794
+ var RESOURCE_LISTING_RETRY = {
9795
+ attempts: 17,
9796
+ initialDelayMs: 1e3,
9797
+ maxDelayMs: 3e4
9798
+ };
9799
+ var RESOURCES_CHANNEL = "browse:resources-requested";
9800
+ async function browseAllResources(bus, options) {
9801
+ const all = [];
9802
+ for (; ; ) {
9803
+ const page = await retryWithBackoff(
9804
+ () => busRequest(bus, RESOURCES_CHANNEL, {
9805
+ ...options.archived !== void 0 ? { archived: options.archived } : {},
9806
+ offset: all.length,
9807
+ limit: options.limit
9808
+ }),
9809
+ isPeerUnavailable,
9810
+ RESOURCE_LISTING_RETRY
9811
+ );
9812
+ all.push(...page.resources);
9813
+ if (page.resources.length === 0 || all.length >= page.total) return all;
9814
+ }
9815
+ }
9792
9816
 
9793
9817
  // src/smelter.ts
9794
9818
  function sameStringSet(a, b) {
@@ -10095,38 +10119,38 @@ var Smelter = class _Smelter {
10095
10119
  * null (logged) when the resource doesn't decode as text, is unavailable,
10096
10120
  * or is empty — callers skip it.
10097
10121
  */
10098
- async fetchEmbeddableText(resourceId6) {
10122
+ async fetchEmbeddableText(resourceId10) {
10099
10123
  try {
10100
- const { data, contentType } = await this.content.getBinary(resourceId(resourceId6));
10124
+ const { data, contentType } = await this.content.getBinary(resourceId(resourceId10));
10101
10125
  const bytes = Buffer.from(data);
10102
10126
  const checksum = calculateChecksum(bytes);
10103
10127
  const extractor = derivingExtractorFor(contentType);
10104
10128
  if (!extractor && textSourceOf(contentType) === "none") {
10105
- this.logger.debug("Skipping resource with no way to read its media type", { resourceId: resourceId6, contentType });
10129
+ this.logger.debug("Skipping resource with no way to read its media type", { resourceId: resourceId10, contentType });
10106
10130
  return { kind: "skipped", checksum, reason: "no-extractor" };
10107
10131
  }
10108
10132
  const extracted = extractor ? await extractor.extract(bytes, contentType, { key: checksum, store: this.anchoredStore }) : { kind: "extracted", text: decodeRepresentation(bytes, contentType), method: "text-passthrough" };
10109
10133
  if (extracted.kind === "declined") {
10110
- this.logger.debug("Extractor declined", { resourceId: resourceId6, contentType, reason: extracted.declined });
10134
+ this.logger.debug("Extractor declined", { resourceId: resourceId10, contentType, reason: extracted.declined });
10111
10135
  return { kind: "skipped", checksum, reason: extracted.declined };
10112
10136
  }
10113
10137
  if (extracted.ocrConfidence && extracted.ocrConfidence.lowConfidenceWords > 0) {
10114
10138
  this.logger.info("OCR read words it was unsure of", {
10115
- resourceId: resourceId6,
10139
+ resourceId: resourceId10,
10116
10140
  contentType,
10117
10141
  ...extracted.ocrConfidence
10118
10142
  });
10119
10143
  }
10120
10144
  if (extracted.unreadPages?.length) {
10121
10145
  this.logger.info("Partial extraction coverage", {
10122
- resourceId: resourceId6,
10146
+ resourceId: resourceId10,
10123
10147
  contentType,
10124
10148
  unreadPages: extracted.unreadPages
10125
10149
  });
10126
10150
  }
10127
10151
  return extracted.text.trim() ? { kind: "text", text: extracted.text, checksum, machineRead: extracted.method === "ocr" } : { kind: "skipped", checksum, reason: "empty" };
10128
10152
  } catch (error) {
10129
- this.logger.warn("Content unavailable for embedding", { resourceId: resourceId6, error: errField(error) });
10153
+ this.logger.warn("Content unavailable for embedding", { resourceId: resourceId10, error: errField(error) });
10130
10154
  return { kind: "unavailable" };
10131
10155
  }
10132
10156
  }
@@ -10136,11 +10160,11 @@ var Smelter = class _Smelter {
10136
10160
  * fold. Best-effort — waiters degrade to their bounded timeout; a signal
10137
10161
  * failure must never fail the embed.
10138
10162
  */
10139
- async emitSettled(resourceId6, contentChecksum, outcome, reason) {
10163
+ async emitSettled(resourceId10, contentChecksum, outcome, reason) {
10140
10164
  try {
10141
- await this.bus.emit("smelt:settled", { resourceId: resourceId6, contentChecksum, outcome, ...reason ? { reason } : {} });
10165
+ await this.bus.emit("smelt:settled", { resourceId: resourceId10, contentChecksum, outcome, ...reason ? { reason } : {} });
10142
10166
  } catch (error) {
10143
- this.logger.warn("Failed to emit smelt:settled", { resourceId: resourceId6, outcome, error: errField(error) });
10167
+ this.logger.warn("Failed to emit smelt:settled", { resourceId: resourceId10, outcome, error: errField(error) });
10144
10168
  }
10145
10169
  }
10146
10170
  /**
@@ -10152,11 +10176,11 @@ var Smelter = class _Smelter {
10152
10176
  * propagates to the pipeline's per-resource error handler (reconcile heals),
10153
10177
  * rather than silently stamping `[]` and letting the resource leak into recall.
10154
10178
  */
10155
- async resolveEntityTypes(resourceId6) {
10179
+ async resolveEntityTypes(resourceId10) {
10156
10180
  const { resource } = await busRequest(
10157
10181
  this.bus,
10158
10182
  "browse:resource-requested",
10159
- { resourceId: resourceId6 }
10183
+ { resourceId: resourceId10 }
10160
10184
  );
10161
10185
  return getResourceEntityTypes(resource);
10162
10186
  }
@@ -10240,11 +10264,11 @@ var Smelter = class _Smelter {
10240
10264
  this.logger.info("Indexed annotation", { annotationId: String(aid) });
10241
10265
  }
10242
10266
  async handleAnnotationRemoved(event) {
10243
- const annotationId3 = event.payload.annotationId;
10244
- if (!annotationId3) return;
10245
- const aid = annotationId(annotationId3);
10267
+ const annotationId5 = event.payload.annotationId;
10268
+ if (!annotationId5) return;
10269
+ const aid = annotationId(annotationId5);
10246
10270
  await this.vectorStore.deleteAnnotationVector(aid);
10247
- this.logger.info("Deleted annotation vector", { annotationId: annotationId3 });
10271
+ this.logger.info("Deleted annotation vector", { annotationId: annotationId5 });
10248
10272
  }
10249
10273
  /**
10250
10274
  * Batch-embed chunks from multiple yield:created events in a single
@@ -10483,16 +10507,16 @@ var Smelter = class _Smelter {
10483
10507
  * resource (S1/S2).
10484
10508
  */
10485
10509
  async rebuildAnchors(command) {
10486
- const { correlationId, resourceId: resourceId6 } = command;
10510
+ const { correlationId, resourceId: resourceId10 } = command;
10487
10511
  try {
10488
10512
  let work;
10489
- if (resourceId6) {
10490
- work = [{ type: "smelt:reanchor", resourceId: resourceId6, payload: {} }];
10513
+ if (resourceId10) {
10514
+ work = [{ type: "smelt:reanchor", resourceId: resourceId10, payload: {} }];
10491
10515
  } else {
10492
10516
  const resources = await this.listAllResources();
10493
10517
  work = [...this.classifyEmbeddable(resources)].filter(([, catalog]) => catalog.yieldsGeometry).map(([rid]) => ({ type: "smelt:reanchor", resourceId: rid, payload: {} }));
10494
10518
  }
10495
- this.logger.info("Anchored-text rebuild started", { scoped: resourceId6 ?? null, resources: work.length });
10519
+ this.logger.info("Anchored-text rebuild started", { scoped: resourceId10 ?? null, resources: work.length });
10496
10520
  const failed = await this.drain(work);
10497
10521
  if (failed > 0) {
10498
10522
  await this.bus.emit("smelt:rebuild-anchors-failed", {
@@ -10502,7 +10526,7 @@ var Smelter = class _Smelter {
10502
10526
  return;
10503
10527
  }
10504
10528
  await this.bus.emit("smelt:rebuild-anchors-ok", correlationId ? { correlationId } : {});
10505
- this.logger.info("Anchored-text rebuild complete", { scoped: resourceId6 ?? null, resources: work.length });
10529
+ this.logger.info("Anchored-text rebuild complete", { scoped: resourceId10 ?? null, resources: work.length });
10506
10530
  } catch (error) {
10507
10531
  this.logger.error("Anchored-text rebuild failed", { error: errField(error) });
10508
10532
  try {
@@ -10544,17 +10568,11 @@ var Smelter = class _Smelter {
10544
10568
  return embeddable;
10545
10569
  }
10546
10570
  /** Page through `browse:resources-requested` until the catalog is exhausted. */
10547
- async listAllResources() {
10548
- const all = [];
10549
- for (; ; ) {
10550
- const page = await busRequest(
10551
- this.bus,
10552
- "browse:resources-requested",
10553
- { archived: false, offset: all.length, limit: _Smelter.RECONCILE_PAGE_SIZE }
10554
- );
10555
- all.push(...page.resources);
10556
- if (page.resources.length === 0 || all.length >= page.total) return all;
10557
- }
10571
+ /** Shared with the weaver since 2026-09-09 — see `browse-resources.ts` for why the
10572
+ * retry lives at the page rather than around the pass. `archived: false` is
10573
+ * the smelter's own filter and the one difference between the two loops. */
10574
+ listAllResources() {
10575
+ return browseAllResources(this.bus, { limit: _Smelter.RECONCILE_PAGE_SIZE, archived: false });
10558
10576
  }
10559
10577
  };
10560
10578
  var MATCHER_CHANNELS = [
@@ -10659,6 +10677,12 @@ async function runBootPass(pass, run, logger2, onState) {
10659
10677
  });
10660
10678
  }
10661
10679
  }
10680
+
10681
+ // src/service.ts
10682
+ var STARTUP_CONNECT_TIMEOUT_MS = 6e4;
10683
+ var RESTART_HINT = "Exiting so the container restart policy can retry \u2014 it is normal for a dependency to be slow when every service restarts at once.";
10684
+
10685
+ // src/smelter-main.ts
10662
10686
  var configPath = join(homedir(), ".semiontconfig");
10663
10687
  var tomlReader = {
10664
10688
  readIfExists: (p) => existsSync(p) ? readFileSync(p, "utf-8") : null
@@ -10731,8 +10755,9 @@ async function authenticate() {
10731
10755
  );
10732
10756
  }
10733
10757
  async function main() {
10734
- const { initObservabilityNode } = await import('@semiont/observability/node');
10758
+ const { initObservabilityNode, registerSupervisorRestartCount } = await import('@semiont/observability/node');
10735
10759
  initObservabilityNode({ serviceName: "semiont-smelter" });
10760
+ registerSupervisorRestartCount();
10736
10761
  logger.info("Authenticating", { baseUrl });
10737
10762
  const tokenSubject = new import_rxjs3.BehaviorSubject(accessToken(await authenticate()));
10738
10763
  logger.info("Authenticated");
@@ -10748,18 +10773,29 @@ async function main() {
10748
10773
  });
10749
10774
  });
10750
10775
  }, 12 * 60 * 60 * 1e3);
10751
- const embeddingProvider = await createEmbeddingProvider({
10752
- type: embeddingType,
10753
- model: embeddingModel,
10754
- baseURL: embeddingBaseURL
10755
- });
10776
+ const embeddingProvider = await withDeadline(
10777
+ "Embedding provider",
10778
+ STARTUP_CONNECT_TIMEOUT_MS,
10779
+ () => createEmbeddingProvider({
10780
+ type: embeddingType,
10781
+ model: embeddingModel,
10782
+ baseURL: embeddingBaseURL
10783
+ }),
10784
+ RESTART_HINT
10785
+ );
10756
10786
  logger.info("Embedding provider ready", { type: embeddingType, model: embeddingModel });
10757
- const vectorStore = await createVectorStore({
10758
- type: "qdrant",
10759
- host: qdrantHost,
10760
- port: qdrantPort,
10761
- dimensions: () => embeddingProvider.dimensions()
10762
- });
10787
+ const vectorStore = await withDeadline(
10788
+ "Vector store",
10789
+ STARTUP_CONNECT_TIMEOUT_MS,
10790
+ (signal) => createVectorStore({
10791
+ signal,
10792
+ type: "qdrant",
10793
+ host: qdrantHost,
10794
+ port: qdrantPort,
10795
+ dimensions: () => embeddingProvider.dimensions()
10796
+ }),
10797
+ RESTART_HINT
10798
+ );
10763
10799
  logger.info("Vector store ready", { host: qdrantHost, port: qdrantPort });
10764
10800
  registerVectorIndexSizeProvider(() => vectorStore.count());
10765
10801
  const httpTransport = new HttpTransport({