@atomicmemory/core 1.0.0
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/CHANGELOG.md +27 -0
- package/LICENSE +201 -0
- package/README.md +314 -0
- package/dist/app/bind-ephemeral.d.ts +18 -0
- package/dist/app/bind-ephemeral.js +22 -0
- package/dist/app/cors-headers.d.ts +12 -0
- package/dist/app/cors-headers.js +18 -0
- package/dist/app/create-app.d.ts +25 -0
- package/dist/app/create-app.js +156 -0
- package/dist/app/runtime-config-route-snapshot.d.ts +27 -0
- package/dist/app/runtime-config-route-snapshot.js +27 -0
- package/dist/app/runtime-container.d.ts +281 -0
- package/dist/app/runtime-container.js +297 -0
- package/dist/app/startup-checks.d.ts +28 -0
- package/dist/app/startup-checks.js +45 -0
- package/dist/bin.d.ts +17 -0
- package/dist/bin.js +128 -0
- package/dist/config.d.ts +680 -0
- package/dist/config.js +808 -0
- package/dist/db/agent-trust-repository.d.ts +49 -0
- package/dist/db/agent-trust-repository.js +66 -0
- package/dist/db/belief-edges-repository.d.ts +68 -0
- package/dist/db/belief-edges-repository.js +124 -0
- package/dist/db/claim-repository.d.ts +6 -0
- package/dist/db/claim-repository.js +4 -0
- package/dist/db/contradictions-repository.d.ts +56 -0
- package/dist/db/contradictions-repository.js +88 -0
- package/dist/db/document-chunk-repository.d.ts +48 -0
- package/dist/db/document-chunk-repository.js +145 -0
- package/dist/db/document-chunk-types.d.ts +35 -0
- package/dist/db/document-chunk-types.js +9 -0
- package/dist/db/document-list-cursor.d.ts +45 -0
- package/dist/db/document-list-cursor.js +111 -0
- package/dist/db/document-list-repository.d.ts +103 -0
- package/dist/db/document-list-repository.js +204 -0
- package/dist/db/entity-cards-repository.d.ts +37 -0
- package/dist/db/entity-cards-repository.js +46 -0
- package/dist/db/entity-values-repository.d.ts +26 -0
- package/dist/db/entity-values-repository.js +57 -0
- package/dist/db/link-repository.d.ts +30 -0
- package/dist/db/link-repository.js +54 -0
- package/dist/db/memory-repository.d.ts +163 -0
- package/dist/db/memory-repository.js +232 -0
- package/dist/db/migrate.d.ts +6 -0
- package/dist/db/migrate.js +36 -0
- package/dist/db/mmr.d.ts +14 -0
- package/dist/db/mmr.js +57 -0
- package/dist/db/passport-feed-repository.d.ts +91 -0
- package/dist/db/passport-feed-repository.js +198 -0
- package/dist/db/pg-episode-store.d.ts +19 -0
- package/dist/db/pg-episode-store.js +17 -0
- package/dist/db/pg-link-store.d.ts +17 -0
- package/dist/db/pg-link-store.js +14 -0
- package/dist/db/pg-memory-store.d.ts +68 -0
- package/dist/db/pg-memory-store.js +53 -0
- package/dist/db/pg-recap-store.d.ts +13 -0
- package/dist/db/pg-recap-store.js +19 -0
- package/dist/db/pg-representation-store.d.ts +17 -0
- package/dist/db/pg-representation-store.js +17 -0
- package/dist/db/pg-search-store.d.ts +29 -0
- package/dist/db/pg-search-store.js +47 -0
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +21 -0
- package/dist/db/ppr.d.ts +56 -0
- package/dist/db/ppr.js +178 -0
- package/dist/db/query-helpers.d.ts +44 -0
- package/dist/db/query-helpers.js +60 -0
- package/dist/db/raw-doc-artifact-sync.d.ts +128 -0
- package/dist/db/raw-doc-artifact-sync.js +259 -0
- package/dist/db/raw-document-blob-repository.d.ts +148 -0
- package/dist/db/raw-document-blob-repository.js +300 -0
- package/dist/db/raw-document-repository.d.ts +104 -0
- package/dist/db/raw-document-repository.js +410 -0
- package/dist/db/raw-document-status-repository.d.ts +122 -0
- package/dist/db/raw-document-status-repository.js +183 -0
- package/dist/db/raw-document-types.d.ts +236 -0
- package/dist/db/raw-document-types.js +10 -0
- package/dist/db/raw-storage-reconciliation-repository.d.ts +110 -0
- package/dist/db/raw-storage-reconciliation-repository.js +200 -0
- package/dist/db/reflection-jobs-repository.d.ts +33 -0
- package/dist/db/reflection-jobs-repository.js +48 -0
- package/dist/db/reflections-repository.d.ts +41 -0
- package/dist/db/reflections-repository.js +83 -0
- package/dist/db/repository-claims.d.ts +141 -0
- package/dist/db/repository-claims.js +376 -0
- package/dist/db/repository-deferred-audn.d.ts +33 -0
- package/dist/db/repository-deferred-audn.js +69 -0
- package/dist/db/repository-document-delete.d.ts +53 -0
- package/dist/db/repository-document-delete.js +156 -0
- package/dist/db/repository-entities.d.ts +114 -0
- package/dist/db/repository-entities.js +317 -0
- package/dist/db/repository-entity-attributes.d.ts +41 -0
- package/dist/db/repository-entity-attributes.js +65 -0
- package/dist/db/repository-entity-graph.d.ts +32 -0
- package/dist/db/repository-entity-graph.js +87 -0
- package/dist/db/repository-first-mentions.d.ts +41 -0
- package/dist/db/repository-first-mentions.js +79 -0
- package/dist/db/repository-lessons.d.ts +51 -0
- package/dist/db/repository-lessons.js +90 -0
- package/dist/db/repository-links.d.ts +26 -0
- package/dist/db/repository-links.js +105 -0
- package/dist/db/repository-observation.d.ts +26 -0
- package/dist/db/repository-observation.js +51 -0
- package/dist/db/repository-read.d.ts +56 -0
- package/dist/db/repository-read.js +271 -0
- package/dist/db/repository-recaps.d.ts +59 -0
- package/dist/db/repository-recaps.js +158 -0
- package/dist/db/repository-representations.d.ts +48 -0
- package/dist/db/repository-representations.js +162 -0
- package/dist/db/repository-temporal-state.d.ts +35 -0
- package/dist/db/repository-temporal-state.js +46 -0
- package/dist/db/repository-tll.d.ts +88 -0
- package/dist/db/repository-tll.js +179 -0
- package/dist/db/repository-types.d.ts +313 -0
- package/dist/db/repository-types.js +142 -0
- package/dist/db/repository-user-profiles.d.ts +17 -0
- package/dist/db/repository-user-profiles.js +28 -0
- package/dist/db/repository-vector-search.d.ts +33 -0
- package/dist/db/repository-vector-search.js +373 -0
- package/dist/db/repository-wipe.d.ts +34 -0
- package/dist/db/repository-wipe.js +94 -0
- package/dist/db/repository-write.d.ts +61 -0
- package/dist/db/repository-write.js +279 -0
- package/dist/db/schema.sql +1355 -0
- package/dist/db/storage-artifact-delete-tx.d.ts +56 -0
- package/dist/db/storage-artifact-delete-tx.js +123 -0
- package/dist/db/storage-artifact-providers.d.ts +21 -0
- package/dist/db/storage-artifact-providers.js +21 -0
- package/dist/db/storage-artifact-recovery-repository.d.ts +66 -0
- package/dist/db/storage-artifact-recovery-repository.js +58 -0
- package/dist/db/storage-artifact-repository.d.ts +329 -0
- package/dist/db/storage-artifact-repository.js +497 -0
- package/dist/db/stores.d.ts +220 -0
- package/dist/db/stores.js +12 -0
- package/dist/db/summaries-repository.d.ts +74 -0
- package/dist/db/summaries-repository.js +125 -0
- package/dist/eval/beam-10m-loader.d.ts +98 -0
- package/dist/eval/beam-10m-loader.js +128 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +17 -0
- package/dist/middleware/require-bearer.d.ts +27 -0
- package/dist/middleware/require-bearer.js +60 -0
- package/dist/middleware/validate-response.d.ts +33 -0
- package/dist/middleware/validate-response.js +55 -0
- package/dist/middleware/validate.d.ts +43 -0
- package/dist/middleware/validate.js +85 -0
- package/dist/routes/agents.d.ts +13 -0
- package/dist/routes/agents.js +89 -0
- package/dist/routes/document-response-formatters.d.ts +98 -0
- package/dist/routes/document-response-formatters.js +243 -0
- package/dist/routes/documents.d.ts +74 -0
- package/dist/routes/documents.js +425 -0
- package/dist/routes/memories.d.ts +29 -0
- package/dist/routes/memories.js +725 -0
- package/dist/routes/memory-response-formatters.d.ts +179 -0
- package/dist/routes/memory-response-formatters.js +210 -0
- package/dist/routes/public-raw-storage-metadata.d.ts +54 -0
- package/dist/routes/public-raw-storage-metadata.js +56 -0
- package/dist/routes/reflect.d.ts +14 -0
- package/dist/routes/reflect.js +19 -0
- package/dist/routes/response-schema-map.d.ts +14 -0
- package/dist/routes/response-schema-map.js +69 -0
- package/dist/routes/route-errors.d.ts +12 -0
- package/dist/routes/route-errors.js +30 -0
- package/dist/routes/storage-error-handlers.d.ts +34 -0
- package/dist/routes/storage-error-handlers.js +185 -0
- package/dist/routes/storage-response-formatters.d.ts +44 -0
- package/dist/routes/storage-response-formatters.js +155 -0
- package/dist/routes/storage.d.ts +38 -0
- package/dist/routes/storage.js +369 -0
- package/dist/routes/upstream-provider-errors.d.ts +19 -0
- package/dist/routes/upstream-provider-errors.js +95 -0
- package/dist/schemas/agents.d.ts +79 -0
- package/dist/schemas/agents.js +126 -0
- package/dist/schemas/common.d.ts +110 -0
- package/dist/schemas/common.js +190 -0
- package/dist/schemas/document-list-responses.d.ts +102 -0
- package/dist/schemas/document-list-responses.js +87 -0
- package/dist/schemas/document-list-schemas.d.ts +123 -0
- package/dist/schemas/document-list-schemas.js +174 -0
- package/dist/schemas/document-response-schemas.d.ts +610 -0
- package/dist/schemas/document-response-schemas.js +264 -0
- package/dist/schemas/document-status-envelope.d.ts +48 -0
- package/dist/schemas/document-status-envelope.js +54 -0
- package/dist/schemas/documents.d.ts +292 -0
- package/dist/schemas/documents.js +449 -0
- package/dist/schemas/errors.d.ts +75 -0
- package/dist/schemas/errors.js +105 -0
- package/dist/schemas/memories.d.ts +378 -0
- package/dist/schemas/memories.js +542 -0
- package/dist/schemas/openapi.d.ts +24 -0
- package/dist/schemas/openapi.js +1038 -0
- package/dist/schemas/response-scalars.d.ts +10 -0
- package/dist/schemas/response-scalars.js +10 -0
- package/dist/schemas/responses.d.ts +536 -0
- package/dist/schemas/responses.js +350 -0
- package/dist/schemas/search-response-parts.d.ts +97 -0
- package/dist/schemas/search-response-parts.js +103 -0
- package/dist/schemas/storage-schemas.d.ts +175 -0
- package/dist/schemas/storage-schemas.js +277 -0
- package/dist/schemas/zod-setup.d.ts +15 -0
- package/dist/schemas/zod-setup.js +17 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.js +57 -0
- package/dist/services/abstract-query-policy.d.ts +13 -0
- package/dist/services/abstract-query-policy.js +50 -0
- package/dist/services/affinity-clustering.d.ts +66 -0
- package/dist/services/affinity-clustering.js +125 -0
- package/dist/services/agentic-retrieval.d.ts +38 -0
- package/dist/services/agentic-retrieval.js +126 -0
- package/dist/services/answer-format.d.ts +56 -0
- package/dist/services/answer-format.js +118 -0
- package/dist/services/answer-rescue.d.ts +72 -0
- package/dist/services/answer-rescue.js +177 -0
- package/dist/services/answer-verifier.d.ts +24 -0
- package/dist/services/answer-verifier.js +73 -0
- package/dist/services/api-retry.d.ts +6 -0
- package/dist/services/api-retry.js +41 -0
- package/dist/services/assistant-turn-filter.d.ts +20 -0
- package/dist/services/assistant-turn-filter.js +69 -0
- package/dist/services/atomicmem-uri.d.ts +33 -0
- package/dist/services/atomicmem-uri.js +86 -0
- package/dist/services/audit-events.d.ts +54 -0
- package/dist/services/audit-events.js +56 -0
- package/dist/services/chunked-extraction.d.ts +21 -0
- package/dist/services/chunked-extraction.js +108 -0
- package/dist/services/claim-slotting.d.ts +27 -0
- package/dist/services/claim-slotting.js +38 -0
- package/dist/services/claude-code-llm.d.ts +19 -0
- package/dist/services/claude-code-llm.js +96 -0
- package/dist/services/composite-dedup.d.ts +50 -0
- package/dist/services/composite-dedup.js +153 -0
- package/dist/services/composite-grouping.d.ts +41 -0
- package/dist/services/composite-grouping.js +111 -0
- package/dist/services/composite-staleness.d.ts +20 -0
- package/dist/services/composite-staleness.js +50 -0
- package/dist/services/conciseness-preference.d.ts +14 -0
- package/dist/services/conciseness-preference.js +42 -0
- package/dist/services/conflict-policy.d.ts +20 -0
- package/dist/services/conflict-policy.js +335 -0
- package/dist/services/consensus-extraction.d.ts +39 -0
- package/dist/services/consensus-extraction.js +147 -0
- package/dist/services/consensus-validation.d.ts +52 -0
- package/dist/services/consensus-validation.js +206 -0
- package/dist/services/consolidation-service.d.ts +60 -0
- package/dist/services/consolidation-service.js +171 -0
- package/dist/services/content-detection.d.ts +18 -0
- package/dist/services/content-detection.js +25 -0
- package/dist/services/contradiction-surfacing.d.ts +62 -0
- package/dist/services/contradiction-surfacing.js +111 -0
- package/dist/services/cost-telemetry.d.ts +39 -0
- package/dist/services/cost-telemetry.js +58 -0
- package/dist/services/counter-evidence.d.ts +34 -0
- package/dist/services/counter-evidence.js +92 -0
- package/dist/services/current-state-ranking.d.ts +21 -0
- package/dist/services/current-state-ranking.js +152 -0
- package/dist/services/deferred-audn.d.ts +47 -0
- package/dist/services/deferred-audn.js +162 -0
- package/dist/services/document-chunker.d.ts +50 -0
- package/dist/services/document-chunker.js +153 -0
- package/dist/services/document-failure-markers.d.ts +91 -0
- package/dist/services/document-failure-markers.js +305 -0
- package/dist/services/document-indexer.d.ts +122 -0
- package/dist/services/document-indexer.js +405 -0
- package/dist/services/document-service.d.ts +245 -0
- package/dist/services/document-service.js +325 -0
- package/dist/services/document-upload-artifact-sync.d.ts +80 -0
- package/dist/services/document-upload-artifact-sync.js +162 -0
- package/dist/services/document-upload-beta2-recovery.d.ts +72 -0
- package/dist/services/document-upload-beta2-recovery.js +94 -0
- package/dist/services/document-upload.d.ts +44 -0
- package/dist/services/document-upload.js +353 -0
- package/dist/services/embedding.d.ts +57 -0
- package/dist/services/embedding.js +416 -0
- package/dist/services/entity-attribute-extractor.d.ts +34 -0
- package/dist/services/entity-attribute-extractor.js +117 -0
- package/dist/services/entity-card-synthesis.d.ts +54 -0
- package/dist/services/entity-card-synthesis.js +92 -0
- package/dist/services/entity-dedup.d.ts +9 -0
- package/dist/services/entity-dedup.js +14 -0
- package/dist/services/entity-graph.d.ts +17 -0
- package/dist/services/entity-graph.js +135 -0
- package/dist/services/entropy-gate.d.ts +52 -0
- package/dist/services/entropy-gate.js +56 -0
- package/dist/services/episode-fetcher.d.ts +47 -0
- package/dist/services/episode-fetcher.js +128 -0
- package/dist/services/event-anchor-facts.d.ts +8 -0
- package/dist/services/event-anchor-facts.js +205 -0
- package/dist/services/event-chain-detector.d.ts +52 -0
- package/dist/services/event-chain-detector.js +83 -0
- package/dist/services/extraction-cache.d.ts +9 -0
- package/dist/services/extraction-cache.js +54 -0
- package/dist/services/extraction-enrichment.d.ts +9 -0
- package/dist/services/extraction-enrichment.js +223 -0
- package/dist/services/extraction.d.ts +69 -0
- package/dist/services/extraction.js +596 -0
- package/dist/services/fact-normalization.d.ts +12 -0
- package/dist/services/fact-normalization.js +248 -0
- package/dist/services/filecoin-observability.d.ts +127 -0
- package/dist/services/filecoin-observability.js +200 -0
- package/dist/services/first-mention-service.d.ts +76 -0
- package/dist/services/first-mention-service.js +186 -0
- package/dist/services/hierarchical-retrieval.d.ts +49 -0
- package/dist/services/hierarchical-retrieval.js +50 -0
- package/dist/services/ingest-fact-pipeline.d.ts +32 -0
- package/dist/services/ingest-fact-pipeline.js +212 -0
- package/dist/services/ingest-post-write.d.ts +50 -0
- package/dist/services/ingest-post-write.js +117 -0
- package/dist/services/ingest-trace.d.ts +32 -0
- package/dist/services/ingest-trace.js +60 -0
- package/dist/services/input-sanitizer.d.ts +41 -0
- package/dist/services/input-sanitizer.js +135 -0
- package/dist/services/iterative-retrieval.d.ts +26 -0
- package/dist/services/iterative-retrieval.js +139 -0
- package/dist/services/keyword-expansion.d.ts +10 -0
- package/dist/services/keyword-expansion.js +26 -0
- package/dist/services/lesson-service.d.ts +68 -0
- package/dist/services/lesson-service.js +178 -0
- package/dist/services/literal-extractor.d.ts +16 -0
- package/dist/services/literal-extractor.js +74 -0
- package/dist/services/literal-list-protection.d.ts +17 -0
- package/dist/services/literal-list-protection.js +134 -0
- package/dist/services/literal-query-expansion.d.ts +20 -0
- package/dist/services/literal-query-expansion.js +181 -0
- package/dist/services/llm.d.ts +61 -0
- package/dist/services/llm.js +265 -0
- package/dist/services/memcell-projection.d.ts +17 -0
- package/dist/services/memcell-projection.js +41 -0
- package/dist/services/memory-audn.d.ts +43 -0
- package/dist/services/memory-audn.js +419 -0
- package/dist/services/memory-crud.d.ts +93 -0
- package/dist/services/memory-crud.js +255 -0
- package/dist/services/memory-ingest.d.ts +21 -0
- package/dist/services/memory-ingest.js +249 -0
- package/dist/services/memory-lifecycle.d.ts +75 -0
- package/dist/services/memory-lifecycle.js +108 -0
- package/dist/services/memory-lineage.d.ts +181 -0
- package/dist/services/memory-lineage.js +232 -0
- package/dist/services/memory-network.d.ts +40 -0
- package/dist/services/memory-network.js +75 -0
- package/dist/services/memory-search-types.d.ts +25 -0
- package/dist/services/memory-search-types.js +10 -0
- package/dist/services/memory-search.d.ts +48 -0
- package/dist/services/memory-search.js +505 -0
- package/dist/services/memory-service-types.d.ts +371 -0
- package/dist/services/memory-service-types.js +8 -0
- package/dist/services/memory-service.d.ts +152 -0
- package/dist/services/memory-service.js +225 -0
- package/dist/services/memory-storage.d.ts +33 -0
- package/dist/services/memory-storage.js +328 -0
- package/dist/services/msr-aggregator.d.ts +38 -0
- package/dist/services/msr-aggregator.js +97 -0
- package/dist/services/msr-detector.d.ts +35 -0
- package/dist/services/msr-detector.js +65 -0
- package/dist/services/namespace-retrieval.d.ts +60 -0
- package/dist/services/namespace-retrieval.js +180 -0
- package/dist/services/observation-date-extraction.d.ts +12 -0
- package/dist/services/observation-date-extraction.js +50 -0
- package/dist/services/observation-service.d.ts +27 -0
- package/dist/services/observation-service.js +84 -0
- package/dist/services/packaging-observability.d.ts +29 -0
- package/dist/services/packaging-observability.js +146 -0
- package/dist/services/query-expansion.d.ts +83 -0
- package/dist/services/query-expansion.js +242 -0
- package/dist/services/query-keyword-matches.d.ts +6 -0
- package/dist/services/query-keyword-matches.js +56 -0
- package/dist/services/query-term-visibility.d.ts +28 -0
- package/dist/services/query-term-visibility.js +100 -0
- package/dist/services/quick-extraction.d.ts +25 -0
- package/dist/services/quick-extraction.js +431 -0
- package/dist/services/quoted-entity-extraction.d.ts +10 -0
- package/dist/services/quoted-entity-extraction.js +161 -0
- package/dist/services/raw-storage-reconciler-backoff.d.ts +8 -0
- package/dist/services/raw-storage-reconciler-backoff.js +14 -0
- package/dist/services/raw-storage-reconciler-scheduler.d.ts +29 -0
- package/dist/services/raw-storage-reconciler-scheduler.js +43 -0
- package/dist/services/raw-storage-reconciler.d.ts +71 -0
- package/dist/services/raw-storage-reconciler.js +278 -0
- package/dist/services/recap-builder.d.ts +49 -0
- package/dist/services/recap-builder.js +157 -0
- package/dist/services/reflect-jobs.d.ts +23 -0
- package/dist/services/reflect-jobs.js +36 -0
- package/dist/services/reflect-prompts.d.ts +71 -0
- package/dist/services/reflect-prompts.js +99 -0
- package/dist/services/reflect-retrieval.d.ts +33 -0
- package/dist/services/reflect-retrieval.js +30 -0
- package/dist/services/reflect.d.ts +49 -0
- package/dist/services/reflect.js +84 -0
- package/dist/services/relative-temporal.d.ts +14 -0
- package/dist/services/relative-temporal.js +163 -0
- package/dist/services/relevance-policy.d.ts +37 -0
- package/dist/services/relevance-policy.js +109 -0
- package/dist/services/rerank.d.ts +32 -0
- package/dist/services/rerank.js +118 -0
- package/dist/services/reranker.d.ts +20 -0
- package/dist/services/reranker.js +99 -0
- package/dist/services/retrieval-channel-rules.d.ts +34 -0
- package/dist/services/retrieval-channel-rules.js +41 -0
- package/dist/services/retrieval-config-overlay.d.ts +36 -0
- package/dist/services/retrieval-config-overlay.js +44 -0
- package/dist/services/retrieval-format.d.ts +119 -0
- package/dist/services/retrieval-format.js +559 -0
- package/dist/services/retrieval-policy.d.ts +69 -0
- package/dist/services/retrieval-policy.js +275 -0
- package/dist/services/retrieval-profiles.d.ts +37 -0
- package/dist/services/retrieval-profiles.js +90 -0
- package/dist/services/retrieval-side-effects.d.ts +14 -0
- package/dist/services/retrieval-side-effects.js +26 -0
- package/dist/services/retrieval-trace.d.ts +108 -0
- package/dist/services/retrieval-trace.js +147 -0
- package/dist/services/rrf-fusion.d.ts +18 -0
- package/dist/services/rrf-fusion.js +34 -0
- package/dist/services/search-pipeline.d.ts +71 -0
- package/dist/services/search-pipeline.js +788 -0
- package/dist/services/session-date.d.ts +20 -0
- package/dist/services/session-date.js +61 -0
- package/dist/services/session-packaging.d.ts +53 -0
- package/dist/services/session-packaging.js +182 -0
- package/dist/services/session-summary-generator.d.ts +53 -0
- package/dist/services/session-summary-generator.js +134 -0
- package/dist/services/specialists/cr-specialist.d.ts +52 -0
- package/dist/services/specialists/cr-specialist.js +121 -0
- package/dist/services/specialists/dispatch.d.ts +53 -0
- package/dist/services/specialists/dispatch.js +102 -0
- package/dist/services/specialists/ie-ku-specialist.d.ts +37 -0
- package/dist/services/specialists/ie-ku-specialist.js +63 -0
- package/dist/services/specialists/msr-specialist.d.ts +61 -0
- package/dist/services/specialists/msr-specialist.js +162 -0
- package/dist/services/specialists/tr-specialist.d.ts +37 -0
- package/dist/services/specialists/tr-specialist.js +146 -0
- package/dist/services/storage-key-prefix.d.ts +42 -0
- package/dist/services/storage-key-prefix.js +45 -0
- package/dist/services/storage-put-recovery.d.ts +71 -0
- package/dist/services/storage-put-recovery.js +269 -0
- package/dist/services/storage-service-errors.d.ts +124 -0
- package/dist/services/storage-service-errors.js +189 -0
- package/dist/services/storage-service.d.ts +176 -0
- package/dist/services/storage-service.js +423 -0
- package/dist/services/subject-aware-ranking.d.ts +19 -0
- package/dist/services/subject-aware-ranking.js +161 -0
- package/dist/services/supplemental-extraction.d.ts +7 -0
- package/dist/services/supplemental-extraction.js +116 -0
- package/dist/services/tbc-execution.d.ts +49 -0
- package/dist/services/tbc-execution.js +284 -0
- package/dist/services/temporal-classifier.d.ts +56 -0
- package/dist/services/temporal-classifier.js +94 -0
- package/dist/services/temporal-endpoint-evidence.d.ts +12 -0
- package/dist/services/temporal-endpoint-evidence.js +313 -0
- package/dist/services/temporal-fingerprint.d.ts +6 -0
- package/dist/services/temporal-fingerprint.js +12 -0
- package/dist/services/temporal-format.d.ts +9 -0
- package/dist/services/temporal-format.js +21 -0
- package/dist/services/temporal-intent.d.ts +39 -0
- package/dist/services/temporal-intent.js +78 -0
- package/dist/services/temporal-query-constraints.d.ts +16 -0
- package/dist/services/temporal-query-constraints.js +107 -0
- package/dist/services/temporal-query-expansion.d.ts +14 -0
- package/dist/services/temporal-query-expansion.js +131 -0
- package/dist/services/temporal-rerank.d.ts +22 -0
- package/dist/services/temporal-rerank.js +47 -0
- package/dist/services/temporal-result-protection.d.ts +7 -0
- package/dist/services/temporal-result-protection.js +60 -0
- package/dist/services/temporal-state-write.d.ts +57 -0
- package/dist/services/temporal-state-write.js +45 -0
- package/dist/services/tiered-context.d.ts +87 -0
- package/dist/services/tiered-context.js +214 -0
- package/dist/services/tiered-loading.d.ts +88 -0
- package/dist/services/tiered-loading.js +263 -0
- package/dist/services/timeline-pack.d.ts +36 -0
- package/dist/services/timeline-pack.js +50 -0
- package/dist/services/timing.d.ts +13 -0
- package/dist/services/timing.js +72 -0
- package/dist/services/tll-augmentation.d.ts +20 -0
- package/dist/services/tll-augmentation.js +125 -0
- package/dist/services/tll-retrieval.d.ts +55 -0
- package/dist/services/tll-retrieval.js +101 -0
- package/dist/services/topic-abstraction.d.ts +36 -0
- package/dist/services/topic-abstraction.js +105 -0
- package/dist/services/trust-scoring.d.ts +43 -0
- package/dist/services/trust-scoring.js +89 -0
- package/dist/services/typed-belief-calculus.d.ts +126 -0
- package/dist/services/typed-belief-calculus.js +204 -0
- package/dist/services/upload-config.d.ts +34 -0
- package/dist/services/upload-config.js +23 -0
- package/dist/services/upload-decision.d.ts +65 -0
- package/dist/services/upload-decision.js +98 -0
- package/dist/services/upload-helpers.d.ts +107 -0
- package/dist/services/upload-helpers.js +148 -0
- package/dist/services/user-profile-builder.d.ts +22 -0
- package/dist/services/user-profile-builder.js +109 -0
- package/dist/services/voyage-embedding.d.ts +22 -0
- package/dist/services/voyage-embedding.js +77 -0
- package/dist/services/write-security.d.ts +31 -0
- package/dist/services/write-security.js +64 -0
- package/dist/storage/artifact-public-redaction.d.ts +34 -0
- package/dist/storage/artifact-public-redaction.js +83 -0
- package/dist/storage/cleanup.d.ts +103 -0
- package/dist/storage/cleanup.js +138 -0
- package/dist/storage/codec-factory.d.ts +17 -0
- package/dist/storage/codec-factory.js +33 -0
- package/dist/storage/codecs/aes-gcm-codec.d.ts +44 -0
- package/dist/storage/codecs/aes-gcm-codec.js +108 -0
- package/dist/storage/codecs/noop-codec.d.ts +16 -0
- package/dist/storage/codecs/noop-codec.js +23 -0
- package/dist/storage/factory.d.ts +44 -0
- package/dist/storage/factory.js +99 -0
- package/dist/storage/filecoin-cid-validation.d.ts +82 -0
- package/dist/storage/filecoin-cid-validation.js +122 -0
- package/dist/storage/filecoin-public-metadata.d.ts +73 -0
- package/dist/storage/filecoin-public-metadata.js +110 -0
- package/dist/storage/local-fs-store.d.ts +39 -0
- package/dist/storage/local-fs-store.js +145 -0
- package/dist/storage/pointer-uri-allowlist.d.ts +38 -0
- package/dist/storage/pointer-uri-allowlist.js +70 -0
- package/dist/storage/provider-metadata-projection.d.ts +27 -0
- package/dist/storage/provider-metadata-projection.js +68 -0
- package/dist/storage/providers/filecoin/backend.d.ts +42 -0
- package/dist/storage/providers/filecoin/backend.js +250 -0
- package/dist/storage/providers/filecoin/config.d.ts +70 -0
- package/dist/storage/providers/filecoin/config.js +275 -0
- package/dist/storage/providers/filecoin/errors.d.ts +45 -0
- package/dist/storage/providers/filecoin/errors.js +56 -0
- package/dist/storage/providers/filecoin/filecoin-pin-car.d.ts +78 -0
- package/dist/storage/providers/filecoin/filecoin-pin-car.js +155 -0
- package/dist/storage/providers/filecoin/filecoin-pin-client.d.ts +92 -0
- package/dist/storage/providers/filecoin/filecoin-pin-client.js +199 -0
- package/dist/storage/providers/filecoin/filecoin-pin-mapping.d.ts +58 -0
- package/dist/storage/providers/filecoin/filecoin-pin-mapping.js +103 -0
- package/dist/storage/providers/filecoin/filecoin-pin-timeout.d.ts +30 -0
- package/dist/storage/providers/filecoin/filecoin-pin-timeout.js +53 -0
- package/dist/storage/providers/filecoin/filecoin-pin-vendor.d.ts +111 -0
- package/dist/storage/providers/filecoin/filecoin-pin-vendor.js +87 -0
- package/dist/storage/providers/filecoin/hints.d.ts +71 -0
- package/dist/storage/providers/filecoin/hints.js +123 -0
- package/dist/storage/providers/filecoin/index.d.ts +51 -0
- package/dist/storage/providers/filecoin/index.js +103 -0
- package/dist/storage/providers/filecoin/ipfs-cid.d.ts +50 -0
- package/dist/storage/providers/filecoin/ipfs-cid.js +64 -0
- package/dist/storage/providers/filecoin/metadata.d.ts +72 -0
- package/dist/storage/providers/filecoin/metadata.js +137 -0
- package/dist/storage/providers/filecoin/piece-cid.d.ts +48 -0
- package/dist/storage/providers/filecoin/piece-cid.js +57 -0
- package/dist/storage/providers/filecoin/provider-client.d.ts +234 -0
- package/dist/storage/providers/filecoin/provider-client.js +27 -0
- package/dist/storage/providers/filecoin/readiness.d.ts +62 -0
- package/dist/storage/providers/filecoin/readiness.js +85 -0
- package/dist/storage/providers/filecoin/retriever.d.ts +82 -0
- package/dist/storage/providers/filecoin/retriever.js +63 -0
- package/dist/storage/providers/filecoin/skeleton-client.d.ts +36 -0
- package/dist/storage/providers/filecoin/skeleton-client.js +55 -0
- package/dist/storage/providers/filecoin/synapse-client.d.ts +169 -0
- package/dist/storage/providers/filecoin/synapse-client.js +343 -0
- package/dist/storage/providers/filecoin/synapse-construction.d.ts +26 -0
- package/dist/storage/providers/filecoin/synapse-construction.js +47 -0
- package/dist/storage/providers/filecoin/synapse-error-mapping.d.ts +23 -0
- package/dist/storage/providers/filecoin/synapse-error-mapping.js +49 -0
- package/dist/storage/providers/filecoin/synapse-readiness.d.ts +37 -0
- package/dist/storage/providers/filecoin/synapse-readiness.js +231 -0
- package/dist/storage/providers/filecoin/uri.d.ts +49 -0
- package/dist/storage/providers/filecoin/uri.js +84 -0
- package/dist/storage/providers/filecoin/verified-fetch-lifecycle.d.ts +77 -0
- package/dist/storage/providers/filecoin/verified-fetch-lifecycle.js +196 -0
- package/dist/storage/providers/filecoin/verified-fetch-retriever.d.ts +54 -0
- package/dist/storage/providers/filecoin/verified-fetch-retriever.js +81 -0
- package/dist/storage/providers/filecoin/verified-fetch-vendor.d.ts +71 -0
- package/dist/storage/providers/filecoin/verified-fetch-vendor.js +94 -0
- package/dist/storage/raw-content-codec.d.ts +89 -0
- package/dist/storage/raw-content-codec.js +47 -0
- package/dist/storage/raw-content-store-backend-adapter.d.ts +28 -0
- package/dist/storage/raw-content-store-backend-adapter.js +67 -0
- package/dist/storage/raw-content-store.d.ts +228 -0
- package/dist/storage/raw-content-store.js +27 -0
- package/dist/storage/s3-store.d.ts +42 -0
- package/dist/storage/s3-store.js +181 -0
- package/dist/storage/storage-backend-registry.d.ts +58 -0
- package/dist/storage/storage-backend-registry.js +56 -0
- package/dist/storage/storage-backend.d.ts +82 -0
- package/dist/storage/storage-backend.js +14 -0
- package/dist/storage/storage-capabilities.d.ts +56 -0
- package/dist/storage/storage-capabilities.js +170 -0
- package/dist/storage/store-registry.d.ts +67 -0
- package/dist/storage/store-registry.js +77 -0
- package/dist/vector-math.d.ts +15 -0
- package/dist/vector-math.js +31 -0
- package/dist/xml-escape.d.ts +5 -0
- package/dist/xml-escape.js +7 -0
- package/openapi.json +15395 -0
- package/openapi.yaml +10794 -0
- package/package.json +119 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Direct storage API orchestration — the seam between the
|
|
3
|
+
* route layer and the `storage_artifacts` repository + the managed
|
|
4
|
+
* `StorageBackend`.
|
|
5
|
+
*
|
|
6
|
+
* Owns the put-pointer/managed branch, get-content pointer-mode 409,
|
|
7
|
+
* the delete-policy state
|
|
8
|
+
* machine (claim → backend-call → mark-success/failure), and the
|
|
9
|
+
* verify shim. Pointer URIs are validated against the operator
|
|
10
|
+
* allowlist here; the service NEVER fetches a pointer URI.
|
|
11
|
+
*
|
|
12
|
+
* Filecoin-shaped direct managed uploads are gated with a 501 by throwing
|
|
13
|
+
* `FilecoinDirectStorageNotSupportedError` before the backend is
|
|
14
|
+
* touched. Pointer mode against these providers is still allowed (it is
|
|
15
|
+
* metadata-only and backend-independent).
|
|
16
|
+
*/
|
|
17
|
+
import { createHash } from 'node:crypto';
|
|
18
|
+
import { claimDeleteAttempt, claimPendingArtifact, countReferencingDocuments, createStorageArtifact, getStorageArtifactById, getStorageArtifactByIdIncludingDeleted, listArtifactsForUser, listReferencingDocumentIds, releaseDeleteClaim, } from '../db/storage-artifact-repository.js';
|
|
19
|
+
import { errorMessage, persistUploadedOrRecover, recordBackendPutFailure, } from './storage-put-recovery.js';
|
|
20
|
+
import { deriveStorageKeyPrefix } from './storage-key-prefix.js';
|
|
21
|
+
import { finalizeArtifactDeleteFailureTx, finalizeArtifactDeleteSuccessTx, } from '../db/storage-artifact-delete-tx.js';
|
|
22
|
+
import { softDeleteDocumentCascade } from '../db/repository-document-delete.js';
|
|
23
|
+
import { isAllowlistedPointerUri, } from '../storage/pointer-uri-allowlist.js';
|
|
24
|
+
import { EXTERNAL_POINTER_PROVIDER } from '../db/storage-artifact-providers.js';
|
|
25
|
+
import { ArtifactDeleteInFlightError, ArtifactInUseError, ArtifactNotReadyError, ArtifactUnavailableError, BackendNotRegisteredError, FilecoinDirectStorageNotSupportedError, InvalidArtifactMetadataError, ManagedStorageDisabledError, PointerContentNotManagedError, StorageArtifactNotFoundError, UnregisteredProviderError, UnsupportedPointerSchemeError, } from './storage-service-errors.js';
|
|
26
|
+
const FILECOIN_PROVIDER = 'filecoin';
|
|
27
|
+
const POINTER_ONLY_PROVIDER = 'none';
|
|
28
|
+
/**
|
|
29
|
+
* Providers that reject `POST /v1/storage/artifacts?mode=managed`
|
|
30
|
+
* with a typed 501 BEFORE `claimPendingArtifact` runs, so no
|
|
31
|
+
* `storage_artifacts` row is created for the rejected request.
|
|
32
|
+
* Only `filecoin` is currently carved out. Other eventual-consistency
|
|
33
|
+
* providers can join this set if their readiness model also requires
|
|
34
|
+
* document-scoped upload paths.
|
|
35
|
+
*/
|
|
36
|
+
const DIRECT_MANAGED_UNSUPPORTED_PROVIDERS = new Set([FILECOIN_PROVIDER]);
|
|
37
|
+
export class StorageService {
|
|
38
|
+
pool;
|
|
39
|
+
backendRegistry;
|
|
40
|
+
pointerSchemes;
|
|
41
|
+
storageKeyHmacSecret;
|
|
42
|
+
constructor(deps) {
|
|
43
|
+
this.pool = deps.pool;
|
|
44
|
+
this.backendRegistry = deps.backendRegistry;
|
|
45
|
+
this.pointerSchemes = deps.pointerSchemes;
|
|
46
|
+
this.storageKeyHmacSecret = deps.storageKeyHmacSecret;
|
|
47
|
+
}
|
|
48
|
+
/** The backend the deployment writes NEW managed artifacts to. */
|
|
49
|
+
get activeBackend() {
|
|
50
|
+
return this.backendRegistry.active;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the backend for an already-persisted managed-mode row.
|
|
54
|
+
* Throws `BackendNotRegisteredError` when no adapter matches the
|
|
55
|
+
* row's `provider`. Pointer rows must short-circuit before this is
|
|
56
|
+
* called; calling it on a pointer row is a service-layer bug.
|
|
57
|
+
*/
|
|
58
|
+
resolveBackendForRow(row) {
|
|
59
|
+
if (row.mode !== 'managed') {
|
|
60
|
+
throw new Error(`resolveBackendForRow: row '${row.id}' is mode='${row.mode}'; ` +
|
|
61
|
+
'pointer-mode dispatch must short-circuit before backend lookup');
|
|
62
|
+
}
|
|
63
|
+
const backend = this.backendRegistry.get(row.provider);
|
|
64
|
+
if (backend === undefined)
|
|
65
|
+
throw new BackendNotRegisteredError(row.provider, row.id);
|
|
66
|
+
return backend;
|
|
67
|
+
}
|
|
68
|
+
async putPointer(input) {
|
|
69
|
+
if (!isAllowlistedPointerUri(input.uri, this.pointerSchemes)) {
|
|
70
|
+
throw new UnsupportedPointerSchemeError(input.uri, this.pointerSchemes);
|
|
71
|
+
}
|
|
72
|
+
const provider = this.activeBackend?.provider ?? POINTER_ONLY_PROVIDER;
|
|
73
|
+
return createStorageArtifact(this.pool, {
|
|
74
|
+
userId: input.userId,
|
|
75
|
+
provider,
|
|
76
|
+
mode: 'pointer',
|
|
77
|
+
uri: input.uri,
|
|
78
|
+
status: 'stored',
|
|
79
|
+
sizeBytes: input.sizeBytes ?? null,
|
|
80
|
+
contentType: input.contentType,
|
|
81
|
+
contentEncoding: 'identity',
|
|
82
|
+
discloseContentHash: false,
|
|
83
|
+
identifiers: input.contentHash ? { contentHash: input.contentHash } : {},
|
|
84
|
+
metadata: input.metadata ?? {},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Managed-mode put — pending-row-first contract.
|
|
89
|
+
*
|
|
90
|
+
* 1. Validate gates: managed-storage enabled, provider registered,
|
|
91
|
+
* Filecoin-direct carve-out (501).
|
|
92
|
+
* 2. INSERT a `status='pending'` row with `uri=NULL` and a fresh
|
|
93
|
+
* `put_attempt_id`. (This is the DB claim; no backend call yet.)
|
|
94
|
+
* 3. Call `backend.put(...)` OUTSIDE the DB transaction.
|
|
95
|
+
* 4. On `backend.put` success: CAS-flip the row to `'stored'` via
|
|
96
|
+
* `recordUploadedArtifact`. Recovery handles the rare case
|
|
97
|
+
* where that UPDATE fails after the bytes are at the backend
|
|
98
|
+
* (single immediate retry, then backend cleanup, then a
|
|
99
|
+
* best-effort failure marker — see `recoverPostPutFailure`).
|
|
100
|
+
* 5. On `backend.put` failure: CAS-flip the row to `'failed'` via
|
|
101
|
+
* `markPutFailed`, then re-throw the original backend error.
|
|
102
|
+
*/
|
|
103
|
+
async putManaged(input) {
|
|
104
|
+
const backend = this.requireWritableBackend();
|
|
105
|
+
const claim = await claimPendingArtifact(this.pool, {
|
|
106
|
+
userId: input.userId,
|
|
107
|
+
provider: backend.provider,
|
|
108
|
+
contentType: input.contentType,
|
|
109
|
+
discloseContentHash: input.discloseContentHash,
|
|
110
|
+
metadata: input.metadata,
|
|
111
|
+
});
|
|
112
|
+
const userPrefix = deriveStorageKeyPrefix(this.storageKeyHmacSecret, input.userId);
|
|
113
|
+
const key = `s/${userPrefix}/${claim.row.id}.bin`;
|
|
114
|
+
let putResult;
|
|
115
|
+
try {
|
|
116
|
+
putResult = await backend.put({ key, body: input.body, contentType: input.contentType });
|
|
117
|
+
}
|
|
118
|
+
catch (putError) {
|
|
119
|
+
await recordBackendPutFailure({
|
|
120
|
+
pool: this.pool,
|
|
121
|
+
userId: input.userId,
|
|
122
|
+
claim,
|
|
123
|
+
provider: backend.provider,
|
|
124
|
+
putError,
|
|
125
|
+
});
|
|
126
|
+
throw putError;
|
|
127
|
+
}
|
|
128
|
+
return persistUploadedOrRecover({
|
|
129
|
+
pool: this.pool,
|
|
130
|
+
userId: input.userId,
|
|
131
|
+
backend,
|
|
132
|
+
claim,
|
|
133
|
+
putResult,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Validate the deployment can accept a managed write. Throws
|
|
138
|
+
* `ManagedStorageDisabledError` for pointer-only deployments,
|
|
139
|
+
* `FilecoinDirectStorageNotSupportedError` for the v1
|
|
140
|
+
* content-addressed eventual-provider carve-out, and
|
|
141
|
+
* `UnregisteredProviderError` as a defensive check
|
|
142
|
+
* against a composition bug where `active` isn't in the registry.
|
|
143
|
+
*/
|
|
144
|
+
requireWritableBackend() {
|
|
145
|
+
const backend = this.activeBackend;
|
|
146
|
+
if (backend === null)
|
|
147
|
+
throw new ManagedStorageDisabledError();
|
|
148
|
+
if (DIRECT_MANAGED_UNSUPPORTED_PROVIDERS.has(backend.provider)) {
|
|
149
|
+
throw new FilecoinDirectStorageNotSupportedError(backend.provider);
|
|
150
|
+
}
|
|
151
|
+
if (!this.backendRegistry.has(backend.provider)
|
|
152
|
+
&& backend.provider !== EXTERNAL_POINTER_PROVIDER) {
|
|
153
|
+
throw new UnregisteredProviderError(backend.provider);
|
|
154
|
+
}
|
|
155
|
+
return backend;
|
|
156
|
+
}
|
|
157
|
+
async getArtifactMetadata(userId, id) {
|
|
158
|
+
const row = await getStorageArtifactById(this.pool, userId, id);
|
|
159
|
+
if (row === null)
|
|
160
|
+
throw new StorageArtifactNotFoundError(id);
|
|
161
|
+
return row;
|
|
162
|
+
}
|
|
163
|
+
async getArtifactContent(userId, id) {
|
|
164
|
+
const row = await this.getArtifactMetadata(userId, id);
|
|
165
|
+
// Pointer short-circuit — never consults the backend registry.
|
|
166
|
+
// Pointer rows always have `uri` set at insert time; assert.
|
|
167
|
+
if (row.mode === 'pointer') {
|
|
168
|
+
throw new PointerContentNotManagedError(row.id, requireUri(row));
|
|
169
|
+
}
|
|
170
|
+
// Managed lifecycle gates before backend dispatch: pending and
|
|
171
|
+
// failed rows have `uri=null` (the upload never reached the
|
|
172
|
+
// `stored` CAS), so a public read against them must surface a
|
|
173
|
+
// typed envelope instead of falling through to `requireUri`'s
|
|
174
|
+
// service-layer bug.
|
|
175
|
+
if (row.status === 'pending') {
|
|
176
|
+
throw new ArtifactNotReadyError(row.id);
|
|
177
|
+
}
|
|
178
|
+
if (row.uri === null || row.status === 'failed') {
|
|
179
|
+
throw new ArtifactUnavailableError(row.id, 'artifact bytes were never persisted');
|
|
180
|
+
}
|
|
181
|
+
// Managed dispatch: resolve the backend whose provider matches
|
|
182
|
+
// the row, not the active write backend. A row written under
|
|
183
|
+
// `local_fs` keeps working after the deployment switches to
|
|
184
|
+
// `s3` as long as `local_fs` stays registered (legacy).
|
|
185
|
+
const backend = this.resolveBackendForRow(row);
|
|
186
|
+
const fetched = await backend.get(row.uri);
|
|
187
|
+
return { row, body: fetched.body };
|
|
188
|
+
}
|
|
189
|
+
async listArtifacts(userId, opts) {
|
|
190
|
+
return listArtifactsForUser(this.pool, userId, opts);
|
|
191
|
+
}
|
|
192
|
+
async deleteArtifact(input) {
|
|
193
|
+
// The delete path is allowed to see soft-deleted rows so a
|
|
194
|
+
// second `DELETE` on a `deleted` artifact returns the prior
|
|
195
|
+
// terminal envelope (plan's idempotency contract).
|
|
196
|
+
const initial = await getStorageArtifactByIdIncludingDeleted(this.pool, input.userId, input.id);
|
|
197
|
+
if (initial === null)
|
|
198
|
+
throw new StorageArtifactNotFoundError(input.id);
|
|
199
|
+
if (initial.status === 'deleted') {
|
|
200
|
+
return { artifact: initial, cascadedDocumentIds: [] };
|
|
201
|
+
}
|
|
202
|
+
// Pre-resolve the backend for managed rows BEFORE any DB
|
|
203
|
+
// mutation (Commit B fix). Pending/failed rows with `uri=null`
|
|
204
|
+
// and pointer rows skip resolution — they have no bytes to
|
|
205
|
+
// clean up at any backend.
|
|
206
|
+
const resolvedBackend = initial.mode === 'managed' && initial.uri !== null
|
|
207
|
+
? this.resolveBackendForRow(initial)
|
|
208
|
+
: null;
|
|
209
|
+
// Claim BEFORE checking references (Commit D fix). Once the
|
|
210
|
+
// row is in `status='deleting'`, `assertArtifactLinkable`
|
|
211
|
+
// refuses to attach new `raw_documents.storage_artifact_id`
|
|
212
|
+
// references, so the reference count is stable for the rest
|
|
213
|
+
// of this call. `delete_failed` retries re-claim and re-check
|
|
214
|
+
// refs, so a new link added between retries surfaces as
|
|
215
|
+
// `ArtifactInUseError` instead of being silently bulldozed.
|
|
216
|
+
const claim = await claimDeleteAttempt(this.pool, input.userId, input.id);
|
|
217
|
+
if (claim === null) {
|
|
218
|
+
// Claim refused — disambiguate by re-reading the row. Three
|
|
219
|
+
// outcomes:
|
|
220
|
+
// - row gone / cross-user → 404 (matches initial gate)
|
|
221
|
+
// - row terminal `deleted` → idempotent success envelope
|
|
222
|
+
// (the plan's idempotency contract for a second DELETE
|
|
223
|
+
// on an already-deleted artifact)
|
|
224
|
+
// - anything else (chiefly `deleting`, also a transient
|
|
225
|
+
// `delete_failed` from a sibling's just-finalized failure)
|
|
226
|
+
// → 409 `delete_in_flight`. Returning the row as if THIS
|
|
227
|
+
// caller succeeded was the prior bug — the caller never
|
|
228
|
+
// ran cascade or backend.delete, so claiming success
|
|
229
|
+
// would falsely promise a delete this caller didn't
|
|
230
|
+
// perform.
|
|
231
|
+
const reread = await getStorageArtifactByIdIncludingDeleted(this.pool, input.userId, input.id);
|
|
232
|
+
if (reread === null)
|
|
233
|
+
throw new StorageArtifactNotFoundError(input.id);
|
|
234
|
+
if (reread.status === 'deleted') {
|
|
235
|
+
return { artifact: reread, cascadedDocumentIds: [] };
|
|
236
|
+
}
|
|
237
|
+
throw new ArtifactDeleteInFlightError(input.id, reread.status);
|
|
238
|
+
}
|
|
239
|
+
let cascadedDocumentIds;
|
|
240
|
+
try {
|
|
241
|
+
cascadedDocumentIds = await this.maybeCascadeDocuments(input);
|
|
242
|
+
}
|
|
243
|
+
catch (err) {
|
|
244
|
+
// Release the claim so the artifact returns to its
|
|
245
|
+
// pre-delete state. Without this revert the row would stay
|
|
246
|
+
// at `status='deleting'` forever (or until another delete
|
|
247
|
+
// call). Restore the pre-claim `last_error` too —
|
|
248
|
+
// `claimDeleteAttempt` clears it on entry so a successful
|
|
249
|
+
// delete doesn't surface stale errors, but a refused delete
|
|
250
|
+
// shouldn't blank an existing operator-visible failure.
|
|
251
|
+
await releaseDeleteClaim(this.pool, {
|
|
252
|
+
userId: input.userId,
|
|
253
|
+
id: input.id,
|
|
254
|
+
claimId: claim.claimId,
|
|
255
|
+
restoreStatus: initial.status,
|
|
256
|
+
restoreLastError: initial.lastError,
|
|
257
|
+
});
|
|
258
|
+
throw err;
|
|
259
|
+
}
|
|
260
|
+
const finalized = await this.executeBackendDelete(input, initial, resolvedBackend, claim.claimId, cascadedDocumentIds);
|
|
261
|
+
return { artifact: finalized, cascadedDocumentIds };
|
|
262
|
+
}
|
|
263
|
+
async verifyArtifact(userId, id) {
|
|
264
|
+
const row = await this.getArtifactMetadata(userId, id);
|
|
265
|
+
// Pointer short-circuit — never consults the backend registry.
|
|
266
|
+
if (row.mode === 'pointer') {
|
|
267
|
+
return { kind: 'unsupported', reason: 'pointer-mode artifacts are not server-verifiable' };
|
|
268
|
+
}
|
|
269
|
+
// Lifecycle gates: pending/failed rows have no bytes to verify.
|
|
270
|
+
// The `verify` envelope is the natural surface for this — we
|
|
271
|
+
// return `kind: 'unsupported'` / `'failed'` rather than throwing,
|
|
272
|
+
// matching the existing pointer-row pattern.
|
|
273
|
+
if (row.status === 'pending') {
|
|
274
|
+
return { kind: 'unsupported', reason: 'artifact is still pending upload finalization' };
|
|
275
|
+
}
|
|
276
|
+
if (row.uri === null || row.status === 'failed') {
|
|
277
|
+
return { kind: 'failed', reason: 'artifact bytes were never persisted' };
|
|
278
|
+
}
|
|
279
|
+
// Per-row dispatch: every managed provider (including filecoin)
|
|
280
|
+
// resolves through the registry. Filecoin's `head` is a real
|
|
281
|
+
// adapter call when registered; an unregistered provider raises
|
|
282
|
+
// `BackendNotRegisteredError`, mapped by the route to 503
|
|
283
|
+
// `storage_backend_unavailable`.
|
|
284
|
+
const backend = this.resolveBackendForRow(row);
|
|
285
|
+
const head = await backend.head(row.uri);
|
|
286
|
+
if (head.exists) {
|
|
287
|
+
return { kind: 'verified', details: { sizeBytes: head.sizeBytes ?? row.sizeBytes ?? 0 } };
|
|
288
|
+
}
|
|
289
|
+
return { kind: 'failed', reason: 'backend reports the artifact bytes are not present' };
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Reference-count gate + optional document cascade. Runs INSIDE
|
|
293
|
+
* the claim window (Commit D): the artifact is already in
|
|
294
|
+
* `status='deleting'`, so concurrent INSERTs are refused by
|
|
295
|
+
* `assertArtifactLinkable` at the link-write sites — the count
|
|
296
|
+
* is stable for the rest of the call.
|
|
297
|
+
*
|
|
298
|
+
* Every `delete_failed` retry rechecks references too. The old
|
|
299
|
+
* "delete_failed short-circuits the gate" rule could silently
|
|
300
|
+
* bulldoze a fresh link added between attempts; this implementation
|
|
301
|
+
* refuses to finalize unless the policy explicitly opts into a
|
|
302
|
+
* cascade.
|
|
303
|
+
*
|
|
304
|
+
* On `ArtifactInUseError` the caller releases the claim and the
|
|
305
|
+
* row goes back to its pre-delete state.
|
|
306
|
+
*/
|
|
307
|
+
async maybeCascadeDocuments(input) {
|
|
308
|
+
const count = await countReferencingDocuments(this.pool, input.userId, input.id);
|
|
309
|
+
if (count === 0)
|
|
310
|
+
return [];
|
|
311
|
+
if (input.policy !== 'with_documents') {
|
|
312
|
+
throw new ArtifactInUseError(input.id, count);
|
|
313
|
+
}
|
|
314
|
+
return this.cascadeDocuments(input.userId, input.id);
|
|
315
|
+
}
|
|
316
|
+
async cascadeDocuments(userId, artifactId) {
|
|
317
|
+
const ids = await listReferencingDocumentIds(this.pool, userId, artifactId);
|
|
318
|
+
const removed = [];
|
|
319
|
+
for (const documentId of ids) {
|
|
320
|
+
const result = await softDeleteDocumentCascade(this.pool, userId, documentId);
|
|
321
|
+
if (result.removed)
|
|
322
|
+
removed.push(documentId);
|
|
323
|
+
}
|
|
324
|
+
return removed;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Run the backend cleanup ONCE (skipped when `backend === null`,
|
|
328
|
+
* which is the pointer-mode case — pointer rows have no bytes at
|
|
329
|
+
* a backend), then finalize the artifact AND propagate the
|
|
330
|
+
* terminal state to every cascaded document in one atomic paired
|
|
331
|
+
* transaction (`finalizeArtifactDeleteSuccessTx` / `…FailureTx`).
|
|
332
|
+
*
|
|
333
|
+
* `backend.delete` runs OUTSIDE the transaction (it is a network
|
|
334
|
+
* call); the DB finalization either commits both rows together or
|
|
335
|
+
* rolls them both back. A partial commit that leaves the artifact
|
|
336
|
+
* terminal while the linked raw_documents stay at
|
|
337
|
+
* `blob_stored`/`blob_available` is no longer possible. The
|
|
338
|
+
* document cleanup path never sees the URI here, so there is no
|
|
339
|
+
* double-delete of the backend object.
|
|
340
|
+
*
|
|
341
|
+
* The backend is resolved BEFORE this is called (see
|
|
342
|
+
* `deleteArtifact` above), so this function never needs to handle
|
|
343
|
+
* `BackendNotRegisteredError`. Any thrown backend error here is a
|
|
344
|
+
* runtime delete failure (network outage, etc.) and lands the
|
|
345
|
+
* artifact in `delete_failed` with a sanitized envelope.
|
|
346
|
+
*/
|
|
347
|
+
async executeBackendDelete(input, initial, backend, claimId, cascadedDocumentIds) {
|
|
348
|
+
let semantics = 'deleted';
|
|
349
|
+
try {
|
|
350
|
+
// Managed rows with a URI go through the backend cleanup.
|
|
351
|
+
// Pending rows with `uri=null` (upload claim, no bytes yet)
|
|
352
|
+
// and failed rows with `uri=null` (backend.put threw) have
|
|
353
|
+
// no backend object to delete — the DB CAS is the entire
|
|
354
|
+
// delete. Pointer rows skip backend.delete unconditionally
|
|
355
|
+
// (they have no bytes either).
|
|
356
|
+
if (initial.mode === 'managed' && backend !== null && initial.uri !== null) {
|
|
357
|
+
const result = await backend.delete(initial.uri);
|
|
358
|
+
semantics = result.semantics ?? 'deleted';
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
return finalizeArtifactDeleteFailureTx(this.pool, {
|
|
363
|
+
userId: input.userId,
|
|
364
|
+
artifactId: input.id,
|
|
365
|
+
claimId,
|
|
366
|
+
cascadedDocumentIds,
|
|
367
|
+
lastError: { layer: 'raw_storage', code: 'backend_delete_failed', message: errorMessage(err) },
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
return finalizeArtifactDeleteSuccessTx(this.pool, {
|
|
371
|
+
userId: input.userId,
|
|
372
|
+
artifactId: input.id,
|
|
373
|
+
claimId,
|
|
374
|
+
cascadedDocumentIds,
|
|
375
|
+
semantics,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Validate caller-supplied metadata: closed value type
|
|
381
|
+
* (`string | number | boolean` only) and ≤ 4 KiB serialized JSON.
|
|
382
|
+
* Throws `InvalidArtifactMetadataError` on violation. The route
|
|
383
|
+
* layer reuses this for both the pointer-mode JSON `metadata` field
|
|
384
|
+
* and the managed-mode `X-AtomicMemory-Metadata` header.
|
|
385
|
+
*/
|
|
386
|
+
const ARTIFACT_METADATA_DECODED_MAX_BYTES = 4 * 1024;
|
|
387
|
+
export function validateArtifactMetadata(value) {
|
|
388
|
+
if (value === undefined || value === null)
|
|
389
|
+
return {};
|
|
390
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
391
|
+
throw new InvalidArtifactMetadataError('metadata must be a JSON object');
|
|
392
|
+
}
|
|
393
|
+
const record = value;
|
|
394
|
+
for (const [key, v] of Object.entries(record)) {
|
|
395
|
+
if (typeof v !== 'string' && typeof v !== 'number' && typeof v !== 'boolean') {
|
|
396
|
+
throw new InvalidArtifactMetadataError(`metadata.${key} must be a string, number, or boolean`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const serialized = JSON.stringify(record);
|
|
400
|
+
if (Buffer.byteLength(serialized, 'utf8') > ARTIFACT_METADATA_DECODED_MAX_BYTES) {
|
|
401
|
+
throw new InvalidArtifactMetadataError(`metadata exceeds the ${ARTIFACT_METADATA_DECODED_MAX_BYTES}-byte serialized cap`);
|
|
402
|
+
}
|
|
403
|
+
return record;
|
|
404
|
+
}
|
|
405
|
+
/** SHA-256 helper exposed for tests of the upload-hash contract. */
|
|
406
|
+
export function sha256Hex(buffer) {
|
|
407
|
+
return createHash('sha256').update(buffer).digest('hex');
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Assert a `storage_artifacts` row carries a non-null `uri`. Used
|
|
411
|
+
* by every backend-dispatch path; pointer rows ALWAYS carry the URI
|
|
412
|
+
* (set at insert time), and managed rows that reached `stored` /
|
|
413
|
+
* `available` carry it post-CAS. Hitting this on a `pending` /
|
|
414
|
+
* `failed` row indicates the caller bypassed the lifecycle gates,
|
|
415
|
+
* which is a service-layer bug.
|
|
416
|
+
*/
|
|
417
|
+
function requireUri(row) {
|
|
418
|
+
if (row.uri === null) {
|
|
419
|
+
throw new Error(`storage-service: row '${row.id}' (mode='${row.mode}', status='${row.status}') ` +
|
|
420
|
+
'has no uri; backend dispatch is only valid for stored / pointer rows');
|
|
421
|
+
}
|
|
422
|
+
return row.uri;
|
|
423
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subject-aware reranking for person-specific questions.
|
|
3
|
+
* Boosts memories that explicitly mention the requested subject and downweights
|
|
4
|
+
* memories that mention a conflicting person name.
|
|
5
|
+
*/
|
|
6
|
+
import type { SearchResult } from '../db/repository-types.js';
|
|
7
|
+
import type { SearchStore } from '../db/stores.js';
|
|
8
|
+
export interface SubjectRankingResult {
|
|
9
|
+
subjects: string[];
|
|
10
|
+
keywords: string[];
|
|
11
|
+
protectedFingerprints: string[];
|
|
12
|
+
results: SearchResult[];
|
|
13
|
+
}
|
|
14
|
+
export declare function applySubjectAwareRanking(query: string, results: SearchResult[]): SubjectRankingResult;
|
|
15
|
+
export declare function extractSubjectQueryAnchors(query: string): string[];
|
|
16
|
+
export declare function expandSubjectQuery(repo: SearchStore, userId: string, query: string, queryEmbedding: number[], excludeIds: Set<string>, limit: number): Promise<{
|
|
17
|
+
memories: SearchResult[];
|
|
18
|
+
anchors: string[];
|
|
19
|
+
}>;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subject-aware reranking for person-specific questions.
|
|
3
|
+
* Boosts memories that explicitly mention the requested subject and downweights
|
|
4
|
+
* memories that mention a conflicting person name.
|
|
5
|
+
*/
|
|
6
|
+
import { buildTemporalFingerprint } from './temporal-fingerprint.js';
|
|
7
|
+
import { fetchAndBoostKeywordCandidates } from './keyword-expansion.js';
|
|
8
|
+
import { countKeywordMatches, normalizeKeywordToken } from './query-keyword-matches.js';
|
|
9
|
+
const MONTH_NAMES = new Set([
|
|
10
|
+
'January', 'February', 'March', 'April', 'May', 'June',
|
|
11
|
+
'July', 'August', 'September', 'October', 'November', 'December',
|
|
12
|
+
]);
|
|
13
|
+
const NON_SUBJECT_TOKENS = new Set(['As', 'User']);
|
|
14
|
+
const QUERY_STOP_WORDS = new Set([
|
|
15
|
+
'When', 'What', 'Where', 'Why', 'How', 'Who', 'Which',
|
|
16
|
+
'Did', 'Does', 'Do', 'Has', 'Have', 'Had',
|
|
17
|
+
]);
|
|
18
|
+
const KEYWORD_STOP_WORDS = new Set([
|
|
19
|
+
'when', 'what', 'where', 'why', 'how', 'who', 'which',
|
|
20
|
+
'did', 'does', 'do', 'has', 'have', 'had',
|
|
21
|
+
'her', 'his', 'their', 'the', 'a', 'an', 'at', 'in', 'on', 'to',
|
|
22
|
+
'and', 'between', 'first', 'second', 'many', 'much', 'months', 'month',
|
|
23
|
+
'weeks', 'week', 'years', 'year', 'days', 'day', 'lapsed', 'elapsed',
|
|
24
|
+
'passed', 'before', 'after',
|
|
25
|
+
]);
|
|
26
|
+
const SUBJECT_MATCH_BONUS = 2;
|
|
27
|
+
const EXTRA_SUBJECT_MATCH_BONUS = 0.75;
|
|
28
|
+
const CONFLICT_SUBJECT_PENALTY = 0.25;
|
|
29
|
+
const KEYWORD_MATCH_BONUS = 0.4;
|
|
30
|
+
const SUBJECT_QUERY_LIMIT = 8;
|
|
31
|
+
const TEMPORAL_PLANNING_PENALTY = 2.25;
|
|
32
|
+
const TEMPORAL_EVENT_QUERY = /\b(when|how long|how many months|how many years|how many weeks|how many days|between|first|second|before|after)\b/i;
|
|
33
|
+
const PLANNING_MARKERS = [
|
|
34
|
+
'plan to', 'planned to', 'planning to', 'going to', 'will ', 'wants to',
|
|
35
|
+
'want to', 'thinking of', 'thinking about', 'considering', 'decided to make',
|
|
36
|
+
'make a new appointment', 'book a new appointment',
|
|
37
|
+
];
|
|
38
|
+
export function applySubjectAwareRanking(query, results) {
|
|
39
|
+
const subjects = extractQuerySubjects(query);
|
|
40
|
+
const keywords = extractQueryKeywords(query, subjects);
|
|
41
|
+
if (subjects.length === 0 && keywords.length === 0) {
|
|
42
|
+
return { subjects: [], keywords: [], protectedFingerprints: [], results };
|
|
43
|
+
}
|
|
44
|
+
const temporalEventQuery = TEMPORAL_EVENT_QUERY.test(query.toLowerCase());
|
|
45
|
+
const scoredResults = results
|
|
46
|
+
.map((result) => scoreSubjectCandidate(result, subjects, keywords, temporalEventQuery))
|
|
47
|
+
.sort((left, right) => right.result.score - left.result.score);
|
|
48
|
+
return {
|
|
49
|
+
subjects,
|
|
50
|
+
keywords,
|
|
51
|
+
protectedFingerprints: buildProtectedFingerprints(scoredResults),
|
|
52
|
+
results: scoredResults.map((item) => item.result),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function extractSubjectQueryAnchors(query) {
|
|
56
|
+
const subjects = extractQuerySubjects(query);
|
|
57
|
+
const keywords = extractQueryKeywords(query, subjects);
|
|
58
|
+
return [...subjects, ...keywords].slice(0, SUBJECT_QUERY_LIMIT);
|
|
59
|
+
}
|
|
60
|
+
export async function expandSubjectQuery(repo, userId, query, queryEmbedding, excludeIds, limit) {
|
|
61
|
+
const anchors = extractSubjectQueryAnchors(query);
|
|
62
|
+
if (anchors.length === 0)
|
|
63
|
+
return { memories: [], anchors: [] };
|
|
64
|
+
const boosted = await fetchAndBoostKeywordCandidates(repo, userId, anchors, queryEmbedding, excludeIds, limit, KEYWORD_MATCH_BONUS);
|
|
65
|
+
return { memories: boosted, anchors };
|
|
66
|
+
}
|
|
67
|
+
function scoreSubjectCandidate(result, subjects, keywords, temporalEventQuery) {
|
|
68
|
+
const mentionedSubjects = extractMentionedSubjects(result.content);
|
|
69
|
+
const requestedSubjectMatches = subjects.filter((subject) => mentionedSubjects.includes(subject)).length;
|
|
70
|
+
const hasRequestedSubject = requestedSubjectMatches > 0;
|
|
71
|
+
const hasConflictingSubject = mentionedSubjects.some((subject) => !subjects.includes(subject));
|
|
72
|
+
const keywordMatches = countKeywordMatches(result.content, keywords);
|
|
73
|
+
const planningPenalty = shouldPenalizePlanning(result.content, temporalEventQuery)
|
|
74
|
+
? TEMPORAL_PLANNING_PENALTY
|
|
75
|
+
: 0;
|
|
76
|
+
let score = result.score;
|
|
77
|
+
if (hasRequestedSubject) {
|
|
78
|
+
score += SUBJECT_MATCH_BONUS + ((requestedSubjectMatches - 1) * EXTRA_SUBJECT_MATCH_BONUS);
|
|
79
|
+
}
|
|
80
|
+
if (hasConflictingSubject && !hasRequestedSubject) {
|
|
81
|
+
score *= CONFLICT_SUBJECT_PENALTY;
|
|
82
|
+
}
|
|
83
|
+
if (keywordMatches > 0) {
|
|
84
|
+
score += keywordMatches * KEYWORD_MATCH_BONUS;
|
|
85
|
+
}
|
|
86
|
+
score -= planningPenalty;
|
|
87
|
+
return {
|
|
88
|
+
result: score === result.score ? result : { ...result, score },
|
|
89
|
+
hasRequestedSubject,
|
|
90
|
+
keywordMatches,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function extractQuerySubjects(query) {
|
|
94
|
+
return extractQueryCandidates(query)
|
|
95
|
+
.filter((candidate) => isSubjectToken(candidate))
|
|
96
|
+
.filter((candidate, index, all) => all.indexOf(candidate) === index);
|
|
97
|
+
}
|
|
98
|
+
function extractMentionedSubjects(content) {
|
|
99
|
+
const tokens = content.match(/\b[A-Z][a-z]+\b/g) ?? [];
|
|
100
|
+
return tokens
|
|
101
|
+
.filter((token) => isSubjectToken(token))
|
|
102
|
+
.filter((token, index, all) => all.indexOf(token) === index);
|
|
103
|
+
}
|
|
104
|
+
function isSubjectToken(token) {
|
|
105
|
+
return !MONTH_NAMES.has(token) && !NON_SUBJECT_TOKENS.has(token) && !token.includes(' ');
|
|
106
|
+
}
|
|
107
|
+
function extractQueryKeywords(query, subjects) {
|
|
108
|
+
const subjectSet = new Set(subjects.map((subject) => subject.toLowerCase()));
|
|
109
|
+
const tokens = query
|
|
110
|
+
.toLowerCase()
|
|
111
|
+
.replace(/[^a-z0-9\s]/g, ' ')
|
|
112
|
+
.split(/\s+/)
|
|
113
|
+
.filter((token) => token.length > 2)
|
|
114
|
+
.filter((token) => !KEYWORD_STOP_WORDS.has(token))
|
|
115
|
+
.filter((token) => !subjectSet.has(token));
|
|
116
|
+
const normalizedTokens = tokens
|
|
117
|
+
.map(normalizeKeywordToken)
|
|
118
|
+
.filter((token) => token.length > 2);
|
|
119
|
+
return [...new Set([
|
|
120
|
+
...tokens,
|
|
121
|
+
...normalizedTokens,
|
|
122
|
+
...buildKeywordBigrams(tokens),
|
|
123
|
+
...buildKeywordBigrams(normalizedTokens),
|
|
124
|
+
])];
|
|
125
|
+
}
|
|
126
|
+
function extractQueryCandidates(query) {
|
|
127
|
+
const words = query.split(/\s+/).map((word) => word.replace(/[^A-Za-z]/g, ''));
|
|
128
|
+
return words.filter((token, index) => {
|
|
129
|
+
if (!token || QUERY_STOP_WORDS.has(token))
|
|
130
|
+
return false;
|
|
131
|
+
if (!/^[A-Z][a-z]+$/.test(token))
|
|
132
|
+
return false;
|
|
133
|
+
const previous = words[index - 1] ?? '';
|
|
134
|
+
const next = words[index + 1] ?? '';
|
|
135
|
+
const previousLooksNamed = /^[A-Z][a-z]+$/.test(previous) && !QUERY_STOP_WORDS.has(previous);
|
|
136
|
+
const nextLooksNamed = /^[A-Z][a-z]+$/.test(next) && !QUERY_STOP_WORDS.has(next);
|
|
137
|
+
const isPartOfTitleCasePhrase = previousLooksNamed || nextLooksNamed;
|
|
138
|
+
return !isPartOfTitleCasePhrase;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function buildProtectedFingerprints(scoredResults) {
|
|
142
|
+
return scoredResults
|
|
143
|
+
.filter((item) => item.hasRequestedSubject && item.keywordMatches > 0)
|
|
144
|
+
.slice(0, 2)
|
|
145
|
+
.map((item) => buildTemporalFingerprint(item.result.content));
|
|
146
|
+
}
|
|
147
|
+
function buildKeywordBigrams(tokens) {
|
|
148
|
+
const bigrams = [];
|
|
149
|
+
for (let i = 0; i < tokens.length - 1; i++) {
|
|
150
|
+
if (bigrams.length >= 4)
|
|
151
|
+
break;
|
|
152
|
+
bigrams.push(`${tokens[i]} ${tokens[i + 1]}`);
|
|
153
|
+
}
|
|
154
|
+
return bigrams;
|
|
155
|
+
}
|
|
156
|
+
function shouldPenalizePlanning(content, temporalEventQuery) {
|
|
157
|
+
if (!temporalEventQuery)
|
|
158
|
+
return false;
|
|
159
|
+
const lower = content.toLowerCase();
|
|
160
|
+
return PLANNING_MARKERS.some((marker) => lower.includes(marker));
|
|
161
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supplemental extraction coverage for high-signal deterministic facts.
|
|
3
|
+
* Merges quick extractor output into the main LLM extraction result when the
|
|
4
|
+
* supplemental fact adds missing entities, relations, or temporal detail.
|
|
5
|
+
*/
|
|
6
|
+
import type { ExtractedFact } from './extraction.js';
|
|
7
|
+
export declare function mergeSupplementalFacts(primaryFacts: ExtractedFact[], conversationText: string): ExtractedFact[];
|