@semiont/make-meaning 0.5.28 → 0.5.30
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 +30 -15
- package/dist/archivist-main.d.ts +2 -0
- package/dist/archivist-main.js +12673 -0
- package/dist/archivist-main.js.map +1 -0
- package/dist/index.d.ts +668 -460
- package/dist/index.js +684 -1068
- package/dist/index.js.map +1 -1
- package/dist/librarian-main.d.ts +2 -0
- package/dist/librarian-main.js +11518 -0
- package/dist/librarian-main.js.map +1 -0
- package/dist/smelter-main.js +145 -39
- package/dist/smelter-main.js.map +1 -1
- package/dist/weaver-main.d.ts +2 -0
- package/dist/weaver-main.js +143 -36
- package/dist/weaver-main.js.map +1 -1
- package/package.json +27 -16
package/dist/smelter-main.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { archivistContentReads, createAnchoredTextStore, EXTRACTORS, calculateChecksum } from '@semiont/content';
|
|
2
|
+
import { replyChannelsFor, 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';
|
|
3
3
|
import { registerVectorIndexSizeProvider, withActorSpan } from '@semiont/observability';
|
|
4
|
-
import
|
|
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';
|
|
@@ -9805,23 +9808,24 @@ function isWorkItem(input) {
|
|
|
9805
9808
|
return WORK_ITEM_TYPES.has(input.type);
|
|
9806
9809
|
}
|
|
9807
9810
|
var Smelter = class _Smelter {
|
|
9808
|
-
constructor(events$, rebuildAnchors$, vectorStore, embeddingProvider, content, bus, chunkingConfig2, timing, logger2) {
|
|
9811
|
+
constructor(events$, rebuildAnchors$, vectorStore, embeddingProvider, content, anchoredStore, bus, chunkingConfig2, timing, logger2) {
|
|
9809
9812
|
this.events$ = events$;
|
|
9810
9813
|
this.rebuildAnchors$ = rebuildAnchors$;
|
|
9811
9814
|
this.vectorStore = vectorStore;
|
|
9812
9815
|
this.embeddingProvider = embeddingProvider;
|
|
9813
9816
|
this.content = content;
|
|
9817
|
+
this.anchoredStore = anchoredStore;
|
|
9814
9818
|
this.bus = bus;
|
|
9815
9819
|
this.chunkingConfig = chunkingConfig2;
|
|
9816
9820
|
this.timing = timing;
|
|
9817
9821
|
this.logger = logger2;
|
|
9818
|
-
this.anchoredStore = anchoredTextStoreOverTransport(content, logger2.child({ component: "anchored-text-cache" }));
|
|
9819
9822
|
}
|
|
9820
9823
|
events$;
|
|
9821
9824
|
rebuildAnchors$;
|
|
9822
9825
|
vectorStore;
|
|
9823
9826
|
embeddingProvider;
|
|
9824
9827
|
content;
|
|
9828
|
+
anchoredStore;
|
|
9825
9829
|
bus;
|
|
9826
9830
|
chunkingConfig;
|
|
9827
9831
|
timing;
|
|
@@ -9845,7 +9849,6 @@ var Smelter = class _Smelter {
|
|
|
9845
9849
|
* OCR pass.
|
|
9846
9850
|
*/
|
|
9847
9851
|
drainChain = Promise.resolve();
|
|
9848
|
-
anchoredStore;
|
|
9849
9852
|
get eventsProcessed() {
|
|
9850
9853
|
return this._eventsProcessed;
|
|
9851
9854
|
}
|
|
@@ -10075,7 +10078,7 @@ var Smelter = class _Smelter {
|
|
|
10075
10078
|
});
|
|
10076
10079
|
return;
|
|
10077
10080
|
}
|
|
10078
|
-
await this.
|
|
10081
|
+
await this.anchoredStore.write(checksum, { ...extracted, items: extracted.items });
|
|
10079
10082
|
this.logger.info("Re-anchored resource", { resourceId: rid, checksum, items: extracted.items.length });
|
|
10080
10083
|
}
|
|
10081
10084
|
async handleResourcePurge(event) {
|
|
@@ -10092,14 +10095,14 @@ 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(
|
|
10098
|
+
async fetchEmbeddableText(resourceId6) {
|
|
10096
10099
|
try {
|
|
10097
|
-
const { data, contentType } = await this.content.getBinary(resourceId(
|
|
10100
|
+
const { data, contentType } = await this.content.getBinary(resourceId(resourceId6));
|
|
10098
10101
|
const bytes = Buffer.from(data);
|
|
10099
10102
|
const checksum = calculateChecksum(bytes);
|
|
10100
10103
|
const extractor = EXTRACTORS[textExtractionOf(contentType)];
|
|
10101
10104
|
if (!extractor) {
|
|
10102
|
-
this.logger.debug("Skipping resource with no extractor for its media type", { resourceId:
|
|
10105
|
+
this.logger.debug("Skipping resource with no extractor for its media type", { resourceId: resourceId6, contentType });
|
|
10103
10106
|
return { kind: "skipped", checksum, reason: "no-extractor" };
|
|
10104
10107
|
}
|
|
10105
10108
|
const extracted = await extractor.extract(bytes, contentType, {
|
|
@@ -10107,26 +10110,26 @@ var Smelter = class _Smelter {
|
|
|
10107
10110
|
store: this.anchoredStore
|
|
10108
10111
|
});
|
|
10109
10112
|
if (extracted.kind === "declined") {
|
|
10110
|
-
this.logger.debug("Extractor declined", { resourceId:
|
|
10113
|
+
this.logger.debug("Extractor declined", { resourceId: resourceId6, contentType, reason: extracted.declined });
|
|
10111
10114
|
return { kind: "skipped", checksum, reason: extracted.declined };
|
|
10112
10115
|
}
|
|
10113
10116
|
if (extracted.ocrConfidence && extracted.ocrConfidence.lowConfidenceWords > 0) {
|
|
10114
10117
|
this.logger.info("OCR read words it was unsure of", {
|
|
10115
|
-
resourceId:
|
|
10118
|
+
resourceId: resourceId6,
|
|
10116
10119
|
contentType,
|
|
10117
10120
|
...extracted.ocrConfidence
|
|
10118
10121
|
});
|
|
10119
10122
|
}
|
|
10120
10123
|
if (extracted.unreadPages?.length) {
|
|
10121
10124
|
this.logger.info("Partial extraction coverage", {
|
|
10122
|
-
resourceId:
|
|
10125
|
+
resourceId: resourceId6,
|
|
10123
10126
|
contentType,
|
|
10124
10127
|
unreadPages: extracted.unreadPages
|
|
10125
10128
|
});
|
|
10126
10129
|
}
|
|
10127
10130
|
return extracted.text.trim() ? { kind: "text", text: extracted.text, checksum, machineRead: extracted.method === "ocr" } : { kind: "skipped", checksum, reason: "empty" };
|
|
10128
10131
|
} catch (error) {
|
|
10129
|
-
this.logger.warn("Content unavailable for embedding", { resourceId:
|
|
10132
|
+
this.logger.warn("Content unavailable for embedding", { resourceId: resourceId6, error: errField(error) });
|
|
10130
10133
|
return { kind: "unavailable" };
|
|
10131
10134
|
}
|
|
10132
10135
|
}
|
|
@@ -10136,11 +10139,11 @@ var Smelter = class _Smelter {
|
|
|
10136
10139
|
* fold. Best-effort — waiters degrade to their bounded timeout; a signal
|
|
10137
10140
|
* failure must never fail the embed.
|
|
10138
10141
|
*/
|
|
10139
|
-
async emitSettled(
|
|
10142
|
+
async emitSettled(resourceId6, contentChecksum, outcome, reason) {
|
|
10140
10143
|
try {
|
|
10141
|
-
await this.bus.emit("smelt:settled", { resourceId, contentChecksum, outcome, ...reason ? { reason } : {} });
|
|
10144
|
+
await this.bus.emit("smelt:settled", { resourceId: resourceId6, contentChecksum, outcome, ...reason ? { reason } : {} });
|
|
10142
10145
|
} catch (error) {
|
|
10143
|
-
this.logger.warn("Failed to emit smelt:settled", { resourceId, outcome, error: errField(error) });
|
|
10146
|
+
this.logger.warn("Failed to emit smelt:settled", { resourceId: resourceId6, outcome, error: errField(error) });
|
|
10144
10147
|
}
|
|
10145
10148
|
}
|
|
10146
10149
|
/**
|
|
@@ -10152,11 +10155,11 @@ var Smelter = class _Smelter {
|
|
|
10152
10155
|
* propagates to the pipeline's per-resource error handler (reconcile heals),
|
|
10153
10156
|
* rather than silently stamping `[]` and letting the resource leak into recall.
|
|
10154
10157
|
*/
|
|
10155
|
-
async resolveEntityTypes(
|
|
10158
|
+
async resolveEntityTypes(resourceId6) {
|
|
10156
10159
|
const { resource } = await busRequest(
|
|
10157
10160
|
this.bus,
|
|
10158
10161
|
"browse:resource-requested",
|
|
10159
|
-
{ resourceId }
|
|
10162
|
+
{ resourceId: resourceId6 }
|
|
10160
10163
|
);
|
|
10161
10164
|
return getResourceEntityTypes(resource);
|
|
10162
10165
|
}
|
|
@@ -10240,11 +10243,11 @@ var Smelter = class _Smelter {
|
|
|
10240
10243
|
this.logger.info("Indexed annotation", { annotationId: String(aid) });
|
|
10241
10244
|
}
|
|
10242
10245
|
async handleAnnotationRemoved(event) {
|
|
10243
|
-
const
|
|
10244
|
-
if (!
|
|
10245
|
-
const aid = annotationId(
|
|
10246
|
+
const annotationId3 = event.payload.annotationId;
|
|
10247
|
+
if (!annotationId3) return;
|
|
10248
|
+
const aid = annotationId(annotationId3);
|
|
10246
10249
|
await this.vectorStore.deleteAnnotationVector(aid);
|
|
10247
|
-
this.logger.info("Deleted annotation vector", { annotationId:
|
|
10250
|
+
this.logger.info("Deleted annotation vector", { annotationId: annotationId3 });
|
|
10248
10251
|
}
|
|
10249
10252
|
/**
|
|
10250
10253
|
* Batch-embed chunks from multiple yield:created events in a single
|
|
@@ -10362,7 +10365,7 @@ var Smelter = class _Smelter {
|
|
|
10362
10365
|
// per resource (PERSIST-ANCHORS P0). Keys are resource ids today;
|
|
10363
10366
|
// P1 rekeys the store by content checksum and this lookup moves
|
|
10364
10367
|
// with it.
|
|
10365
|
-
this.
|
|
10368
|
+
this.anchoredStore.list().then((keys) => new Set(keys))
|
|
10366
10369
|
]);
|
|
10367
10370
|
const resources = await this.listAllResources();
|
|
10368
10371
|
this.logger.info("Reconcile started", {
|
|
@@ -10483,16 +10486,16 @@ var Smelter = class _Smelter {
|
|
|
10483
10486
|
* resource (S1/S2).
|
|
10484
10487
|
*/
|
|
10485
10488
|
async rebuildAnchors(command) {
|
|
10486
|
-
const { correlationId, resourceId } = command;
|
|
10489
|
+
const { correlationId, resourceId: resourceId6 } = command;
|
|
10487
10490
|
try {
|
|
10488
10491
|
let work;
|
|
10489
|
-
if (
|
|
10490
|
-
work = [{ type: "smelt:reanchor", resourceId, payload: {} }];
|
|
10492
|
+
if (resourceId6) {
|
|
10493
|
+
work = [{ type: "smelt:reanchor", resourceId: resourceId6, payload: {} }];
|
|
10491
10494
|
} else {
|
|
10492
10495
|
const resources = await this.listAllResources();
|
|
10493
10496
|
work = [...this.classifyEmbeddable(resources)].filter(([, catalog]) => catalog.yieldsGeometry).map(([rid]) => ({ type: "smelt:reanchor", resourceId: rid, payload: {} }));
|
|
10494
10497
|
}
|
|
10495
|
-
this.logger.info("Anchored-text rebuild started", { scoped:
|
|
10498
|
+
this.logger.info("Anchored-text rebuild started", { scoped: resourceId6 ?? null, resources: work.length });
|
|
10496
10499
|
const failed = await this.drain(work);
|
|
10497
10500
|
if (failed > 0) {
|
|
10498
10501
|
await this.bus.emit("smelt:rebuild-anchors-failed", {
|
|
@@ -10502,7 +10505,7 @@ var Smelter = class _Smelter {
|
|
|
10502
10505
|
return;
|
|
10503
10506
|
}
|
|
10504
10507
|
await this.bus.emit("smelt:rebuild-anchors-ok", correlationId ? { correlationId } : {});
|
|
10505
|
-
this.logger.info("Anchored-text rebuild complete", { scoped:
|
|
10508
|
+
this.logger.info("Anchored-text rebuild complete", { scoped: resourceId6 ?? null, resources: work.length });
|
|
10506
10509
|
} catch (error) {
|
|
10507
10510
|
this.logger.error("Anchored-text rebuild failed", { error: errField(error) });
|
|
10508
10511
|
try {
|
|
@@ -10555,6 +10558,98 @@ var Smelter = class _Smelter {
|
|
|
10555
10558
|
}
|
|
10556
10559
|
}
|
|
10557
10560
|
};
|
|
10561
|
+
var MATCHER_CHANNELS = [
|
|
10562
|
+
"match:search-requested"
|
|
10563
|
+
];
|
|
10564
|
+
|
|
10565
|
+
// src/gatherer.ts
|
|
10566
|
+
var GATHERER_CHANNELS = [
|
|
10567
|
+
"gather:requested",
|
|
10568
|
+
"gather:resource-requested"
|
|
10569
|
+
];
|
|
10570
|
+
var STOWER_CHANNELS = [
|
|
10571
|
+
"yield:create",
|
|
10572
|
+
"yield:clone-persist",
|
|
10573
|
+
"yield:update",
|
|
10574
|
+
"yield:mv",
|
|
10575
|
+
"mark:create",
|
|
10576
|
+
"mark:commit",
|
|
10577
|
+
"mark:delete",
|
|
10578
|
+
"mark:update-body",
|
|
10579
|
+
"frame:add-entity-type",
|
|
10580
|
+
"frame:add-tag-schema",
|
|
10581
|
+
"mark:archive",
|
|
10582
|
+
"mark:unarchive",
|
|
10583
|
+
"mark:update-entity-types",
|
|
10584
|
+
"job:start",
|
|
10585
|
+
"job:complete",
|
|
10586
|
+
"job:fail"
|
|
10587
|
+
];
|
|
10588
|
+
|
|
10589
|
+
// src/browser.ts
|
|
10590
|
+
var BROWSER_CHANNELS = [
|
|
10591
|
+
"browse:resource-requested",
|
|
10592
|
+
"browse:anchored-text-requested",
|
|
10593
|
+
"browse:anchored-text-by-checksum-requested",
|
|
10594
|
+
"browse:resources-requested",
|
|
10595
|
+
"browse:annotations-requested",
|
|
10596
|
+
"browse:annotation-requested",
|
|
10597
|
+
"browse:events-requested",
|
|
10598
|
+
"browse:annotation-history-requested",
|
|
10599
|
+
"browse:referenced-by-requested",
|
|
10600
|
+
"browse:entity-types-requested",
|
|
10601
|
+
"browse:tag-schemas-requested",
|
|
10602
|
+
"browse:agents-requested",
|
|
10603
|
+
"browse:directory-requested"
|
|
10604
|
+
];
|
|
10605
|
+
|
|
10606
|
+
// src/clone-token-manager.ts
|
|
10607
|
+
var CLONE_TOKEN_CHANNELS = [
|
|
10608
|
+
"yield:clone-token-requested",
|
|
10609
|
+
"yield:clone-resource-requested",
|
|
10610
|
+
"yield:clone-create"
|
|
10611
|
+
];
|
|
10612
|
+
|
|
10613
|
+
// src/service-channels.ts
|
|
10614
|
+
var SMELTER_AWAITED_OPERATIONS = [
|
|
10615
|
+
"browse:resource-requested",
|
|
10616
|
+
"browse:annotations-requested",
|
|
10617
|
+
"browse:resources-requested"
|
|
10618
|
+
];
|
|
10619
|
+
var SMELTER_REPLY_CHANNELS = replyChannelsFor(SMELTER_AWAITED_OPERATIONS);
|
|
10620
|
+
var WEAVER_AWAITED_OPERATIONS = [
|
|
10621
|
+
"browse:resources-requested",
|
|
10622
|
+
"browse:events-requested",
|
|
10623
|
+
"browse:annotations-requested"
|
|
10624
|
+
];
|
|
10625
|
+
replyChannelsFor(WEAVER_AWAITED_OPERATIONS);
|
|
10626
|
+
var LIBRARIAN_INBOUND_CHANNELS = [
|
|
10627
|
+
...MATCHER_CHANNELS,
|
|
10628
|
+
...GATHERER_CHANNELS,
|
|
10629
|
+
"gather:summary-requested",
|
|
10630
|
+
"weave:applied",
|
|
10631
|
+
"smelt:settled"
|
|
10632
|
+
];
|
|
10633
|
+
replyChannelsFor(LIBRARIAN_INBOUND_CHANNELS);
|
|
10634
|
+
var ARCHIVIST_INBOUND_CHANNELS = [
|
|
10635
|
+
...STOWER_CHANNELS,
|
|
10636
|
+
...BROWSER_CHANNELS,
|
|
10637
|
+
...CLONE_TOKEN_CHANNELS,
|
|
10638
|
+
"mark:create-request",
|
|
10639
|
+
"smelt:settled",
|
|
10640
|
+
// The annotation-context read moved here with the bytes (SINGLE-KB-MOUNT D5).
|
|
10641
|
+
"browse:annotation-context-requested"
|
|
10642
|
+
];
|
|
10643
|
+
var ARCHIVIST_OUTBOUND_STRAYS = [
|
|
10644
|
+
"mark:body-update-failed",
|
|
10645
|
+
// op keyed 'bind:update-body' (gateway handler re-emits mark:update-body)
|
|
10646
|
+
"yield:move-failed"
|
|
10647
|
+
// yield:mv has no registered operation; failure is direct-subscribed
|
|
10648
|
+
];
|
|
10649
|
+
[
|
|
10650
|
+
...ARCHIVIST_OUTBOUND_STRAYS,
|
|
10651
|
+
...replyChannelsFor(ARCHIVIST_INBOUND_CHANNELS)
|
|
10652
|
+
];
|
|
10558
10653
|
var configPath = join(homedir(), ".semiontconfig");
|
|
10559
10654
|
var tomlReader = {
|
|
10560
10655
|
readIfExists: (p) => existsSync(p) ? readFileSync(p, "utf-8") : null
|
|
@@ -10564,11 +10659,11 @@ var envConfig = createTomlConfigLoader(
|
|
|
10564
10659
|
configPath,
|
|
10565
10660
|
process.env
|
|
10566
10661
|
)(null);
|
|
10567
|
-
var
|
|
10568
|
-
if (!
|
|
10569
|
-
throw new Error("services.
|
|
10662
|
+
var gatewayPublicURL = envConfig.services?.gateway?.publicURL;
|
|
10663
|
+
if (!gatewayPublicURL) {
|
|
10664
|
+
throw new Error("services.gateway.publicURL is required in ~/.semiontconfig");
|
|
10570
10665
|
}
|
|
10571
|
-
var baseUrl =
|
|
10666
|
+
var baseUrl = gatewayPublicURL;
|
|
10572
10667
|
var embedding = envConfig.services?.embedding;
|
|
10573
10668
|
if (!embedding?.type || !embedding?.model) {
|
|
10574
10669
|
throw new Error("services.embedding.{type,model} are required in ~/.semiontconfig");
|
|
@@ -10590,7 +10685,7 @@ var chunkingConfig = {
|
|
|
10590
10685
|
overlap: embedding.chunking?.overlap ?? 64
|
|
10591
10686
|
};
|
|
10592
10687
|
var workerSecret = process.env.SEMIONT_WORKER_SECRET ?? "";
|
|
10593
|
-
var healthPort =
|
|
10688
|
+
var healthPort = 24101;
|
|
10594
10689
|
var logger = createProcessLogger("smelter");
|
|
10595
10690
|
async function authenticate() {
|
|
10596
10691
|
if (!workerSecret) {
|
|
@@ -10617,7 +10712,7 @@ async function authenticate() {
|
|
|
10617
10712
|
isTransientFetchError,
|
|
10618
10713
|
STARTUP_FETCH_RETRY,
|
|
10619
10714
|
({ attempt, attempts, delayMs, error }) => {
|
|
10620
|
-
logger.warn("
|
|
10715
|
+
logger.warn("Gateway unreachable, retrying authentication", {
|
|
10621
10716
|
attempt,
|
|
10622
10717
|
attempts,
|
|
10623
10718
|
retryInMs: delayMs,
|
|
@@ -10661,19 +10756,30 @@ async function main() {
|
|
|
10661
10756
|
const httpTransport = new HttpTransport({
|
|
10662
10757
|
baseUrl: baseUrl$1(baseUrl),
|
|
10663
10758
|
token$: tokenSubject,
|
|
10664
|
-
tokenRefresher: refreshToken
|
|
10759
|
+
tokenRefresher: refreshToken,
|
|
10760
|
+
// Only the reply channels this process awaits — not the full bridged
|
|
10761
|
+
// set, whose global reply fan-out is the worker-OOM failure mode. See
|
|
10762
|
+
// SMELTER_AWAITED_OPERATIONS. The domain-event channels are added by
|
|
10763
|
+
// the actor state unit's start() below.
|
|
10764
|
+
channels: SMELTER_REPLY_CHANNELS
|
|
10665
10765
|
});
|
|
10666
10766
|
const actorStateUnit = createSmelterActorStateUnit({
|
|
10667
10767
|
bus: httpTransport.actor
|
|
10668
10768
|
});
|
|
10669
|
-
const
|
|
10670
|
-
logger.info("Content
|
|
10769
|
+
const contentReads = archivistContentReads(envConfig);
|
|
10770
|
+
logger.info("Content reads ready", { via: "archivist" });
|
|
10771
|
+
const anchoredTextDir = process.env.SEMIONT_ANCHORED_TEXT_DIR;
|
|
10772
|
+
if (!anchoredTextDir) {
|
|
10773
|
+
throw new Error("SEMIONT_ANCHORED_TEXT_DIR is required \u2014 the Smelter owns the anchored-text store and has no default for where it lives");
|
|
10774
|
+
}
|
|
10775
|
+
const anchoredStore = createAnchoredTextStore(anchoredTextDir, logger.child({ component: "anchored-text-store" }));
|
|
10671
10776
|
const smelter = new Smelter(
|
|
10672
10777
|
actorStateUnit.events$,
|
|
10673
10778
|
actorStateUnit.rebuildAnchors$,
|
|
10674
10779
|
vectorStore,
|
|
10675
10780
|
embeddingProvider,
|
|
10676
|
-
|
|
10781
|
+
contentReads,
|
|
10782
|
+
anchoredStore,
|
|
10677
10783
|
httpTransport,
|
|
10678
10784
|
chunkingConfig,
|
|
10679
10785
|
{ burstWindowMs: 50, maxBatchSize: 100, idleTimeoutMs: 200 },
|