@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.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, getTargetSource, getBodySource, resourceId, getTargetSelector, getResourceEntityTypes, getResourceId, getTextPositionSelector, annotationId, errField, userId, generateUuid, getExactText, cloneToken, baseMediaType, isSupportedMediaType, capabilitiesOf, didToAgent, assembleAnnotation, jobId, entityType, baseUrl, busLog, BRIDGED_CHANNELS, burstBuffer, textExtractionOf, getPrimaryMediaType, extensionForMediaType, applyBodyOperations, findBodyItem } from '@semiont/core';
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 firstValueFrom5(source, config) {
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 = firstValueFrom5;
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 map6(project, thisArg) {
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 = map6;
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 timer5(dueTime, intervalOrScheduler, scheduler) {
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 = timer5;
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 race5() {
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 = race5;
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 catchError(selector) {
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, catchError(selector)(source)));
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 = 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 take3(count) {
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 = take3;
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 race5() {
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 = race5;
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 import_rxjs9 = __toESM(require_cjs());
9740
- var import_operators9 = __toESM(require_operators());
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 context", { resourceId: resourceId10 });
10410
- const [connections, referencedByAnnotations, entityTypeStats] = await Promise.all([
10411
- kb.graph.getResourceConnections(resourceId10),
10412
- kb.graph.getResourceReferencedBy(resourceId10),
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.targetResource.name).slice(0, 10);
10443
- const citedByNames = Array.from(citedByMap.values()).slice(0, 5);
10444
- const siblingTypes = Array.from(siblingEntityTypes).slice(0, 10);
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 generationContext = {
10509
- annotation,
10510
- sourceResource: sourceDoc,
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
- graphContext,
10568
+ ...inferredRelationshipSummary ? { inferredRelationshipSummary } : {},
10517
10569
  ...semanticContext ? { semanticContext } : {}
10518
10570
  };
10519
- if (sourceContext) {
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.buildGraphRepresentation(
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
- for (const node of graph.nodes) {
10849
- if (node.id !== resourceIdStr) {
10850
- const relatedDoc = await ResourceContext.getResourceMetadata(resourceId(node.id), kb);
10851
- if (relatedDoc) {
10852
- relatedDocs.push(relatedDoc);
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 relatedResourcesContent = {};
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 content = await ResourceContext.getResourceContent(doc, kb);
10863
- if (content) {
10864
- relatedResourcesContent[docId] = content;
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
- mainResource: mainDoc,
10879
- relatedResources: relatedDocs,
10880
- annotations,
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
- ...mainContent ? { mainResourceContent: mainContent } : {},
10883
- ...options.includeContent ? { relatedResourcesContent } : {},
10884
- ...summary ? { summary } : {},
10885
- ...suggestedReferences ? { suggestedReferences } : {}
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
- const selectedText = context.sourceContext?.selected ?? "";
11046
- const userHint = context.userHint ?? "";
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?.entityTypes ?? [];
11094
- const connections = context.graphContext?.connections ?? [];
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.graphContext?.entityTypeFrequencies ?? {};
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 = context.graphContext?.citedByCount ?? 0;
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 = [context.sourceContext?.selected, context.userHint].filter(Boolean).join(" \u2014 ") || searchTerm;
11245
- const entityTypes = context.metadata?.entityTypes ?? [];
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: ${context.annotation.motivation}`);
11255
- contextParts.push(`Source resource: ${context.sourceResource.name}`);
11256
- const { motivation, body } = context.annotation;
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.graphContext?.inferredRelationshipSummary) {
11270
- contextParts.push(`Relationship context: ${context.graphContext.inferredRelationshipSummary}`);
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
- const resource = {
11415
- "@context": "https://schema.org/",
11416
- "@id": rId,
11417
- name: event.name,
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({ resourceId: event.resourceId });
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
- resourceId: event.resourceId,
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
- if (event.storageUri) {
11602
- await this.kb.content.remove(event.storageUri, { keepFile: event.keepFile, noGit: event.noGit });
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
- if (event.storageUri) {
11617
- const absPath = this.kb.content.resolveUri(event.storageUri);
11618
- try {
11619
- await promises.access(absPath);
11620
- } catch {
11621
- this.logger.warn("Unarchive failed: file not found at storageUri", { storageUri: event.storageUri });
11622
- return;
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 result$ = (0, import_rxjs6.race)(
12221
- eventBus.get("yield:create-ok").pipe(
12222
- (0, import_operators6.take)(1),
12223
- (0, import_operators6.map)((result) => ({ ok: true, result }))
12224
- ),
12225
- eventBus.get("yield:create-failed").pipe(
12226
- (0, import_operators6.take)(1),
12227
- (0, import_operators6.map)((failure) => ({ ok: false, error: new Error(failure.message) }))
12228
- ),
12229
- (0, import_rxjs6.timer)(3e4).pipe(
12230
- (0, import_operators6.map)(() => ({ ok: false, error: new Error("Resource creation timed out") }))
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
- eventBus.get("yield:create").next({
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, import_operators7.mergeMap)((event) => (0, import_rxjs7.from)(this.handleGenerateToken(event)))
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, import_operators7.mergeMap)((event) => (0, import_rxjs7.from)(this.handleGetResource(event)))
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, import_operators7.mergeMap)((event) => (0, import_rxjs7.from)(this.handleCreateResource(event)))
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
- const result$ = (0, import_rxjs8.race)(
12470
- eventBus.get("frame:entity-type-added").pipe((0, import_operators8.take)(1), (0, import_operators8.map)(() => ({ ok: true }))),
12471
- eventBus.get("frame:entity-type-add-failed").pipe((0, import_operators8.take)(1), (0, import_operators8.map)((f) => ({ ok: false, error: new Error(f.message) }))),
12472
- (0, import_rxjs8.timer)(1e4).pipe((0, import_operators8.map)(() => ({ ok: false, error: new Error(`Timeout adding entity type: ${entityType2}`) })))
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
- maxRetries: jobType === "generation" ? 3 : 1
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, import_operators9.mergeMap)((event) => (0, import_rxjs9.from)((async () => {
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 import_rxjs10 = __toESM(require_cjs());
12994
+ var import_rxjs8 = __toESM(require_cjs());
12968
12995
  var LocalTransport = class {
12969
12996
  baseUrl;
12970
12997
  state$;
12971
- errorsSubject = new import_rxjs10.Subject();
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 import_rxjs10.BehaviorSubject("open");
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 import_rxjs11 = __toESM(require_cjs());
13126
- var import_operators10 = __toESM(require_operators());
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 import_rxjs11.Subject();
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, import_operators10.groupBy)((e) => e.resourceId ?? "__unknown__"),
13168
- (0, import_operators10.mergeMap)(
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, import_operators10.concatMap)((inputOrBatch) => {
13202
+ (0, import_operators8.concatMap)((inputOrBatch) => {
13176
13203
  if (Array.isArray(inputOrBatch)) {
13177
- return (0, import_rxjs11.from)(
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, import_rxjs11.from)(
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
- resourceData.push({ rid: resourceId(rid), chunks, checksum: fetched.checksum });
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 import_rxjs12 = __toESM(require_cjs());
13597
- var import_operators11 = __toESM(require_operators());
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, import_rxjs12.merge)(
13651
+ const events$ = (0, import_rxjs10.merge)(
13610
13652
  ...SMELTER_CHANNELS.map(
13611
13653
  (channel) => bus.on$(channel).pipe(
13612
- (0, import_operators11.map)((payload) => ({
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/replay.ts
13816
- var import_rxjs13 = __toESM(require_cjs());
13817
- var import_operators12 = __toESM(require_operators());
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
- const result$ = (0, import_rxjs13.race)(
13882
- eventBus.get("frame:entity-type-added").pipe((0, import_operators12.map)(() => "ok")),
13883
- eventBus.get("frame:entity-type-add-failed").pipe((0, import_operators12.map)((e) => {
13884
- throw new Error(e.message);
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
- const result$ = (0, import_rxjs13.race)(
13907
- eventBus.get("yield:create-ok").pipe((0, import_operators12.map)((r) => r)),
13908
- eventBus.get("yield:create-failed").pipe((0, import_operators12.map)((e) => {
13909
- throw new Error(e.message);
13910
- })),
13911
- (0, import_rxjs13.timer)(REPLAY_TIMEOUT_MS).pipe((0, import_operators12.map)(() => {
13912
- throw new Error("Timeout waiting for yield:create-ok");
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
- const result$ = (0, import_rxjs13.race)(
13933
- eventBus.get("mark:create-ok").pipe((0, import_operators12.map)(() => "ok")),
13934
- eventBus.get("mark:create-failed").pipe((0, import_operators12.map)((e) => {
13935
- throw new Error(e.message);
13936
- })),
13937
- (0, import_rxjs13.timer)(REPLAY_TIMEOUT_MS).pipe((0, import_operators12.map)(() => {
13938
- throw new Error("Timeout waiting for mark:create-ok");
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
- const result$ = (0, import_rxjs13.race)(
13951
- eventBus.get("mark:body-updated").pipe((0, import_operators12.map)(() => "ok")),
13952
- eventBus.get("mark:body-update-failed").pipe((0, import_operators12.map)((e) => {
13953
- throw new Error(e.message);
13954
- })),
13955
- (0, import_rxjs13.timer)(REPLAY_TIMEOUT_MS).pipe((0, import_operators12.map)(() => {
13956
- throw new Error("Timeout waiting for mark:body-updated");
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
- const result$ = (0, import_rxjs13.race)(
13970
- eventBus.get("mark:delete-ok").pipe((0, import_operators12.map)(() => "ok")),
13971
- eventBus.get("mark:delete-failed").pipe((0, import_operators12.map)((e) => {
13972
- throw new Error(e.message);
13973
- })),
13974
- (0, import_rxjs13.timer)(REPLAY_TIMEOUT_MS).pipe((0, import_operators12.map)(() => {
13975
- throw new Error("Timeout waiting for mark:delete-ok");
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
- const result$ = (0, import_rxjs14.race)(
14372
- eventBus.get("frame:entity-type-added").pipe((0, import_operators13.map)(() => "ok")),
14373
- eventBus.get("frame:entity-type-add-failed").pipe((0, import_operators13.map)((e) => {
14374
- throw new Error(e.message);
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 createResult$ = (0, import_rxjs14.race)(
14412
- eventBus.get("yield:create-ok").pipe((0, import_operators13.map)((r) => r)),
14413
- eventBus.get("yield:create-failed").pipe((0, import_operators13.map)((e) => {
14414
- throw new Error(e.message);
14415
- })),
14416
- (0, import_rxjs14.timer)(IMPORT_TIMEOUT_MS).pipe((0, import_operators13.map)(() => {
14417
- throw new Error("Timeout waiting for yield:create-ok");
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
- eventBus.get("yield:create").next({
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
- const result$ = (0, import_rxjs14.race)(
14444
- eventBus.get("mark:create-ok").pipe((0, import_operators13.map)(() => "ok")),
14445
- eventBus.get("mark:create-failed").pipe((0, import_operators13.map)((e) => {
14446
- throw new Error(e.message);
14447
- })),
14448
- (0, import_rxjs14.timer)(IMPORT_TIMEOUT_MS).pipe((0, import_operators13.map)(() => {
14449
- throw new Error("Timeout waiting for mark:create-ok");
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 {