@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,65 @@
|
|
|
1
|
+
export class EntityAttributesRepository {
|
|
2
|
+
pool;
|
|
3
|
+
constructor(pool) {
|
|
4
|
+
this.pool = pool;
|
|
5
|
+
}
|
|
6
|
+
async bulkInsert(rows) {
|
|
7
|
+
if (rows.length === 0)
|
|
8
|
+
return 0;
|
|
9
|
+
const values = [];
|
|
10
|
+
const placeholders = [];
|
|
11
|
+
rows.forEach((r, i) => {
|
|
12
|
+
const base = i * 7;
|
|
13
|
+
placeholders.push(`($${base + 1},$${base + 2},$${base + 3},$${base + 4},$${base + 5},$${base + 6},$${base + 7})`);
|
|
14
|
+
values.push(r.userId, r.entityName, r.attributeKey, r.attributeValue, r.valueType, r.sourceMemoryId ?? null, r.observedAt ?? new Date());
|
|
15
|
+
});
|
|
16
|
+
const sql = 'INSERT INTO entity_attributes (user_id, entity_name, attribute_key, attribute_value, value_type, source_memory_id, observed_at) VALUES ' +
|
|
17
|
+
placeholders.join(',');
|
|
18
|
+
const result = await this.pool.query(sql, values);
|
|
19
|
+
return result.rowCount ?? 0;
|
|
20
|
+
}
|
|
21
|
+
/** Lookup attributes by entity name (case-insensitive). Returns most-recent first. */
|
|
22
|
+
async findByEntity(userId, entityName, limit = 20) {
|
|
23
|
+
const result = await this.pool.query(`SELECT id, user_id, entity_name, attribute_key, attribute_value, value_type,
|
|
24
|
+
source_memory_id, observed_at, created_at
|
|
25
|
+
FROM entity_attributes
|
|
26
|
+
WHERE user_id = $1 AND lower(entity_name) = lower($2)
|
|
27
|
+
ORDER BY observed_at DESC
|
|
28
|
+
LIMIT $3`, [userId, entityName, limit]);
|
|
29
|
+
return result.rows;
|
|
30
|
+
}
|
|
31
|
+
/** Lookup attributes by attribute key (case-insensitive). Useful for "how many X" queries. */
|
|
32
|
+
async findByAttribute(userId, attributeKey, limit = 20) {
|
|
33
|
+
const result = await this.pool.query(`SELECT id, user_id, entity_name, attribute_key, attribute_value, value_type,
|
|
34
|
+
source_memory_id, observed_at, created_at
|
|
35
|
+
FROM entity_attributes
|
|
36
|
+
WHERE user_id = $1 AND lower(attribute_key) = lower($2)
|
|
37
|
+
ORDER BY observed_at DESC
|
|
38
|
+
LIMIT $3`, [userId, attributeKey, limit]);
|
|
39
|
+
return result.rows;
|
|
40
|
+
}
|
|
41
|
+
/** Combined lookup: entity OR attribute matches; useful when query mentions both. */
|
|
42
|
+
async findByEntityOrAttribute(userId, tokens, limit = 20) {
|
|
43
|
+
if (tokens.length === 0)
|
|
44
|
+
return [];
|
|
45
|
+
const params = [userId];
|
|
46
|
+
const orClauses = [];
|
|
47
|
+
tokens.forEach((t) => {
|
|
48
|
+
params.push(t.toLowerCase());
|
|
49
|
+
orClauses.push(`lower(entity_name) = $${params.length} OR lower(attribute_key) = $${params.length}`);
|
|
50
|
+
});
|
|
51
|
+
params.push(limit);
|
|
52
|
+
const sql = `SELECT id, user_id, entity_name, attribute_key, attribute_value, value_type,
|
|
53
|
+
source_memory_id, observed_at, created_at
|
|
54
|
+
FROM entity_attributes
|
|
55
|
+
WHERE user_id = $1 AND (${orClauses.join(' OR ')})
|
|
56
|
+
ORDER BY observed_at DESC
|
|
57
|
+
LIMIT $${params.length}`;
|
|
58
|
+
const result = await this.pool.query(sql, params);
|
|
59
|
+
return result.rows;
|
|
60
|
+
}
|
|
61
|
+
async deleteAllForUser(userId) {
|
|
62
|
+
const result = await this.pool.query('DELETE FROM entity_attributes WHERE user_id = $1', [userId]);
|
|
63
|
+
return result.rowCount ?? 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository for entity co-occurrence graph operations.
|
|
3
|
+
* Stores pairwise entity edges per memory and supports neighbor lookups
|
|
4
|
+
* for spreading activation retrieval.
|
|
5
|
+
*/
|
|
6
|
+
import pg from 'pg';
|
|
7
|
+
export interface EntityEdge {
|
|
8
|
+
entityA: string;
|
|
9
|
+
entityB: string;
|
|
10
|
+
memoryId: string;
|
|
11
|
+
}
|
|
12
|
+
export interface NeighborResult {
|
|
13
|
+
entity: string;
|
|
14
|
+
memoryId: string;
|
|
15
|
+
}
|
|
16
|
+
/** Store pairwise entity edges for a single memory. */
|
|
17
|
+
export declare function storeEntityEdges(pool: pg.Pool, userId: string, memoryId: string, entities: string[]): Promise<number>;
|
|
18
|
+
/** Remove all entity edges for a memory (used before UPDATE/SUPERSEDE). */
|
|
19
|
+
export declare function removeEntityEdges(pool: pg.Pool, memoryId: string): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Find all neighbors of a set of entities (one hop).
|
|
22
|
+
* Returns entities connected to any seed entity, along with which memory links them.
|
|
23
|
+
*/
|
|
24
|
+
export declare function findNeighbors(pool: pg.Pool, userId: string, seedEntities: string[]): Promise<NeighborResult[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Find all memory IDs linked to a set of entities (direct lookup, no traversal).
|
|
27
|
+
* Used to score memories by accumulated activation after spreading.
|
|
28
|
+
*/
|
|
29
|
+
export declare function findMemoriesForEntities(pool: pg.Pool, userId: string, entities: string[]): Promise<Array<{
|
|
30
|
+
memoryId: string;
|
|
31
|
+
entity: string;
|
|
32
|
+
}>>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository for entity co-occurrence graph operations.
|
|
3
|
+
* Stores pairwise entity edges per memory and supports neighbor lookups
|
|
4
|
+
* for spreading activation retrieval.
|
|
5
|
+
*/
|
|
6
|
+
/** Store pairwise entity edges for a single memory. */
|
|
7
|
+
export async function storeEntityEdges(pool, userId, memoryId, entities) {
|
|
8
|
+
if (entities.length < 2)
|
|
9
|
+
return 0;
|
|
10
|
+
const pairs = buildCanonicalPairs(entities);
|
|
11
|
+
if (pairs.length === 0)
|
|
12
|
+
return 0;
|
|
13
|
+
const values = [];
|
|
14
|
+
const placeholders = [];
|
|
15
|
+
let paramIndex = 1;
|
|
16
|
+
for (const [a, b] of pairs) {
|
|
17
|
+
placeholders.push(`($${paramIndex}, $${paramIndex + 1}, $${paramIndex + 2}, $${paramIndex + 3})`);
|
|
18
|
+
values.push(userId, a, b, memoryId);
|
|
19
|
+
paramIndex += 4;
|
|
20
|
+
}
|
|
21
|
+
const sql = `
|
|
22
|
+
INSERT INTO entity_edges (user_id, entity_a, entity_b, memory_id)
|
|
23
|
+
VALUES ${placeholders.join(', ')}
|
|
24
|
+
ON CONFLICT (user_id, entity_a, entity_b, memory_id) DO NOTHING
|
|
25
|
+
`;
|
|
26
|
+
await pool.query(sql, values);
|
|
27
|
+
return pairs.length;
|
|
28
|
+
}
|
|
29
|
+
/** Remove all entity edges for a memory (used before UPDATE/SUPERSEDE). */
|
|
30
|
+
export async function removeEntityEdges(pool, memoryId) {
|
|
31
|
+
await pool.query('DELETE FROM entity_edges WHERE memory_id = $1', [memoryId]);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Find all neighbors of a set of entities (one hop).
|
|
35
|
+
* Returns entities connected to any seed entity, along with which memory links them.
|
|
36
|
+
*/
|
|
37
|
+
export async function findNeighbors(pool, userId, seedEntities) {
|
|
38
|
+
if (seedEntities.length === 0)
|
|
39
|
+
return [];
|
|
40
|
+
const result = await pool.query(`SELECT DISTINCT
|
|
41
|
+
CASE WHEN entity_a = ANY($2) THEN entity_b ELSE entity_a END AS entity,
|
|
42
|
+
e.memory_id
|
|
43
|
+
FROM entity_edges e
|
|
44
|
+
JOIN memories m ON m.id = e.memory_id AND m.deleted_at IS NULL
|
|
45
|
+
WHERE e.user_id = $1
|
|
46
|
+
AND (e.entity_a = ANY($2) OR e.entity_b = ANY($2))`, [userId, seedEntities]);
|
|
47
|
+
return result.rows;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Find all memory IDs linked to a set of entities (direct lookup, no traversal).
|
|
51
|
+
* Used to score memories by accumulated activation after spreading.
|
|
52
|
+
*/
|
|
53
|
+
export async function findMemoriesForEntities(pool, userId, entities) {
|
|
54
|
+
if (entities.length === 0)
|
|
55
|
+
return [];
|
|
56
|
+
const result = await pool.query(`SELECT DISTINCT e.memory_id AS "memoryId",
|
|
57
|
+
CASE WHEN e.entity_a = ANY($2) THEN e.entity_a ELSE e.entity_b END AS entity
|
|
58
|
+
FROM entity_edges e
|
|
59
|
+
JOIN memories m ON m.id = e.memory_id AND m.deleted_at IS NULL
|
|
60
|
+
WHERE e.user_id = $1
|
|
61
|
+
AND (e.entity_a = ANY($2) OR e.entity_b = ANY($2))`, [userId, entities]);
|
|
62
|
+
return result.rows;
|
|
63
|
+
}
|
|
64
|
+
/** Delete all entity edges for a user (used in eval cleanup). */
|
|
65
|
+
async function deleteAllEntityEdges(pool, userId) {
|
|
66
|
+
if (userId) {
|
|
67
|
+
await pool.query('DELETE FROM entity_edges WHERE user_id = $1', [userId]);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
await pool.query('TRUNCATE entity_edges CASCADE');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Build canonical pairs from entity list.
|
|
75
|
+
* Ensures entity_a < entity_b for consistent deduplication.
|
|
76
|
+
*/
|
|
77
|
+
function buildCanonicalPairs(entities) {
|
|
78
|
+
const pairs = [];
|
|
79
|
+
for (let i = 0; i < entities.length; i++) {
|
|
80
|
+
for (let j = i + 1; j < entities.length; j++) {
|
|
81
|
+
const a = entities[i];
|
|
82
|
+
const b = entities[j];
|
|
83
|
+
pairs.push(a < b ? [a, b] : [b, a]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return pairs;
|
|
87
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository for first-mention events — per-user chronological list of
|
|
3
|
+
* "the first time topic X was introduced in conversation."
|
|
4
|
+
*
|
|
5
|
+
* Distinct from atomic facts (claims) and memories (chunks). The grain
|
|
6
|
+
* matches BEAM event-ordering rubrics: which aspects did the user bring
|
|
7
|
+
* up, and in what order.
|
|
8
|
+
*
|
|
9
|
+
* Entries are produced post-ingest by FirstMentionService via a single
|
|
10
|
+
* LLM scan of the full conversation. Storage is idempotent on
|
|
11
|
+
* (user_id, memory_id) so re-running the extractor does not duplicate.
|
|
12
|
+
*/
|
|
13
|
+
import pg from 'pg';
|
|
14
|
+
export interface FirstMentionEvent {
|
|
15
|
+
topic: string;
|
|
16
|
+
turnId: number;
|
|
17
|
+
memoryId: string;
|
|
18
|
+
anchorDate: Date | null;
|
|
19
|
+
positionInConversation: number;
|
|
20
|
+
}
|
|
21
|
+
export declare class FirstMentionRepository {
|
|
22
|
+
private pool;
|
|
23
|
+
constructor(pool: pg.Pool);
|
|
24
|
+
/**
|
|
25
|
+
* Idempotent batch INSERT. Conflicts on (user_id, memory_id) are
|
|
26
|
+
* silently dropped, so re-running the extractor for the same
|
|
27
|
+
* conversation does not produce duplicate rows.
|
|
28
|
+
*/
|
|
29
|
+
store(userId: string, sourceSite: string, events: FirstMentionEvent[]): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Look up a single first-mention event by memory_id.
|
|
32
|
+
* Returns null if no event is associated with the memory.
|
|
33
|
+
*/
|
|
34
|
+
getByMemoryId(userId: string, memoryId: string): Promise<FirstMentionEvent | null>;
|
|
35
|
+
/**
|
|
36
|
+
* List all first-mention events for a user, ordered by
|
|
37
|
+
* position_in_conversation ASC. Used by EO/MSR retrieval to surface
|
|
38
|
+
* the chronological topic-introduction list to the answer generator.
|
|
39
|
+
*/
|
|
40
|
+
list(userId: string, limit?: number): Promise<FirstMentionEvent[]>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository for first-mention events — per-user chronological list of
|
|
3
|
+
* "the first time topic X was introduced in conversation."
|
|
4
|
+
*
|
|
5
|
+
* Distinct from atomic facts (claims) and memories (chunks). The grain
|
|
6
|
+
* matches BEAM event-ordering rubrics: which aspects did the user bring
|
|
7
|
+
* up, and in what order.
|
|
8
|
+
*
|
|
9
|
+
* Entries are produced post-ingest by FirstMentionService via a single
|
|
10
|
+
* LLM scan of the full conversation. Storage is idempotent on
|
|
11
|
+
* (user_id, memory_id) so re-running the extractor does not duplicate.
|
|
12
|
+
*/
|
|
13
|
+
export class FirstMentionRepository {
|
|
14
|
+
pool;
|
|
15
|
+
constructor(pool) {
|
|
16
|
+
this.pool = pool;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Idempotent batch INSERT. Conflicts on (user_id, memory_id) are
|
|
20
|
+
* silently dropped, so re-running the extractor for the same
|
|
21
|
+
* conversation does not produce duplicate rows.
|
|
22
|
+
*/
|
|
23
|
+
async store(userId, sourceSite, events) {
|
|
24
|
+
if (events.length === 0)
|
|
25
|
+
return;
|
|
26
|
+
const values = [];
|
|
27
|
+
const params = [];
|
|
28
|
+
let p = 1;
|
|
29
|
+
for (const ev of events) {
|
|
30
|
+
values.push(`($${p}, $${p + 1}, $${p + 2}, $${p + 3}, $${p + 4}, $${p + 5}, $${p + 6})`);
|
|
31
|
+
params.push(userId, ev.topic, ev.turnId, ev.memoryId, ev.anchorDate, ev.positionInConversation, sourceSite);
|
|
32
|
+
p += 7;
|
|
33
|
+
}
|
|
34
|
+
await this.pool.query(`INSERT INTO first_mention_events
|
|
35
|
+
(user_id, topic, turn_id, memory_id, anchor_date,
|
|
36
|
+
position_in_conversation, source_site)
|
|
37
|
+
VALUES ${values.join(', ')}
|
|
38
|
+
ON CONFLICT (user_id, memory_id) DO NOTHING`, params);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Look up a single first-mention event by memory_id.
|
|
42
|
+
* Returns null if no event is associated with the memory.
|
|
43
|
+
*/
|
|
44
|
+
async getByMemoryId(userId, memoryId) {
|
|
45
|
+
const result = await this.pool.query(`SELECT topic, turn_id, memory_id, anchor_date, position_in_conversation
|
|
46
|
+
FROM first_mention_events
|
|
47
|
+
WHERE user_id = $1 AND memory_id = $2
|
|
48
|
+
LIMIT 1`, [userId, memoryId]);
|
|
49
|
+
if (result.rows.length === 0)
|
|
50
|
+
return null;
|
|
51
|
+
const row = result.rows[0];
|
|
52
|
+
return {
|
|
53
|
+
topic: row.topic,
|
|
54
|
+
turnId: row.turn_id,
|
|
55
|
+
memoryId: row.memory_id,
|
|
56
|
+
anchorDate: row.anchor_date,
|
|
57
|
+
positionInConversation: row.position_in_conversation,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* List all first-mention events for a user, ordered by
|
|
62
|
+
* position_in_conversation ASC. Used by EO/MSR retrieval to surface
|
|
63
|
+
* the chronological topic-introduction list to the answer generator.
|
|
64
|
+
*/
|
|
65
|
+
async list(userId, limit = 100) {
|
|
66
|
+
const result = await this.pool.query(`SELECT topic, turn_id, memory_id, anchor_date, position_in_conversation
|
|
67
|
+
FROM first_mention_events
|
|
68
|
+
WHERE user_id = $1
|
|
69
|
+
ORDER BY position_in_conversation ASC
|
|
70
|
+
LIMIT $2`, [userId, limit]);
|
|
71
|
+
return result.rows.map((row) => ({
|
|
72
|
+
topic: row.topic,
|
|
73
|
+
turnId: row.turn_id,
|
|
74
|
+
memoryId: row.memory_id,
|
|
75
|
+
anchorDate: row.anchor_date,
|
|
76
|
+
positionInConversation: row.position_in_conversation,
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lesson repository — CRUD and similarity search for detected failure patterns.
|
|
3
|
+
*
|
|
4
|
+
* Lessons capture attack/failure patterns from sanitization blocks, trust
|
|
5
|
+
* violations, contradictions, and user reports. Pre-retrieval checks query
|
|
6
|
+
* lessons by embedding similarity to block known-bad patterns before they
|
|
7
|
+
* reach the user.
|
|
8
|
+
*
|
|
9
|
+
* Phase 6 (A-MemGuard): self-reinforcing defense via pattern accumulation.
|
|
10
|
+
*/
|
|
11
|
+
import pg from 'pg';
|
|
12
|
+
export type LessonType = 'injection_blocked' | 'false_memory' | 'contradiction_pattern' | 'user_reported' | 'consensus_violation' | 'trust_violation';
|
|
13
|
+
export type LessonSeverity = 'low' | 'medium' | 'high' | 'critical';
|
|
14
|
+
export interface LessonRow {
|
|
15
|
+
id: string;
|
|
16
|
+
user_id: string;
|
|
17
|
+
lesson_type: LessonType;
|
|
18
|
+
pattern: string;
|
|
19
|
+
embedding: number[];
|
|
20
|
+
source_memory_ids: string[];
|
|
21
|
+
source_query: string | null;
|
|
22
|
+
severity: LessonSeverity;
|
|
23
|
+
active: boolean;
|
|
24
|
+
metadata: Record<string, unknown>;
|
|
25
|
+
created_at: Date;
|
|
26
|
+
}
|
|
27
|
+
export interface CreateLessonInput {
|
|
28
|
+
userId: string;
|
|
29
|
+
lessonType: LessonType;
|
|
30
|
+
pattern: string;
|
|
31
|
+
embedding: number[];
|
|
32
|
+
sourceMemoryIds?: string[];
|
|
33
|
+
sourceQuery?: string;
|
|
34
|
+
severity?: LessonSeverity;
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export interface LessonMatch {
|
|
38
|
+
lesson: LessonRow;
|
|
39
|
+
similarity: number;
|
|
40
|
+
}
|
|
41
|
+
export declare class LessonRepository {
|
|
42
|
+
private pool;
|
|
43
|
+
constructor(pool: pg.Pool);
|
|
44
|
+
createLesson(input: CreateLessonInput): Promise<string>;
|
|
45
|
+
findSimilarLessons(userId: string, embedding: number[], threshold: number, limit?: number): Promise<LessonMatch[]>;
|
|
46
|
+
getLessonsByUser(userId: string, activeOnly?: boolean): Promise<LessonRow[]>;
|
|
47
|
+
getLessonsByType(userId: string, lessonType: LessonType): Promise<LessonRow[]>;
|
|
48
|
+
deactivateLesson(userId: string, lessonId: string): Promise<void>;
|
|
49
|
+
countActiveLessons(userId: string): Promise<number>;
|
|
50
|
+
deleteAll(): Promise<void>;
|
|
51
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lesson repository — CRUD and similarity search for detected failure patterns.
|
|
3
|
+
*
|
|
4
|
+
* Lessons capture attack/failure patterns from sanitization blocks, trust
|
|
5
|
+
* violations, contradictions, and user reports. Pre-retrieval checks query
|
|
6
|
+
* lessons by embedding similarity to block known-bad patterns before they
|
|
7
|
+
* reach the user.
|
|
8
|
+
*
|
|
9
|
+
* Phase 6 (A-MemGuard): self-reinforcing defense via pattern accumulation.
|
|
10
|
+
*/
|
|
11
|
+
import pgvector from 'pgvector/pg';
|
|
12
|
+
import { config } from '../config.js';
|
|
13
|
+
export class LessonRepository {
|
|
14
|
+
pool;
|
|
15
|
+
constructor(pool) {
|
|
16
|
+
this.pool = pool;
|
|
17
|
+
}
|
|
18
|
+
async createLesson(input) {
|
|
19
|
+
const result = await this.pool.query(`INSERT INTO lessons (user_id, lesson_type, pattern, embedding, source_memory_ids, source_query, severity, metadata)
|
|
20
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
21
|
+
RETURNING id`, [
|
|
22
|
+
input.userId,
|
|
23
|
+
input.lessonType,
|
|
24
|
+
input.pattern,
|
|
25
|
+
pgvector.toSql(input.embedding),
|
|
26
|
+
input.sourceMemoryIds ?? [],
|
|
27
|
+
input.sourceQuery ?? null,
|
|
28
|
+
input.severity ?? 'medium',
|
|
29
|
+
JSON.stringify(input.metadata ?? {}),
|
|
30
|
+
]);
|
|
31
|
+
return result.rows[0].id;
|
|
32
|
+
}
|
|
33
|
+
async findSimilarLessons(userId, embedding, threshold, limit = 5) {
|
|
34
|
+
const result = await this.pool.query(`SELECT *, 1 - (embedding <=> $1) AS similarity
|
|
35
|
+
FROM lessons
|
|
36
|
+
WHERE user_id = $2 AND active = true
|
|
37
|
+
AND 1 - (embedding <=> $1) >= $3
|
|
38
|
+
ORDER BY similarity DESC
|
|
39
|
+
LIMIT $4`, [pgvector.toSql(embedding), userId, threshold, limit]);
|
|
40
|
+
return result.rows.map((row) => ({
|
|
41
|
+
lesson: parseRow(row),
|
|
42
|
+
similarity: parseFloat(row.similarity),
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
async getLessonsByUser(userId, activeOnly = true) {
|
|
46
|
+
const activeClause = activeOnly ? 'AND active = true' : '';
|
|
47
|
+
const result = await this.pool.query(`SELECT * FROM lessons WHERE user_id = $1 ${activeClause} ORDER BY created_at DESC`, [userId]);
|
|
48
|
+
return result.rows.map(parseRow);
|
|
49
|
+
}
|
|
50
|
+
async getLessonsByType(userId, lessonType) {
|
|
51
|
+
const result = await this.pool.query(`SELECT * FROM lessons WHERE user_id = $1 AND lesson_type = $2 AND active = true ORDER BY created_at DESC`, [userId, lessonType]);
|
|
52
|
+
return result.rows.map(parseRow);
|
|
53
|
+
}
|
|
54
|
+
async deactivateLesson(userId, lessonId) {
|
|
55
|
+
await this.pool.query(`UPDATE lessons SET active = false WHERE id = $1 AND user_id = $2`, [lessonId, userId]);
|
|
56
|
+
}
|
|
57
|
+
async countActiveLessons(userId) {
|
|
58
|
+
const result = await this.pool.query(`SELECT COUNT(*)::int AS count FROM lessons WHERE user_id = $1 AND active = true`, [userId]);
|
|
59
|
+
return result.rows[0].count;
|
|
60
|
+
}
|
|
61
|
+
async deleteAll() {
|
|
62
|
+
await this.pool.query('DELETE FROM lessons');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function parseRow(row) {
|
|
66
|
+
const rawEmb = row.embedding;
|
|
67
|
+
let embedding;
|
|
68
|
+
if (typeof rawEmb === 'string') {
|
|
69
|
+
embedding = rawEmb.replace(/[\[\]]/g, '').split(',').map(Number);
|
|
70
|
+
}
|
|
71
|
+
else if (Array.isArray(rawEmb)) {
|
|
72
|
+
embedding = rawEmb;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
embedding = Array(config.embeddingDimensions).fill(0);
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
id: row.id,
|
|
79
|
+
user_id: row.user_id,
|
|
80
|
+
lesson_type: row.lesson_type,
|
|
81
|
+
pattern: row.pattern,
|
|
82
|
+
embedding,
|
|
83
|
+
source_memory_ids: row.source_memory_ids ?? [],
|
|
84
|
+
source_query: row.source_query ?? null,
|
|
85
|
+
severity: row.severity,
|
|
86
|
+
active: row.active,
|
|
87
|
+
metadata: (typeof row.metadata === 'string' ? JSON.parse(row.metadata) : row.metadata ?? {}),
|
|
88
|
+
created_at: row.created_at,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory link storage and 1-hop traversal queries.
|
|
3
|
+
*
|
|
4
|
+
* Links are bidirectional pairs stored with source_id < target_id to avoid
|
|
5
|
+
* duplicates. Generated at write time when embedding similarity exceeds the
|
|
6
|
+
* configured threshold (Phase 2 roadmap, A-MEM pattern).
|
|
7
|
+
*/
|
|
8
|
+
import pg from 'pg';
|
|
9
|
+
import { type SearchResult } from './repository-types.js';
|
|
10
|
+
export interface MemoryLink {
|
|
11
|
+
sourceId: string;
|
|
12
|
+
targetId: string;
|
|
13
|
+
similarity: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function createLinks(pool: pg.Pool, links: MemoryLink[]): Promise<number>;
|
|
16
|
+
export declare function findLinkedMemoryIds(pool: pg.Pool, memoryIds: string[], excludeIds: Set<string>, limit: number): Promise<string[]>;
|
|
17
|
+
export declare function fetchMemoriesByIds(pool: pg.Pool, userId: string, ids: string[], queryEmbedding: number[], referenceTime?: Date, includeExpired?: boolean): Promise<SearchResult[]>;
|
|
18
|
+
export declare function findLinkCandidates(pool: pg.Pool, userId: string, embedding: number[], threshold: number, excludeId: string, limit: number): Promise<Array<{
|
|
19
|
+
id: string;
|
|
20
|
+
similarity: number;
|
|
21
|
+
}>>;
|
|
22
|
+
export declare function findLinkCandidatesWithClient(client: pg.PoolClient, userId: string, embedding: number[], threshold: number, excludeId: string, limit: number): Promise<Array<{
|
|
23
|
+
id: string;
|
|
24
|
+
similarity: number;
|
|
25
|
+
}>>;
|
|
26
|
+
export declare function countLinks(pool: pg.Pool): Promise<number>;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory link storage and 1-hop traversal queries.
|
|
3
|
+
*
|
|
4
|
+
* Links are bidirectional pairs stored with source_id < target_id to avoid
|
|
5
|
+
* duplicates. Generated at write time when embedding similarity exceeds the
|
|
6
|
+
* configured threshold (Phase 2 roadmap, A-MEM pattern).
|
|
7
|
+
*/
|
|
8
|
+
import pgvector from 'pgvector/pg';
|
|
9
|
+
import { config } from '../config.js';
|
|
10
|
+
import { normalizeSearchRow } from './repository-types.js';
|
|
11
|
+
export async function createLinks(pool, links) {
|
|
12
|
+
return createLinksWithClient(pool, links);
|
|
13
|
+
}
|
|
14
|
+
async function createLinksWithClient(client, links) {
|
|
15
|
+
if (links.length === 0)
|
|
16
|
+
return 0;
|
|
17
|
+
const deduped = new Map();
|
|
18
|
+
for (const link of links) {
|
|
19
|
+
const [lo, hi] = canonicalPair(link.sourceId, link.targetId);
|
|
20
|
+
const key = `${lo}:${hi}`;
|
|
21
|
+
const existing = deduped.get(key);
|
|
22
|
+
if (!existing || link.similarity > existing.similarity) {
|
|
23
|
+
deduped.set(key, { lo, hi, similarity: link.similarity });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const values = [];
|
|
27
|
+
const params = [];
|
|
28
|
+
for (const { lo, hi, similarity } of deduped.values()) {
|
|
29
|
+
const offset = params.length;
|
|
30
|
+
values.push(`($${offset + 1}, $${offset + 2}, $${offset + 3})`);
|
|
31
|
+
params.push(lo, hi, similarity);
|
|
32
|
+
}
|
|
33
|
+
const result = await client.query(`INSERT INTO memory_links (source_id, target_id, similarity)
|
|
34
|
+
VALUES ${values.join(', ')}
|
|
35
|
+
ON CONFLICT (source_id, target_id)
|
|
36
|
+
DO UPDATE SET similarity = EXCLUDED.similarity
|
|
37
|
+
RETURNING source_id`, params);
|
|
38
|
+
return result.rowCount ?? 0;
|
|
39
|
+
}
|
|
40
|
+
export async function findLinkedMemoryIds(pool, memoryIds, excludeIds, limit) {
|
|
41
|
+
if (memoryIds.length === 0)
|
|
42
|
+
return [];
|
|
43
|
+
const result = await pool.query(`SELECT DISTINCT links.linked_id, links.similarity FROM (
|
|
44
|
+
SELECT target_id AS linked_id, similarity
|
|
45
|
+
FROM memory_links WHERE source_id = ANY($1)
|
|
46
|
+
UNION ALL
|
|
47
|
+
SELECT source_id AS linked_id, similarity
|
|
48
|
+
FROM memory_links WHERE target_id = ANY($1)
|
|
49
|
+
) AS links
|
|
50
|
+
JOIN memories m ON m.id = links.linked_id AND m.workspace_id IS NULL
|
|
51
|
+
ORDER BY links.similarity DESC
|
|
52
|
+
LIMIT $2`, [memoryIds, limit * 2]);
|
|
53
|
+
return result.rows
|
|
54
|
+
.map((row) => row.linked_id)
|
|
55
|
+
.filter((id) => !excludeIds.has(id))
|
|
56
|
+
.slice(0, limit);
|
|
57
|
+
}
|
|
58
|
+
export async function fetchMemoriesByIds(pool, userId, ids, queryEmbedding, referenceTime, includeExpired = false) {
|
|
59
|
+
if (ids.length === 0)
|
|
60
|
+
return [];
|
|
61
|
+
const wSim = config.scoringWeightSimilarity;
|
|
62
|
+
const wImp = config.scoringWeightImportance;
|
|
63
|
+
const wRec = config.scoringWeightRecency;
|
|
64
|
+
const refTime = (referenceTime ?? new Date()).toISOString();
|
|
65
|
+
const expiredClause = includeExpired ? '' : 'AND expired_at IS NULL';
|
|
66
|
+
const result = await pool.query(`SELECT *,
|
|
67
|
+
1 - (embedding <=> $1) AS similarity,
|
|
68
|
+
(
|
|
69
|
+
$4 * (1 - (embedding <=> $1))
|
|
70
|
+
+ $5 * importance
|
|
71
|
+
+ $6 * EXP(-EXTRACT(EPOCH FROM ($7::timestamptz - last_accessed_at)) / 2592000.0)
|
|
72
|
+
) * COALESCE(trust_score, 1.0) AS score
|
|
73
|
+
FROM memories
|
|
74
|
+
WHERE id = ANY($2)
|
|
75
|
+
AND user_id = $3
|
|
76
|
+
AND deleted_at IS NULL
|
|
77
|
+
${expiredClause}
|
|
78
|
+
AND status = 'active'
|
|
79
|
+
AND workspace_id IS NULL
|
|
80
|
+
ORDER BY score DESC`, [pgvector.toSql(queryEmbedding), ids, userId, wSim, wImp, wRec, refTime]);
|
|
81
|
+
return result.rows.map(normalizeSearchRow);
|
|
82
|
+
}
|
|
83
|
+
export async function findLinkCandidates(pool, userId, embedding, threshold, excludeId, limit) {
|
|
84
|
+
return findLinkCandidatesWithClient(pool, userId, embedding, threshold, excludeId, limit);
|
|
85
|
+
}
|
|
86
|
+
export async function findLinkCandidatesWithClient(client, userId, embedding, threshold, excludeId, limit) {
|
|
87
|
+
const result = await client.query(`SELECT id, 1 - (embedding <=> $1) AS similarity
|
|
88
|
+
FROM memories
|
|
89
|
+
WHERE user_id = $2
|
|
90
|
+
AND deleted_at IS NULL
|
|
91
|
+
AND expired_at IS NULL
|
|
92
|
+
AND status = 'active'
|
|
93
|
+
AND id != $3
|
|
94
|
+
AND 1 - (embedding <=> $1) > $4
|
|
95
|
+
ORDER BY similarity DESC
|
|
96
|
+
LIMIT $5`, [pgvector.toSql(embedding), userId, excludeId, threshold, limit]);
|
|
97
|
+
return result.rows;
|
|
98
|
+
}
|
|
99
|
+
export async function countLinks(pool) {
|
|
100
|
+
const result = await pool.query('SELECT COUNT(*)::int AS count FROM memory_links');
|
|
101
|
+
return result.rows[0].count;
|
|
102
|
+
}
|
|
103
|
+
function canonicalPair(a, b) {
|
|
104
|
+
return a < b ? [a, b] : [b, a];
|
|
105
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository for observation network dirty-marking and regeneration queries.
|
|
3
|
+
* Observations are synthesized entity profiles — regenerated asynchronously
|
|
4
|
+
* when new facts about an entity are ingested.
|
|
5
|
+
*/
|
|
6
|
+
import pg from 'pg';
|
|
7
|
+
export declare class ObservationRepository {
|
|
8
|
+
private pool;
|
|
9
|
+
constructor(pool: pg.Pool);
|
|
10
|
+
/** Mark entity subjects as needing observation regeneration. Idempotent. */
|
|
11
|
+
markDirty(userId: string, subjects: string[]): Promise<void>;
|
|
12
|
+
/** Get all pending observation regeneration tasks. */
|
|
13
|
+
getPending(limit?: number): Promise<Array<{
|
|
14
|
+
userId: string;
|
|
15
|
+
subject: string;
|
|
16
|
+
}>>;
|
|
17
|
+
/** Clear a dirty mark after successful regeneration. */
|
|
18
|
+
clearDirty(userId: string, subject: string): Promise<void>;
|
|
19
|
+
/** Find all memory content linked to a subject entity for synthesis. */
|
|
20
|
+
findMemoriesForSubject(userId: string, subject: string): Promise<Array<{
|
|
21
|
+
id: string;
|
|
22
|
+
content: string;
|
|
23
|
+
}>>;
|
|
24
|
+
/** Find the existing observation for a subject (to expire it on regeneration). */
|
|
25
|
+
findExistingObservation(userId: string, subject: string): Promise<string | null>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository for observation network dirty-marking and regeneration queries.
|
|
3
|
+
* Observations are synthesized entity profiles — regenerated asynchronously
|
|
4
|
+
* when new facts about an entity are ingested.
|
|
5
|
+
*/
|
|
6
|
+
export class ObservationRepository {
|
|
7
|
+
pool;
|
|
8
|
+
constructor(pool) {
|
|
9
|
+
this.pool = pool;
|
|
10
|
+
}
|
|
11
|
+
/** Mark entity subjects as needing observation regeneration. Idempotent. */
|
|
12
|
+
async markDirty(userId, subjects) {
|
|
13
|
+
if (subjects.length === 0)
|
|
14
|
+
return;
|
|
15
|
+
const values = subjects.map((_, i) => `($1, $${i + 2}, NOW())`).join(', ');
|
|
16
|
+
await this.pool.query(`INSERT INTO observation_dirty (user_id, subject, marked_at) VALUES ${values}
|
|
17
|
+
ON CONFLICT (user_id, subject) DO UPDATE SET marked_at = NOW()`, [userId, ...subjects]);
|
|
18
|
+
}
|
|
19
|
+
/** Get all pending observation regeneration tasks. */
|
|
20
|
+
async getPending(limit = 50) {
|
|
21
|
+
const result = await this.pool.query(`SELECT user_id, subject FROM observation_dirty ORDER BY marked_at ASC LIMIT $1`, [limit]);
|
|
22
|
+
return result.rows.map((r) => ({ userId: r.user_id, subject: r.subject }));
|
|
23
|
+
}
|
|
24
|
+
/** Clear a dirty mark after successful regeneration. */
|
|
25
|
+
async clearDirty(userId, subject) {
|
|
26
|
+
await this.pool.query(`DELETE FROM observation_dirty WHERE user_id = $1 AND subject = $2`, [userId, subject]);
|
|
27
|
+
}
|
|
28
|
+
/** Find all memory content linked to a subject entity for synthesis. */
|
|
29
|
+
async findMemoriesForSubject(userId, subject) {
|
|
30
|
+
const result = await this.pool.query(`SELECT DISTINCT m.id, m.content, m.created_at
|
|
31
|
+
FROM memories m
|
|
32
|
+
JOIN memory_entities me ON me.memory_id = m.id
|
|
33
|
+
JOIN entities e ON e.id = me.entity_id
|
|
34
|
+
WHERE m.user_id = $1
|
|
35
|
+
AND (e.name ILIKE $2 OR $2 = ANY(e.alias_names))
|
|
36
|
+
AND m.deleted_at IS NULL AND m.expired_at IS NULL
|
|
37
|
+
AND m.network != 'observation'
|
|
38
|
+
ORDER BY m.created_at DESC
|
|
39
|
+
LIMIT 50`, [userId, subject]);
|
|
40
|
+
return result.rows;
|
|
41
|
+
}
|
|
42
|
+
/** Find the existing observation for a subject (to expire it on regeneration). */
|
|
43
|
+
async findExistingObservation(userId, subject) {
|
|
44
|
+
const result = await this.pool.query(`SELECT id FROM memories
|
|
45
|
+
WHERE user_id = $1 AND network = 'observation'
|
|
46
|
+
AND observation_subject = $2
|
|
47
|
+
AND deleted_at IS NULL AND expired_at IS NULL
|
|
48
|
+
LIMIT 1`, [userId, subject]);
|
|
49
|
+
return result.rows[0]?.id ?? null;
|
|
50
|
+
}
|
|
51
|
+
}
|