@semiont/make-meaning 0.5.9 → 0.5.11
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 +3 -3
- package/dist/index.d.ts +53 -31
- package/dist/index.js +641 -540
- 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, softwareToAgent } 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
|
|
|
@@ -9734,10 +9733,19 @@ function resolveActorInference(config, actor) {
|
|
|
9734
9733
|
`No inference config found for actor '${actor}'. Set actors.${actor}.inference in your config.`
|
|
9735
9734
|
);
|
|
9736
9735
|
}
|
|
9736
|
+
function resolveWorkerInference(config, workerType) {
|
|
9737
|
+
const specific = config.workers?.[workerType];
|
|
9738
|
+
if (specific) return specific;
|
|
9739
|
+
const defaultWorker = config.workers?.default;
|
|
9740
|
+
if (defaultWorker) return defaultWorker;
|
|
9741
|
+
throw new Error(
|
|
9742
|
+
`No inference config found for worker '${workerType}'. Set workers.${workerType}.inference or workers.default.inference in your config.`
|
|
9743
|
+
);
|
|
9744
|
+
}
|
|
9737
9745
|
|
|
9738
9746
|
// src/service.ts
|
|
9739
|
-
var
|
|
9740
|
-
var
|
|
9747
|
+
var import_rxjs7 = __toESM(require_cjs());
|
|
9748
|
+
var import_operators7 = __toESM(require_operators());
|
|
9741
9749
|
|
|
9742
9750
|
// src/graph/consumer.ts
|
|
9743
9751
|
var import_rxjs = __toESM(require_cjs());
|
|
@@ -10056,7 +10064,7 @@ var GraphDBConsumer = class _GraphDBConsumer {
|
|
|
10056
10064
|
{
|
|
10057
10065
|
const rid = resourceId(event.resourceId);
|
|
10058
10066
|
const doc = await graphDb.getResource(rid);
|
|
10059
|
-
if (doc) {
|
|
10067
|
+
if (doc && !(doc.entityTypes || []).includes(event.payload.entityType)) {
|
|
10060
10068
|
await graphDb.updateResource(rid, {
|
|
10061
10069
|
entityTypes: [...doc.entityTypes || [], event.payload.entityType]
|
|
10062
10070
|
});
|
|
@@ -10293,6 +10301,93 @@ var ResourceContext = class _ResourceContext {
|
|
|
10293
10301
|
return void 0;
|
|
10294
10302
|
}
|
|
10295
10303
|
};
|
|
10304
|
+
var GraphContext = class {
|
|
10305
|
+
/**
|
|
10306
|
+
* Get all resources referencing this resource (backlinks)
|
|
10307
|
+
* Requires graph traversal - must use graph database
|
|
10308
|
+
*/
|
|
10309
|
+
static async getBacklinks(resourceId10, kb) {
|
|
10310
|
+
return kb.graph.getResourceReferencedBy(resourceId10);
|
|
10311
|
+
}
|
|
10312
|
+
/**
|
|
10313
|
+
* Find shortest path between two resources
|
|
10314
|
+
* Requires graph traversal - must use graph database
|
|
10315
|
+
*/
|
|
10316
|
+
static async findPath(fromResourceId, toResourceId, kb, maxDepth) {
|
|
10317
|
+
return kb.graph.findPath(fromResourceId, toResourceId, maxDepth);
|
|
10318
|
+
}
|
|
10319
|
+
/**
|
|
10320
|
+
* Get resource connections (graph edges)
|
|
10321
|
+
* Requires graph traversal - must use graph database
|
|
10322
|
+
*/
|
|
10323
|
+
static async getResourceConnections(resourceId10, kb) {
|
|
10324
|
+
return kb.graph.getResourceConnections(resourceId10);
|
|
10325
|
+
}
|
|
10326
|
+
/**
|
|
10327
|
+
* Search resources by name (cross-resource query)
|
|
10328
|
+
* Requires full-text search - must use graph database
|
|
10329
|
+
*/
|
|
10330
|
+
static async searchResources(query, kb, limit) {
|
|
10331
|
+
return kb.graph.searchResources(query, limit);
|
|
10332
|
+
}
|
|
10333
|
+
/**
|
|
10334
|
+
* Build the unified knowledge graph for a resource's neighborhood:
|
|
10335
|
+
* resources AND annotations as typed nodes, typed/directional edges.
|
|
10336
|
+
*
|
|
10337
|
+
* This is the single graph builder (CONTEXT-UNIFICATION D3) — both the
|
|
10338
|
+
* matcher (ranking) and the resource/viz path consume it. The flattened
|
|
10339
|
+
* signals the matcher reads today (`connections`, `citedBy`/count,
|
|
10340
|
+
* `siblingEntityTypes`, `bidirectional`) are all derivable from this:
|
|
10341
|
+
* - peer connections → resource nodes + main→peer edges carrying `bidirectional`
|
|
10342
|
+
* - inbound citations → citing-resource nodes + `citation` edges (citing→main),
|
|
10343
|
+
* so citedByCount = inbound citation-edge count
|
|
10344
|
+
* - annotations on the resource → `annotation` nodes + `annotation-of` edges,
|
|
10345
|
+
* so siblingEntityTypes = union of those nodes' entityTypes
|
|
10346
|
+
*/
|
|
10347
|
+
static async buildKnowledgeGraph(resourceId10, kb) {
|
|
10348
|
+
const mainDoc = await kb.graph.getResource(resourceId10);
|
|
10349
|
+
if (!mainDoc) {
|
|
10350
|
+
throw new Error("Resource not found");
|
|
10351
|
+
}
|
|
10352
|
+
const mainId = String(resourceId10);
|
|
10353
|
+
const [connections, referencedBy, annotations] = await Promise.all([
|
|
10354
|
+
kb.graph.getResourceConnections(resourceId10),
|
|
10355
|
+
kb.graph.getResourceReferencedBy(resourceId10),
|
|
10356
|
+
kb.graph.getResourceAnnotations(resourceId10)
|
|
10357
|
+
]);
|
|
10358
|
+
const nodes = [];
|
|
10359
|
+
const edges = [];
|
|
10360
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10361
|
+
const addResourceNode = (id, label, entityTypes) => {
|
|
10362
|
+
if (!id || seen.has(id)) return;
|
|
10363
|
+
nodes.push({ id, type: "resource", label, entityTypes });
|
|
10364
|
+
seen.add(id);
|
|
10365
|
+
};
|
|
10366
|
+
addResourceNode(mainId, mainDoc.name, getResourceEntityTypes(mainDoc));
|
|
10367
|
+
for (const conn of connections) {
|
|
10368
|
+
const peerId = getResourceId(conn.targetResource);
|
|
10369
|
+
if (!peerId) continue;
|
|
10370
|
+
addResourceNode(peerId, conn.targetResource.name, getResourceEntityTypes(conn.targetResource));
|
|
10371
|
+
edges.push({ source: mainId, target: peerId, type: conn.relationshipType || "link", bidirectional: conn.bidirectional });
|
|
10372
|
+
}
|
|
10373
|
+
const citedSeen = /* @__PURE__ */ new Set();
|
|
10374
|
+
for (const ann of referencedBy) {
|
|
10375
|
+
const source = getTargetSource(ann.target);
|
|
10376
|
+
if (!source || source === String(resourceId10) || citedSeen.has(source)) continue;
|
|
10377
|
+
citedSeen.add(source);
|
|
10378
|
+
const view = await kb.views.get(resourceId(source));
|
|
10379
|
+
addResourceNode(source, view?.resource?.name ?? source, view?.resource ? getResourceEntityTypes(view.resource) : []);
|
|
10380
|
+
edges.push({ source, target: mainId, type: "citation" });
|
|
10381
|
+
}
|
|
10382
|
+
for (const ann of annotations) {
|
|
10383
|
+
if (!ann.id || seen.has(ann.id)) continue;
|
|
10384
|
+
nodes.push({ id: ann.id, type: "annotation", label: ann.motivation ?? "annotation", entityTypes: getEntityTypes(ann) });
|
|
10385
|
+
seen.add(ann.id);
|
|
10386
|
+
edges.push({ source: ann.id, target: mainId, type: "annotation-of" });
|
|
10387
|
+
}
|
|
10388
|
+
return { nodes, edges };
|
|
10389
|
+
}
|
|
10390
|
+
};
|
|
10296
10391
|
|
|
10297
10392
|
// src/annotation-context.ts
|
|
10298
10393
|
var AnnotationContext = class {
|
|
@@ -10406,42 +10501,21 @@ var AnnotationContext = class {
|
|
|
10406
10501
|
};
|
|
10407
10502
|
}
|
|
10408
10503
|
}
|
|
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
|
-
}
|
|
10504
|
+
logger?.debug("Building knowledge graph", { resourceId: resourceId10 });
|
|
10505
|
+
const graph = await GraphContext.buildKnowledgeGraph(resourceId10, kb);
|
|
10506
|
+
const views = deriveViews(graph, String(resourceId10), annotationId5);
|
|
10507
|
+
const entityTypeStats = await kb.graph.getEntityTypeStats();
|
|
10435
10508
|
const entityTypeFrequencies = {};
|
|
10436
10509
|
for (const stat of entityTypeStats) {
|
|
10437
10510
|
entityTypeFrequencies[stat.type] = stat.count;
|
|
10438
10511
|
}
|
|
10512
|
+
const annotationEntityTypes = getEntityTypes(annotation);
|
|
10439
10513
|
let inferredRelationshipSummary;
|
|
10440
10514
|
if (inferenceClient && sourceContext) {
|
|
10441
10515
|
try {
|
|
10442
|
-
const connNames = connections.map((c) => c.
|
|
10443
|
-
const citedByNames =
|
|
10444
|
-
const siblingTypes =
|
|
10516
|
+
const connNames = views.connections.map((c) => c.resourceName).slice(0, 10);
|
|
10517
|
+
const citedByNames = views.citedBy.map((c) => c.resourceName).slice(0, 5);
|
|
10518
|
+
const siblingTypes = views.siblingEntityTypes.slice(0, 10);
|
|
10445
10519
|
const parts = [];
|
|
10446
10520
|
parts.push(`Passage: "${sourceContext.selected}"`);
|
|
10447
10521
|
if (connNames.length > 0) parts.push(`Connected resources: ${connNames.join(", ")}`);
|
|
@@ -10459,27 +10533,6 @@ Summary:`;
|
|
|
10459
10533
|
logger?.warn("Failed to generate inferred relationship summary", { error });
|
|
10460
10534
|
}
|
|
10461
10535
|
}
|
|
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
10536
|
let semanticContext;
|
|
10484
10537
|
if (kb.vectors && embeddingProvider && sourceContext?.selected) {
|
|
10485
10538
|
try {
|
|
@@ -10505,32 +10558,26 @@ Summary:`;
|
|
|
10505
10558
|
logger?.warn("Semantic context search failed", { error });
|
|
10506
10559
|
}
|
|
10507
10560
|
}
|
|
10508
|
-
const
|
|
10509
|
-
|
|
10510
|
-
|
|
10561
|
+
const context = {
|
|
10562
|
+
focus: {
|
|
10563
|
+
kind: "annotation",
|
|
10564
|
+
annotation,
|
|
10565
|
+
sourceResource: sourceDoc,
|
|
10566
|
+
...sourceContext ? { selected: { before: sourceContext.before || "", text: sourceContext.selected, after: sourceContext.after || "" } } : {},
|
|
10567
|
+
...targetDoc ? { targetResource: targetDoc } : {},
|
|
10568
|
+
...targetContext ? { targetContext } : {}
|
|
10569
|
+
},
|
|
10570
|
+
graph,
|
|
10511
10571
|
metadata: {
|
|
10512
10572
|
resourceType: "document",
|
|
10513
10573
|
language: sourceDoc.language,
|
|
10514
|
-
entityTypes: annotationEntityTypes
|
|
10574
|
+
entityTypes: annotationEntityTypes,
|
|
10575
|
+
entityTypeFrequencies
|
|
10515
10576
|
},
|
|
10516
|
-
|
|
10577
|
+
...inferredRelationshipSummary ? { inferredRelationshipSummary } : {},
|
|
10517
10578
|
...semanticContext ? { semanticContext } : {}
|
|
10518
10579
|
};
|
|
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;
|
|
10580
|
+
return context;
|
|
10534
10581
|
}
|
|
10535
10582
|
/**
|
|
10536
10583
|
* Get resource annotations from view storage (fast path)
|
|
@@ -10764,69 +10811,6 @@ Entity types: ${entityTypes.join(", ")}`;
|
|
|
10764
10811
|
return inferenceClient.generateText(summaryPrompt, 500, 0.5);
|
|
10765
10812
|
}
|
|
10766
10813
|
};
|
|
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
10814
|
var LLMContext = class {
|
|
10831
10815
|
/**
|
|
10832
10816
|
* Get comprehensive LLM context for a resource
|
|
@@ -10838,35 +10822,29 @@ var LLMContext = class {
|
|
|
10838
10822
|
throw new Error("Resource not found");
|
|
10839
10823
|
}
|
|
10840
10824
|
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 = [];
|
|
10825
|
+
const graph = await GraphContext.buildKnowledgeGraph(resourceId10, kb);
|
|
10847
10826
|
const resourceIdStr = resourceId10.toString();
|
|
10848
|
-
|
|
10849
|
-
|
|
10850
|
-
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
|
|
10827
|
+
const relatedDocs = [];
|
|
10828
|
+
const relatedNodes = graph.nodes.filter((node) => node.type === "resource" && node.id !== resourceIdStr).slice(0, Math.max(0, options.maxResources - 1));
|
|
10829
|
+
for (const node of relatedNodes) {
|
|
10830
|
+
const relatedDoc = await ResourceContext.getResourceMetadata(resourceId(node.id), kb);
|
|
10831
|
+
if (relatedDoc) {
|
|
10832
|
+
relatedDocs.push(relatedDoc);
|
|
10854
10833
|
}
|
|
10855
10834
|
}
|
|
10856
|
-
const
|
|
10835
|
+
const relatedContent = {};
|
|
10857
10836
|
if (options.includeContent) {
|
|
10858
10837
|
await Promise.all(
|
|
10859
10838
|
relatedDocs.map(async (doc) => {
|
|
10860
10839
|
const docId = getResourceId(doc);
|
|
10861
10840
|
if (!docId) return;
|
|
10862
|
-
const
|
|
10863
|
-
if (
|
|
10864
|
-
|
|
10841
|
+
const content2 = await ResourceContext.getResourceContent(doc, kb);
|
|
10842
|
+
if (content2) {
|
|
10843
|
+
relatedContent[docId] = content2;
|
|
10865
10844
|
}
|
|
10866
10845
|
})
|
|
10867
10846
|
);
|
|
10868
10847
|
}
|
|
10869
|
-
const annotations = await AnnotationContext.getAllAnnotations(resourceId10, kb);
|
|
10870
10848
|
const summary = options.includeSummary && mainContent ? await generateResourceSummary(
|
|
10871
10849
|
mainDoc.name,
|
|
10872
10850
|
mainContent,
|
|
@@ -10874,15 +10852,44 @@ var LLMContext = class {
|
|
|
10874
10852
|
inferenceClient
|
|
10875
10853
|
) : void 0;
|
|
10876
10854
|
const suggestedReferences = mainContent ? await generateReferenceSuggestions(mainContent, inferenceClient) : void 0;
|
|
10855
|
+
const content = {};
|
|
10856
|
+
if (mainContent) content.main = mainContent;
|
|
10857
|
+
if (options.includeContent) content.related = relatedContent;
|
|
10858
|
+
let semanticContext;
|
|
10859
|
+
if (kb.vectors) {
|
|
10860
|
+
const excludeEntityTypes = options.excludeEntityTypes ?? [];
|
|
10861
|
+
const matches = await kb.vectors.searchByResource(resourceId10, {
|
|
10862
|
+
limit: options.maxResources,
|
|
10863
|
+
scoreThreshold: 0.5,
|
|
10864
|
+
...excludeEntityTypes.length ? { filter: { excludeEntityTypes } } : {}
|
|
10865
|
+
});
|
|
10866
|
+
if (matches.length > 0) {
|
|
10867
|
+
semanticContext = {
|
|
10868
|
+
similar: matches.map((m) => ({
|
|
10869
|
+
text: m.text,
|
|
10870
|
+
resourceId: m.resourceId,
|
|
10871
|
+
...m.annotationId ? { annotationId: m.annotationId } : {},
|
|
10872
|
+
score: m.score,
|
|
10873
|
+
...m.entityTypes ? { entityTypes: m.entityTypes } : {}
|
|
10874
|
+
})),
|
|
10875
|
+
...excludeEntityTypes.length ? { excludedEntityTypes: excludeEntityTypes } : {}
|
|
10876
|
+
};
|
|
10877
|
+
}
|
|
10878
|
+
}
|
|
10877
10879
|
return {
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10880
|
+
focus: {
|
|
10881
|
+
kind: "resource",
|
|
10882
|
+
resource: mainDoc,
|
|
10883
|
+
...summary ? { summary } : {},
|
|
10884
|
+
...suggestedReferences ? { suggestedReferences } : {},
|
|
10885
|
+
...Object.keys(content).length > 0 ? { content } : {}
|
|
10886
|
+
},
|
|
10881
10887
|
graph,
|
|
10882
|
-
...
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10888
|
+
...semanticContext ? { semanticContext } : {},
|
|
10889
|
+
metadata: {
|
|
10890
|
+
resourceType: "document",
|
|
10891
|
+
language: mainDoc.language
|
|
10892
|
+
}
|
|
10886
10893
|
};
|
|
10887
10894
|
}
|
|
10888
10895
|
};
|
|
@@ -11042,8 +11049,13 @@ var Matcher = class {
|
|
|
11042
11049
|
async handleSearch(event) {
|
|
11043
11050
|
try {
|
|
11044
11051
|
const context = event.context;
|
|
11045
|
-
|
|
11046
|
-
|
|
11052
|
+
if (context.focus.kind !== "annotation") {
|
|
11053
|
+
throw new Error(`Matcher expected annotation focus, received '${context.focus.kind}'`);
|
|
11054
|
+
}
|
|
11055
|
+
const focus = context.focus;
|
|
11056
|
+
const mainResourceId = String(event.resourceId);
|
|
11057
|
+
const selectedText = focus.selected?.text ?? "";
|
|
11058
|
+
const userHint = focus.userHint ?? "";
|
|
11047
11059
|
const searchTerm = [selectedText, userHint].filter(Boolean).join(" ");
|
|
11048
11060
|
this.logger.debug("Searching for binding candidates", {
|
|
11049
11061
|
referenceId: event.referenceId,
|
|
@@ -11054,6 +11066,8 @@ var Matcher = class {
|
|
|
11054
11066
|
const scored = await this.contextDrivenSearch(
|
|
11055
11067
|
searchTerm,
|
|
11056
11068
|
context,
|
|
11069
|
+
focus,
|
|
11070
|
+
mainResourceId,
|
|
11057
11071
|
event.useSemanticScoring
|
|
11058
11072
|
);
|
|
11059
11073
|
const limited = event.limit ? scored.slice(0, event.limit) : scored;
|
|
@@ -11089,9 +11103,10 @@ var Matcher = class {
|
|
|
11089
11103
|
* - Name match quality (exact > prefix > contains)
|
|
11090
11104
|
* - Recency (newer resources scored higher)
|
|
11091
11105
|
*/
|
|
11092
|
-
async contextDrivenSearch(searchTerm, context, useSemanticScoring) {
|
|
11093
|
-
const annotationEntityTypes = context.metadata
|
|
11094
|
-
const
|
|
11106
|
+
async contextDrivenSearch(searchTerm, context, focus, mainResourceId, useSemanticScoring) {
|
|
11107
|
+
const annotationEntityTypes = context.metadata.entityTypes ?? [];
|
|
11108
|
+
const views = deriveViews(context.graph, mainResourceId);
|
|
11109
|
+
const connections = views.connections;
|
|
11095
11110
|
const [nameMatches, entityTypeMatches, semanticMatches] = await Promise.all([
|
|
11096
11111
|
this.kb.graph.searchResources(searchTerm),
|
|
11097
11112
|
annotationEntityTypes.length > 0 ? this.kb.graph.listResources({ entityTypes: annotationEntityTypes, limit: 50 }).then((r) => r.resources) : Promise.resolve([]),
|
|
@@ -11136,7 +11151,7 @@ var Matcher = class {
|
|
|
11136
11151
|
const bidirectionalIds = new Set(
|
|
11137
11152
|
connections.filter((c) => c.bidirectional).map((c) => c.resourceId)
|
|
11138
11153
|
);
|
|
11139
|
-
const entityTypeFreqs = context.
|
|
11154
|
+
const entityTypeFreqs = context.metadata.entityTypeFrequencies ?? {};
|
|
11140
11155
|
const searchTermLower = searchTerm.toLowerCase();
|
|
11141
11156
|
const scored = Array.from(candidateMap.values()).map(({ resource, sources }) => {
|
|
11142
11157
|
const id = getResourceId(resource) ?? "";
|
|
@@ -11165,7 +11180,7 @@ var Matcher = class {
|
|
|
11165
11180
|
score += 10;
|
|
11166
11181
|
reasons.push("connected");
|
|
11167
11182
|
}
|
|
11168
|
-
const citedByCount =
|
|
11183
|
+
const citedByCount = views.citedByCount;
|
|
11169
11184
|
if (sources.has("neighborhood") && citedByCount > 0) {
|
|
11170
11185
|
score += Math.min(citedByCount * 2, 15);
|
|
11171
11186
|
}
|
|
@@ -11206,6 +11221,8 @@ var Matcher = class {
|
|
|
11206
11221
|
const inferenceScores = await this.inferenceSemanticScore(
|
|
11207
11222
|
searchTerm,
|
|
11208
11223
|
context,
|
|
11224
|
+
focus,
|
|
11225
|
+
connections,
|
|
11209
11226
|
scored.slice(0, 20)
|
|
11210
11227
|
// Limit to top 20 candidates for cost
|
|
11211
11228
|
);
|
|
@@ -11240,20 +11257,18 @@ var Matcher = class {
|
|
|
11240
11257
|
*
|
|
11241
11258
|
* @returns Map of resourceId → score (0-1)
|
|
11242
11259
|
*/
|
|
11243
|
-
async inferenceSemanticScore(searchTerm, context, candidates) {
|
|
11244
|
-
const passage = [
|
|
11245
|
-
const entityTypes = context.metadata
|
|
11246
|
-
const graphConnections = context.graphContext?.connections;
|
|
11247
|
-
const connections = graphConnections ?? [];
|
|
11260
|
+
async inferenceSemanticScore(searchTerm, context, focus, connections, candidates) {
|
|
11261
|
+
const passage = [focus.selected?.text, focus.userHint].filter(Boolean).join(" \u2014 ") || searchTerm;
|
|
11262
|
+
const entityTypes = context.metadata.entityTypes ?? [];
|
|
11248
11263
|
const candidateLines = candidates.map((c, i) => {
|
|
11249
11264
|
const id = getResourceId(c) ?? "";
|
|
11250
11265
|
const cEntityTypes = getResourceEntityTypes(c);
|
|
11251
11266
|
return `${i + 1}. "${c.name}" (id: ${id}, types: ${cEntityTypes.join(", ") || "none"})`;
|
|
11252
11267
|
}).join("\n");
|
|
11253
11268
|
const contextParts = [];
|
|
11254
|
-
contextParts.push(`Annotation motivation: ${
|
|
11255
|
-
contextParts.push(`Source resource: ${
|
|
11256
|
-
const { motivation, body } =
|
|
11269
|
+
contextParts.push(`Annotation motivation: ${focus.annotation.motivation}`);
|
|
11270
|
+
contextParts.push(`Source resource: ${focus.sourceResource.name}`);
|
|
11271
|
+
const { motivation, body } = focus.annotation;
|
|
11257
11272
|
if (motivation === "commenting" || motivation === "assessing") {
|
|
11258
11273
|
const bodyItem = Array.isArray(body) ? body[0] : body;
|
|
11259
11274
|
if (bodyItem && "value" in bodyItem && bodyItem.value) {
|
|
@@ -11266,8 +11281,8 @@ var Matcher = class {
|
|
|
11266
11281
|
const connNames = connections.slice(0, 5).map((c) => c.resourceName);
|
|
11267
11282
|
contextParts.push(`Connected resources: ${connNames.join(", ")}`);
|
|
11268
11283
|
}
|
|
11269
|
-
if (context.
|
|
11270
|
-
contextParts.push(`Relationship context: ${context.
|
|
11284
|
+
if (context.inferredRelationshipSummary) {
|
|
11285
|
+
contextParts.push(`Relationship context: ${context.inferredRelationshipSummary}`);
|
|
11271
11286
|
}
|
|
11272
11287
|
const prompt = `Given this passage and context, score each candidate resource's semantic relevance on a scale of 0.0 to 1.0.
|
|
11273
11288
|
|
|
@@ -11339,14 +11354,59 @@ For each candidate, output a line with the number and score, like:
|
|
|
11339
11354
|
// src/stower.ts
|
|
11340
11355
|
var import_rxjs4 = __toESM(require_cjs());
|
|
11341
11356
|
var import_operators4 = __toESM(require_operators());
|
|
11357
|
+
async function readEntityTypesProjection(project) {
|
|
11358
|
+
const entityTypesPath = path3.join(
|
|
11359
|
+
project.stateDir,
|
|
11360
|
+
"projections",
|
|
11361
|
+
"__system__",
|
|
11362
|
+
"entitytypes.json"
|
|
11363
|
+
);
|
|
11364
|
+
try {
|
|
11365
|
+
const content = await promises.readFile(entityTypesPath, "utf-8");
|
|
11366
|
+
const projection = JSON.parse(content);
|
|
11367
|
+
return projection.entityTypes || [];
|
|
11368
|
+
} catch (error) {
|
|
11369
|
+
if (error.code === "ENOENT") {
|
|
11370
|
+
return [];
|
|
11371
|
+
}
|
|
11372
|
+
throw error;
|
|
11373
|
+
}
|
|
11374
|
+
}
|
|
11375
|
+
|
|
11376
|
+
// src/views/projection-validators.ts
|
|
11377
|
+
function resolveTagSchema(tagSchemas, schemaId) {
|
|
11378
|
+
if (typeof schemaId !== "string" || !schemaId) {
|
|
11379
|
+
return { error: "tag-annotation requires schemaId" };
|
|
11380
|
+
}
|
|
11381
|
+
const schema = tagSchemas.find((s) => s.id === schemaId);
|
|
11382
|
+
if (!schema) {
|
|
11383
|
+
return { error: `Tag schema not registered: ${schemaId}` };
|
|
11384
|
+
}
|
|
11385
|
+
return { schema };
|
|
11386
|
+
}
|
|
11387
|
+
function validateEntityTypes(registered, requested) {
|
|
11388
|
+
if (!requested || requested.length === 0) {
|
|
11389
|
+
return { ok: true };
|
|
11390
|
+
}
|
|
11391
|
+
const set = new Set(registered);
|
|
11392
|
+
const unknown = requested.filter((t) => !set.has(t));
|
|
11393
|
+
return unknown.length > 0 ? { ok: false, unknown } : { ok: true };
|
|
11394
|
+
}
|
|
11395
|
+
function entityTypesNotRegisteredMessage(unknown) {
|
|
11396
|
+
return `Entity type not registered: ${unknown.join(", ")}`;
|
|
11397
|
+
}
|
|
11398
|
+
|
|
11399
|
+
// src/stower.ts
|
|
11342
11400
|
var Stower = class {
|
|
11343
|
-
constructor(kb, eventBus, logger) {
|
|
11401
|
+
constructor(kb, eventBus, project, logger) {
|
|
11344
11402
|
this.kb = kb;
|
|
11345
11403
|
this.eventBus = eventBus;
|
|
11404
|
+
this.project = project;
|
|
11346
11405
|
this.logger = logger;
|
|
11347
11406
|
}
|
|
11348
11407
|
kb;
|
|
11349
11408
|
eventBus;
|
|
11409
|
+
project;
|
|
11350
11410
|
subscription = null;
|
|
11351
11411
|
logger;
|
|
11352
11412
|
async initialize() {
|
|
@@ -11411,26 +11471,10 @@ var Stower = class {
|
|
|
11411
11471
|
generator: event.generator
|
|
11412
11472
|
}
|
|
11413
11473
|
});
|
|
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 });
|
|
11474
|
+
this.eventBus.get("yield:create-ok").next({
|
|
11475
|
+
correlationId: event.correlationId,
|
|
11476
|
+
response: { resourceId: rId }
|
|
11477
|
+
});
|
|
11434
11478
|
if (generatedFrom) {
|
|
11435
11479
|
this.eventBus.get("mark:update-body").next({
|
|
11436
11480
|
annotationId: generatedFrom.annotationId,
|
|
@@ -11456,6 +11500,7 @@ var Stower = class {
|
|
|
11456
11500
|
} catch (error) {
|
|
11457
11501
|
this.logger.error("Failed to create resource", { error: errField(error) });
|
|
11458
11502
|
this.eventBus.get("yield:create-failed").next({
|
|
11503
|
+
correlationId: event.correlationId,
|
|
11459
11504
|
message: error instanceof Error ? error.message : String(error)
|
|
11460
11505
|
});
|
|
11461
11506
|
}
|
|
@@ -11476,11 +11521,14 @@ var Stower = class {
|
|
|
11476
11521
|
contentByteSize: event.byteSize
|
|
11477
11522
|
}
|
|
11478
11523
|
});
|
|
11479
|
-
this.eventBus.get("yield:update-ok").next({
|
|
11524
|
+
this.eventBus.get("yield:update-ok").next({
|
|
11525
|
+
correlationId: event.correlationId,
|
|
11526
|
+
response: { resourceId: event.resourceId }
|
|
11527
|
+
});
|
|
11480
11528
|
} catch (error) {
|
|
11481
11529
|
this.logger.error("Failed to update resource", { error: errField(error) });
|
|
11482
11530
|
this.eventBus.get("yield:update-failed").next({
|
|
11483
|
-
|
|
11531
|
+
correlationId: event.correlationId,
|
|
11484
11532
|
message: error instanceof Error ? error.message : String(error)
|
|
11485
11533
|
});
|
|
11486
11534
|
}
|
|
@@ -11513,7 +11561,6 @@ var Stower = class {
|
|
|
11513
11561
|
toUri: event.toUri
|
|
11514
11562
|
}
|
|
11515
11563
|
});
|
|
11516
|
-
this.eventBus.get("yield:move-ok").next({ resourceId: rId });
|
|
11517
11564
|
} catch (error) {
|
|
11518
11565
|
this.logger.error("Failed to move resource", { error: errField(error) });
|
|
11519
11566
|
this.eventBus.get("yield:move-failed").next({
|
|
@@ -11561,10 +11608,11 @@ var Stower = class {
|
|
|
11561
11608
|
version: 1,
|
|
11562
11609
|
payload: { annotationId: annotationId(event.annotationId) }
|
|
11563
11610
|
});
|
|
11564
|
-
this.eventBus.get("mark:delete-ok").next({ annotationId: event.annotationId });
|
|
11611
|
+
this.eventBus.get("mark:delete-ok").next({ correlationId: event.correlationId, response: { annotationId: event.annotationId } });
|
|
11565
11612
|
} catch (error) {
|
|
11566
11613
|
this.logger.error("Failed to delete annotation", { error: errField(error) });
|
|
11567
11614
|
this.eventBus.get("mark:delete-failed").next({
|
|
11615
|
+
correlationId: event.correlationId,
|
|
11568
11616
|
message: error instanceof Error ? error.message : String(error)
|
|
11569
11617
|
});
|
|
11570
11618
|
}
|
|
@@ -11598,37 +11646,54 @@ var Stower = class {
|
|
|
11598
11646
|
if (!event._userId) {
|
|
11599
11647
|
throw new Error("mark:archive missing _userId (gateway injection)");
|
|
11600
11648
|
}
|
|
11601
|
-
|
|
11602
|
-
|
|
11649
|
+
try {
|
|
11650
|
+
if (event.storageUri) {
|
|
11651
|
+
await this.kb.content.remove(event.storageUri, { keepFile: event.keepFile, noGit: event.noGit });
|
|
11652
|
+
}
|
|
11653
|
+
await this.kb.eventStore.appendEvent({
|
|
11654
|
+
type: "mark:archived",
|
|
11655
|
+
resourceId: resourceId(event.resourceId),
|
|
11656
|
+
userId: userId(event._userId),
|
|
11657
|
+
version: 1,
|
|
11658
|
+
payload: { reason: void 0 }
|
|
11659
|
+
});
|
|
11660
|
+
this.eventBus.get("mark:archive-ok").next({ correlationId: event.correlationId });
|
|
11661
|
+
} catch (error) {
|
|
11662
|
+
this.logger.error("Failed to archive resource", { error: errField(error) });
|
|
11663
|
+
this.eventBus.get("mark:archive-failed").next({
|
|
11664
|
+
correlationId: event.correlationId,
|
|
11665
|
+
message: error instanceof Error ? error.message : String(error)
|
|
11666
|
+
});
|
|
11603
11667
|
}
|
|
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
11668
|
}
|
|
11612
11669
|
async handleMarkUnarchive(event) {
|
|
11613
11670
|
if (!event._userId) {
|
|
11614
11671
|
throw new Error("mark:unarchive missing _userId (gateway injection)");
|
|
11615
11672
|
}
|
|
11616
|
-
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11673
|
+
try {
|
|
11674
|
+
if (event.storageUri) {
|
|
11675
|
+
const absPath = this.kb.content.resolveUri(event.storageUri);
|
|
11676
|
+
try {
|
|
11677
|
+
await promises.access(absPath);
|
|
11678
|
+
} catch {
|
|
11679
|
+
throw new Error(`Cannot unarchive: file not found at ${event.storageUri}`);
|
|
11680
|
+
}
|
|
11623
11681
|
}
|
|
11682
|
+
await this.kb.eventStore.appendEvent({
|
|
11683
|
+
type: "mark:unarchived",
|
|
11684
|
+
resourceId: resourceId(event.resourceId),
|
|
11685
|
+
userId: userId(event._userId),
|
|
11686
|
+
version: 1,
|
|
11687
|
+
payload: {}
|
|
11688
|
+
});
|
|
11689
|
+
this.eventBus.get("mark:unarchive-ok").next({ correlationId: event.correlationId });
|
|
11690
|
+
} catch (error) {
|
|
11691
|
+
this.logger.error("Failed to unarchive resource", { error: errField(error) });
|
|
11692
|
+
this.eventBus.get("mark:unarchive-failed").next({
|
|
11693
|
+
correlationId: event.correlationId,
|
|
11694
|
+
message: error instanceof Error ? error.message : String(error)
|
|
11695
|
+
});
|
|
11624
11696
|
}
|
|
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
11697
|
}
|
|
11633
11698
|
async handleAddEntityType(event) {
|
|
11634
11699
|
if (!event._userId) {
|
|
@@ -11641,9 +11706,11 @@ var Stower = class {
|
|
|
11641
11706
|
version: 1,
|
|
11642
11707
|
payload: { entityType: event.tag }
|
|
11643
11708
|
});
|
|
11709
|
+
this.eventBus.get("frame:entity-type-add-ok").next({ correlationId: event.correlationId });
|
|
11644
11710
|
} catch (error) {
|
|
11645
11711
|
this.logger.error("Failed to add entity type", { error: errField(error) });
|
|
11646
11712
|
this.eventBus.get("frame:entity-type-add-failed").next({
|
|
11713
|
+
correlationId: event.correlationId,
|
|
11647
11714
|
message: error instanceof Error ? error.message : String(error)
|
|
11648
11715
|
});
|
|
11649
11716
|
}
|
|
@@ -11659,9 +11726,11 @@ var Stower = class {
|
|
|
11659
11726
|
version: 1,
|
|
11660
11727
|
payload: { schema: event.schema }
|
|
11661
11728
|
});
|
|
11729
|
+
this.eventBus.get("frame:tag-schema-add-ok").next({ correlationId: event.correlationId });
|
|
11662
11730
|
} catch (error) {
|
|
11663
11731
|
this.logger.error("Failed to add tag schema", { schemaId: event.schema?.id, error: errField(error) });
|
|
11664
11732
|
this.eventBus.get("frame:tag-schema-add-failed").next({
|
|
11733
|
+
correlationId: event.correlationId,
|
|
11665
11734
|
message: error instanceof Error ? error.message : String(error)
|
|
11666
11735
|
});
|
|
11667
11736
|
}
|
|
@@ -11673,22 +11742,38 @@ var Stower = class {
|
|
|
11673
11742
|
const uid = userId(event._userId);
|
|
11674
11743
|
const added = event.updatedEntityTypes.filter((et) => !event.currentEntityTypes.includes(et));
|
|
11675
11744
|
const removed = event.currentEntityTypes.filter((et) => !event.updatedEntityTypes.includes(et));
|
|
11676
|
-
|
|
11677
|
-
|
|
11678
|
-
|
|
11679
|
-
|
|
11680
|
-
|
|
11681
|
-
|
|
11682
|
-
|
|
11683
|
-
}
|
|
11684
|
-
|
|
11685
|
-
|
|
11686
|
-
|
|
11687
|
-
|
|
11688
|
-
|
|
11689
|
-
|
|
11690
|
-
|
|
11691
|
-
|
|
11745
|
+
try {
|
|
11746
|
+
if (added.length > 0) {
|
|
11747
|
+
const registered = await readEntityTypesProjection(this.project);
|
|
11748
|
+
const result = validateEntityTypes(registered, added);
|
|
11749
|
+
if (!result.ok) {
|
|
11750
|
+
throw new Error(entityTypesNotRegisteredMessage(result.unknown));
|
|
11751
|
+
}
|
|
11752
|
+
}
|
|
11753
|
+
for (const entityType2 of added) {
|
|
11754
|
+
await this.kb.eventStore.appendEvent({
|
|
11755
|
+
type: "mark:entity-tag-added",
|
|
11756
|
+
resourceId: resourceId(event.resourceId),
|
|
11757
|
+
userId: uid,
|
|
11758
|
+
version: 1,
|
|
11759
|
+
payload: { entityType: entityType2 }
|
|
11760
|
+
});
|
|
11761
|
+
}
|
|
11762
|
+
for (const entityType2 of removed) {
|
|
11763
|
+
await this.kb.eventStore.appendEvent({
|
|
11764
|
+
type: "mark:entity-tag-removed",
|
|
11765
|
+
resourceId: resourceId(event.resourceId),
|
|
11766
|
+
userId: uid,
|
|
11767
|
+
version: 1,
|
|
11768
|
+
payload: { entityType: entityType2 }
|
|
11769
|
+
});
|
|
11770
|
+
}
|
|
11771
|
+
this.eventBus.get("mark:update-entity-types-ok").next({ correlationId: event.correlationId });
|
|
11772
|
+
} catch (error) {
|
|
11773
|
+
this.logger.error("Failed to update entity types", { error: errField(error) });
|
|
11774
|
+
this.eventBus.get("mark:update-entity-types-failed").next({
|
|
11775
|
+
correlationId: event.correlationId,
|
|
11776
|
+
message: error instanceof Error ? error.message : String(error)
|
|
11692
11777
|
});
|
|
11693
11778
|
}
|
|
11694
11779
|
}
|
|
@@ -11752,24 +11837,6 @@ var Stower = class {
|
|
|
11752
11837
|
// src/browser.ts
|
|
11753
11838
|
var import_rxjs5 = __toESM(require_cjs());
|
|
11754
11839
|
var import_operators5 = __toESM(require_operators());
|
|
11755
|
-
async function readEntityTypesProjection(project) {
|
|
11756
|
-
const entityTypesPath = path3.join(
|
|
11757
|
-
project.stateDir,
|
|
11758
|
-
"projections",
|
|
11759
|
-
"__system__",
|
|
11760
|
-
"entitytypes.json"
|
|
11761
|
-
);
|
|
11762
|
-
try {
|
|
11763
|
-
const content = await promises.readFile(entityTypesPath, "utf-8");
|
|
11764
|
-
const projection = JSON.parse(content);
|
|
11765
|
-
return projection.entityTypes || [];
|
|
11766
|
-
} catch (error) {
|
|
11767
|
-
if (error.code === "ENOENT") {
|
|
11768
|
-
return [];
|
|
11769
|
-
}
|
|
11770
|
-
throw error;
|
|
11771
|
-
}
|
|
11772
|
-
}
|
|
11773
11840
|
async function readTagSchemasProjection(project) {
|
|
11774
11841
|
const tagSchemasPath = path3.join(
|
|
11775
11842
|
project.stateDir,
|
|
@@ -11800,20 +11867,66 @@ async function assembleResourceGraph(kb, resourceId10) {
|
|
|
11800
11867
|
});
|
|
11801
11868
|
return { resource: stored.resource, annotations, entityReferences };
|
|
11802
11869
|
}
|
|
11870
|
+
var JOB_TYPES = [
|
|
11871
|
+
"reference-annotation",
|
|
11872
|
+
"highlight-annotation",
|
|
11873
|
+
"assessment-annotation",
|
|
11874
|
+
"comment-annotation",
|
|
11875
|
+
"tag-annotation",
|
|
11876
|
+
"generation"
|
|
11877
|
+
];
|
|
11878
|
+
function deriveAgentRoster(config) {
|
|
11879
|
+
const domain = config.site?.domain;
|
|
11880
|
+
if (!domain) {
|
|
11881
|
+
throw new Error(
|
|
11882
|
+
"site.domain is required to mint agent DIDs \u2014 the directory must use the same canonical domain /api/tokens/agent mints worker DIDs from (no topology fallback)"
|
|
11883
|
+
);
|
|
11884
|
+
}
|
|
11885
|
+
const roster = /* @__PURE__ */ new Map();
|
|
11886
|
+
const admit = (inference, jobType) => {
|
|
11887
|
+
const key = `${inference.type}\0${inference.model}`;
|
|
11888
|
+
let entry = roster.get(key);
|
|
11889
|
+
if (!entry) {
|
|
11890
|
+
entry = {
|
|
11891
|
+
agent: softwareToAgent({ domain, provider: inference.type, model: inference.model }),
|
|
11892
|
+
servesJobTypes: []
|
|
11893
|
+
};
|
|
11894
|
+
roster.set(key, entry);
|
|
11895
|
+
}
|
|
11896
|
+
if (jobType) entry.servesJobTypes.push(jobType);
|
|
11897
|
+
};
|
|
11898
|
+
for (const jobType of JOB_TYPES) {
|
|
11899
|
+
try {
|
|
11900
|
+
admit(resolveWorkerInference(config, jobType), jobType);
|
|
11901
|
+
} catch {
|
|
11902
|
+
}
|
|
11903
|
+
}
|
|
11904
|
+
for (const actor of ["gatherer", "matcher"]) {
|
|
11905
|
+
try {
|
|
11906
|
+
admit(resolveActorInference(config, actor));
|
|
11907
|
+
} catch {
|
|
11908
|
+
}
|
|
11909
|
+
}
|
|
11910
|
+
return [...roster.values()].map(
|
|
11911
|
+
({ agent, servesJobTypes }) => servesJobTypes.length ? { agent, servesJobTypes } : { agent }
|
|
11912
|
+
);
|
|
11913
|
+
}
|
|
11803
11914
|
|
|
11804
11915
|
// src/browser.ts
|
|
11805
11916
|
var Browser = class {
|
|
11806
|
-
constructor(views, kb, eventBus, project, logger) {
|
|
11917
|
+
constructor(views, kb, eventBus, project, config, logger) {
|
|
11807
11918
|
this.views = views;
|
|
11808
11919
|
this.kb = kb;
|
|
11809
11920
|
this.eventBus = eventBus;
|
|
11810
11921
|
this.project = project;
|
|
11922
|
+
this.config = config;
|
|
11811
11923
|
this.logger = logger;
|
|
11812
11924
|
}
|
|
11813
11925
|
views;
|
|
11814
11926
|
kb;
|
|
11815
11927
|
eventBus;
|
|
11816
11928
|
project;
|
|
11929
|
+
config;
|
|
11817
11930
|
subscriptions = [];
|
|
11818
11931
|
logger;
|
|
11819
11932
|
async initialize() {
|
|
@@ -11821,7 +11934,19 @@ var Browser = class {
|
|
|
11821
11934
|
const errorHandler = (err) => this.logger.error("Browser pipeline error", { error: err });
|
|
11822
11935
|
const pipe = (name, handler) => this.eventBus.get(name).pipe(
|
|
11823
11936
|
(0, import_operators5.mergeMap)(
|
|
11824
|
-
(event) => (0, import_rxjs5.from)(withActorSpan("browser", name, () => handler(event)))
|
|
11937
|
+
(event) => (0, import_rxjs5.from)(withActorSpan("browser", name, () => handler(event))).pipe(
|
|
11938
|
+
// Isolate per-event failures: a single handler throw must NOT tear down the
|
|
11939
|
+
// channel subscription for every future request — that's the browse:entity-types
|
|
11940
|
+
// wedge (.plans/bugs/browse-entity-types-never-responds.md). Handlers emit their
|
|
11941
|
+
// own *-failed reply; this is the structural backstop for any throw that escapes a
|
|
11942
|
+
// handler's try/catch — the channel survives, the offending request is logged.
|
|
11943
|
+
// (A per-channel *-failed can't be emitted from this generic helper without the
|
|
11944
|
+
// request→failure mapping — that's the Tier 1 operations registry.)
|
|
11945
|
+
(0, import_operators5.catchError)((error) => {
|
|
11946
|
+
this.logger.error(`browse handler threw on ${name}`, { error: errField(error) });
|
|
11947
|
+
return import_rxjs5.EMPTY;
|
|
11948
|
+
})
|
|
11949
|
+
)
|
|
11825
11950
|
)
|
|
11826
11951
|
);
|
|
11827
11952
|
this.subscriptions.push(
|
|
@@ -11834,6 +11959,7 @@ var Browser = class {
|
|
|
11834
11959
|
pipe("browse:referenced-by-requested", (e) => this.handleReferencedBy(e)).subscribe({ error: errorHandler }),
|
|
11835
11960
|
pipe("browse:entity-types-requested", (e) => this.handleEntityTypes(e)).subscribe({ error: errorHandler }),
|
|
11836
11961
|
pipe("browse:tag-schemas-requested", (e) => this.handleTagSchemas(e)).subscribe({ error: errorHandler }),
|
|
11962
|
+
pipe("browse:agents-requested", (e) => this.handleBrowseAgents(e)).subscribe({ error: errorHandler }),
|
|
11837
11963
|
pipe("browse:directory-requested", (e) => this.handleBrowseDirectory(e)).subscribe({ error: errorHandler })
|
|
11838
11964
|
);
|
|
11839
11965
|
}
|
|
@@ -12082,6 +12208,21 @@ var Browser = class {
|
|
|
12082
12208
|
});
|
|
12083
12209
|
}
|
|
12084
12210
|
}
|
|
12211
|
+
async handleBrowseAgents(event) {
|
|
12212
|
+
try {
|
|
12213
|
+
const agents = deriveAgentRoster(this.config);
|
|
12214
|
+
this.eventBus.get("browse:agents-result").next({
|
|
12215
|
+
correlationId: event.correlationId,
|
|
12216
|
+
response: { agents }
|
|
12217
|
+
});
|
|
12218
|
+
} catch (error) {
|
|
12219
|
+
this.logger.error("Agent roster derivation failed", { error: errField(error) });
|
|
12220
|
+
this.eventBus.get("browse:agents-failed").next({
|
|
12221
|
+
correlationId: event.correlationId,
|
|
12222
|
+
message: error instanceof Error ? error.message : String(error)
|
|
12223
|
+
});
|
|
12224
|
+
}
|
|
12225
|
+
}
|
|
12085
12226
|
// ========================================================================
|
|
12086
12227
|
// Filesystem read handler
|
|
12087
12228
|
// ========================================================================
|
|
@@ -12206,49 +12347,48 @@ async function readAnnotationFromView(kb, resourceId10, annotationId5) {
|
|
|
12206
12347
|
}
|
|
12207
12348
|
|
|
12208
12349
|
// 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
12350
|
var import_rxjs6 = __toESM(require_cjs());
|
|
12214
12351
|
var import_operators6 = __toESM(require_operators());
|
|
12352
|
+
|
|
12353
|
+
// src/bus-request-local.ts
|
|
12354
|
+
function asBusRequestPrimitive(eventBus) {
|
|
12355
|
+
return {
|
|
12356
|
+
emit(channel, payload) {
|
|
12357
|
+
eventBus.get(channel).next(payload);
|
|
12358
|
+
return Promise.resolve();
|
|
12359
|
+
},
|
|
12360
|
+
stream(channel) {
|
|
12361
|
+
return eventBus.get(channel).asObservable();
|
|
12362
|
+
}
|
|
12363
|
+
};
|
|
12364
|
+
}
|
|
12365
|
+
|
|
12366
|
+
// src/resource-operations.ts
|
|
12215
12367
|
var ResourceOperations = class {
|
|
12216
12368
|
/**
|
|
12217
12369
|
* Create a new resource via EventBus → Stower
|
|
12218
12370
|
*/
|
|
12219
12371
|
static async createResource(input, userId3, eventBus) {
|
|
12220
|
-
const
|
|
12221
|
-
eventBus
|
|
12222
|
-
|
|
12223
|
-
|
|
12224
|
-
|
|
12225
|
-
|
|
12226
|
-
|
|
12227
|
-
|
|
12228
|
-
|
|
12229
|
-
|
|
12230
|
-
|
|
12231
|
-
|
|
12372
|
+
const { resourceId: rId } = await busRequest(
|
|
12373
|
+
asBusRequestPrimitive(eventBus),
|
|
12374
|
+
"yield:create",
|
|
12375
|
+
{
|
|
12376
|
+
name: input.name,
|
|
12377
|
+
storageUri: input.storageUri,
|
|
12378
|
+
contentChecksum: input.contentChecksum,
|
|
12379
|
+
byteSize: input.byteSize,
|
|
12380
|
+
format: input.format,
|
|
12381
|
+
_userId: userId3,
|
|
12382
|
+
language: input.language,
|
|
12383
|
+
entityTypes: input.entityTypes,
|
|
12384
|
+
generatedFrom: input.generatedFrom,
|
|
12385
|
+
generationPrompt: input.generationPrompt,
|
|
12386
|
+
generator: input.generator,
|
|
12387
|
+
isDraft: input.isDraft
|
|
12388
|
+
},
|
|
12389
|
+
3e4
|
|
12232
12390
|
);
|
|
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);
|
|
12391
|
+
return resourceId(rId);
|
|
12252
12392
|
}
|
|
12253
12393
|
};
|
|
12254
12394
|
|
|
@@ -12268,13 +12408,13 @@ var CloneTokenManager = class {
|
|
|
12268
12408
|
this.logger.info("CloneTokenManager actor initialized");
|
|
12269
12409
|
const errorHandler = (err) => this.logger.error("CloneTokenManager pipeline error", { error: err });
|
|
12270
12410
|
const generateToken$ = this.eventBus.get("yield:clone-token-requested").pipe(
|
|
12271
|
-
(0,
|
|
12411
|
+
(0, import_operators6.mergeMap)((event) => (0, import_rxjs6.from)(this.handleGenerateToken(event)))
|
|
12272
12412
|
);
|
|
12273
12413
|
const getResource$ = this.eventBus.get("yield:clone-resource-requested").pipe(
|
|
12274
|
-
(0,
|
|
12414
|
+
(0, import_operators6.mergeMap)((event) => (0, import_rxjs6.from)(this.handleGetResource(event)))
|
|
12275
12415
|
);
|
|
12276
12416
|
const createResource$ = this.eventBus.get("yield:clone-create").pipe(
|
|
12277
|
-
(0,
|
|
12417
|
+
(0, import_operators6.mergeMap)((event) => (0, import_rxjs6.from)(this.handleCreateResource(event)))
|
|
12278
12418
|
);
|
|
12279
12419
|
this.subscriptions.push(
|
|
12280
12420
|
generateToken$.subscribe({ error: errorHandler }),
|
|
@@ -12448,10 +12588,6 @@ var CloneTokenManager = class {
|
|
|
12448
12588
|
this.logger.info("CloneTokenManager actor stopped");
|
|
12449
12589
|
}
|
|
12450
12590
|
};
|
|
12451
|
-
|
|
12452
|
-
// src/bootstrap/entity-types.ts
|
|
12453
|
-
var import_rxjs8 = __toESM(require_cjs());
|
|
12454
|
-
var import_operators8 = __toESM(require_operators());
|
|
12455
12591
|
async function bootstrapEntityTypes(eventBus, eventStore, logger) {
|
|
12456
12592
|
const systemEvents = await eventStore.log.getEvents(resourceId("__system__"));
|
|
12457
12593
|
const existingTypes = new Set(
|
|
@@ -12466,16 +12602,12 @@ async function bootstrapEntityTypes(eventBus, eventStore, logger) {
|
|
|
12466
12602
|
const SYSTEM_USER_ID = userId("00000000-0000-0000-0000-000000000000");
|
|
12467
12603
|
for (const entityType2 of missing) {
|
|
12468
12604
|
logger?.debug("Adding entity type via EventBus", { entityType: entityType2 });
|
|
12469
|
-
|
|
12470
|
-
eventBus
|
|
12471
|
-
|
|
12472
|
-
|
|
12605
|
+
await busRequest(
|
|
12606
|
+
asBusRequestPrimitive(eventBus),
|
|
12607
|
+
"frame:add-entity-type",
|
|
12608
|
+
{ tag: entityType2, _userId: SYSTEM_USER_ID },
|
|
12609
|
+
1e4
|
|
12473
12610
|
);
|
|
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
12611
|
}
|
|
12480
12612
|
logger?.info("Entity types bootstrap completed", { added: missing.length, total: DEFAULT_ENTITY_TYPES.length });
|
|
12481
12613
|
}
|
|
@@ -12636,10 +12768,7 @@ function registerBindUpdateBodyHandler(eventBus, parentLogger) {
|
|
|
12636
12768
|
if (!cid || !inflight.has(cid)) return;
|
|
12637
12769
|
inflight.delete(cid);
|
|
12638
12770
|
const annId = event.payload?.annotationId;
|
|
12639
|
-
eventBus.get("bind:body-updated").next({
|
|
12640
|
-
correlationId: cid,
|
|
12641
|
-
annotationId: annId
|
|
12642
|
-
});
|
|
12771
|
+
eventBus.get("bind:body-updated").next({ correlationId: cid });
|
|
12643
12772
|
logger.info("Bind body-updated confirmed", { annotationId: annId, correlationId: cid });
|
|
12644
12773
|
});
|
|
12645
12774
|
eventBus.get("mark:body-update-failed").subscribe((event) => {
|
|
@@ -12654,31 +12783,6 @@ function registerBindUpdateBodyHandler(eventBus, parentLogger) {
|
|
|
12654
12783
|
logger.warn("Bind body-update failed after forwarding", { correlationId: cid, message });
|
|
12655
12784
|
});
|
|
12656
12785
|
}
|
|
12657
|
-
|
|
12658
|
-
// src/views/projection-validators.ts
|
|
12659
|
-
function resolveTagSchema(tagSchemas, schemaId) {
|
|
12660
|
-
if (typeof schemaId !== "string" || !schemaId) {
|
|
12661
|
-
return { error: "tag-annotation requires schemaId" };
|
|
12662
|
-
}
|
|
12663
|
-
const schema = tagSchemas.find((s) => s.id === schemaId);
|
|
12664
|
-
if (!schema) {
|
|
12665
|
-
return { error: `Tag schema not registered: ${schemaId}` };
|
|
12666
|
-
}
|
|
12667
|
-
return { schema };
|
|
12668
|
-
}
|
|
12669
|
-
function validateEntityTypes(registered, requested) {
|
|
12670
|
-
if (!requested || requested.length === 0) {
|
|
12671
|
-
return { ok: true };
|
|
12672
|
-
}
|
|
12673
|
-
const set = new Set(registered);
|
|
12674
|
-
const unknown = requested.filter((t) => !set.has(t));
|
|
12675
|
-
return unknown.length > 0 ? { ok: false, unknown } : { ok: true };
|
|
12676
|
-
}
|
|
12677
|
-
function entityTypesNotRegisteredMessage(unknown) {
|
|
12678
|
-
return `Entity type not registered: ${unknown.join(", ")}`;
|
|
12679
|
-
}
|
|
12680
|
-
|
|
12681
|
-
// src/handlers/job-commands.ts
|
|
12682
12786
|
function parseDidUser(did) {
|
|
12683
12787
|
const parts = did.split(":");
|
|
12684
12788
|
const usersIdx = parts.indexOf("users");
|
|
@@ -12706,7 +12810,11 @@ function registerJobCommandHandlers(eventBus, jobQueue, project, parentLogger) {
|
|
|
12706
12810
|
userDomain: user.domain,
|
|
12707
12811
|
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12708
12812
|
retryCount: 0,
|
|
12709
|
-
|
|
12813
|
+
// Generation is non-idempotent — a retry re-runs the LLM and produces
|
|
12814
|
+
// *different* content (not a replay) — and expensive. Surface the failure
|
|
12815
|
+
// to the caller rather than silently re-rolling. Detection jobs re-scan the
|
|
12816
|
+
// same content (≈idempotent) and keep one self-heal retry.
|
|
12817
|
+
maxRetries: jobType === "generation" ? 0 : 1
|
|
12710
12818
|
},
|
|
12711
12819
|
params: {
|
|
12712
12820
|
resourceId: resourceId(resId),
|
|
@@ -12823,11 +12931,19 @@ function registerJobCommandHandlers(eventBus, jobQueue, project, parentLogger) {
|
|
|
12823
12931
|
try {
|
|
12824
12932
|
const cancelled = await jobQueue.cancelPendingJobs(event.jobType);
|
|
12825
12933
|
logger.info("Cancel requested", { jobType: event.jobType, cancelled });
|
|
12934
|
+
eventBus.get("job:cancel-ok").next({
|
|
12935
|
+
correlationId: event.correlationId,
|
|
12936
|
+
response: { cancelled }
|
|
12937
|
+
});
|
|
12826
12938
|
} catch (error) {
|
|
12827
12939
|
logger.error("Failed to cancel pending jobs", {
|
|
12828
12940
|
jobType: event.jobType,
|
|
12829
12941
|
error: error.message
|
|
12830
12942
|
});
|
|
12943
|
+
eventBus.get("job:cancel-failed").next({
|
|
12944
|
+
correlationId: event.correlationId,
|
|
12945
|
+
message: error.message
|
|
12946
|
+
});
|
|
12831
12947
|
}
|
|
12832
12948
|
});
|
|
12833
12949
|
}
|
|
@@ -12847,7 +12963,7 @@ async function createJobQueue(project, eventBus, logger) {
|
|
|
12847
12963
|
await jobQueue.initialize();
|
|
12848
12964
|
registerJobQueueProvider(() => jobQueue.getStats());
|
|
12849
12965
|
const jobStatusSubscription = eventBus.get("job:status-requested").pipe(
|
|
12850
|
-
(0,
|
|
12966
|
+
(0, import_operators7.mergeMap)((event) => (0, import_rxjs7.from)((async () => {
|
|
12851
12967
|
try {
|
|
12852
12968
|
const job = await jobQueue.getJob(jobId(event.jobId));
|
|
12853
12969
|
if (!job) {
|
|
@@ -12917,7 +13033,7 @@ async function createKnowledgeSystemFromConfig(project, config, eventBus, logger
|
|
|
12917
13033
|
if (annotation === null) return event;
|
|
12918
13034
|
return { ...event, annotation };
|
|
12919
13035
|
});
|
|
12920
|
-
const stower = new Stower(kb, eventBus, logger.child({ component: "stower" }));
|
|
13036
|
+
const stower = new Stower(kb, eventBus, project, logger.child({ component: "stower" }));
|
|
12921
13037
|
await stower.initialize();
|
|
12922
13038
|
await bootstrapEntityTypes(eventBus, eventStore, logger.child({ component: "entity-types-bootstrap" }));
|
|
12923
13039
|
const gatherer = new Gatherer(
|
|
@@ -12936,7 +13052,7 @@ async function createKnowledgeSystemFromConfig(project, config, eventBus, logger
|
|
|
12936
13052
|
embeddingProvider
|
|
12937
13053
|
);
|
|
12938
13054
|
await matcher.initialize();
|
|
12939
|
-
const browser = new Browser(kb.views, kb, eventBus, project, logger.child({ component: "browser" }));
|
|
13055
|
+
const browser = new Browser(kb.views, kb, eventBus, project, config, logger.child({ component: "browser" }));
|
|
12940
13056
|
await browser.initialize();
|
|
12941
13057
|
const cloneTokenManager = new CloneTokenManager(kb, eventBus, logger.child({ component: "clone-token-manager" }));
|
|
12942
13058
|
await cloneTokenManager.initialize();
|
|
@@ -12964,11 +13080,11 @@ async function startMakeMeaning(project, config, eventBus, logger, options) {
|
|
|
12964
13080
|
}
|
|
12965
13081
|
|
|
12966
13082
|
// src/local-transport.ts
|
|
12967
|
-
var
|
|
13083
|
+
var import_rxjs8 = __toESM(require_cjs());
|
|
12968
13084
|
var LocalTransport = class {
|
|
12969
13085
|
baseUrl;
|
|
12970
13086
|
state$;
|
|
12971
|
-
errorsSubject = new
|
|
13087
|
+
errorsSubject = new import_rxjs8.Subject();
|
|
12972
13088
|
/**
|
|
12973
13089
|
* Stream of `SemiontError` instances surfaced from transport-mediated
|
|
12974
13090
|
* round-trips (typed-wire methods on this transport that fail). The
|
|
@@ -12989,7 +13105,7 @@ var LocalTransport = class {
|
|
|
12989
13105
|
this.bus = cfg.eventBus;
|
|
12990
13106
|
this.userId = cfg.userId;
|
|
12991
13107
|
this.baseUrl = cfg.baseUrl ?? baseUrl("local://in-process");
|
|
12992
|
-
this.state$ = new
|
|
13108
|
+
this.state$ = new import_rxjs8.BehaviorSubject("open");
|
|
12993
13109
|
}
|
|
12994
13110
|
// ── Bus primitives ──────────────────────────────────────────────────────
|
|
12995
13111
|
async emit(channel, payload, resourceScope) {
|
|
@@ -13122,8 +13238,8 @@ var LocalContentTransport = class {
|
|
|
13122
13238
|
};
|
|
13123
13239
|
|
|
13124
13240
|
// src/smelter.ts
|
|
13125
|
-
var
|
|
13126
|
-
var
|
|
13241
|
+
var import_rxjs9 = __toESM(require_cjs());
|
|
13242
|
+
var import_operators8 = __toESM(require_operators());
|
|
13127
13243
|
function isWorkItem(input) {
|
|
13128
13244
|
return input.type.startsWith("smelt:");
|
|
13129
13245
|
}
|
|
@@ -13149,7 +13265,7 @@ var Smelter = class _Smelter {
|
|
|
13149
13265
|
static RECONCILE_PAGE_SIZE = 200;
|
|
13150
13266
|
/** Bound on concurrently in-flight reconcile work — a cold rebuild must not fan out unbounded embedding calls. */
|
|
13151
13267
|
static RECONCILE_WAVE = 8;
|
|
13152
|
-
eventSubject = new
|
|
13268
|
+
eventSubject = new import_rxjs9.Subject();
|
|
13153
13269
|
sourceSubscription = null;
|
|
13154
13270
|
pipelineSubscription = null;
|
|
13155
13271
|
_eventsProcessed = 0;
|
|
@@ -13164,23 +13280,23 @@ var Smelter = class _Smelter {
|
|
|
13164
13280
|
}
|
|
13165
13281
|
initialize() {
|
|
13166
13282
|
this.pipelineSubscription = this.eventSubject.pipe(
|
|
13167
|
-
(0,
|
|
13168
|
-
(0,
|
|
13283
|
+
(0, import_operators8.groupBy)((e) => e.resourceId ?? "__unknown__"),
|
|
13284
|
+
(0, import_operators8.mergeMap)(
|
|
13169
13285
|
(group) => group.pipe(
|
|
13170
13286
|
burstBuffer({
|
|
13171
13287
|
burstWindowMs: this.timing.burstWindowMs,
|
|
13172
13288
|
maxBatchSize: this.timing.maxBatchSize,
|
|
13173
13289
|
idleTimeoutMs: this.timing.idleTimeoutMs
|
|
13174
13290
|
}),
|
|
13175
|
-
(0,
|
|
13291
|
+
(0, import_operators8.concatMap)((inputOrBatch) => {
|
|
13176
13292
|
if (Array.isArray(inputOrBatch)) {
|
|
13177
|
-
return (0,
|
|
13293
|
+
return (0, import_rxjs9.from)(
|
|
13178
13294
|
withActorSpan("smelter", "batch", async () => {
|
|
13179
13295
|
this._eventsProcessed += await this.processBatch(inputOrBatch);
|
|
13180
13296
|
}, { "batch.size": inputOrBatch.length })
|
|
13181
13297
|
);
|
|
13182
13298
|
}
|
|
13183
|
-
return (0,
|
|
13299
|
+
return (0, import_rxjs9.from)(
|
|
13184
13300
|
withActorSpan("smelter", inputOrBatch.type, async () => {
|
|
13185
13301
|
const ok = await this.safeProcessEvent(inputOrBatch);
|
|
13186
13302
|
if (isWorkItem(inputOrBatch)) this.noteWorkDone(1);
|
|
@@ -13339,6 +13455,23 @@ var Smelter = class _Smelter {
|
|
|
13339
13455
|
return null;
|
|
13340
13456
|
}
|
|
13341
13457
|
}
|
|
13458
|
+
/**
|
|
13459
|
+
* Read a resource's current entity types from the materialized view — the
|
|
13460
|
+
* authoritative source, updated before the EventBus fires to consumers — so
|
|
13461
|
+
* its vectors carry the discriminator `searchResources` filters on (e.g.
|
|
13462
|
+
* exclude `['Question']`). One read on every embed path, mirroring how the
|
|
13463
|
+
* smelter already reads current content and annotations; a failed read
|
|
13464
|
+
* propagates to the pipeline's per-resource error handler (reconcile heals),
|
|
13465
|
+
* rather than silently stamping `[]` and letting the resource leak into recall.
|
|
13466
|
+
*/
|
|
13467
|
+
async resolveEntityTypes(resourceId10) {
|
|
13468
|
+
const { resource } = await busRequest(
|
|
13469
|
+
this.bus,
|
|
13470
|
+
"browse:resource-requested",
|
|
13471
|
+
{ resourceId: resourceId10 }
|
|
13472
|
+
);
|
|
13473
|
+
return getResourceEntityTypes(resource);
|
|
13474
|
+
}
|
|
13342
13475
|
async embedResource(event, logMessage) {
|
|
13343
13476
|
const rid = event.resourceId;
|
|
13344
13477
|
if (!rid) return;
|
|
@@ -13346,13 +13479,14 @@ var Smelter = class _Smelter {
|
|
|
13346
13479
|
if (!fetched) return;
|
|
13347
13480
|
const chunks = chunkText(fetched.text, this.chunkingConfig);
|
|
13348
13481
|
if (chunks.length === 0) return;
|
|
13482
|
+
const entityTypes = await this.resolveEntityTypes(rid);
|
|
13349
13483
|
const embeddings = await this.embeddingProvider.embedBatch(chunks);
|
|
13350
13484
|
const embeddingChunks = chunks.map((t, i) => ({
|
|
13351
13485
|
chunkIndex: i,
|
|
13352
13486
|
text: t,
|
|
13353
13487
|
embedding: embeddings[i]
|
|
13354
13488
|
}));
|
|
13355
|
-
await this.vectorStore.upsertResourceVectors(resourceId(rid), embeddingChunks, fetched.checksum);
|
|
13489
|
+
await this.vectorStore.upsertResourceVectors(resourceId(rid), embeddingChunks, fetched.checksum, entityTypes);
|
|
13356
13490
|
this.logger.info(logMessage, { resourceId: rid, chunks: chunks.length });
|
|
13357
13491
|
}
|
|
13358
13492
|
async handleResourceArchived(event) {
|
|
@@ -13403,19 +13537,20 @@ var Smelter = class _Smelter {
|
|
|
13403
13537
|
if (!fetched) continue;
|
|
13404
13538
|
const chunks = chunkText(fetched.text, this.chunkingConfig);
|
|
13405
13539
|
if (chunks.length === 0) continue;
|
|
13406
|
-
|
|
13540
|
+
const entityTypes = await this.resolveEntityTypes(rid);
|
|
13541
|
+
resourceData.push({ rid: resourceId(rid), chunks, checksum: fetched.checksum, entityTypes });
|
|
13407
13542
|
allChunks.push(...chunks);
|
|
13408
13543
|
}
|
|
13409
13544
|
if (allChunks.length === 0) return events.length;
|
|
13410
13545
|
const allEmbeddings = await this.embeddingProvider.embedBatch(allChunks);
|
|
13411
13546
|
let offset = 0;
|
|
13412
|
-
for (const { rid, chunks, checksum } of resourceData) {
|
|
13547
|
+
for (const { rid, chunks, checksum, entityTypes } of resourceData) {
|
|
13413
13548
|
const embeddingChunks = chunks.map((t, i) => ({
|
|
13414
13549
|
chunkIndex: i,
|
|
13415
13550
|
text: t,
|
|
13416
13551
|
embedding: allEmbeddings[offset + i]
|
|
13417
13552
|
}));
|
|
13418
|
-
await this.vectorStore.upsertResourceVectors(rid, embeddingChunks, checksum);
|
|
13553
|
+
await this.vectorStore.upsertResourceVectors(rid, embeddingChunks, checksum, entityTypes);
|
|
13419
13554
|
this.logger.info("Batch-indexed resource", { resourceId: String(rid), chunks: chunks.length });
|
|
13420
13555
|
offset += chunks.length;
|
|
13421
13556
|
}
|
|
@@ -13522,9 +13657,7 @@ var Smelter = class _Smelter {
|
|
|
13522
13657
|
const { annotations } = await busRequest(
|
|
13523
13658
|
this.bus,
|
|
13524
13659
|
"browse:annotations-requested",
|
|
13525
|
-
{ resourceId: rid }
|
|
13526
|
-
"browse:annotations-result",
|
|
13527
|
-
"browse:annotations-failed"
|
|
13660
|
+
{ resourceId: rid }
|
|
13528
13661
|
);
|
|
13529
13662
|
for (const annotation of annotations) {
|
|
13530
13663
|
const exactText = getExactText(getTargetSelector(annotation.target));
|
|
@@ -13582,9 +13715,7 @@ var Smelter = class _Smelter {
|
|
|
13582
13715
|
const page = await busRequest(
|
|
13583
13716
|
this.bus,
|
|
13584
13717
|
"browse:resources-requested",
|
|
13585
|
-
{ archived: false, offset: all.length, limit: _Smelter.RECONCILE_PAGE_SIZE }
|
|
13586
|
-
"browse:resources-result",
|
|
13587
|
-
"browse:resources-failed"
|
|
13718
|
+
{ archived: false, offset: all.length, limit: _Smelter.RECONCILE_PAGE_SIZE }
|
|
13588
13719
|
);
|
|
13589
13720
|
all.push(...page.resources);
|
|
13590
13721
|
if (page.resources.length === 0 || all.length >= page.total) return all;
|
|
@@ -13593,8 +13724,8 @@ var Smelter = class _Smelter {
|
|
|
13593
13724
|
};
|
|
13594
13725
|
|
|
13595
13726
|
// src/smelter-actor-state-unit.ts
|
|
13596
|
-
var
|
|
13597
|
-
var
|
|
13727
|
+
var import_rxjs10 = __toESM(require_cjs());
|
|
13728
|
+
var import_operators9 = __toESM(require_operators());
|
|
13598
13729
|
var SMELTER_CHANNELS = [
|
|
13599
13730
|
"yield:created",
|
|
13600
13731
|
"yield:updated",
|
|
@@ -13606,10 +13737,10 @@ var SMELTER_CHANNELS = [
|
|
|
13606
13737
|
function createSmelterActorStateUnit(options) {
|
|
13607
13738
|
const { bus } = options;
|
|
13608
13739
|
let started = false;
|
|
13609
|
-
const events$ = (0,
|
|
13740
|
+
const events$ = (0, import_rxjs10.merge)(
|
|
13610
13741
|
...SMELTER_CHANNELS.map(
|
|
13611
13742
|
(channel) => bus.on$(channel).pipe(
|
|
13612
|
-
(0,
|
|
13743
|
+
(0, import_operators9.map)((payload) => ({
|
|
13613
13744
|
type: channel,
|
|
13614
13745
|
resourceId: payload.resourceId,
|
|
13615
13746
|
payload
|
|
@@ -13812,11 +13943,28 @@ function collectContentRefs(streamData) {
|
|
|
13812
13943
|
return refs;
|
|
13813
13944
|
}
|
|
13814
13945
|
|
|
13815
|
-
// src/exchange/
|
|
13816
|
-
var
|
|
13817
|
-
var
|
|
13946
|
+
// src/exchange/await-reply.ts
|
|
13947
|
+
var import_rxjs11 = __toESM(require_cjs());
|
|
13948
|
+
var import_operators10 = __toESM(require_operators());
|
|
13949
|
+
function awaitReply(eventBus, command, payload, okChannel, failedChannel, timeoutMs) {
|
|
13950
|
+
const result$ = (0, import_rxjs11.race)(
|
|
13951
|
+
eventBus.get(okChannel).pipe((0, import_operators10.map)(() => void 0)),
|
|
13952
|
+
eventBus.get(failedChannel).pipe(
|
|
13953
|
+
(0, import_operators10.map)((e) => {
|
|
13954
|
+
throw new Error(e.message ?? `${command} failed`);
|
|
13955
|
+
})
|
|
13956
|
+
),
|
|
13957
|
+
(0, import_rxjs11.timer)(timeoutMs).pipe(
|
|
13958
|
+
(0, import_operators10.map)(() => {
|
|
13959
|
+
throw new Error(`Timeout waiting for ${okChannel}`);
|
|
13960
|
+
})
|
|
13961
|
+
)
|
|
13962
|
+
);
|
|
13963
|
+
eventBus.get(command).next(payload);
|
|
13964
|
+
return (0, import_rxjs11.firstValueFrom)(result$);
|
|
13965
|
+
}
|
|
13818
13966
|
var REPLAY_TIMEOUT_MS = 3e4;
|
|
13819
|
-
async function replayEventStream(jsonl, eventBus, resolveBlob, contentStore, logger) {
|
|
13967
|
+
async function replayEventStream(jsonl, eventBus, eventStore, resolveBlob, contentStore, logger) {
|
|
13820
13968
|
const lines = jsonl.trim().split("\n").filter((l) => l.length > 0);
|
|
13821
13969
|
const storedEvents = lines.map((line) => JSON.parse(line));
|
|
13822
13970
|
const stats = {
|
|
@@ -13826,12 +13974,12 @@ async function replayEventStream(jsonl, eventBus, resolveBlob, contentStore, log
|
|
|
13826
13974
|
entityTypesAdded: 0
|
|
13827
13975
|
};
|
|
13828
13976
|
for (const stored of storedEvents) {
|
|
13829
|
-
await replayEvent(stored, eventBus, resolveBlob, contentStore, stats, logger);
|
|
13977
|
+
await replayEvent(stored, eventBus, eventStore, resolveBlob, contentStore, stats, logger);
|
|
13830
13978
|
stats.eventsReplayed++;
|
|
13831
13979
|
}
|
|
13832
13980
|
return { stats };
|
|
13833
13981
|
}
|
|
13834
|
-
async function replayEvent(event, eventBus, resolveBlob, contentStore, stats, logger) {
|
|
13982
|
+
async function replayEvent(event, eventBus, eventStore, resolveBlob, contentStore, stats, logger) {
|
|
13835
13983
|
switch (event.type) {
|
|
13836
13984
|
case "frame:entity-type-added":
|
|
13837
13985
|
await replayEntityTypeAdded(event, eventBus, logger);
|
|
@@ -13859,7 +14007,7 @@ async function replayEvent(event, eventBus, resolveBlob, contentStore, stats, lo
|
|
|
13859
14007
|
break;
|
|
13860
14008
|
case "mark:entity-tag-added":
|
|
13861
14009
|
case "mark:entity-tag-removed":
|
|
13862
|
-
await replayEntityTagChange(event,
|
|
14010
|
+
await replayEntityTagChange(event, eventStore, logger);
|
|
13863
14011
|
break;
|
|
13864
14012
|
// Job events are transient — skip during replay
|
|
13865
14013
|
case "job:started":
|
|
@@ -13878,20 +14026,12 @@ async function replayEvent(event, eventBus, resolveBlob, contentStore, stats, lo
|
|
|
13878
14026
|
}
|
|
13879
14027
|
}
|
|
13880
14028
|
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
|
-
}))
|
|
14029
|
+
await busRequest(
|
|
14030
|
+
asBusRequestPrimitive(eventBus),
|
|
14031
|
+
"frame:add-entity-type",
|
|
14032
|
+
{ tag: event.payload.entityType, _userId: event.userId },
|
|
14033
|
+
REPLAY_TIMEOUT_MS
|
|
13889
14034
|
);
|
|
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
14035
|
logger?.debug("Replayed entitytype.added", { entityType: event.payload.entityType });
|
|
13896
14036
|
}
|
|
13897
14037
|
async function replayResourceCreated(event, eventBus, resolveBlob, contentStore, logger) {
|
|
@@ -13903,84 +14043,70 @@ async function replayResourceCreated(event, eventBus, resolveBlob, contentStore,
|
|
|
13903
14043
|
const base = baseMediaType(payload.format);
|
|
13904
14044
|
const resolvedUri = payload.storageUri || deriveStorageUri(payload.name, isSupportedMediaType(base) ? base : "application/octet-stream");
|
|
13905
14045
|
const stored = await contentStore.store(blob, resolvedUri);
|
|
13906
|
-
|
|
13907
|
-
eventBus
|
|
13908
|
-
|
|
13909
|
-
|
|
13910
|
-
|
|
13911
|
-
|
|
13912
|
-
|
|
13913
|
-
|
|
14046
|
+
await busRequest(
|
|
14047
|
+
asBusRequestPrimitive(eventBus),
|
|
14048
|
+
"yield:create",
|
|
14049
|
+
{
|
|
14050
|
+
name: payload.name,
|
|
14051
|
+
storageUri: resolvedUri,
|
|
14052
|
+
contentChecksum: stored.checksum,
|
|
14053
|
+
byteSize: stored.byteSize,
|
|
14054
|
+
format: payload.format,
|
|
14055
|
+
_userId: event.userId,
|
|
14056
|
+
language: payload.language,
|
|
14057
|
+
entityTypes: payload.entityTypes,
|
|
14058
|
+
isDraft: payload.isDraft,
|
|
14059
|
+
generatedFrom: payload.generatedFrom,
|
|
14060
|
+
generationPrompt: payload.generationPrompt
|
|
14061
|
+
},
|
|
14062
|
+
REPLAY_TIMEOUT_MS
|
|
13914
14063
|
);
|
|
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
14064
|
logger?.debug("Replayed resource.created", { name: payload.name });
|
|
13930
14065
|
}
|
|
13931
14066
|
async function replayAnnotationAdded(event, eventBus, logger) {
|
|
13932
|
-
|
|
13933
|
-
eventBus
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
}
|
|
14067
|
+
await awaitReply(
|
|
14068
|
+
eventBus,
|
|
14069
|
+
"mark:create",
|
|
14070
|
+
{
|
|
14071
|
+
annotation: event.payload.annotation,
|
|
14072
|
+
_userId: event.userId,
|
|
14073
|
+
resourceId: event.resourceId
|
|
14074
|
+
},
|
|
14075
|
+
"mark:create-ok",
|
|
14076
|
+
"mark:create-failed",
|
|
14077
|
+
REPLAY_TIMEOUT_MS
|
|
13940
14078
|
);
|
|
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
14079
|
logger?.debug("Replayed annotation.added", { annotationId: event.payload.annotation.id });
|
|
13948
14080
|
}
|
|
13949
14081
|
async function replayAnnotationBodyUpdated(event, eventBus, logger) {
|
|
13950
|
-
|
|
13951
|
-
eventBus
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
14082
|
+
await awaitReply(
|
|
14083
|
+
eventBus,
|
|
14084
|
+
"mark:update-body",
|
|
14085
|
+
{
|
|
14086
|
+
annotationId: event.payload.annotationId,
|
|
14087
|
+
_userId: event.userId,
|
|
14088
|
+
resourceId: event.resourceId,
|
|
14089
|
+
operations: event.payload.operations
|
|
14090
|
+
},
|
|
14091
|
+
"mark:body-updated",
|
|
14092
|
+
"mark:body-update-failed",
|
|
14093
|
+
REPLAY_TIMEOUT_MS
|
|
13958
14094
|
);
|
|
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
14095
|
logger?.debug("Replayed annotation.body.updated", { annotationId: event.payload.annotationId });
|
|
13967
14096
|
}
|
|
13968
14097
|
async function replayAnnotationRemoved(event, eventBus, logger) {
|
|
13969
|
-
|
|
13970
|
-
eventBus
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
}
|
|
14098
|
+
await awaitReply(
|
|
14099
|
+
eventBus,
|
|
14100
|
+
"mark:delete",
|
|
14101
|
+
{
|
|
14102
|
+
annotationId: event.payload.annotationId,
|
|
14103
|
+
_userId: event.userId,
|
|
14104
|
+
resourceId: event.resourceId
|
|
14105
|
+
},
|
|
14106
|
+
"mark:delete-ok",
|
|
14107
|
+
"mark:delete-failed",
|
|
14108
|
+
REPLAY_TIMEOUT_MS
|
|
13977
14109
|
);
|
|
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
14110
|
logger?.debug("Replayed annotation.removed", { annotationId: event.payload.annotationId });
|
|
13985
14111
|
}
|
|
13986
14112
|
async function replayResourceArchived(event, eventBus, logger) {
|
|
@@ -13997,25 +14123,18 @@ async function replayResourceUnarchived(event, eventBus, logger) {
|
|
|
13997
14123
|
});
|
|
13998
14124
|
logger?.debug("Replayed resource.unarchived", { resourceId: event.resourceId });
|
|
13999
14125
|
}
|
|
14000
|
-
async function replayEntityTagChange(event,
|
|
14001
|
-
const
|
|
14002
|
-
|
|
14126
|
+
async function replayEntityTagChange(event, eventStore, logger) {
|
|
14127
|
+
const base = {
|
|
14128
|
+
resourceId: event.resourceId,
|
|
14129
|
+
userId: event.userId,
|
|
14130
|
+
version: event.version
|
|
14131
|
+
};
|
|
14003
14132
|
if (event.type === "mark:entity-tag-added") {
|
|
14004
|
-
|
|
14005
|
-
resourceId: resourceId10,
|
|
14006
|
-
_userId: event.userId,
|
|
14007
|
-
currentEntityTypes: [],
|
|
14008
|
-
updatedEntityTypes: [entityType2]
|
|
14009
|
-
});
|
|
14133
|
+
await eventStore.appendEvent({ ...base, type: "mark:entity-tag-added", payload: event.payload });
|
|
14010
14134
|
} else {
|
|
14011
|
-
|
|
14012
|
-
resourceId: resourceId10,
|
|
14013
|
-
_userId: event.userId,
|
|
14014
|
-
currentEntityTypes: [entityType2],
|
|
14015
|
-
updatedEntityTypes: []
|
|
14016
|
-
});
|
|
14135
|
+
await eventStore.appendEvent({ ...base, type: "mark:entity-tag-removed", payload: event.payload });
|
|
14017
14136
|
}
|
|
14018
|
-
logger?.debug("Replayed entity tag change", { type: event.type, entityType:
|
|
14137
|
+
logger?.debug("Replayed entity tag change", { type: event.type, entityType: event.payload.entityType });
|
|
14019
14138
|
}
|
|
14020
14139
|
|
|
14021
14140
|
// src/exchange/backup-importer.ts
|
|
@@ -14034,7 +14153,7 @@ function buildBlobResolver(entries) {
|
|
|
14034
14153
|
};
|
|
14035
14154
|
}
|
|
14036
14155
|
async function importBackup(archive, options) {
|
|
14037
|
-
const { eventBus, contentStore, logger } = options;
|
|
14156
|
+
const { eventBus, eventStore, contentStore, logger } = options;
|
|
14038
14157
|
const entries = /* @__PURE__ */ new Map();
|
|
14039
14158
|
for await (const entry of readTarGz(archive)) {
|
|
14040
14159
|
entries.set(entry.name, entry.data);
|
|
@@ -14062,6 +14181,7 @@ async function importBackup(archive, options) {
|
|
|
14062
14181
|
const result = await replayEventStream(
|
|
14063
14182
|
systemData.toString("utf8"),
|
|
14064
14183
|
eventBus,
|
|
14184
|
+
eventStore,
|
|
14065
14185
|
resolveBlob,
|
|
14066
14186
|
contentStore,
|
|
14067
14187
|
logger
|
|
@@ -14078,6 +14198,7 @@ async function importBackup(archive, options) {
|
|
|
14078
14198
|
const result = await replayEventStream(
|
|
14079
14199
|
eventData.toString("utf8"),
|
|
14080
14200
|
eventBus,
|
|
14201
|
+
eventStore,
|
|
14081
14202
|
resolveBlob,
|
|
14082
14203
|
contentStore,
|
|
14083
14204
|
logger
|
|
@@ -14263,10 +14384,6 @@ function collectContentRefsFromResource(resource, refs) {
|
|
|
14263
14384
|
refs.set(resource.storageUri, mediaType);
|
|
14264
14385
|
}
|
|
14265
14386
|
}
|
|
14266
|
-
|
|
14267
|
-
// src/exchange/linked-data-importer.ts
|
|
14268
|
-
var import_rxjs14 = __toESM(require_cjs());
|
|
14269
|
-
var import_operators13 = __toESM(require_operators());
|
|
14270
14387
|
var IMPORT_TIMEOUT_MS = 3e4;
|
|
14271
14388
|
function stripUriToId(uri) {
|
|
14272
14389
|
if (!uri.includes("/")) return uri;
|
|
@@ -14368,20 +14485,12 @@ async function importLinkedData(archive, options) {
|
|
|
14368
14485
|
};
|
|
14369
14486
|
}
|
|
14370
14487
|
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
|
-
}))
|
|
14488
|
+
await busRequest(
|
|
14489
|
+
asBusRequestPrimitive(eventBus),
|
|
14490
|
+
"frame:add-entity-type",
|
|
14491
|
+
{ tag: entityType2, _userId: userId3 },
|
|
14492
|
+
IMPORT_TIMEOUT_MS
|
|
14379
14493
|
);
|
|
14380
|
-
eventBus.get("frame:add-entity-type").next({
|
|
14381
|
-
tag: entityType2,
|
|
14382
|
-
_userId: userId3
|
|
14383
|
-
});
|
|
14384
|
-
await (0, import_rxjs14.firstValueFrom)(result$);
|
|
14385
14494
|
logger?.debug("Added entity type", { entityType: entityType2 });
|
|
14386
14495
|
}
|
|
14387
14496
|
async function importResource(doc, userId3, eventBus, contentStore, resolveBlob, logger) {
|
|
@@ -14408,27 +14517,22 @@ async function importResource(doc, userId3, eventBus, contentStore, resolveBlob,
|
|
|
14408
14517
|
const base = baseMediaType(format);
|
|
14409
14518
|
const resolvedUri = deriveStorageUri(name, isSupportedMediaType(base) ? base : "application/octet-stream");
|
|
14410
14519
|
const stored = await contentStore.store(blob, resolvedUri);
|
|
14411
|
-
const
|
|
14412
|
-
eventBus
|
|
14413
|
-
|
|
14414
|
-
|
|
14415
|
-
|
|
14416
|
-
|
|
14417
|
-
|
|
14418
|
-
|
|
14520
|
+
const { resourceId: createdId } = await busRequest(
|
|
14521
|
+
asBusRequestPrimitive(eventBus),
|
|
14522
|
+
"yield:create",
|
|
14523
|
+
{
|
|
14524
|
+
name,
|
|
14525
|
+
storageUri: resolvedUri,
|
|
14526
|
+
contentChecksum: stored.checksum,
|
|
14527
|
+
byteSize: stored.byteSize,
|
|
14528
|
+
format,
|
|
14529
|
+
_userId: userId3,
|
|
14530
|
+
language,
|
|
14531
|
+
entityTypes: entityTypes ?? []
|
|
14532
|
+
},
|
|
14533
|
+
IMPORT_TIMEOUT_MS
|
|
14419
14534
|
);
|
|
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);
|
|
14535
|
+
const resourceId10 = resourceId(createdId);
|
|
14432
14536
|
logger?.debug("Created resource from JSON-LD", { name, resourceId: resourceId10 });
|
|
14433
14537
|
let annotationsCreated = 0;
|
|
14434
14538
|
if (annotations && annotations.length > 0) {
|
|
@@ -14440,21 +14544,18 @@ async function importResource(doc, userId3, eventBus, contentStore, resolveBlob,
|
|
|
14440
14544
|
return { annotationsCreated };
|
|
14441
14545
|
}
|
|
14442
14546
|
async function createAnnotation(annotation, resourceId10, userId3, eventBus, logger) {
|
|
14443
|
-
|
|
14444
|
-
eventBus
|
|
14445
|
-
|
|
14446
|
-
|
|
14447
|
-
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
}
|
|
14547
|
+
await awaitReply(
|
|
14548
|
+
eventBus,
|
|
14549
|
+
"mark:create",
|
|
14550
|
+
{
|
|
14551
|
+
annotation: dehydrateAnnotation(annotation),
|
|
14552
|
+
_userId: userId3,
|
|
14553
|
+
resourceId: resourceId10
|
|
14554
|
+
},
|
|
14555
|
+
"mark:create-ok",
|
|
14556
|
+
"mark:create-failed",
|
|
14557
|
+
IMPORT_TIMEOUT_MS
|
|
14451
14558
|
);
|
|
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
14559
|
logger?.debug("Created annotation", { annotationId: annotation.id });
|
|
14459
14560
|
}
|
|
14460
14561
|
var AnnotationOperations = class {
|