@semiont/make-meaning 0.5.9 → 0.5.10
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.d.ts +34 -29
- package/dist/index.js +472 -455
- package/dist/index.js.map +1 -1
- package/dist/smelter-main.js +26 -12
- package/dist/smelter-main.js.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FsJobQueue } from '@semiont/jobs';
|
|
2
2
|
import { FilesystemViewStorage, resolveStorageUri, EventQuery, createEventStore } from '@semiont/event-sourcing';
|
|
3
|
-
import { getPrimaryRepresentation, decodeRepresentation,
|
|
3
|
+
import { getPrimaryRepresentation, decodeRepresentation, getResourceEntityTypes, getResourceId, getTargetSource, resourceId, getBodySource, getTargetSelector, deriveViews, getTextPositionSelector, annotationId, errField, userId, generateUuid, getExactText, busRequest, cloneToken, baseMediaType, isSupportedMediaType, capabilitiesOf, didToAgent, assembleAnnotation, jobId, entityType, baseUrl, busLog, BRIDGED_CHANNELS, burstBuffer, textExtractionOf, getPrimaryMediaType, extensionForMediaType, applyBodyOperations, findBodyItem } from '@semiont/core';
|
|
4
4
|
import { withActorSpan, recordBusEmit, withSpan, SpanKind, registerJobQueueProvider, registerVectorIndexSizeProvider } from '@semiont/observability';
|
|
5
5
|
import { createInferenceClient } from '@semiont/inference';
|
|
6
6
|
import { getGraphDatabase } from '@semiont/graph';
|
|
@@ -9,7 +9,6 @@ import { getEntityTypes, DEFAULT_ENTITY_TYPES } from '@semiont/ontology';
|
|
|
9
9
|
import { promises } from 'fs';
|
|
10
10
|
import * as path3 from 'path';
|
|
11
11
|
import { chunkText } from '@semiont/vectors';
|
|
12
|
-
import { busRequest } from '@semiont/sdk';
|
|
13
12
|
import { createGzip, createGunzip } from 'zlib';
|
|
14
13
|
import { pipeline, Readable } from 'stream';
|
|
15
14
|
import { promisify } from 'util';
|
|
@@ -3569,7 +3568,7 @@ var require_firstValueFrom = __commonJS({
|
|
|
3569
3568
|
exports.firstValueFrom = void 0;
|
|
3570
3569
|
var EmptyError_1 = require_EmptyError();
|
|
3571
3570
|
var Subscriber_1 = require_Subscriber();
|
|
3572
|
-
function
|
|
3571
|
+
function firstValueFrom2(source, config) {
|
|
3573
3572
|
var hasConfig = typeof config === "object";
|
|
3574
3573
|
return new Promise(function(resolve2, reject) {
|
|
3575
3574
|
var subscriber = new Subscriber_1.SafeSubscriber({
|
|
@@ -3589,7 +3588,7 @@ var require_firstValueFrom = __commonJS({
|
|
|
3589
3588
|
source.subscribe(subscriber);
|
|
3590
3589
|
});
|
|
3591
3590
|
}
|
|
3592
|
-
exports.firstValueFrom =
|
|
3591
|
+
exports.firstValueFrom = firstValueFrom2;
|
|
3593
3592
|
}
|
|
3594
3593
|
});
|
|
3595
3594
|
|
|
@@ -3728,7 +3727,7 @@ var require_map = __commonJS({
|
|
|
3728
3727
|
exports.map = void 0;
|
|
3729
3728
|
var lift_1 = require_lift();
|
|
3730
3729
|
var OperatorSubscriber_1 = require_OperatorSubscriber();
|
|
3731
|
-
function
|
|
3730
|
+
function map3(project, thisArg) {
|
|
3732
3731
|
return lift_1.operate(function(source, subscriber) {
|
|
3733
3732
|
var index = 0;
|
|
3734
3733
|
source.subscribe(OperatorSubscriber_1.createOperatorSubscriber(subscriber, function(value) {
|
|
@@ -3736,7 +3735,7 @@ var require_map = __commonJS({
|
|
|
3736
3735
|
}));
|
|
3737
3736
|
});
|
|
3738
3737
|
}
|
|
3739
|
-
exports.map =
|
|
3738
|
+
exports.map = map3;
|
|
3740
3739
|
}
|
|
3741
3740
|
});
|
|
3742
3741
|
|
|
@@ -4566,7 +4565,7 @@ var require_timer = __commonJS({
|
|
|
4566
4565
|
var async_1 = require_async();
|
|
4567
4566
|
var isScheduler_1 = require_isScheduler();
|
|
4568
4567
|
var isDate_1 = require_isDate();
|
|
4569
|
-
function
|
|
4568
|
+
function timer2(dueTime, intervalOrScheduler, scheduler) {
|
|
4570
4569
|
if (dueTime === void 0) {
|
|
4571
4570
|
dueTime = 0;
|
|
4572
4571
|
}
|
|
@@ -4599,7 +4598,7 @@ var require_timer = __commonJS({
|
|
|
4599
4598
|
}, due);
|
|
4600
4599
|
});
|
|
4601
4600
|
}
|
|
4602
|
-
exports.timer =
|
|
4601
|
+
exports.timer = timer2;
|
|
4603
4602
|
}
|
|
4604
4603
|
});
|
|
4605
4604
|
|
|
@@ -4789,7 +4788,7 @@ var require_race = __commonJS({
|
|
|
4789
4788
|
var innerFrom_1 = require_innerFrom();
|
|
4790
4789
|
var argsOrArgArray_1 = require_argsOrArgArray();
|
|
4791
4790
|
var OperatorSubscriber_1 = require_OperatorSubscriber();
|
|
4792
|
-
function
|
|
4791
|
+
function race2() {
|
|
4793
4792
|
var sources = [];
|
|
4794
4793
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
4795
4794
|
sources[_i] = arguments[_i];
|
|
@@ -4797,7 +4796,7 @@ var require_race = __commonJS({
|
|
|
4797
4796
|
sources = argsOrArgArray_1.argsOrArgArray(sources);
|
|
4798
4797
|
return sources.length === 1 ? innerFrom_1.innerFrom(sources[0]) : new Observable_1.Observable(raceInit(sources));
|
|
4799
4798
|
}
|
|
4800
|
-
exports.race =
|
|
4799
|
+
exports.race = race2;
|
|
4801
4800
|
function raceInit(sources) {
|
|
4802
4801
|
return function(subscriber) {
|
|
4803
4802
|
var subscriptions = [];
|
|
@@ -5371,13 +5370,13 @@ var require_catchError = __commonJS({
|
|
|
5371
5370
|
var innerFrom_1 = require_innerFrom();
|
|
5372
5371
|
var OperatorSubscriber_1 = require_OperatorSubscriber();
|
|
5373
5372
|
var lift_1 = require_lift();
|
|
5374
|
-
function
|
|
5373
|
+
function catchError2(selector) {
|
|
5375
5374
|
return lift_1.operate(function(source, subscriber) {
|
|
5376
5375
|
var innerSub = null;
|
|
5377
5376
|
var syncUnsub = false;
|
|
5378
5377
|
var handledResult;
|
|
5379
5378
|
innerSub = source.subscribe(OperatorSubscriber_1.createOperatorSubscriber(subscriber, void 0, void 0, function(err) {
|
|
5380
|
-
handledResult = innerFrom_1.innerFrom(selector(err,
|
|
5379
|
+
handledResult = innerFrom_1.innerFrom(selector(err, catchError2(selector)(source)));
|
|
5381
5380
|
if (innerSub) {
|
|
5382
5381
|
innerSub.unsubscribe();
|
|
5383
5382
|
innerSub = null;
|
|
@@ -5393,7 +5392,7 @@ var require_catchError = __commonJS({
|
|
|
5393
5392
|
}
|
|
5394
5393
|
});
|
|
5395
5394
|
}
|
|
5396
|
-
exports.catchError =
|
|
5395
|
+
exports.catchError = catchError2;
|
|
5397
5396
|
}
|
|
5398
5397
|
});
|
|
5399
5398
|
|
|
@@ -5888,7 +5887,7 @@ var require_take = __commonJS({
|
|
|
5888
5887
|
var empty_1 = require_empty();
|
|
5889
5888
|
var lift_1 = require_lift();
|
|
5890
5889
|
var OperatorSubscriber_1 = require_OperatorSubscriber();
|
|
5891
|
-
function
|
|
5890
|
+
function take(count) {
|
|
5892
5891
|
return count <= 0 ? function() {
|
|
5893
5892
|
return empty_1.EMPTY;
|
|
5894
5893
|
} : lift_1.operate(function(source, subscriber) {
|
|
@@ -5903,7 +5902,7 @@ var require_take = __commonJS({
|
|
|
5903
5902
|
}));
|
|
5904
5903
|
});
|
|
5905
5904
|
}
|
|
5906
|
-
exports.take =
|
|
5905
|
+
exports.take = take;
|
|
5907
5906
|
}
|
|
5908
5907
|
});
|
|
5909
5908
|
|
|
@@ -9253,14 +9252,14 @@ var require_race2 = __commonJS({
|
|
|
9253
9252
|
exports.race = void 0;
|
|
9254
9253
|
var argsOrArgArray_1 = require_argsOrArgArray();
|
|
9255
9254
|
var raceWith_1 = require_raceWith();
|
|
9256
|
-
function
|
|
9255
|
+
function race2() {
|
|
9257
9256
|
var args = [];
|
|
9258
9257
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
9259
9258
|
args[_i] = arguments[_i];
|
|
9260
9259
|
}
|
|
9261
9260
|
return raceWith_1.raceWith.apply(void 0, __spreadArray([], __read(argsOrArgArray_1.argsOrArgArray(args))));
|
|
9262
9261
|
}
|
|
9263
|
-
exports.race =
|
|
9262
|
+
exports.race = race2;
|
|
9264
9263
|
}
|
|
9265
9264
|
});
|
|
9266
9265
|
|
|
@@ -9736,8 +9735,8 @@ function resolveActorInference(config, actor) {
|
|
|
9736
9735
|
}
|
|
9737
9736
|
|
|
9738
9737
|
// src/service.ts
|
|
9739
|
-
var
|
|
9740
|
-
var
|
|
9738
|
+
var import_rxjs7 = __toESM(require_cjs());
|
|
9739
|
+
var import_operators7 = __toESM(require_operators());
|
|
9741
9740
|
|
|
9742
9741
|
// src/graph/consumer.ts
|
|
9743
9742
|
var import_rxjs = __toESM(require_cjs());
|
|
@@ -10293,6 +10292,93 @@ var ResourceContext = class _ResourceContext {
|
|
|
10293
10292
|
return void 0;
|
|
10294
10293
|
}
|
|
10295
10294
|
};
|
|
10295
|
+
var GraphContext = class {
|
|
10296
|
+
/**
|
|
10297
|
+
* Get all resources referencing this resource (backlinks)
|
|
10298
|
+
* Requires graph traversal - must use graph database
|
|
10299
|
+
*/
|
|
10300
|
+
static async getBacklinks(resourceId10, kb) {
|
|
10301
|
+
return kb.graph.getResourceReferencedBy(resourceId10);
|
|
10302
|
+
}
|
|
10303
|
+
/**
|
|
10304
|
+
* Find shortest path between two resources
|
|
10305
|
+
* Requires graph traversal - must use graph database
|
|
10306
|
+
*/
|
|
10307
|
+
static async findPath(fromResourceId, toResourceId, kb, maxDepth) {
|
|
10308
|
+
return kb.graph.findPath(fromResourceId, toResourceId, maxDepth);
|
|
10309
|
+
}
|
|
10310
|
+
/**
|
|
10311
|
+
* Get resource connections (graph edges)
|
|
10312
|
+
* Requires graph traversal - must use graph database
|
|
10313
|
+
*/
|
|
10314
|
+
static async getResourceConnections(resourceId10, kb) {
|
|
10315
|
+
return kb.graph.getResourceConnections(resourceId10);
|
|
10316
|
+
}
|
|
10317
|
+
/**
|
|
10318
|
+
* Search resources by name (cross-resource query)
|
|
10319
|
+
* Requires full-text search - must use graph database
|
|
10320
|
+
*/
|
|
10321
|
+
static async searchResources(query, kb, limit) {
|
|
10322
|
+
return kb.graph.searchResources(query, limit);
|
|
10323
|
+
}
|
|
10324
|
+
/**
|
|
10325
|
+
* Build the unified knowledge graph for a resource's neighborhood:
|
|
10326
|
+
* resources AND annotations as typed nodes, typed/directional edges.
|
|
10327
|
+
*
|
|
10328
|
+
* This is the single graph builder (CONTEXT-UNIFICATION D3) — both the
|
|
10329
|
+
* matcher (ranking) and the resource/viz path consume it. The flattened
|
|
10330
|
+
* signals the matcher reads today (`connections`, `citedBy`/count,
|
|
10331
|
+
* `siblingEntityTypes`, `bidirectional`) are all derivable from this:
|
|
10332
|
+
* - peer connections → resource nodes + main→peer edges carrying `bidirectional`
|
|
10333
|
+
* - inbound citations → citing-resource nodes + `citation` edges (citing→main),
|
|
10334
|
+
* so citedByCount = inbound citation-edge count
|
|
10335
|
+
* - annotations on the resource → `annotation` nodes + `annotation-of` edges,
|
|
10336
|
+
* so siblingEntityTypes = union of those nodes' entityTypes
|
|
10337
|
+
*/
|
|
10338
|
+
static async buildKnowledgeGraph(resourceId10, kb) {
|
|
10339
|
+
const mainDoc = await kb.graph.getResource(resourceId10);
|
|
10340
|
+
if (!mainDoc) {
|
|
10341
|
+
throw new Error("Resource not found");
|
|
10342
|
+
}
|
|
10343
|
+
const mainId = String(resourceId10);
|
|
10344
|
+
const [connections, referencedBy, annotations] = await Promise.all([
|
|
10345
|
+
kb.graph.getResourceConnections(resourceId10),
|
|
10346
|
+
kb.graph.getResourceReferencedBy(resourceId10),
|
|
10347
|
+
kb.graph.getResourceAnnotations(resourceId10)
|
|
10348
|
+
]);
|
|
10349
|
+
const nodes = [];
|
|
10350
|
+
const edges = [];
|
|
10351
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10352
|
+
const addResourceNode = (id, label, entityTypes) => {
|
|
10353
|
+
if (!id || seen.has(id)) return;
|
|
10354
|
+
nodes.push({ id, type: "resource", label, entityTypes });
|
|
10355
|
+
seen.add(id);
|
|
10356
|
+
};
|
|
10357
|
+
addResourceNode(mainId, mainDoc.name, getResourceEntityTypes(mainDoc));
|
|
10358
|
+
for (const conn of connections) {
|
|
10359
|
+
const peerId = getResourceId(conn.targetResource);
|
|
10360
|
+
if (!peerId) continue;
|
|
10361
|
+
addResourceNode(peerId, conn.targetResource.name, getResourceEntityTypes(conn.targetResource));
|
|
10362
|
+
edges.push({ source: mainId, target: peerId, type: conn.relationshipType || "link", bidirectional: conn.bidirectional });
|
|
10363
|
+
}
|
|
10364
|
+
const citedSeen = /* @__PURE__ */ new Set();
|
|
10365
|
+
for (const ann of referencedBy) {
|
|
10366
|
+
const source = getTargetSource(ann.target);
|
|
10367
|
+
if (!source || source === String(resourceId10) || citedSeen.has(source)) continue;
|
|
10368
|
+
citedSeen.add(source);
|
|
10369
|
+
const view = await kb.views.get(resourceId(source));
|
|
10370
|
+
addResourceNode(source, view?.resource?.name ?? source, view?.resource ? getResourceEntityTypes(view.resource) : []);
|
|
10371
|
+
edges.push({ source, target: mainId, type: "citation" });
|
|
10372
|
+
}
|
|
10373
|
+
for (const ann of annotations) {
|
|
10374
|
+
if (!ann.id || seen.has(ann.id)) continue;
|
|
10375
|
+
nodes.push({ id: ann.id, type: "annotation", label: ann.motivation ?? "annotation", entityTypes: getEntityTypes(ann) });
|
|
10376
|
+
seen.add(ann.id);
|
|
10377
|
+
edges.push({ source: ann.id, target: mainId, type: "annotation-of" });
|
|
10378
|
+
}
|
|
10379
|
+
return { nodes, edges };
|
|
10380
|
+
}
|
|
10381
|
+
};
|
|
10296
10382
|
|
|
10297
10383
|
// src/annotation-context.ts
|
|
10298
10384
|
var AnnotationContext = class {
|
|
@@ -10406,42 +10492,21 @@ var AnnotationContext = class {
|
|
|
10406
10492
|
};
|
|
10407
10493
|
}
|
|
10408
10494
|
}
|
|
10409
|
-
logger?.debug("Building graph
|
|
10410
|
-
const
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
kb.graph.getEntityTypeStats()
|
|
10414
|
-
]);
|
|
10415
|
-
const citedByMap = /* @__PURE__ */ new Map();
|
|
10416
|
-
for (const ann of referencedByAnnotations) {
|
|
10417
|
-
const source = getTargetSource(ann.target);
|
|
10418
|
-
if (source && source !== String(resourceId10)) {
|
|
10419
|
-
const sourceResId = resourceId(source);
|
|
10420
|
-
const sourceView2 = await kb.views.get(sourceResId);
|
|
10421
|
-
if (sourceView2?.resource) {
|
|
10422
|
-
citedByMap.set(source, sourceView2.resource.name);
|
|
10423
|
-
}
|
|
10424
|
-
}
|
|
10425
|
-
}
|
|
10426
|
-
const annotationEntityTypes = getEntityTypes(annotation);
|
|
10427
|
-
const siblingEntityTypes = /* @__PURE__ */ new Set();
|
|
10428
|
-
for (const ann of sourceView.annotations.annotations) {
|
|
10429
|
-
if (ann.id !== annotationId5) {
|
|
10430
|
-
for (const et of getEntityTypes(ann)) {
|
|
10431
|
-
siblingEntityTypes.add(et);
|
|
10432
|
-
}
|
|
10433
|
-
}
|
|
10434
|
-
}
|
|
10495
|
+
logger?.debug("Building knowledge graph", { resourceId: resourceId10 });
|
|
10496
|
+
const graph = await GraphContext.buildKnowledgeGraph(resourceId10, kb);
|
|
10497
|
+
const views = deriveViews(graph, String(resourceId10), annotationId5);
|
|
10498
|
+
const entityTypeStats = await kb.graph.getEntityTypeStats();
|
|
10435
10499
|
const entityTypeFrequencies = {};
|
|
10436
10500
|
for (const stat of entityTypeStats) {
|
|
10437
10501
|
entityTypeFrequencies[stat.type] = stat.count;
|
|
10438
10502
|
}
|
|
10503
|
+
const annotationEntityTypes = getEntityTypes(annotation);
|
|
10439
10504
|
let inferredRelationshipSummary;
|
|
10440
10505
|
if (inferenceClient && sourceContext) {
|
|
10441
10506
|
try {
|
|
10442
|
-
const connNames = connections.map((c) => c.
|
|
10443
|
-
const citedByNames =
|
|
10444
|
-
const siblingTypes =
|
|
10507
|
+
const connNames = views.connections.map((c) => c.resourceName).slice(0, 10);
|
|
10508
|
+
const citedByNames = views.citedBy.map((c) => c.resourceName).slice(0, 5);
|
|
10509
|
+
const siblingTypes = views.siblingEntityTypes.slice(0, 10);
|
|
10445
10510
|
const parts = [];
|
|
10446
10511
|
parts.push(`Passage: "${sourceContext.selected}"`);
|
|
10447
10512
|
if (connNames.length > 0) parts.push(`Connected resources: ${connNames.join(", ")}`);
|
|
@@ -10459,27 +10524,6 @@ Summary:`;
|
|
|
10459
10524
|
logger?.warn("Failed to generate inferred relationship summary", { error });
|
|
10460
10525
|
}
|
|
10461
10526
|
}
|
|
10462
|
-
const graphContext = {
|
|
10463
|
-
connections: connections.map((conn) => ({
|
|
10464
|
-
resourceId: getResourceId(conn.targetResource) ?? "",
|
|
10465
|
-
resourceName: conn.targetResource.name,
|
|
10466
|
-
entityTypes: getResourceEntityTypes(conn.targetResource),
|
|
10467
|
-
bidirectional: conn.bidirectional
|
|
10468
|
-
})),
|
|
10469
|
-
citedByCount: citedByMap.size,
|
|
10470
|
-
citedBy: Array.from(citedByMap.entries()).map(([id, name]) => ({
|
|
10471
|
-
resourceId: id,
|
|
10472
|
-
resourceName: name
|
|
10473
|
-
})),
|
|
10474
|
-
siblingEntityTypes: Array.from(siblingEntityTypes),
|
|
10475
|
-
entityTypeFrequencies,
|
|
10476
|
-
...inferredRelationshipSummary ? { inferredRelationshipSummary } : {}
|
|
10477
|
-
};
|
|
10478
|
-
logger?.debug("Built graph context", {
|
|
10479
|
-
connections: connections.length,
|
|
10480
|
-
citedByCount: citedByMap.size,
|
|
10481
|
-
siblingEntityTypes: siblingEntityTypes.size
|
|
10482
|
-
});
|
|
10483
10527
|
let semanticContext;
|
|
10484
10528
|
if (kb.vectors && embeddingProvider && sourceContext?.selected) {
|
|
10485
10529
|
try {
|
|
@@ -10505,32 +10549,26 @@ Summary:`;
|
|
|
10505
10549
|
logger?.warn("Semantic context search failed", { error });
|
|
10506
10550
|
}
|
|
10507
10551
|
}
|
|
10508
|
-
const
|
|
10509
|
-
|
|
10510
|
-
|
|
10552
|
+
const context = {
|
|
10553
|
+
focus: {
|
|
10554
|
+
kind: "annotation",
|
|
10555
|
+
annotation,
|
|
10556
|
+
sourceResource: sourceDoc,
|
|
10557
|
+
...sourceContext ? { selected: { before: sourceContext.before || "", text: sourceContext.selected, after: sourceContext.after || "" } } : {},
|
|
10558
|
+
...targetDoc ? { targetResource: targetDoc } : {},
|
|
10559
|
+
...targetContext ? { targetContext } : {}
|
|
10560
|
+
},
|
|
10561
|
+
graph,
|
|
10511
10562
|
metadata: {
|
|
10512
10563
|
resourceType: "document",
|
|
10513
10564
|
language: sourceDoc.language,
|
|
10514
|
-
entityTypes: annotationEntityTypes
|
|
10565
|
+
entityTypes: annotationEntityTypes,
|
|
10566
|
+
entityTypeFrequencies
|
|
10515
10567
|
},
|
|
10516
|
-
|
|
10568
|
+
...inferredRelationshipSummary ? { inferredRelationshipSummary } : {},
|
|
10517
10569
|
...semanticContext ? { semanticContext } : {}
|
|
10518
10570
|
};
|
|
10519
|
-
|
|
10520
|
-
generationContext.sourceContext = {
|
|
10521
|
-
before: sourceContext.before || "",
|
|
10522
|
-
selected: sourceContext.selected,
|
|
10523
|
-
after: sourceContext.after || ""
|
|
10524
|
-
};
|
|
10525
|
-
}
|
|
10526
|
-
const response = {
|
|
10527
|
-
annotation,
|
|
10528
|
-
sourceResource: sourceDoc,
|
|
10529
|
-
targetResource: targetDoc,
|
|
10530
|
-
context: generationContext,
|
|
10531
|
-
...targetContext ? { targetContext } : {}
|
|
10532
|
-
};
|
|
10533
|
-
return response;
|
|
10571
|
+
return context;
|
|
10534
10572
|
}
|
|
10535
10573
|
/**
|
|
10536
10574
|
* Get resource annotations from view storage (fast path)
|
|
@@ -10764,69 +10802,6 @@ Entity types: ${entityTypes.join(", ")}`;
|
|
|
10764
10802
|
return inferenceClient.generateText(summaryPrompt, 500, 0.5);
|
|
10765
10803
|
}
|
|
10766
10804
|
};
|
|
10767
|
-
var GraphContext = class {
|
|
10768
|
-
/**
|
|
10769
|
-
* Get all resources referencing this resource (backlinks)
|
|
10770
|
-
* Requires graph traversal - must use graph database
|
|
10771
|
-
*/
|
|
10772
|
-
static async getBacklinks(resourceId10, kb) {
|
|
10773
|
-
return kb.graph.getResourceReferencedBy(resourceId10);
|
|
10774
|
-
}
|
|
10775
|
-
/**
|
|
10776
|
-
* Find shortest path between two resources
|
|
10777
|
-
* Requires graph traversal - must use graph database
|
|
10778
|
-
*/
|
|
10779
|
-
static async findPath(fromResourceId, toResourceId, kb, maxDepth) {
|
|
10780
|
-
return kb.graph.findPath(fromResourceId, toResourceId, maxDepth);
|
|
10781
|
-
}
|
|
10782
|
-
/**
|
|
10783
|
-
* Get resource connections (graph edges)
|
|
10784
|
-
* Requires graph traversal - must use graph database
|
|
10785
|
-
*/
|
|
10786
|
-
static async getResourceConnections(resourceId10, kb) {
|
|
10787
|
-
return kb.graph.getResourceConnections(resourceId10);
|
|
10788
|
-
}
|
|
10789
|
-
/**
|
|
10790
|
-
* Search resources by name (cross-resource query)
|
|
10791
|
-
* Requires full-text search - must use graph database
|
|
10792
|
-
*/
|
|
10793
|
-
static async searchResources(query, kb, limit) {
|
|
10794
|
-
return kb.graph.searchResources(query, limit);
|
|
10795
|
-
}
|
|
10796
|
-
/**
|
|
10797
|
-
* Build graph representation with nodes and edges for a resource and its connections
|
|
10798
|
-
* Retrieves connections from graph and builds visualization-ready structure
|
|
10799
|
-
*/
|
|
10800
|
-
static async buildGraphRepresentation(resourceId10, maxRelated, kb) {
|
|
10801
|
-
const mainDoc = await kb.graph.getResource(resourceId10);
|
|
10802
|
-
if (!mainDoc) {
|
|
10803
|
-
throw new Error("Resource not found");
|
|
10804
|
-
}
|
|
10805
|
-
const connections = await kb.graph.getResourceConnections(resourceId10);
|
|
10806
|
-
const relatedDocs = connections.map((conn) => conn.targetResource).slice(0, maxRelated - 1);
|
|
10807
|
-
const nodes = [
|
|
10808
|
-
{
|
|
10809
|
-
id: getResourceId(mainDoc),
|
|
10810
|
-
type: "resource",
|
|
10811
|
-
label: mainDoc.name,
|
|
10812
|
-
metadata: { entityTypes: getResourceEntityTypes(mainDoc) }
|
|
10813
|
-
},
|
|
10814
|
-
...relatedDocs.map((doc) => ({
|
|
10815
|
-
id: getResourceId(doc),
|
|
10816
|
-
type: "resource",
|
|
10817
|
-
label: doc.name,
|
|
10818
|
-
metadata: { entityTypes: getResourceEntityTypes(doc) }
|
|
10819
|
-
}))
|
|
10820
|
-
].filter((node) => node.id !== void 0);
|
|
10821
|
-
const edges = connections.slice(0, maxRelated - 1).map((conn) => ({
|
|
10822
|
-
source: resourceId10,
|
|
10823
|
-
target: getResourceId(conn.targetResource),
|
|
10824
|
-
type: conn.relationshipType || "link",
|
|
10825
|
-
metadata: {}
|
|
10826
|
-
})).filter((edge) => edge.target !== void 0);
|
|
10827
|
-
return { nodes, edges };
|
|
10828
|
-
}
|
|
10829
|
-
};
|
|
10830
10805
|
var LLMContext = class {
|
|
10831
10806
|
/**
|
|
10832
10807
|
* Get comprehensive LLM context for a resource
|
|
@@ -10838,35 +10813,29 @@ var LLMContext = class {
|
|
|
10838
10813
|
throw new Error("Resource not found");
|
|
10839
10814
|
}
|
|
10840
10815
|
const mainContent = options.includeContent ? await ResourceContext.getResourceContent(mainDoc, kb) : void 0;
|
|
10841
|
-
const graph = await GraphContext.
|
|
10842
|
-
resourceId10,
|
|
10843
|
-
options.maxResources,
|
|
10844
|
-
kb
|
|
10845
|
-
);
|
|
10846
|
-
const relatedDocs = [];
|
|
10816
|
+
const graph = await GraphContext.buildKnowledgeGraph(resourceId10, kb);
|
|
10847
10817
|
const resourceIdStr = resourceId10.toString();
|
|
10848
|
-
|
|
10849
|
-
|
|
10850
|
-
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
|
|
10818
|
+
const relatedDocs = [];
|
|
10819
|
+
const relatedNodes = graph.nodes.filter((node) => node.type === "resource" && node.id !== resourceIdStr).slice(0, Math.max(0, options.maxResources - 1));
|
|
10820
|
+
for (const node of relatedNodes) {
|
|
10821
|
+
const relatedDoc = await ResourceContext.getResourceMetadata(resourceId(node.id), kb);
|
|
10822
|
+
if (relatedDoc) {
|
|
10823
|
+
relatedDocs.push(relatedDoc);
|
|
10854
10824
|
}
|
|
10855
10825
|
}
|
|
10856
|
-
const
|
|
10826
|
+
const relatedContent = {};
|
|
10857
10827
|
if (options.includeContent) {
|
|
10858
10828
|
await Promise.all(
|
|
10859
10829
|
relatedDocs.map(async (doc) => {
|
|
10860
10830
|
const docId = getResourceId(doc);
|
|
10861
10831
|
if (!docId) return;
|
|
10862
|
-
const
|
|
10863
|
-
if (
|
|
10864
|
-
|
|
10832
|
+
const content2 = await ResourceContext.getResourceContent(doc, kb);
|
|
10833
|
+
if (content2) {
|
|
10834
|
+
relatedContent[docId] = content2;
|
|
10865
10835
|
}
|
|
10866
10836
|
})
|
|
10867
10837
|
);
|
|
10868
10838
|
}
|
|
10869
|
-
const annotations = await AnnotationContext.getAllAnnotations(resourceId10, kb);
|
|
10870
10839
|
const summary = options.includeSummary && mainContent ? await generateResourceSummary(
|
|
10871
10840
|
mainDoc.name,
|
|
10872
10841
|
mainContent,
|
|
@@ -10874,15 +10843,44 @@ var LLMContext = class {
|
|
|
10874
10843
|
inferenceClient
|
|
10875
10844
|
) : void 0;
|
|
10876
10845
|
const suggestedReferences = mainContent ? await generateReferenceSuggestions(mainContent, inferenceClient) : void 0;
|
|
10846
|
+
const content = {};
|
|
10847
|
+
if (mainContent) content.main = mainContent;
|
|
10848
|
+
if (options.includeContent) content.related = relatedContent;
|
|
10849
|
+
let semanticContext;
|
|
10850
|
+
if (kb.vectors) {
|
|
10851
|
+
const excludeEntityTypes = options.excludeEntityTypes ?? [];
|
|
10852
|
+
const matches = await kb.vectors.searchByResource(resourceId10, {
|
|
10853
|
+
limit: options.maxResources,
|
|
10854
|
+
scoreThreshold: 0.5,
|
|
10855
|
+
...excludeEntityTypes.length ? { filter: { excludeEntityTypes } } : {}
|
|
10856
|
+
});
|
|
10857
|
+
if (matches.length > 0) {
|
|
10858
|
+
semanticContext = {
|
|
10859
|
+
similar: matches.map((m) => ({
|
|
10860
|
+
text: m.text,
|
|
10861
|
+
resourceId: m.resourceId,
|
|
10862
|
+
...m.annotationId ? { annotationId: m.annotationId } : {},
|
|
10863
|
+
score: m.score,
|
|
10864
|
+
...m.entityTypes ? { entityTypes: m.entityTypes } : {}
|
|
10865
|
+
})),
|
|
10866
|
+
...excludeEntityTypes.length ? { excludedEntityTypes: excludeEntityTypes } : {}
|
|
10867
|
+
};
|
|
10868
|
+
}
|
|
10869
|
+
}
|
|
10877
10870
|
return {
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10871
|
+
focus: {
|
|
10872
|
+
kind: "resource",
|
|
10873
|
+
resource: mainDoc,
|
|
10874
|
+
...summary ? { summary } : {},
|
|
10875
|
+
...suggestedReferences ? { suggestedReferences } : {},
|
|
10876
|
+
...Object.keys(content).length > 0 ? { content } : {}
|
|
10877
|
+
},
|
|
10881
10878
|
graph,
|
|
10882
|
-
...
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10879
|
+
...semanticContext ? { semanticContext } : {},
|
|
10880
|
+
metadata: {
|
|
10881
|
+
resourceType: "document",
|
|
10882
|
+
language: mainDoc.language
|
|
10883
|
+
}
|
|
10886
10884
|
};
|
|
10887
10885
|
}
|
|
10888
10886
|
};
|
|
@@ -11042,8 +11040,13 @@ var Matcher = class {
|
|
|
11042
11040
|
async handleSearch(event) {
|
|
11043
11041
|
try {
|
|
11044
11042
|
const context = event.context;
|
|
11045
|
-
|
|
11046
|
-
|
|
11043
|
+
if (context.focus.kind !== "annotation") {
|
|
11044
|
+
throw new Error(`Matcher expected annotation focus, received '${context.focus.kind}'`);
|
|
11045
|
+
}
|
|
11046
|
+
const focus = context.focus;
|
|
11047
|
+
const mainResourceId = String(event.resourceId);
|
|
11048
|
+
const selectedText = focus.selected?.text ?? "";
|
|
11049
|
+
const userHint = focus.userHint ?? "";
|
|
11047
11050
|
const searchTerm = [selectedText, userHint].filter(Boolean).join(" ");
|
|
11048
11051
|
this.logger.debug("Searching for binding candidates", {
|
|
11049
11052
|
referenceId: event.referenceId,
|
|
@@ -11054,6 +11057,8 @@ var Matcher = class {
|
|
|
11054
11057
|
const scored = await this.contextDrivenSearch(
|
|
11055
11058
|
searchTerm,
|
|
11056
11059
|
context,
|
|
11060
|
+
focus,
|
|
11061
|
+
mainResourceId,
|
|
11057
11062
|
event.useSemanticScoring
|
|
11058
11063
|
);
|
|
11059
11064
|
const limited = event.limit ? scored.slice(0, event.limit) : scored;
|
|
@@ -11089,9 +11094,10 @@ var Matcher = class {
|
|
|
11089
11094
|
* - Name match quality (exact > prefix > contains)
|
|
11090
11095
|
* - Recency (newer resources scored higher)
|
|
11091
11096
|
*/
|
|
11092
|
-
async contextDrivenSearch(searchTerm, context, useSemanticScoring) {
|
|
11093
|
-
const annotationEntityTypes = context.metadata
|
|
11094
|
-
const
|
|
11097
|
+
async contextDrivenSearch(searchTerm, context, focus, mainResourceId, useSemanticScoring) {
|
|
11098
|
+
const annotationEntityTypes = context.metadata.entityTypes ?? [];
|
|
11099
|
+
const views = deriveViews(context.graph, mainResourceId);
|
|
11100
|
+
const connections = views.connections;
|
|
11095
11101
|
const [nameMatches, entityTypeMatches, semanticMatches] = await Promise.all([
|
|
11096
11102
|
this.kb.graph.searchResources(searchTerm),
|
|
11097
11103
|
annotationEntityTypes.length > 0 ? this.kb.graph.listResources({ entityTypes: annotationEntityTypes, limit: 50 }).then((r) => r.resources) : Promise.resolve([]),
|
|
@@ -11136,7 +11142,7 @@ var Matcher = class {
|
|
|
11136
11142
|
const bidirectionalIds = new Set(
|
|
11137
11143
|
connections.filter((c) => c.bidirectional).map((c) => c.resourceId)
|
|
11138
11144
|
);
|
|
11139
|
-
const entityTypeFreqs = context.
|
|
11145
|
+
const entityTypeFreqs = context.metadata.entityTypeFrequencies ?? {};
|
|
11140
11146
|
const searchTermLower = searchTerm.toLowerCase();
|
|
11141
11147
|
const scored = Array.from(candidateMap.values()).map(({ resource, sources }) => {
|
|
11142
11148
|
const id = getResourceId(resource) ?? "";
|
|
@@ -11165,7 +11171,7 @@ var Matcher = class {
|
|
|
11165
11171
|
score += 10;
|
|
11166
11172
|
reasons.push("connected");
|
|
11167
11173
|
}
|
|
11168
|
-
const citedByCount =
|
|
11174
|
+
const citedByCount = views.citedByCount;
|
|
11169
11175
|
if (sources.has("neighborhood") && citedByCount > 0) {
|
|
11170
11176
|
score += Math.min(citedByCount * 2, 15);
|
|
11171
11177
|
}
|
|
@@ -11206,6 +11212,8 @@ var Matcher = class {
|
|
|
11206
11212
|
const inferenceScores = await this.inferenceSemanticScore(
|
|
11207
11213
|
searchTerm,
|
|
11208
11214
|
context,
|
|
11215
|
+
focus,
|
|
11216
|
+
connections,
|
|
11209
11217
|
scored.slice(0, 20)
|
|
11210
11218
|
// Limit to top 20 candidates for cost
|
|
11211
11219
|
);
|
|
@@ -11240,20 +11248,18 @@ var Matcher = class {
|
|
|
11240
11248
|
*
|
|
11241
11249
|
* @returns Map of resourceId → score (0-1)
|
|
11242
11250
|
*/
|
|
11243
|
-
async inferenceSemanticScore(searchTerm, context, candidates) {
|
|
11244
|
-
const passage = [
|
|
11245
|
-
const entityTypes = context.metadata
|
|
11246
|
-
const graphConnections = context.graphContext?.connections;
|
|
11247
|
-
const connections = graphConnections ?? [];
|
|
11251
|
+
async inferenceSemanticScore(searchTerm, context, focus, connections, candidates) {
|
|
11252
|
+
const passage = [focus.selected?.text, focus.userHint].filter(Boolean).join(" \u2014 ") || searchTerm;
|
|
11253
|
+
const entityTypes = context.metadata.entityTypes ?? [];
|
|
11248
11254
|
const candidateLines = candidates.map((c, i) => {
|
|
11249
11255
|
const id = getResourceId(c) ?? "";
|
|
11250
11256
|
const cEntityTypes = getResourceEntityTypes(c);
|
|
11251
11257
|
return `${i + 1}. "${c.name}" (id: ${id}, types: ${cEntityTypes.join(", ") || "none"})`;
|
|
11252
11258
|
}).join("\n");
|
|
11253
11259
|
const contextParts = [];
|
|
11254
|
-
contextParts.push(`Annotation motivation: ${
|
|
11255
|
-
contextParts.push(`Source resource: ${
|
|
11256
|
-
const { motivation, body } =
|
|
11260
|
+
contextParts.push(`Annotation motivation: ${focus.annotation.motivation}`);
|
|
11261
|
+
contextParts.push(`Source resource: ${focus.sourceResource.name}`);
|
|
11262
|
+
const { motivation, body } = focus.annotation;
|
|
11257
11263
|
if (motivation === "commenting" || motivation === "assessing") {
|
|
11258
11264
|
const bodyItem = Array.isArray(body) ? body[0] : body;
|
|
11259
11265
|
if (bodyItem && "value" in bodyItem && bodyItem.value) {
|
|
@@ -11266,8 +11272,8 @@ var Matcher = class {
|
|
|
11266
11272
|
const connNames = connections.slice(0, 5).map((c) => c.resourceName);
|
|
11267
11273
|
contextParts.push(`Connected resources: ${connNames.join(", ")}`);
|
|
11268
11274
|
}
|
|
11269
|
-
if (context.
|
|
11270
|
-
contextParts.push(`Relationship context: ${context.
|
|
11275
|
+
if (context.inferredRelationshipSummary) {
|
|
11276
|
+
contextParts.push(`Relationship context: ${context.inferredRelationshipSummary}`);
|
|
11271
11277
|
}
|
|
11272
11278
|
const prompt = `Given this passage and context, score each candidate resource's semantic relevance on a scale of 0.0 to 1.0.
|
|
11273
11279
|
|
|
@@ -11411,26 +11417,10 @@ var Stower = class {
|
|
|
11411
11417
|
generator: event.generator
|
|
11412
11418
|
}
|
|
11413
11419
|
});
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
|
|
11418
|
-
archived: false,
|
|
11419
|
-
entityTypes: event.entityTypes || [],
|
|
11420
|
-
storageUri: event.storageUri,
|
|
11421
|
-
currentChecksum: checksum,
|
|
11422
|
-
dateCreated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11423
|
-
representations: [
|
|
11424
|
-
{
|
|
11425
|
-
mediaType: event.format,
|
|
11426
|
-
checksum,
|
|
11427
|
-
byteSize,
|
|
11428
|
-
rel: "original",
|
|
11429
|
-
language: event.language
|
|
11430
|
-
}
|
|
11431
|
-
]
|
|
11432
|
-
};
|
|
11433
|
-
this.eventBus.get("yield:create-ok").next({ resourceId: rId, resource });
|
|
11420
|
+
this.eventBus.get("yield:create-ok").next({
|
|
11421
|
+
correlationId: event.correlationId,
|
|
11422
|
+
response: { resourceId: rId }
|
|
11423
|
+
});
|
|
11434
11424
|
if (generatedFrom) {
|
|
11435
11425
|
this.eventBus.get("mark:update-body").next({
|
|
11436
11426
|
annotationId: generatedFrom.annotationId,
|
|
@@ -11456,6 +11446,7 @@ var Stower = class {
|
|
|
11456
11446
|
} catch (error) {
|
|
11457
11447
|
this.logger.error("Failed to create resource", { error: errField(error) });
|
|
11458
11448
|
this.eventBus.get("yield:create-failed").next({
|
|
11449
|
+
correlationId: event.correlationId,
|
|
11459
11450
|
message: error instanceof Error ? error.message : String(error)
|
|
11460
11451
|
});
|
|
11461
11452
|
}
|
|
@@ -11476,11 +11467,14 @@ var Stower = class {
|
|
|
11476
11467
|
contentByteSize: event.byteSize
|
|
11477
11468
|
}
|
|
11478
11469
|
});
|
|
11479
|
-
this.eventBus.get("yield:update-ok").next({
|
|
11470
|
+
this.eventBus.get("yield:update-ok").next({
|
|
11471
|
+
correlationId: event.correlationId,
|
|
11472
|
+
response: { resourceId: event.resourceId }
|
|
11473
|
+
});
|
|
11480
11474
|
} catch (error) {
|
|
11481
11475
|
this.logger.error("Failed to update resource", { error: errField(error) });
|
|
11482
11476
|
this.eventBus.get("yield:update-failed").next({
|
|
11483
|
-
|
|
11477
|
+
correlationId: event.correlationId,
|
|
11484
11478
|
message: error instanceof Error ? error.message : String(error)
|
|
11485
11479
|
});
|
|
11486
11480
|
}
|
|
@@ -11513,7 +11507,6 @@ var Stower = class {
|
|
|
11513
11507
|
toUri: event.toUri
|
|
11514
11508
|
}
|
|
11515
11509
|
});
|
|
11516
|
-
this.eventBus.get("yield:move-ok").next({ resourceId: rId });
|
|
11517
11510
|
} catch (error) {
|
|
11518
11511
|
this.logger.error("Failed to move resource", { error: errField(error) });
|
|
11519
11512
|
this.eventBus.get("yield:move-failed").next({
|
|
@@ -11561,10 +11554,11 @@ var Stower = class {
|
|
|
11561
11554
|
version: 1,
|
|
11562
11555
|
payload: { annotationId: annotationId(event.annotationId) }
|
|
11563
11556
|
});
|
|
11564
|
-
this.eventBus.get("mark:delete-ok").next({ annotationId: event.annotationId });
|
|
11557
|
+
this.eventBus.get("mark:delete-ok").next({ correlationId: event.correlationId, response: { annotationId: event.annotationId } });
|
|
11565
11558
|
} catch (error) {
|
|
11566
11559
|
this.logger.error("Failed to delete annotation", { error: errField(error) });
|
|
11567
11560
|
this.eventBus.get("mark:delete-failed").next({
|
|
11561
|
+
correlationId: event.correlationId,
|
|
11568
11562
|
message: error instanceof Error ? error.message : String(error)
|
|
11569
11563
|
});
|
|
11570
11564
|
}
|
|
@@ -11598,37 +11592,54 @@ var Stower = class {
|
|
|
11598
11592
|
if (!event._userId) {
|
|
11599
11593
|
throw new Error("mark:archive missing _userId (gateway injection)");
|
|
11600
11594
|
}
|
|
11601
|
-
|
|
11602
|
-
|
|
11595
|
+
try {
|
|
11596
|
+
if (event.storageUri) {
|
|
11597
|
+
await this.kb.content.remove(event.storageUri, { keepFile: event.keepFile, noGit: event.noGit });
|
|
11598
|
+
}
|
|
11599
|
+
await this.kb.eventStore.appendEvent({
|
|
11600
|
+
type: "mark:archived",
|
|
11601
|
+
resourceId: resourceId(event.resourceId),
|
|
11602
|
+
userId: userId(event._userId),
|
|
11603
|
+
version: 1,
|
|
11604
|
+
payload: { reason: void 0 }
|
|
11605
|
+
});
|
|
11606
|
+
this.eventBus.get("mark:archive-ok").next({ correlationId: event.correlationId });
|
|
11607
|
+
} catch (error) {
|
|
11608
|
+
this.logger.error("Failed to archive resource", { error: errField(error) });
|
|
11609
|
+
this.eventBus.get("mark:archive-failed").next({
|
|
11610
|
+
correlationId: event.correlationId,
|
|
11611
|
+
message: error instanceof Error ? error.message : String(error)
|
|
11612
|
+
});
|
|
11603
11613
|
}
|
|
11604
|
-
await this.kb.eventStore.appendEvent({
|
|
11605
|
-
type: "mark:archived",
|
|
11606
|
-
resourceId: resourceId(event.resourceId),
|
|
11607
|
-
userId: userId(event._userId),
|
|
11608
|
-
version: 1,
|
|
11609
|
-
payload: { reason: void 0 }
|
|
11610
|
-
});
|
|
11611
11614
|
}
|
|
11612
11615
|
async handleMarkUnarchive(event) {
|
|
11613
11616
|
if (!event._userId) {
|
|
11614
11617
|
throw new Error("mark:unarchive missing _userId (gateway injection)");
|
|
11615
11618
|
}
|
|
11616
|
-
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11619
|
+
try {
|
|
11620
|
+
if (event.storageUri) {
|
|
11621
|
+
const absPath = this.kb.content.resolveUri(event.storageUri);
|
|
11622
|
+
try {
|
|
11623
|
+
await promises.access(absPath);
|
|
11624
|
+
} catch {
|
|
11625
|
+
throw new Error(`Cannot unarchive: file not found at ${event.storageUri}`);
|
|
11626
|
+
}
|
|
11623
11627
|
}
|
|
11628
|
+
await this.kb.eventStore.appendEvent({
|
|
11629
|
+
type: "mark:unarchived",
|
|
11630
|
+
resourceId: resourceId(event.resourceId),
|
|
11631
|
+
userId: userId(event._userId),
|
|
11632
|
+
version: 1,
|
|
11633
|
+
payload: {}
|
|
11634
|
+
});
|
|
11635
|
+
this.eventBus.get("mark:unarchive-ok").next({ correlationId: event.correlationId });
|
|
11636
|
+
} catch (error) {
|
|
11637
|
+
this.logger.error("Failed to unarchive resource", { error: errField(error) });
|
|
11638
|
+
this.eventBus.get("mark:unarchive-failed").next({
|
|
11639
|
+
correlationId: event.correlationId,
|
|
11640
|
+
message: error instanceof Error ? error.message : String(error)
|
|
11641
|
+
});
|
|
11624
11642
|
}
|
|
11625
|
-
await this.kb.eventStore.appendEvent({
|
|
11626
|
-
type: "mark:unarchived",
|
|
11627
|
-
resourceId: resourceId(event.resourceId),
|
|
11628
|
-
userId: userId(event._userId),
|
|
11629
|
-
version: 1,
|
|
11630
|
-
payload: {}
|
|
11631
|
-
});
|
|
11632
11643
|
}
|
|
11633
11644
|
async handleAddEntityType(event) {
|
|
11634
11645
|
if (!event._userId) {
|
|
@@ -11641,9 +11652,11 @@ var Stower = class {
|
|
|
11641
11652
|
version: 1,
|
|
11642
11653
|
payload: { entityType: event.tag }
|
|
11643
11654
|
});
|
|
11655
|
+
this.eventBus.get("frame:entity-type-add-ok").next({ correlationId: event.correlationId });
|
|
11644
11656
|
} catch (error) {
|
|
11645
11657
|
this.logger.error("Failed to add entity type", { error: errField(error) });
|
|
11646
11658
|
this.eventBus.get("frame:entity-type-add-failed").next({
|
|
11659
|
+
correlationId: event.correlationId,
|
|
11647
11660
|
message: error instanceof Error ? error.message : String(error)
|
|
11648
11661
|
});
|
|
11649
11662
|
}
|
|
@@ -11659,9 +11672,11 @@ var Stower = class {
|
|
|
11659
11672
|
version: 1,
|
|
11660
11673
|
payload: { schema: event.schema }
|
|
11661
11674
|
});
|
|
11675
|
+
this.eventBus.get("frame:tag-schema-add-ok").next({ correlationId: event.correlationId });
|
|
11662
11676
|
} catch (error) {
|
|
11663
11677
|
this.logger.error("Failed to add tag schema", { schemaId: event.schema?.id, error: errField(error) });
|
|
11664
11678
|
this.eventBus.get("frame:tag-schema-add-failed").next({
|
|
11679
|
+
correlationId: event.correlationId,
|
|
11665
11680
|
message: error instanceof Error ? error.message : String(error)
|
|
11666
11681
|
});
|
|
11667
11682
|
}
|
|
@@ -11821,7 +11836,19 @@ var Browser = class {
|
|
|
11821
11836
|
const errorHandler = (err) => this.logger.error("Browser pipeline error", { error: err });
|
|
11822
11837
|
const pipe = (name, handler) => this.eventBus.get(name).pipe(
|
|
11823
11838
|
(0, import_operators5.mergeMap)(
|
|
11824
|
-
(event) => (0, import_rxjs5.from)(withActorSpan("browser", name, () => handler(event)))
|
|
11839
|
+
(event) => (0, import_rxjs5.from)(withActorSpan("browser", name, () => handler(event))).pipe(
|
|
11840
|
+
// Isolate per-event failures: a single handler throw must NOT tear down the
|
|
11841
|
+
// channel subscription for every future request — that's the browse:entity-types
|
|
11842
|
+
// wedge (.plans/bugs/browse-entity-types-never-responds.md). Handlers emit their
|
|
11843
|
+
// own *-failed reply; this is the structural backstop for any throw that escapes a
|
|
11844
|
+
// handler's try/catch — the channel survives, the offending request is logged.
|
|
11845
|
+
// (A per-channel *-failed can't be emitted from this generic helper without the
|
|
11846
|
+
// request→failure mapping — that's the Tier 1 operations registry.)
|
|
11847
|
+
(0, import_operators5.catchError)((error) => {
|
|
11848
|
+
this.logger.error(`browse handler threw on ${name}`, { error: errField(error) });
|
|
11849
|
+
return import_rxjs5.EMPTY;
|
|
11850
|
+
})
|
|
11851
|
+
)
|
|
11825
11852
|
)
|
|
11826
11853
|
);
|
|
11827
11854
|
this.subscriptions.push(
|
|
@@ -12206,49 +12233,48 @@ async function readAnnotationFromView(kb, resourceId10, annotationId5) {
|
|
|
12206
12233
|
}
|
|
12207
12234
|
|
|
12208
12235
|
// src/clone-token-manager.ts
|
|
12209
|
-
var import_rxjs7 = __toESM(require_cjs());
|
|
12210
|
-
var import_operators7 = __toESM(require_operators());
|
|
12211
|
-
|
|
12212
|
-
// src/resource-operations.ts
|
|
12213
12236
|
var import_rxjs6 = __toESM(require_cjs());
|
|
12214
12237
|
var import_operators6 = __toESM(require_operators());
|
|
12238
|
+
|
|
12239
|
+
// src/bus-request-local.ts
|
|
12240
|
+
function asBusRequestPrimitive(eventBus) {
|
|
12241
|
+
return {
|
|
12242
|
+
emit(channel, payload) {
|
|
12243
|
+
eventBus.get(channel).next(payload);
|
|
12244
|
+
return Promise.resolve();
|
|
12245
|
+
},
|
|
12246
|
+
stream(channel) {
|
|
12247
|
+
return eventBus.get(channel).asObservable();
|
|
12248
|
+
}
|
|
12249
|
+
};
|
|
12250
|
+
}
|
|
12251
|
+
|
|
12252
|
+
// src/resource-operations.ts
|
|
12215
12253
|
var ResourceOperations = class {
|
|
12216
12254
|
/**
|
|
12217
12255
|
* Create a new resource via EventBus → Stower
|
|
12218
12256
|
*/
|
|
12219
12257
|
static async createResource(input, userId3, eventBus) {
|
|
12220
|
-
const
|
|
12221
|
-
eventBus
|
|
12222
|
-
|
|
12223
|
-
|
|
12224
|
-
|
|
12225
|
-
|
|
12226
|
-
|
|
12227
|
-
|
|
12228
|
-
|
|
12229
|
-
|
|
12230
|
-
|
|
12231
|
-
|
|
12258
|
+
const { resourceId: rId } = await busRequest(
|
|
12259
|
+
asBusRequestPrimitive(eventBus),
|
|
12260
|
+
"yield:create",
|
|
12261
|
+
{
|
|
12262
|
+
name: input.name,
|
|
12263
|
+
storageUri: input.storageUri,
|
|
12264
|
+
contentChecksum: input.contentChecksum,
|
|
12265
|
+
byteSize: input.byteSize,
|
|
12266
|
+
format: input.format,
|
|
12267
|
+
_userId: userId3,
|
|
12268
|
+
language: input.language,
|
|
12269
|
+
entityTypes: input.entityTypes,
|
|
12270
|
+
generatedFrom: input.generatedFrom,
|
|
12271
|
+
generationPrompt: input.generationPrompt,
|
|
12272
|
+
generator: input.generator,
|
|
12273
|
+
isDraft: input.isDraft
|
|
12274
|
+
},
|
|
12275
|
+
3e4
|
|
12232
12276
|
);
|
|
12233
|
-
|
|
12234
|
-
name: input.name,
|
|
12235
|
-
storageUri: input.storageUri,
|
|
12236
|
-
contentChecksum: input.contentChecksum,
|
|
12237
|
-
byteSize: input.byteSize,
|
|
12238
|
-
format: input.format,
|
|
12239
|
-
_userId: userId3,
|
|
12240
|
-
language: input.language,
|
|
12241
|
-
entityTypes: input.entityTypes,
|
|
12242
|
-
generatedFrom: input.generatedFrom,
|
|
12243
|
-
generationPrompt: input.generationPrompt,
|
|
12244
|
-
generator: input.generator,
|
|
12245
|
-
isDraft: input.isDraft
|
|
12246
|
-
});
|
|
12247
|
-
const outcome = await (0, import_rxjs6.firstValueFrom)(result$);
|
|
12248
|
-
if (!outcome.ok) {
|
|
12249
|
-
throw outcome.error;
|
|
12250
|
-
}
|
|
12251
|
-
return resourceId(outcome.result.resourceId);
|
|
12277
|
+
return resourceId(rId);
|
|
12252
12278
|
}
|
|
12253
12279
|
};
|
|
12254
12280
|
|
|
@@ -12268,13 +12294,13 @@ var CloneTokenManager = class {
|
|
|
12268
12294
|
this.logger.info("CloneTokenManager actor initialized");
|
|
12269
12295
|
const errorHandler = (err) => this.logger.error("CloneTokenManager pipeline error", { error: err });
|
|
12270
12296
|
const generateToken$ = this.eventBus.get("yield:clone-token-requested").pipe(
|
|
12271
|
-
(0,
|
|
12297
|
+
(0, import_operators6.mergeMap)((event) => (0, import_rxjs6.from)(this.handleGenerateToken(event)))
|
|
12272
12298
|
);
|
|
12273
12299
|
const getResource$ = this.eventBus.get("yield:clone-resource-requested").pipe(
|
|
12274
|
-
(0,
|
|
12300
|
+
(0, import_operators6.mergeMap)((event) => (0, import_rxjs6.from)(this.handleGetResource(event)))
|
|
12275
12301
|
);
|
|
12276
12302
|
const createResource$ = this.eventBus.get("yield:clone-create").pipe(
|
|
12277
|
-
(0,
|
|
12303
|
+
(0, import_operators6.mergeMap)((event) => (0, import_rxjs6.from)(this.handleCreateResource(event)))
|
|
12278
12304
|
);
|
|
12279
12305
|
this.subscriptions.push(
|
|
12280
12306
|
generateToken$.subscribe({ error: errorHandler }),
|
|
@@ -12448,10 +12474,6 @@ var CloneTokenManager = class {
|
|
|
12448
12474
|
this.logger.info("CloneTokenManager actor stopped");
|
|
12449
12475
|
}
|
|
12450
12476
|
};
|
|
12451
|
-
|
|
12452
|
-
// src/bootstrap/entity-types.ts
|
|
12453
|
-
var import_rxjs8 = __toESM(require_cjs());
|
|
12454
|
-
var import_operators8 = __toESM(require_operators());
|
|
12455
12477
|
async function bootstrapEntityTypes(eventBus, eventStore, logger) {
|
|
12456
12478
|
const systemEvents = await eventStore.log.getEvents(resourceId("__system__"));
|
|
12457
12479
|
const existingTypes = new Set(
|
|
@@ -12466,16 +12488,12 @@ async function bootstrapEntityTypes(eventBus, eventStore, logger) {
|
|
|
12466
12488
|
const SYSTEM_USER_ID = userId("00000000-0000-0000-0000-000000000000");
|
|
12467
12489
|
for (const entityType2 of missing) {
|
|
12468
12490
|
logger?.debug("Adding entity type via EventBus", { entityType: entityType2 });
|
|
12469
|
-
|
|
12470
|
-
eventBus
|
|
12471
|
-
|
|
12472
|
-
|
|
12491
|
+
await busRequest(
|
|
12492
|
+
asBusRequestPrimitive(eventBus),
|
|
12493
|
+
"frame:add-entity-type",
|
|
12494
|
+
{ tag: entityType2, _userId: SYSTEM_USER_ID },
|
|
12495
|
+
1e4
|
|
12473
12496
|
);
|
|
12474
|
-
eventBus.get("frame:add-entity-type").next({ tag: entityType2, _userId: SYSTEM_USER_ID });
|
|
12475
|
-
const outcome = await (0, import_rxjs8.firstValueFrom)(result$);
|
|
12476
|
-
if (!outcome.ok) {
|
|
12477
|
-
throw outcome.error;
|
|
12478
|
-
}
|
|
12479
12497
|
}
|
|
12480
12498
|
logger?.info("Entity types bootstrap completed", { added: missing.length, total: DEFAULT_ENTITY_TYPES.length });
|
|
12481
12499
|
}
|
|
@@ -12636,10 +12654,7 @@ function registerBindUpdateBodyHandler(eventBus, parentLogger) {
|
|
|
12636
12654
|
if (!cid || !inflight.has(cid)) return;
|
|
12637
12655
|
inflight.delete(cid);
|
|
12638
12656
|
const annId = event.payload?.annotationId;
|
|
12639
|
-
eventBus.get("bind:body-updated").next({
|
|
12640
|
-
correlationId: cid,
|
|
12641
|
-
annotationId: annId
|
|
12642
|
-
});
|
|
12657
|
+
eventBus.get("bind:body-updated").next({ correlationId: cid });
|
|
12643
12658
|
logger.info("Bind body-updated confirmed", { annotationId: annId, correlationId: cid });
|
|
12644
12659
|
});
|
|
12645
12660
|
eventBus.get("mark:body-update-failed").subscribe((event) => {
|
|
@@ -12706,7 +12721,11 @@ function registerJobCommandHandlers(eventBus, jobQueue, project, parentLogger) {
|
|
|
12706
12721
|
userDomain: user.domain,
|
|
12707
12722
|
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12708
12723
|
retryCount: 0,
|
|
12709
|
-
|
|
12724
|
+
// Generation is non-idempotent — a retry re-runs the LLM and produces
|
|
12725
|
+
// *different* content (not a replay) — and expensive. Surface the failure
|
|
12726
|
+
// to the caller rather than silently re-rolling. Detection jobs re-scan the
|
|
12727
|
+
// same content (≈idempotent) and keep one self-heal retry.
|
|
12728
|
+
maxRetries: jobType === "generation" ? 0 : 1
|
|
12710
12729
|
},
|
|
12711
12730
|
params: {
|
|
12712
12731
|
resourceId: resourceId(resId),
|
|
@@ -12823,11 +12842,19 @@ function registerJobCommandHandlers(eventBus, jobQueue, project, parentLogger) {
|
|
|
12823
12842
|
try {
|
|
12824
12843
|
const cancelled = await jobQueue.cancelPendingJobs(event.jobType);
|
|
12825
12844
|
logger.info("Cancel requested", { jobType: event.jobType, cancelled });
|
|
12845
|
+
eventBus.get("job:cancel-ok").next({
|
|
12846
|
+
correlationId: event.correlationId,
|
|
12847
|
+
response: { cancelled }
|
|
12848
|
+
});
|
|
12826
12849
|
} catch (error) {
|
|
12827
12850
|
logger.error("Failed to cancel pending jobs", {
|
|
12828
12851
|
jobType: event.jobType,
|
|
12829
12852
|
error: error.message
|
|
12830
12853
|
});
|
|
12854
|
+
eventBus.get("job:cancel-failed").next({
|
|
12855
|
+
correlationId: event.correlationId,
|
|
12856
|
+
message: error.message
|
|
12857
|
+
});
|
|
12831
12858
|
}
|
|
12832
12859
|
});
|
|
12833
12860
|
}
|
|
@@ -12847,7 +12874,7 @@ async function createJobQueue(project, eventBus, logger) {
|
|
|
12847
12874
|
await jobQueue.initialize();
|
|
12848
12875
|
registerJobQueueProvider(() => jobQueue.getStats());
|
|
12849
12876
|
const jobStatusSubscription = eventBus.get("job:status-requested").pipe(
|
|
12850
|
-
(0,
|
|
12877
|
+
(0, import_operators7.mergeMap)((event) => (0, import_rxjs7.from)((async () => {
|
|
12851
12878
|
try {
|
|
12852
12879
|
const job = await jobQueue.getJob(jobId(event.jobId));
|
|
12853
12880
|
if (!job) {
|
|
@@ -12964,11 +12991,11 @@ async function startMakeMeaning(project, config, eventBus, logger, options) {
|
|
|
12964
12991
|
}
|
|
12965
12992
|
|
|
12966
12993
|
// src/local-transport.ts
|
|
12967
|
-
var
|
|
12994
|
+
var import_rxjs8 = __toESM(require_cjs());
|
|
12968
12995
|
var LocalTransport = class {
|
|
12969
12996
|
baseUrl;
|
|
12970
12997
|
state$;
|
|
12971
|
-
errorsSubject = new
|
|
12998
|
+
errorsSubject = new import_rxjs8.Subject();
|
|
12972
12999
|
/**
|
|
12973
13000
|
* Stream of `SemiontError` instances surfaced from transport-mediated
|
|
12974
13001
|
* round-trips (typed-wire methods on this transport that fail). The
|
|
@@ -12989,7 +13016,7 @@ var LocalTransport = class {
|
|
|
12989
13016
|
this.bus = cfg.eventBus;
|
|
12990
13017
|
this.userId = cfg.userId;
|
|
12991
13018
|
this.baseUrl = cfg.baseUrl ?? baseUrl("local://in-process");
|
|
12992
|
-
this.state$ = new
|
|
13019
|
+
this.state$ = new import_rxjs8.BehaviorSubject("open");
|
|
12993
13020
|
}
|
|
12994
13021
|
// ── Bus primitives ──────────────────────────────────────────────────────
|
|
12995
13022
|
async emit(channel, payload, resourceScope) {
|
|
@@ -13122,8 +13149,8 @@ var LocalContentTransport = class {
|
|
|
13122
13149
|
};
|
|
13123
13150
|
|
|
13124
13151
|
// src/smelter.ts
|
|
13125
|
-
var
|
|
13126
|
-
var
|
|
13152
|
+
var import_rxjs9 = __toESM(require_cjs());
|
|
13153
|
+
var import_operators8 = __toESM(require_operators());
|
|
13127
13154
|
function isWorkItem(input) {
|
|
13128
13155
|
return input.type.startsWith("smelt:");
|
|
13129
13156
|
}
|
|
@@ -13149,7 +13176,7 @@ var Smelter = class _Smelter {
|
|
|
13149
13176
|
static RECONCILE_PAGE_SIZE = 200;
|
|
13150
13177
|
/** Bound on concurrently in-flight reconcile work — a cold rebuild must not fan out unbounded embedding calls. */
|
|
13151
13178
|
static RECONCILE_WAVE = 8;
|
|
13152
|
-
eventSubject = new
|
|
13179
|
+
eventSubject = new import_rxjs9.Subject();
|
|
13153
13180
|
sourceSubscription = null;
|
|
13154
13181
|
pipelineSubscription = null;
|
|
13155
13182
|
_eventsProcessed = 0;
|
|
@@ -13164,23 +13191,23 @@ var Smelter = class _Smelter {
|
|
|
13164
13191
|
}
|
|
13165
13192
|
initialize() {
|
|
13166
13193
|
this.pipelineSubscription = this.eventSubject.pipe(
|
|
13167
|
-
(0,
|
|
13168
|
-
(0,
|
|
13194
|
+
(0, import_operators8.groupBy)((e) => e.resourceId ?? "__unknown__"),
|
|
13195
|
+
(0, import_operators8.mergeMap)(
|
|
13169
13196
|
(group) => group.pipe(
|
|
13170
13197
|
burstBuffer({
|
|
13171
13198
|
burstWindowMs: this.timing.burstWindowMs,
|
|
13172
13199
|
maxBatchSize: this.timing.maxBatchSize,
|
|
13173
13200
|
idleTimeoutMs: this.timing.idleTimeoutMs
|
|
13174
13201
|
}),
|
|
13175
|
-
(0,
|
|
13202
|
+
(0, import_operators8.concatMap)((inputOrBatch) => {
|
|
13176
13203
|
if (Array.isArray(inputOrBatch)) {
|
|
13177
|
-
return (0,
|
|
13204
|
+
return (0, import_rxjs9.from)(
|
|
13178
13205
|
withActorSpan("smelter", "batch", async () => {
|
|
13179
13206
|
this._eventsProcessed += await this.processBatch(inputOrBatch);
|
|
13180
13207
|
}, { "batch.size": inputOrBatch.length })
|
|
13181
13208
|
);
|
|
13182
13209
|
}
|
|
13183
|
-
return (0,
|
|
13210
|
+
return (0, import_rxjs9.from)(
|
|
13184
13211
|
withActorSpan("smelter", inputOrBatch.type, async () => {
|
|
13185
13212
|
const ok = await this.safeProcessEvent(inputOrBatch);
|
|
13186
13213
|
if (isWorkItem(inputOrBatch)) this.noteWorkDone(1);
|
|
@@ -13339,6 +13366,23 @@ var Smelter = class _Smelter {
|
|
|
13339
13366
|
return null;
|
|
13340
13367
|
}
|
|
13341
13368
|
}
|
|
13369
|
+
/**
|
|
13370
|
+
* Read a resource's current entity types from the materialized view — the
|
|
13371
|
+
* authoritative source, updated before the EventBus fires to consumers — so
|
|
13372
|
+
* its vectors carry the discriminator `searchResources` filters on (e.g.
|
|
13373
|
+
* exclude `['Question']`). One read on every embed path, mirroring how the
|
|
13374
|
+
* smelter already reads current content and annotations; a failed read
|
|
13375
|
+
* propagates to the pipeline's per-resource error handler (reconcile heals),
|
|
13376
|
+
* rather than silently stamping `[]` and letting the resource leak into recall.
|
|
13377
|
+
*/
|
|
13378
|
+
async resolveEntityTypes(resourceId10) {
|
|
13379
|
+
const { resource } = await busRequest(
|
|
13380
|
+
this.bus,
|
|
13381
|
+
"browse:resource-requested",
|
|
13382
|
+
{ resourceId: resourceId10 }
|
|
13383
|
+
);
|
|
13384
|
+
return getResourceEntityTypes(resource);
|
|
13385
|
+
}
|
|
13342
13386
|
async embedResource(event, logMessage) {
|
|
13343
13387
|
const rid = event.resourceId;
|
|
13344
13388
|
if (!rid) return;
|
|
@@ -13346,13 +13390,14 @@ var Smelter = class _Smelter {
|
|
|
13346
13390
|
if (!fetched) return;
|
|
13347
13391
|
const chunks = chunkText(fetched.text, this.chunkingConfig);
|
|
13348
13392
|
if (chunks.length === 0) return;
|
|
13393
|
+
const entityTypes = await this.resolveEntityTypes(rid);
|
|
13349
13394
|
const embeddings = await this.embeddingProvider.embedBatch(chunks);
|
|
13350
13395
|
const embeddingChunks = chunks.map((t, i) => ({
|
|
13351
13396
|
chunkIndex: i,
|
|
13352
13397
|
text: t,
|
|
13353
13398
|
embedding: embeddings[i]
|
|
13354
13399
|
}));
|
|
13355
|
-
await this.vectorStore.upsertResourceVectors(resourceId(rid), embeddingChunks, fetched.checksum);
|
|
13400
|
+
await this.vectorStore.upsertResourceVectors(resourceId(rid), embeddingChunks, fetched.checksum, entityTypes);
|
|
13356
13401
|
this.logger.info(logMessage, { resourceId: rid, chunks: chunks.length });
|
|
13357
13402
|
}
|
|
13358
13403
|
async handleResourceArchived(event) {
|
|
@@ -13403,19 +13448,20 @@ var Smelter = class _Smelter {
|
|
|
13403
13448
|
if (!fetched) continue;
|
|
13404
13449
|
const chunks = chunkText(fetched.text, this.chunkingConfig);
|
|
13405
13450
|
if (chunks.length === 0) continue;
|
|
13406
|
-
|
|
13451
|
+
const entityTypes = await this.resolveEntityTypes(rid);
|
|
13452
|
+
resourceData.push({ rid: resourceId(rid), chunks, checksum: fetched.checksum, entityTypes });
|
|
13407
13453
|
allChunks.push(...chunks);
|
|
13408
13454
|
}
|
|
13409
13455
|
if (allChunks.length === 0) return events.length;
|
|
13410
13456
|
const allEmbeddings = await this.embeddingProvider.embedBatch(allChunks);
|
|
13411
13457
|
let offset = 0;
|
|
13412
|
-
for (const { rid, chunks, checksum } of resourceData) {
|
|
13458
|
+
for (const { rid, chunks, checksum, entityTypes } of resourceData) {
|
|
13413
13459
|
const embeddingChunks = chunks.map((t, i) => ({
|
|
13414
13460
|
chunkIndex: i,
|
|
13415
13461
|
text: t,
|
|
13416
13462
|
embedding: allEmbeddings[offset + i]
|
|
13417
13463
|
}));
|
|
13418
|
-
await this.vectorStore.upsertResourceVectors(rid, embeddingChunks, checksum);
|
|
13464
|
+
await this.vectorStore.upsertResourceVectors(rid, embeddingChunks, checksum, entityTypes);
|
|
13419
13465
|
this.logger.info("Batch-indexed resource", { resourceId: String(rid), chunks: chunks.length });
|
|
13420
13466
|
offset += chunks.length;
|
|
13421
13467
|
}
|
|
@@ -13522,9 +13568,7 @@ var Smelter = class _Smelter {
|
|
|
13522
13568
|
const { annotations } = await busRequest(
|
|
13523
13569
|
this.bus,
|
|
13524
13570
|
"browse:annotations-requested",
|
|
13525
|
-
{ resourceId: rid }
|
|
13526
|
-
"browse:annotations-result",
|
|
13527
|
-
"browse:annotations-failed"
|
|
13571
|
+
{ resourceId: rid }
|
|
13528
13572
|
);
|
|
13529
13573
|
for (const annotation of annotations) {
|
|
13530
13574
|
const exactText = getExactText(getTargetSelector(annotation.target));
|
|
@@ -13582,9 +13626,7 @@ var Smelter = class _Smelter {
|
|
|
13582
13626
|
const page = await busRequest(
|
|
13583
13627
|
this.bus,
|
|
13584
13628
|
"browse:resources-requested",
|
|
13585
|
-
{ archived: false, offset: all.length, limit: _Smelter.RECONCILE_PAGE_SIZE }
|
|
13586
|
-
"browse:resources-result",
|
|
13587
|
-
"browse:resources-failed"
|
|
13629
|
+
{ archived: false, offset: all.length, limit: _Smelter.RECONCILE_PAGE_SIZE }
|
|
13588
13630
|
);
|
|
13589
13631
|
all.push(...page.resources);
|
|
13590
13632
|
if (page.resources.length === 0 || all.length >= page.total) return all;
|
|
@@ -13593,8 +13635,8 @@ var Smelter = class _Smelter {
|
|
|
13593
13635
|
};
|
|
13594
13636
|
|
|
13595
13637
|
// src/smelter-actor-state-unit.ts
|
|
13596
|
-
var
|
|
13597
|
-
var
|
|
13638
|
+
var import_rxjs10 = __toESM(require_cjs());
|
|
13639
|
+
var import_operators9 = __toESM(require_operators());
|
|
13598
13640
|
var SMELTER_CHANNELS = [
|
|
13599
13641
|
"yield:created",
|
|
13600
13642
|
"yield:updated",
|
|
@@ -13606,10 +13648,10 @@ var SMELTER_CHANNELS = [
|
|
|
13606
13648
|
function createSmelterActorStateUnit(options) {
|
|
13607
13649
|
const { bus } = options;
|
|
13608
13650
|
let started = false;
|
|
13609
|
-
const events$ = (0,
|
|
13651
|
+
const events$ = (0, import_rxjs10.merge)(
|
|
13610
13652
|
...SMELTER_CHANNELS.map(
|
|
13611
13653
|
(channel) => bus.on$(channel).pipe(
|
|
13612
|
-
(0,
|
|
13654
|
+
(0, import_operators9.map)((payload) => ({
|
|
13613
13655
|
type: channel,
|
|
13614
13656
|
resourceId: payload.resourceId,
|
|
13615
13657
|
payload
|
|
@@ -13812,9 +13854,26 @@ function collectContentRefs(streamData) {
|
|
|
13812
13854
|
return refs;
|
|
13813
13855
|
}
|
|
13814
13856
|
|
|
13815
|
-
// src/exchange/
|
|
13816
|
-
var
|
|
13817
|
-
var
|
|
13857
|
+
// src/exchange/await-reply.ts
|
|
13858
|
+
var import_rxjs11 = __toESM(require_cjs());
|
|
13859
|
+
var import_operators10 = __toESM(require_operators());
|
|
13860
|
+
function awaitReply(eventBus, command, payload, okChannel, failedChannel, timeoutMs) {
|
|
13861
|
+
const result$ = (0, import_rxjs11.race)(
|
|
13862
|
+
eventBus.get(okChannel).pipe((0, import_operators10.map)(() => void 0)),
|
|
13863
|
+
eventBus.get(failedChannel).pipe(
|
|
13864
|
+
(0, import_operators10.map)((e) => {
|
|
13865
|
+
throw new Error(e.message ?? `${command} failed`);
|
|
13866
|
+
})
|
|
13867
|
+
),
|
|
13868
|
+
(0, import_rxjs11.timer)(timeoutMs).pipe(
|
|
13869
|
+
(0, import_operators10.map)(() => {
|
|
13870
|
+
throw new Error(`Timeout waiting for ${okChannel}`);
|
|
13871
|
+
})
|
|
13872
|
+
)
|
|
13873
|
+
);
|
|
13874
|
+
eventBus.get(command).next(payload);
|
|
13875
|
+
return (0, import_rxjs11.firstValueFrom)(result$);
|
|
13876
|
+
}
|
|
13818
13877
|
var REPLAY_TIMEOUT_MS = 3e4;
|
|
13819
13878
|
async function replayEventStream(jsonl, eventBus, resolveBlob, contentStore, logger) {
|
|
13820
13879
|
const lines = jsonl.trim().split("\n").filter((l) => l.length > 0);
|
|
@@ -13878,20 +13937,12 @@ async function replayEvent(event, eventBus, resolveBlob, contentStore, stats, lo
|
|
|
13878
13937
|
}
|
|
13879
13938
|
}
|
|
13880
13939
|
async function replayEntityTypeAdded(event, eventBus, logger) {
|
|
13881
|
-
|
|
13882
|
-
eventBus
|
|
13883
|
-
|
|
13884
|
-
|
|
13885
|
-
|
|
13886
|
-
(0, import_rxjs13.timer)(REPLAY_TIMEOUT_MS).pipe((0, import_operators12.map)(() => {
|
|
13887
|
-
throw new Error("Timeout waiting for frame:entity-type-added");
|
|
13888
|
-
}))
|
|
13940
|
+
await busRequest(
|
|
13941
|
+
asBusRequestPrimitive(eventBus),
|
|
13942
|
+
"frame:add-entity-type",
|
|
13943
|
+
{ tag: event.payload.entityType, _userId: event.userId },
|
|
13944
|
+
REPLAY_TIMEOUT_MS
|
|
13889
13945
|
);
|
|
13890
|
-
eventBus.get("frame:add-entity-type").next({
|
|
13891
|
-
tag: event.payload.entityType,
|
|
13892
|
-
_userId: event.userId
|
|
13893
|
-
});
|
|
13894
|
-
await (0, import_rxjs13.firstValueFrom)(result$);
|
|
13895
13946
|
logger?.debug("Replayed entitytype.added", { entityType: event.payload.entityType });
|
|
13896
13947
|
}
|
|
13897
13948
|
async function replayResourceCreated(event, eventBus, resolveBlob, contentStore, logger) {
|
|
@@ -13903,84 +13954,70 @@ async function replayResourceCreated(event, eventBus, resolveBlob, contentStore,
|
|
|
13903
13954
|
const base = baseMediaType(payload.format);
|
|
13904
13955
|
const resolvedUri = payload.storageUri || deriveStorageUri(payload.name, isSupportedMediaType(base) ? base : "application/octet-stream");
|
|
13905
13956
|
const stored = await contentStore.store(blob, resolvedUri);
|
|
13906
|
-
|
|
13907
|
-
eventBus
|
|
13908
|
-
|
|
13909
|
-
|
|
13910
|
-
|
|
13911
|
-
|
|
13912
|
-
|
|
13913
|
-
|
|
13957
|
+
await busRequest(
|
|
13958
|
+
asBusRequestPrimitive(eventBus),
|
|
13959
|
+
"yield:create",
|
|
13960
|
+
{
|
|
13961
|
+
name: payload.name,
|
|
13962
|
+
storageUri: resolvedUri,
|
|
13963
|
+
contentChecksum: stored.checksum,
|
|
13964
|
+
byteSize: stored.byteSize,
|
|
13965
|
+
format: payload.format,
|
|
13966
|
+
_userId: event.userId,
|
|
13967
|
+
language: payload.language,
|
|
13968
|
+
entityTypes: payload.entityTypes,
|
|
13969
|
+
isDraft: payload.isDraft,
|
|
13970
|
+
generatedFrom: payload.generatedFrom,
|
|
13971
|
+
generationPrompt: payload.generationPrompt
|
|
13972
|
+
},
|
|
13973
|
+
REPLAY_TIMEOUT_MS
|
|
13914
13974
|
);
|
|
13915
|
-
eventBus.get("yield:create").next({
|
|
13916
|
-
name: payload.name,
|
|
13917
|
-
storageUri: resolvedUri,
|
|
13918
|
-
contentChecksum: stored.checksum,
|
|
13919
|
-
byteSize: stored.byteSize,
|
|
13920
|
-
format: payload.format,
|
|
13921
|
-
_userId: event.userId,
|
|
13922
|
-
language: payload.language,
|
|
13923
|
-
entityTypes: payload.entityTypes,
|
|
13924
|
-
isDraft: payload.isDraft,
|
|
13925
|
-
generatedFrom: payload.generatedFrom,
|
|
13926
|
-
generationPrompt: payload.generationPrompt
|
|
13927
|
-
});
|
|
13928
|
-
await (0, import_rxjs13.firstValueFrom)(result$);
|
|
13929
13975
|
logger?.debug("Replayed resource.created", { name: payload.name });
|
|
13930
13976
|
}
|
|
13931
13977
|
async function replayAnnotationAdded(event, eventBus, logger) {
|
|
13932
|
-
|
|
13933
|
-
eventBus
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
}
|
|
13978
|
+
await awaitReply(
|
|
13979
|
+
eventBus,
|
|
13980
|
+
"mark:create",
|
|
13981
|
+
{
|
|
13982
|
+
annotation: event.payload.annotation,
|
|
13983
|
+
_userId: event.userId,
|
|
13984
|
+
resourceId: event.resourceId
|
|
13985
|
+
},
|
|
13986
|
+
"mark:create-ok",
|
|
13987
|
+
"mark:create-failed",
|
|
13988
|
+
REPLAY_TIMEOUT_MS
|
|
13940
13989
|
);
|
|
13941
|
-
eventBus.get("mark:create").next({
|
|
13942
|
-
annotation: event.payload.annotation,
|
|
13943
|
-
_userId: event.userId,
|
|
13944
|
-
resourceId: event.resourceId
|
|
13945
|
-
});
|
|
13946
|
-
await (0, import_rxjs13.firstValueFrom)(result$);
|
|
13947
13990
|
logger?.debug("Replayed annotation.added", { annotationId: event.payload.annotation.id });
|
|
13948
13991
|
}
|
|
13949
13992
|
async function replayAnnotationBodyUpdated(event, eventBus, logger) {
|
|
13950
|
-
|
|
13951
|
-
eventBus
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13993
|
+
await awaitReply(
|
|
13994
|
+
eventBus,
|
|
13995
|
+
"mark:update-body",
|
|
13996
|
+
{
|
|
13997
|
+
annotationId: event.payload.annotationId,
|
|
13998
|
+
_userId: event.userId,
|
|
13999
|
+
resourceId: event.resourceId,
|
|
14000
|
+
operations: event.payload.operations
|
|
14001
|
+
},
|
|
14002
|
+
"mark:body-updated",
|
|
14003
|
+
"mark:body-update-failed",
|
|
14004
|
+
REPLAY_TIMEOUT_MS
|
|
13958
14005
|
);
|
|
13959
|
-
eventBus.get("mark:update-body").next({
|
|
13960
|
-
annotationId: event.payload.annotationId,
|
|
13961
|
-
_userId: event.userId,
|
|
13962
|
-
resourceId: event.resourceId,
|
|
13963
|
-
operations: event.payload.operations
|
|
13964
|
-
});
|
|
13965
|
-
await (0, import_rxjs13.firstValueFrom)(result$);
|
|
13966
14006
|
logger?.debug("Replayed annotation.body.updated", { annotationId: event.payload.annotationId });
|
|
13967
14007
|
}
|
|
13968
14008
|
async function replayAnnotationRemoved(event, eventBus, logger) {
|
|
13969
|
-
|
|
13970
|
-
eventBus
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
}
|
|
14009
|
+
await awaitReply(
|
|
14010
|
+
eventBus,
|
|
14011
|
+
"mark:delete",
|
|
14012
|
+
{
|
|
14013
|
+
annotationId: event.payload.annotationId,
|
|
14014
|
+
_userId: event.userId,
|
|
14015
|
+
resourceId: event.resourceId
|
|
14016
|
+
},
|
|
14017
|
+
"mark:delete-ok",
|
|
14018
|
+
"mark:delete-failed",
|
|
14019
|
+
REPLAY_TIMEOUT_MS
|
|
13977
14020
|
);
|
|
13978
|
-
eventBus.get("mark:delete").next({
|
|
13979
|
-
annotationId: event.payload.annotationId,
|
|
13980
|
-
_userId: event.userId,
|
|
13981
|
-
resourceId: event.resourceId
|
|
13982
|
-
});
|
|
13983
|
-
await (0, import_rxjs13.firstValueFrom)(result$);
|
|
13984
14021
|
logger?.debug("Replayed annotation.removed", { annotationId: event.payload.annotationId });
|
|
13985
14022
|
}
|
|
13986
14023
|
async function replayResourceArchived(event, eventBus, logger) {
|
|
@@ -14263,10 +14300,6 @@ function collectContentRefsFromResource(resource, refs) {
|
|
|
14263
14300
|
refs.set(resource.storageUri, mediaType);
|
|
14264
14301
|
}
|
|
14265
14302
|
}
|
|
14266
|
-
|
|
14267
|
-
// src/exchange/linked-data-importer.ts
|
|
14268
|
-
var import_rxjs14 = __toESM(require_cjs());
|
|
14269
|
-
var import_operators13 = __toESM(require_operators());
|
|
14270
14303
|
var IMPORT_TIMEOUT_MS = 3e4;
|
|
14271
14304
|
function stripUriToId(uri) {
|
|
14272
14305
|
if (!uri.includes("/")) return uri;
|
|
@@ -14368,20 +14401,12 @@ async function importLinkedData(archive, options) {
|
|
|
14368
14401
|
};
|
|
14369
14402
|
}
|
|
14370
14403
|
async function addEntityType(entityType2, userId3, eventBus, logger) {
|
|
14371
|
-
|
|
14372
|
-
eventBus
|
|
14373
|
-
|
|
14374
|
-
|
|
14375
|
-
|
|
14376
|
-
(0, import_rxjs14.timer)(IMPORT_TIMEOUT_MS).pipe((0, import_operators13.map)(() => {
|
|
14377
|
-
throw new Error("Timeout waiting for frame:entity-type-added");
|
|
14378
|
-
}))
|
|
14404
|
+
await busRequest(
|
|
14405
|
+
asBusRequestPrimitive(eventBus),
|
|
14406
|
+
"frame:add-entity-type",
|
|
14407
|
+
{ tag: entityType2, _userId: userId3 },
|
|
14408
|
+
IMPORT_TIMEOUT_MS
|
|
14379
14409
|
);
|
|
14380
|
-
eventBus.get("frame:add-entity-type").next({
|
|
14381
|
-
tag: entityType2,
|
|
14382
|
-
_userId: userId3
|
|
14383
|
-
});
|
|
14384
|
-
await (0, import_rxjs14.firstValueFrom)(result$);
|
|
14385
14410
|
logger?.debug("Added entity type", { entityType: entityType2 });
|
|
14386
14411
|
}
|
|
14387
14412
|
async function importResource(doc, userId3, eventBus, contentStore, resolveBlob, logger) {
|
|
@@ -14408,27 +14433,22 @@ async function importResource(doc, userId3, eventBus, contentStore, resolveBlob,
|
|
|
14408
14433
|
const base = baseMediaType(format);
|
|
14409
14434
|
const resolvedUri = deriveStorageUri(name, isSupportedMediaType(base) ? base : "application/octet-stream");
|
|
14410
14435
|
const stored = await contentStore.store(blob, resolvedUri);
|
|
14411
|
-
const
|
|
14412
|
-
eventBus
|
|
14413
|
-
|
|
14414
|
-
|
|
14415
|
-
|
|
14416
|
-
|
|
14417
|
-
|
|
14418
|
-
|
|
14436
|
+
const { resourceId: createdId } = await busRequest(
|
|
14437
|
+
asBusRequestPrimitive(eventBus),
|
|
14438
|
+
"yield:create",
|
|
14439
|
+
{
|
|
14440
|
+
name,
|
|
14441
|
+
storageUri: resolvedUri,
|
|
14442
|
+
contentChecksum: stored.checksum,
|
|
14443
|
+
byteSize: stored.byteSize,
|
|
14444
|
+
format,
|
|
14445
|
+
_userId: userId3,
|
|
14446
|
+
language,
|
|
14447
|
+
entityTypes: entityTypes ?? []
|
|
14448
|
+
},
|
|
14449
|
+
IMPORT_TIMEOUT_MS
|
|
14419
14450
|
);
|
|
14420
|
-
|
|
14421
|
-
name,
|
|
14422
|
-
storageUri: resolvedUri,
|
|
14423
|
-
contentChecksum: stored.checksum,
|
|
14424
|
-
byteSize: stored.byteSize,
|
|
14425
|
-
format,
|
|
14426
|
-
_userId: userId3,
|
|
14427
|
-
language,
|
|
14428
|
-
entityTypes: entityTypes ?? []
|
|
14429
|
-
});
|
|
14430
|
-
const created = await (0, import_rxjs14.firstValueFrom)(createResult$);
|
|
14431
|
-
const resourceId10 = resourceId(created.resourceId);
|
|
14451
|
+
const resourceId10 = resourceId(createdId);
|
|
14432
14452
|
logger?.debug("Created resource from JSON-LD", { name, resourceId: resourceId10 });
|
|
14433
14453
|
let annotationsCreated = 0;
|
|
14434
14454
|
if (annotations && annotations.length > 0) {
|
|
@@ -14440,21 +14460,18 @@ async function importResource(doc, userId3, eventBus, contentStore, resolveBlob,
|
|
|
14440
14460
|
return { annotationsCreated };
|
|
14441
14461
|
}
|
|
14442
14462
|
async function createAnnotation(annotation, resourceId10, userId3, eventBus, logger) {
|
|
14443
|
-
|
|
14444
|
-
eventBus
|
|
14445
|
-
|
|
14446
|
-
|
|
14447
|
-
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
}
|
|
14463
|
+
await awaitReply(
|
|
14464
|
+
eventBus,
|
|
14465
|
+
"mark:create",
|
|
14466
|
+
{
|
|
14467
|
+
annotation: dehydrateAnnotation(annotation),
|
|
14468
|
+
_userId: userId3,
|
|
14469
|
+
resourceId: resourceId10
|
|
14470
|
+
},
|
|
14471
|
+
"mark:create-ok",
|
|
14472
|
+
"mark:create-failed",
|
|
14473
|
+
IMPORT_TIMEOUT_MS
|
|
14451
14474
|
);
|
|
14452
|
-
eventBus.get("mark:create").next({
|
|
14453
|
-
annotation: dehydrateAnnotation(annotation),
|
|
14454
|
-
_userId: userId3,
|
|
14455
|
-
resourceId: resourceId10
|
|
14456
|
-
});
|
|
14457
|
-
await (0, import_rxjs14.firstValueFrom)(result$);
|
|
14458
14475
|
logger?.debug("Created annotation", { annotationId: annotation.id });
|
|
14459
14476
|
}
|
|
14460
14477
|
var AnnotationOperations = class {
|