@semiont/make-meaning 0.5.25 → 0.5.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -330,7 +330,7 @@ declare class Matcher {
330
330
  * Context-driven search: multi-source retrieval + composite scoring
331
331
  *
332
332
  * Retrieval sources:
333
- * 1. Name match — graph.searchResources(searchTerm)
333
+ * 1. Name match — graph.listResources({ search: searchTerm })
334
334
  * 2. Entity type match — graph.listResources({ entityTypes })
335
335
  * 3. Graph neighborhood — connections from GatheredContext
336
336
  *
@@ -1387,6 +1387,14 @@ declare class AnnotationOperations {
1387
1387
  interface ListResourcesFilters {
1388
1388
  search?: string;
1389
1389
  archived?: boolean;
1390
+ entityType?: string;
1391
+ offset?: number;
1392
+ limit?: number;
1393
+ }
1394
+ interface ListResourcesResult {
1395
+ resources: ResourceDescriptor[];
1396
+ /** Size of the whole match set, not of the returned page. */
1397
+ total: number;
1390
1398
  }
1391
1399
  declare class ResourceContext {
1392
1400
  /**
@@ -1394,17 +1402,20 @@ declare class ResourceContext {
1394
1402
  */
1395
1403
  static getResourceMetadata(resourceId: ResourceId, kb: KnowledgeBase): Promise<ResourceDescriptor | null>;
1396
1404
  /**
1397
- * List resources, optionally filtered.
1405
+ * List resources, optionally filtered, as one page plus the size of the whole
1406
+ * match set. Every filter is applied before pagination on both paths — a
1407
+ * filter applied afterwards narrows the page rather than the match set, which
1408
+ * is how a search scoped to an entity type can come back empty while hundreds
1409
+ * of resources match.
1398
1410
  *
1399
- * When `search` is set, delegates to `kb.graph.searchResources`, which runs
1400
- * the name match in the graph engine instead of scanning every view in JS.
1401
- * The graph result is then narrowed by `archived` if requested.
1411
+ * When `search` is set, the entire query filtering, ordering and
1412
+ * pagination runs inside the graph engine.
1402
1413
  *
1403
- * When `search` is unset, falls back to scanning all materialized views.
1404
- * (TODO: also push the listing path through the graph for large KBs.)
1414
+ * When `search` is unset, the materialized views answer instead. They are the
1415
+ * barrier-stamped projection, so an unsearched listing is read-your-writes
1416
+ * where the graph is only eventually consistent.
1405
1417
  */
1406
- static listResources(filters: ListResourcesFilters | undefined, kb: KnowledgeBase): Promise<ResourceDescriptor[]>;
1407
- private static sortByDateDesc;
1418
+ static listResources(filters: ListResourcesFilters | undefined, kb: KnowledgeBase): Promise<ListResourcesResult>;
1408
1419
  /**
1409
1420
  * Add content previews to resources (for search results)
1410
1421
  * Retrieves and decodes the first 200 characters of each resource's primary representation
@@ -1540,11 +1551,6 @@ declare class GraphContext {
1540
1551
  * Requires graph traversal - must use graph database
1541
1552
  */
1542
1553
  static getResourceConnections(resourceId: ResourceId, kb: KnowledgeBase): Promise<GraphConnection[]>;
1543
- /**
1544
- * Search resources by name (cross-resource query)
1545
- * Requires full-text search - must use graph database
1546
- */
1547
- static searchResources(query: string, kb: KnowledgeBase, limit?: number): Promise<ResourceDescriptor[]>;
1548
1554
  /**
1549
1555
  * Build the unified knowledge graph for a resource's neighborhood:
1550
1556
  * resources AND annotations as typed nodes, typed/directional edges.
@@ -1620,4 +1626,4 @@ declare function generateResourceSummary(resourceName: string, content: string,
1620
1626
  declare function generateReferenceSuggestions(referenceTitle: string, client: InferenceClient, entityType?: string, currentContent?: string): Promise<string[] | null>;
1621
1627
 
1622
1628
  export { AnnotationContext, AnnotationOperations, BACKUP_FORMAT, Browser, CloneTokenManager, FORMAT_VERSION, Gatherer$1 as Gatherer, GraphContext, LLMContext, LocalContentTransport, LocalTransport, Matcher, ResourceContext, ResourceOperations, Smelter, Stower, asBusRequestPrimitive, bootstrapEntityTypes, createKnowledgeBase, createSmelterActorStateUnit, exportBackup, exportLinkedData, generateReferenceSuggestions, generateResourceSummary, importBackup, importLinkedData, isBackupManifest, readEntityTypesProjection, registerAnnotationAssemblyHandler, registerAnnotationLookupHandlers, registerBindUpdateBodyHandler, registerBusHandlers, registerJobCommandHandlers, startMakeMeaning, stopKnowledgeSystem, validateManifestVersion };
1623
- export type { BackupContentReader, BackupEventStoreReader, BackupExporterOptions, BackupImportResult, BackupImporterOptions, BackupManifestHeader, BackupStreamSummary, BuildContextOptions, ContentBlobResolver, CreateAnnotationResult, CreateResourceInput, CreateResourceResult, KnowledgeBase, KnowledgeSystem, LLMContextOptions, LinkedDataContentReader, LinkedDataExporterOptions, LinkedDataImportResult, LinkedDataImporterOptions, LinkedDataViewReader, ListResourcesFilters, LocalTransportConfig, MakeMeaningConfig, MakeMeaningService, ReconcileState, ReconcileSummary, ReplayStats, SmelterActorStateUnit, SmelterActorStateUnitOptions, SmelterEvent, SmelterInput, SmelterTiming, SmelterWorkItem, UpdateAnnotationBodyResult };
1629
+ export type { BackupContentReader, BackupEventStoreReader, BackupExporterOptions, BackupImportResult, BackupImporterOptions, BackupManifestHeader, BackupStreamSummary, BuildContextOptions, ContentBlobResolver, CreateAnnotationResult, CreateResourceInput, CreateResourceResult, KnowledgeBase, KnowledgeSystem, LLMContextOptions, LinkedDataContentReader, LinkedDataExporterOptions, LinkedDataImportResult, LinkedDataImporterOptions, LinkedDataViewReader, ListResourcesFilters, ListResourcesResult, LocalTransportConfig, MakeMeaningConfig, MakeMeaningService, ReconcileState, ReconcileSummary, ReplayStats, SmelterActorStateUnit, SmelterActorStateUnitOptions, SmelterEvent, SmelterInput, SmelterTiming, SmelterWorkItem, UpdateAnnotationBodyResult };
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { FilesystemViewStorage, resolveStorageUri, EventQuery, createEventStore
3
3
  import { getResourceEntityTypes, getResourceId, getTargetSource, resourceId, getPrimaryRepresentation, decodeRepresentation, getBodySource, getTargetSelector, deriveViews, getTextPositionSelector, annotationId, errField, userId, generateUuid, getExactText, busRequest, cloneToken, baseMediaType, isSupportedMediaType, capabilitiesOf, didToAgent, assembleAnnotation, jobId, entityType, baseUrl, busLog, BRIDGED_CHANNELS, burstBuffer, textExtractionOf, chunkText, getPrimaryMediaType, extensionForMediaType, applyBodyOperations, softwareToAgent } from '@semiont/core';
4
4
  import { recordGatherDegrade, withActorSpan, recordBusEmit, withSpan, SpanKind, registerJobQueueProvider, registerVectorIndexSizeProvider } from '@semiont/observability';
5
5
  import { createInferenceClient } from '@semiont/inference';
6
- import { getGraphDatabase } from '@semiont/graph';
6
+ import { compareByRecencyThenId, getGraphDatabase } from '@semiont/graph';
7
7
  import { WorkingTreeStore, createAnchoredTextStore, deriveStorageUri, anchoredTextStoreOverTransport, EXTRACTORS, calculateChecksum } from '@semiont/content';
8
8
  import { getEntityTypes, DEFAULT_ENTITY_TYPES } from '@semiont/ontology';
9
9
  import { promises } from 'fs';
@@ -9937,13 +9937,6 @@ var GraphContext = class {
9937
9937
  static async getResourceConnections(resourceId10, kb) {
9938
9938
  return kb.graph.getResourceConnections(resourceId10);
9939
9939
  }
9940
- /**
9941
- * Search resources by name (cross-resource query)
9942
- * Requires full-text search - must use graph database
9943
- */
9944
- static async searchResources(query, kb, limit) {
9945
- return kb.graph.searchResources(query, limit);
9946
- }
9947
9940
  /**
9948
9941
  * Build the unified knowledge graph for a resource's neighborhood:
9949
9942
  * resources AND annotations as typed nodes, typed/directional edges.
@@ -10064,7 +10057,7 @@ Format as a simple list, one suggestion per line.`;
10064
10057
  }
10065
10058
  return response.split("\n").map((line) => line.replace(/^[-*•]\s*/, "").trim()).filter((line) => line.length > 0).slice(0, 3);
10066
10059
  }
10067
- var ResourceContext = class _ResourceContext {
10060
+ var ResourceContext = class {
10068
10061
  /**
10069
10062
  * Get resource metadata from view storage
10070
10063
  */
@@ -10076,38 +10069,34 @@ var ResourceContext = class _ResourceContext {
10076
10069
  return view.resource;
10077
10070
  }
10078
10071
  /**
10079
- * List resources, optionally filtered.
10072
+ * List resources, optionally filtered, as one page plus the size of the whole
10073
+ * match set. Every filter is applied before pagination on both paths — a
10074
+ * filter applied afterwards narrows the page rather than the match set, which
10075
+ * is how a search scoped to an entity type can come back empty while hundreds
10076
+ * of resources match.
10080
10077
  *
10081
- * When `search` is set, delegates to `kb.graph.searchResources`, which runs
10082
- * the name match in the graph engine instead of scanning every view in JS.
10083
- * The graph result is then narrowed by `archived` if requested.
10078
+ * When `search` is set, the entire query filtering, ordering and
10079
+ * pagination runs inside the graph engine.
10084
10080
  *
10085
- * When `search` is unset, falls back to scanning all materialized views.
10086
- * (TODO: also push the listing path through the graph for large KBs.)
10081
+ * When `search` is unset, the materialized views answer instead. They are the
10082
+ * barrier-stamped projection, so an unsearched listing is read-your-writes
10083
+ * where the graph is only eventually consistent.
10087
10084
  */
10088
10085
  static async listResources(filters, kb) {
10089
- if (filters?.search) {
10090
- const matches = await kb.graph.searchResources(filters.search);
10091
- const filtered = filters.archived !== void 0 ? matches.filter((doc) => doc.archived === filters.archived) : matches;
10092
- return _ResourceContext.sortByDateDesc(filtered);
10086
+ const { search: rawSearch, archived, entityType: entityType2, offset = 0, limit = 50 } = filters ?? {};
10087
+ const search = rawSearch?.trim() || void 0;
10088
+ if (search) {
10089
+ return kb.graph.listResources({
10090
+ search,
10091
+ archived,
10092
+ entityTypes: entityType2 ? [entityType2] : void 0,
10093
+ offset,
10094
+ limit
10095
+ });
10093
10096
  }
10094
10097
  const allViews = await kb.views.getAll();
10095
- const resources = [];
10096
- for (const view of allViews) {
10097
- const doc = view.resource;
10098
- if (filters?.archived !== void 0 && doc.archived !== filters.archived) {
10099
- continue;
10100
- }
10101
- resources.push(doc);
10102
- }
10103
- return _ResourceContext.sortByDateDesc(resources);
10104
- }
10105
- static sortByDateDesc(resources) {
10106
- return [...resources].sort((a, b) => {
10107
- const aTime = a.dateCreated ? new Date(a.dateCreated).getTime() : 0;
10108
- const bTime = b.dateCreated ? new Date(b.dateCreated).getTime() : 0;
10109
- return bTime - aTime;
10110
- });
10098
+ const matches = allViews.map((view) => view.resource).filter((doc) => archived === void 0 || doc.archived === archived).filter((doc) => !entityType2 || getResourceEntityTypes(doc).includes(entityType2)).sort(compareByRecencyThenId);
10099
+ return { resources: matches.slice(offset, offset + limit), total: matches.length };
10111
10100
  }
10112
10101
  /**
10113
10102
  * Add content previews to resources (for search results)
@@ -10885,7 +10874,7 @@ var Matcher = class {
10885
10874
  * Context-driven search: multi-source retrieval + composite scoring
10886
10875
  *
10887
10876
  * Retrieval sources:
10888
- * 1. Name match — graph.searchResources(searchTerm)
10877
+ * 1. Name match — graph.listResources({ search: searchTerm })
10889
10878
  * 2. Entity type match — graph.listResources({ entityTypes })
10890
10879
  * 3. Graph neighborhood — connections from GatheredContext
10891
10880
  *
@@ -10901,7 +10890,7 @@ var Matcher = class {
10901
10890
  const views = deriveViews(context.graph, mainResourceId);
10902
10891
  const connections = views.connections;
10903
10892
  const [nameMatches, entityTypeMatches, semanticMatches] = await Promise.all([
10904
- this.kb.graph.searchResources(searchTerm),
10893
+ this.kb.graph.listResources({ search: searchTerm, limit: 20 }).then((r) => r.resources),
10905
10894
  annotationEntityTypes.length > 0 ? this.kb.graph.listResources({ entityTypes: annotationEntityTypes, limit: 50 }).then((r) => r.resources) : Promise.resolve([]),
10906
10895
  // 4. Semantic match — vector similarity search (if vectors configured)
10907
10896
  this.searchVectors(searchTerm)
@@ -11835,22 +11824,21 @@ var Browser = class {
11835
11824
  }
11836
11825
  async handleBrowseResources(event) {
11837
11826
  try {
11838
- let filteredDocs = await ResourceContext.listResources({
11839
- search: event.search,
11840
- archived: event.archived
11841
- }, this.kb);
11842
- if (event.entityType) {
11843
- filteredDocs = filteredDocs.filter((doc) => getResourceEntityTypes(doc).includes(event.entityType));
11844
- }
11845
11827
  const offset = event.offset ?? 0;
11846
11828
  const limit = event.limit ?? 50;
11847
- const paginatedDocs = filteredDocs.slice(offset, offset + limit);
11848
- const formattedDocs = event.search ? await ResourceContext.addContentPreviews(paginatedDocs, this.kb) : paginatedDocs;
11829
+ const { resources, total } = await ResourceContext.listResources({
11830
+ search: event.search,
11831
+ archived: event.archived,
11832
+ entityType: event.entityType,
11833
+ offset,
11834
+ limit
11835
+ }, this.kb);
11836
+ const formattedDocs = event.search ? await ResourceContext.addContentPreviews(resources, this.kb) : resources;
11849
11837
  this.eventBus.get("browse:resources-result").next({
11850
11838
  correlationId: event.correlationId,
11851
11839
  response: {
11852
11840
  resources: formattedDocs,
11853
- total: filteredDocs.length,
11841
+ total,
11854
11842
  offset,
11855
11843
  limit
11856
11844
  }