@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,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lesson detection and pre-retrieval defense service.
|
|
3
|
+
*
|
|
4
|
+
* Implements A-MemGuard's self-reinforcing defense:
|
|
5
|
+
* 1. Detect failure patterns during ingest (sanitizer blocks, trust violations,
|
|
6
|
+
* high-confidence contradictions) and store as lessons.
|
|
7
|
+
* 2. Before retrieval, check query against known lessons to warn or block.
|
|
8
|
+
*
|
|
9
|
+
* Phase 6 security layer — builds on Phase 3 trust scoring and sanitization.
|
|
10
|
+
*/
|
|
11
|
+
import { embedText } from './embedding.js';
|
|
12
|
+
import { emitAuditEvent } from './audit-events.js';
|
|
13
|
+
import { config } from '../config.js';
|
|
14
|
+
const LESSON_SIMILARITY_THRESHOLD = 0.75;
|
|
15
|
+
const LESSON_CHECK_LIMIT = 3;
|
|
16
|
+
/**
|
|
17
|
+
* Check a query against known lessons before returning retrieval results.
|
|
18
|
+
* Returns warnings for medium/high severity, blocks on critical.
|
|
19
|
+
*/
|
|
20
|
+
export async function checkLessons(repo, userId, query) {
|
|
21
|
+
const embedding = await embedText(query);
|
|
22
|
+
const matches = await repo.findSimilarLessons(userId, embedding, LESSON_SIMILARITY_THRESHOLD, LESSON_CHECK_LIMIT);
|
|
23
|
+
if (matches.length === 0) {
|
|
24
|
+
return { safe: true, matchedLessons: [], warnings: [], highestSeverity: 'none' };
|
|
25
|
+
}
|
|
26
|
+
const warnings = matches.map((m) => formatLessonWarning(m));
|
|
27
|
+
const highestSeverity = resolveHighestSeverity(matches.map((m) => m.lesson.severity));
|
|
28
|
+
const safe = highestSeverity !== 'critical';
|
|
29
|
+
if (config.auditLoggingEnabled) {
|
|
30
|
+
emitAuditEvent('lesson:match', userId, {
|
|
31
|
+
query: query.slice(0, 200),
|
|
32
|
+
matchCount: matches.length,
|
|
33
|
+
highestSeverity,
|
|
34
|
+
safe,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return { safe, matchedLessons: matches, warnings, highestSeverity };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Detect and store a lesson from a sanitization block.
|
|
41
|
+
* Called when input sanitizer catches an injection attempt.
|
|
42
|
+
*/
|
|
43
|
+
export async function recordInjectionLesson(repo, ctx) {
|
|
44
|
+
if (!ctx.sanitizationResult || ctx.sanitizationResult.passed)
|
|
45
|
+
return null;
|
|
46
|
+
const blockFindings = ctx.sanitizationResult.findings.filter((f) => f.severity === 'block');
|
|
47
|
+
if (blockFindings.length === 0)
|
|
48
|
+
return null;
|
|
49
|
+
const pattern = buildInjectionPattern(ctx.content, blockFindings);
|
|
50
|
+
const embedding = await embedText(pattern);
|
|
51
|
+
const severity = blockFindings.length >= 3 ? 'critical' : 'high';
|
|
52
|
+
const lessonId = await repo.createLesson({
|
|
53
|
+
userId: ctx.userId,
|
|
54
|
+
lessonType: 'injection_blocked',
|
|
55
|
+
pattern,
|
|
56
|
+
embedding,
|
|
57
|
+
severity,
|
|
58
|
+
metadata: {
|
|
59
|
+
sourceSite: ctx.sourceSite,
|
|
60
|
+
findingCount: blockFindings.length,
|
|
61
|
+
rules: blockFindings.map((f) => f.rule),
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
emitLessonAuditEvent(ctx.userId, 'injection_blocked', lessonId, severity);
|
|
65
|
+
return lessonId;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Detect and store a lesson from a trust score violation.
|
|
69
|
+
* Called when a fact is rejected for being below the trust threshold.
|
|
70
|
+
*/
|
|
71
|
+
export async function recordTrustViolationLesson(repo, ctx) {
|
|
72
|
+
if (ctx.trustScore === undefined || ctx.trustScore >= config.trustScoreMinThreshold)
|
|
73
|
+
return null;
|
|
74
|
+
const pattern = `Low-trust content from ${ctx.sourceSite}: "${ctx.content.slice(0, 200)}"`;
|
|
75
|
+
const embedding = await embedText(pattern);
|
|
76
|
+
const lessonId = await repo.createLesson({
|
|
77
|
+
userId: ctx.userId,
|
|
78
|
+
lessonType: 'trust_violation',
|
|
79
|
+
pattern,
|
|
80
|
+
embedding,
|
|
81
|
+
severity: ctx.trustScore < 0.1 ? 'high' : 'medium',
|
|
82
|
+
metadata: {
|
|
83
|
+
sourceSite: ctx.sourceSite,
|
|
84
|
+
trustScore: ctx.trustScore,
|
|
85
|
+
threshold: config.trustScoreMinThreshold,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
emitLessonAuditEvent(ctx.userId, 'trust_violation', lessonId, 'medium');
|
|
89
|
+
return lessonId;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Detect and store a lesson from a high-confidence contradiction.
|
|
93
|
+
* Called when SUPERSEDE or DELETE fires with high contradiction confidence.
|
|
94
|
+
*/
|
|
95
|
+
export async function recordContradictionLesson(repo, ctx) {
|
|
96
|
+
if (!ctx.contradictionConfidence || ctx.contradictionConfidence < 0.8)
|
|
97
|
+
return null;
|
|
98
|
+
const pattern = `High-confidence contradiction (${ctx.contradictionConfidence.toFixed(2)}): "${ctx.content.slice(0, 200)}"`;
|
|
99
|
+
const embedding = await embedText(pattern);
|
|
100
|
+
const lessonId = await repo.createLesson({
|
|
101
|
+
userId: ctx.userId,
|
|
102
|
+
lessonType: 'contradiction_pattern',
|
|
103
|
+
pattern,
|
|
104
|
+
embedding,
|
|
105
|
+
sourceMemoryIds: ctx.supersededMemoryId ? [ctx.supersededMemoryId] : [],
|
|
106
|
+
severity: 'medium',
|
|
107
|
+
metadata: {
|
|
108
|
+
contradictionConfidence: ctx.contradictionConfidence,
|
|
109
|
+
supersededMemoryId: ctx.supersededMemoryId,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
emitLessonAuditEvent(ctx.userId, 'contradiction_pattern', lessonId, 'medium');
|
|
113
|
+
return lessonId;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Record a user-reported lesson (explicit feedback that a memory was wrong).
|
|
117
|
+
*/
|
|
118
|
+
export async function recordUserReportedLesson(repo, userId, pattern, sourceMemoryIds, severity = 'high') {
|
|
119
|
+
const embedding = await embedText(pattern);
|
|
120
|
+
const lessonId = await repo.createLesson({
|
|
121
|
+
userId,
|
|
122
|
+
lessonType: 'user_reported',
|
|
123
|
+
pattern,
|
|
124
|
+
embedding,
|
|
125
|
+
sourceMemoryIds,
|
|
126
|
+
severity,
|
|
127
|
+
});
|
|
128
|
+
emitLessonAuditEvent(userId, 'user_reported', lessonId, severity);
|
|
129
|
+
return lessonId;
|
|
130
|
+
}
|
|
131
|
+
/** Get all active lessons for a user. */
|
|
132
|
+
export async function getUserLessons(repo, userId) {
|
|
133
|
+
return repo.getLessonsByUser(userId);
|
|
134
|
+
}
|
|
135
|
+
/** Get lesson stats for a user. */
|
|
136
|
+
export async function getLessonStats(repo, userId) {
|
|
137
|
+
const lessons = await repo.getLessonsByUser(userId);
|
|
138
|
+
const byType = {};
|
|
139
|
+
for (const lesson of lessons) {
|
|
140
|
+
byType[lesson.lesson_type] = (byType[lesson.lesson_type] ?? 0) + 1;
|
|
141
|
+
}
|
|
142
|
+
return { totalActive: lessons.length, byType };
|
|
143
|
+
}
|
|
144
|
+
function formatLessonWarning(match) {
|
|
145
|
+
return `[${match.lesson.severity}] ${match.lesson.lesson_type}: ${match.lesson.pattern.slice(0, 100)} (similarity: ${match.similarity.toFixed(2)})`;
|
|
146
|
+
}
|
|
147
|
+
function resolveHighestSeverity(severities) {
|
|
148
|
+
const order = ['low', 'medium', 'high', 'critical'];
|
|
149
|
+
let highest = 0;
|
|
150
|
+
for (const s of severities) {
|
|
151
|
+
const idx = order.indexOf(s);
|
|
152
|
+
if (idx > highest)
|
|
153
|
+
highest = idx;
|
|
154
|
+
}
|
|
155
|
+
return order[highest];
|
|
156
|
+
}
|
|
157
|
+
function buildInjectionPattern(content, findings) {
|
|
158
|
+
const rules = findings.map((f) => f.rule).join(', ');
|
|
159
|
+
return `Injection attempt blocked (${rules}): "${content.slice(0, 200)}"`;
|
|
160
|
+
}
|
|
161
|
+
function emitLessonAuditEvent(userId, lessonType, lessonId, severity) {
|
|
162
|
+
if (!config.auditLoggingEnabled)
|
|
163
|
+
return;
|
|
164
|
+
emitAuditEvent('lesson:created', userId, { lessonType, severity }, { lessonId });
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Record lessons for memories removed by consensus validation.
|
|
168
|
+
* Creates a `consensus_violation` lesson for each divergent memory.
|
|
169
|
+
*/
|
|
170
|
+
export async function recordConsensusLessons(lessons, userId, result, memories) {
|
|
171
|
+
for (const judgment of result.judgments) {
|
|
172
|
+
if (judgment.aligned)
|
|
173
|
+
continue;
|
|
174
|
+
const memory = memories.find((m) => m.id === judgment.memoryId);
|
|
175
|
+
const pattern = `Consensus violation: "${memory?.content.slice(0, 150) ?? judgment.memoryId}" — ${judgment.divergenceReason}`;
|
|
176
|
+
await recordUserReportedLesson(lessons, userId, pattern, [judgment.memoryId], 'medium');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EntityValuesRepository } from '../db/entity-values-repository.js';
|
|
2
|
+
export interface LiteralExtractorDeps {
|
|
3
|
+
values: EntityValuesRepository;
|
|
4
|
+
model: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ExtractInput {
|
|
7
|
+
userId: string;
|
|
8
|
+
factId: string;
|
|
9
|
+
factText: string;
|
|
10
|
+
observedAt: Date;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Extract literal (entity, attribute, value) triples from a single fact text
|
|
14
|
+
* and persist them to entity_values. Returns the count of triples inserted.
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractLiteralsFromFact(deps: LiteralExtractorDeps, input: ExtractInput): Promise<number>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ingest-side literal-value extractor.
|
|
3
|
+
*
|
|
4
|
+
* For each new fact, calls Haiku with tool-use to extract zero or more
|
|
5
|
+
* (entity, attribute, value, value_type) triples. Persists them to the
|
|
6
|
+
* entity_values table.
|
|
7
|
+
*
|
|
8
|
+
* The extractor errs on the side of NOT extracting — only literals that
|
|
9
|
+
* clearly map to "what is the X" / "when does X" / "how many X" question
|
|
10
|
+
* shapes are persisted. Narrative facts without a clean entity/attribute
|
|
11
|
+
* structure are skipped.
|
|
12
|
+
*/
|
|
13
|
+
import { callAnthropicTool } from './llm.js';
|
|
14
|
+
const EXTRACT_TOOL_SCHEMA = {
|
|
15
|
+
name: 'extract_literal_triples',
|
|
16
|
+
description: 'Extract structured (entity, attribute, value) triples from a fact, if any.',
|
|
17
|
+
input_schema: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {
|
|
20
|
+
triples: {
|
|
21
|
+
type: 'array',
|
|
22
|
+
items: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
required: ['entity', 'attribute', 'value', 'value_type'],
|
|
25
|
+
properties: {
|
|
26
|
+
entity: { type: 'string', description: 'The subject. e.g. "first sprint", "API key", "test coverage"' },
|
|
27
|
+
attribute: { type: 'string', description: 'The relation. e.g. "end date", "daily quota", "percentage"' },
|
|
28
|
+
value: { type: 'string', description: 'LITERAL value AS IT APPEARS in the fact. Do not paraphrase.' },
|
|
29
|
+
value_type: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
enum: ['date', 'number', 'string', 'duration', 'list'],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: ['triples'],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
const EXTRACTOR_SYSTEM = `You are extracting (entity, attribute, value) triples from a single user fact.
|
|
41
|
+
|
|
42
|
+
Output triples ONLY when the fact contains a clean structured claim like:
|
|
43
|
+
- "first sprint ends March 29" → (first sprint, end date, March 29, date)
|
|
44
|
+
- "API key has 1,200 daily calls" → (API key, daily quota, 1,200 calls per day, number)
|
|
45
|
+
- "test coverage is 78%" → (test coverage, percentage, 78%, number)
|
|
46
|
+
- "uses vanilla JavaScript ES2021" → (project, technology, vanilla JavaScript ES2021, string)
|
|
47
|
+
|
|
48
|
+
Skip facts that are narrative ("the user decided to..."), opinions, or vague.
|
|
49
|
+
|
|
50
|
+
CRITICAL: the value field must be the LITERAL string from the fact. Do not paraphrase. "1,200 calls per day" not "around 1000 calls". "March 29" not "end of March". "78%" not "high coverage".
|
|
51
|
+
|
|
52
|
+
Call extract_literal_triples. If no triples, return an empty array.`;
|
|
53
|
+
/**
|
|
54
|
+
* Extract literal (entity, attribute, value) triples from a single fact text
|
|
55
|
+
* and persist them to entity_values. Returns the count of triples inserted.
|
|
56
|
+
*/
|
|
57
|
+
export async function extractLiteralsFromFact(deps, input) {
|
|
58
|
+
if (!input.factText.trim())
|
|
59
|
+
return 0;
|
|
60
|
+
const result = await callAnthropicTool(deps.model, EXTRACTOR_SYSTEM, `Fact: ${input.factText}`, EXTRACT_TOOL_SCHEMA);
|
|
61
|
+
if (result.triples.length === 0)
|
|
62
|
+
return 0;
|
|
63
|
+
const rows = result.triples.map(t => ({
|
|
64
|
+
userId: input.userId,
|
|
65
|
+
entity: t.entity,
|
|
66
|
+
attribute: t.attribute,
|
|
67
|
+
value: t.value,
|
|
68
|
+
valueType: t.value_type,
|
|
69
|
+
observedAt: input.observedAt,
|
|
70
|
+
factId: input.factId,
|
|
71
|
+
}));
|
|
72
|
+
await deps.values.insertMany(rows);
|
|
73
|
+
return rows.length;
|
|
74
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protect literal list-answer candidates from late-stage diversity selection.
|
|
3
|
+
*
|
|
4
|
+
* LoCoMo-style questions such as "What are Melanie's pets' names?" and
|
|
5
|
+
* "What musical artists has Melanie seen?" often need short memories that
|
|
6
|
+
* contain the exact named answer. These memories can be less semantically broad
|
|
7
|
+
* than neighboring context, so MMR may drop them unless we mark high-signal
|
|
8
|
+
* candidates as protected before final selection.
|
|
9
|
+
*/
|
|
10
|
+
import type { SearchResult } from '../db/repository-types.js';
|
|
11
|
+
export interface LiteralListProtectionResult {
|
|
12
|
+
protectedFingerprints: string[];
|
|
13
|
+
protectedIds: string[];
|
|
14
|
+
reasons: string[];
|
|
15
|
+
results: SearchResult[];
|
|
16
|
+
}
|
|
17
|
+
export declare function protectLiteralListAnswerCandidates(query: string, candidates: SearchResult[], maxProtected: number): LiteralListProtectionResult;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protect literal list-answer candidates from late-stage diversity selection.
|
|
3
|
+
*
|
|
4
|
+
* LoCoMo-style questions such as "What are Melanie's pets' names?" and
|
|
5
|
+
* "What musical artists has Melanie seen?" often need short memories that
|
|
6
|
+
* contain the exact named answer. These memories can be less semantically broad
|
|
7
|
+
* than neighboring context, so MMR may drop them unless we mark high-signal
|
|
8
|
+
* candidates as protected before final selection.
|
|
9
|
+
*/
|
|
10
|
+
import { buildTemporalFingerprint } from './temporal-fingerprint.js';
|
|
11
|
+
import { isLiteralDetailQuery } from './literal-query-expansion.js';
|
|
12
|
+
const MIN_SIGNAL_SCORE = 3;
|
|
13
|
+
const PROTECTED_SCORE_BONUS = 4;
|
|
14
|
+
const PET_TERMS = ['pet', 'pets', 'cat', 'cats', 'dog', 'dogs'];
|
|
15
|
+
const MUSIC_TERMS = ['artist', 'artists', 'band', 'bands', 'music', 'musical', 'concert', 'song', 'songs'];
|
|
16
|
+
const BOOK_TERMS = ['book', 'books', 'title', 'read', 'reading'];
|
|
17
|
+
const NAME_TERMS = ['name', 'names', 'called', 'named'];
|
|
18
|
+
const SEEN_EVENT_TERMS = ['seen', 'saw', 'attended', 'concert', 'show'];
|
|
19
|
+
const PERFORMANCE_TERMS = ['played', 'playing', 'dancing', 'singing', 'live', 'stage', 'show', 'concert'];
|
|
20
|
+
const ATTENDANCE_TERMS = ['attended', 'saw', 'seen', 'concert', 'show'];
|
|
21
|
+
export function protectLiteralListAnswerCandidates(query, candidates, maxProtected) {
|
|
22
|
+
if (maxProtected <= 0 || !isLiteralDetailQuery(query)) {
|
|
23
|
+
return emptyProtection(candidates);
|
|
24
|
+
}
|
|
25
|
+
const intent = classifyListIntent(query);
|
|
26
|
+
if (!intent.hasListIntent) {
|
|
27
|
+
return emptyProtection(candidates);
|
|
28
|
+
}
|
|
29
|
+
const protectedCandidates = candidates
|
|
30
|
+
.map((candidate) => scoreCandidate(candidate, intent))
|
|
31
|
+
.filter((candidate) => candidate.score >= MIN_SIGNAL_SCORE)
|
|
32
|
+
.sort((left, right) => right.score - left.score)
|
|
33
|
+
.slice(0, maxProtected);
|
|
34
|
+
return {
|
|
35
|
+
protectedFingerprints: protectedCandidates.map((item) => buildTemporalFingerprint(item.result.content)),
|
|
36
|
+
protectedIds: protectedCandidates.map((item) => item.result.id),
|
|
37
|
+
reasons: [...new Set(protectedCandidates.flatMap((item) => item.reasons))],
|
|
38
|
+
results: boostProtectedCandidates(candidates, protectedCandidates),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function classifyListIntent(query) {
|
|
42
|
+
const lower = query.toLowerCase();
|
|
43
|
+
return {
|
|
44
|
+
hasListIntent: containsAny(lower, NAME_TERMS) || containsAny(lower, PET_TERMS)
|
|
45
|
+
|| containsAny(lower, MUSIC_TERMS) || containsAny(lower, BOOK_TERMS),
|
|
46
|
+
wantsNames: containsAny(lower, NAME_TERMS),
|
|
47
|
+
wantsPets: containsAny(lower, PET_TERMS),
|
|
48
|
+
wantsMusic: containsAny(lower, MUSIC_TERMS),
|
|
49
|
+
wantsBooks: containsAny(lower, BOOK_TERMS),
|
|
50
|
+
wantsSeenEvent: containsAny(lower, SEEN_EVENT_TERMS),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function scoreCandidate(result, intent) {
|
|
54
|
+
const content = result.content;
|
|
55
|
+
const lower = content.toLowerCase();
|
|
56
|
+
const hasQuoted = hasQuotedTitle(content);
|
|
57
|
+
const hasLeadingQuote = hasLeadingQuotedTitle(content);
|
|
58
|
+
const hasAttendance = containsAny(lower, ATTENDANCE_TERMS);
|
|
59
|
+
const reasons = [];
|
|
60
|
+
const score = scoreNamedEntity(content, intent, reasons)
|
|
61
|
+
+ scoreQuotedOrAttendance(intent, hasQuoted, hasLeadingQuote, hasAttendance, reasons)
|
|
62
|
+
+ scoreDomainTerms(lower, intent, reasons)
|
|
63
|
+
+ scorePerformanceEvent(lower, intent, hasLeadingQuote, reasons);
|
|
64
|
+
return { result, score, reasons };
|
|
65
|
+
}
|
|
66
|
+
function scoreNamedEntity(content, intent, reasons) {
|
|
67
|
+
if (!(intent.wantsPets || intent.wantsNames))
|
|
68
|
+
return 0;
|
|
69
|
+
if (!/\bnamed\s+[A-Z][A-Za-z'-]+/.test(content))
|
|
70
|
+
return 0;
|
|
71
|
+
reasons.push('named-entity');
|
|
72
|
+
return 3;
|
|
73
|
+
}
|
|
74
|
+
function scoreQuotedOrAttendance(intent, hasQuoted, hasLeadingQuote, hasAttendance, reasons) {
|
|
75
|
+
const seenEventScore = scoreSeenMusicEvent(intent, hasLeadingQuote, hasAttendance, reasons);
|
|
76
|
+
if (seenEventScore > 0)
|
|
77
|
+
return seenEventScore;
|
|
78
|
+
if ((intent.wantsMusic || intent.wantsBooks) && hasQuoted) {
|
|
79
|
+
reasons.push('quoted-title');
|
|
80
|
+
return 3;
|
|
81
|
+
}
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
function scoreSeenMusicEvent(intent, hasLeadingQuote, hasAttendance, reasons) {
|
|
85
|
+
if (!intent.wantsMusic || !intent.wantsSeenEvent)
|
|
86
|
+
return 0;
|
|
87
|
+
if (hasLeadingQuote) {
|
|
88
|
+
reasons.push('quoted-title');
|
|
89
|
+
return 4;
|
|
90
|
+
}
|
|
91
|
+
if (!hasAttendance)
|
|
92
|
+
return 0;
|
|
93
|
+
reasons.push('attendance-event');
|
|
94
|
+
return 3;
|
|
95
|
+
}
|
|
96
|
+
function scoreDomainTerms(lower, intent, reasons) {
|
|
97
|
+
let score = 0;
|
|
98
|
+
score += addSignal(intent.wantsPets && containsAny(lower, PET_TERMS), reasons, 'pet-domain', 1.5);
|
|
99
|
+
score += addSignal(intent.wantsMusic && containsAny(lower, MUSIC_TERMS), reasons, 'music-domain', 1.5);
|
|
100
|
+
score += addSignal(intent.wantsBooks && containsAny(lower, BOOK_TERMS), reasons, 'book-domain', 1.5);
|
|
101
|
+
return score;
|
|
102
|
+
}
|
|
103
|
+
function scorePerformanceEvent(lower, intent, hasLeadingQuote, reasons) {
|
|
104
|
+
const hasPerformanceSignal = intent.wantsMusic && intent.wantsSeenEvent
|
|
105
|
+
&& hasLeadingQuote && containsAny(lower, PERFORMANCE_TERMS);
|
|
106
|
+
return addSignal(hasPerformanceSignal, reasons, 'performance-event', 2.5);
|
|
107
|
+
}
|
|
108
|
+
function addSignal(enabled, reasons, reason, score) {
|
|
109
|
+
if (!enabled)
|
|
110
|
+
return 0;
|
|
111
|
+
reasons.push(reason);
|
|
112
|
+
return score;
|
|
113
|
+
}
|
|
114
|
+
function hasQuotedTitle(content) {
|
|
115
|
+
return /["'“‘][A-Z][^"'”’]{2,}["'”’]/.test(content);
|
|
116
|
+
}
|
|
117
|
+
function hasLeadingQuotedTitle(content) {
|
|
118
|
+
return /^\s*["'“‘][A-Z][^"'”’]{2,}["'”’]/.test(content);
|
|
119
|
+
}
|
|
120
|
+
function containsAny(content, terms) {
|
|
121
|
+
return terms.some((term) => new RegExp(`\\b${term}\\b`).test(content));
|
|
122
|
+
}
|
|
123
|
+
function boostProtectedCandidates(candidates, protectedCandidates) {
|
|
124
|
+
const protectedIds = new Set(protectedCandidates.map((item) => item.result.id));
|
|
125
|
+
return candidates.map((candidate) => {
|
|
126
|
+
if (!protectedIds.has(candidate.id)) {
|
|
127
|
+
return candidate;
|
|
128
|
+
}
|
|
129
|
+
return { ...candidate, score: candidate.score + PROTECTED_SCORE_BONUS };
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function emptyProtection(results) {
|
|
133
|
+
return { protectedFingerprints: [], protectedIds: [], reasons: [], results };
|
|
134
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic retrieval helpers for literal autobiographical lookups.
|
|
3
|
+
*
|
|
4
|
+
* These queries ask for exact titles, quotes, object details, pets, photos,
|
|
5
|
+
* posters, store details, or other concrete memory fragments. Pure semantic
|
|
6
|
+
* retrieval often under-ranks those rows because the query phrasing is broad
|
|
7
|
+
* while the target memory contains a short literal detail.
|
|
8
|
+
*
|
|
9
|
+
* This module extracts high-signal lexical anchors from the query, finds exact
|
|
10
|
+
* keyword candidates, and boosts them enough to survive later reranking.
|
|
11
|
+
*/
|
|
12
|
+
import type { SearchResult } from '../db/repository-types.js';
|
|
13
|
+
import type { SearchStore } from '../db/stores.js';
|
|
14
|
+
export interface LiteralQueryExpansionResult {
|
|
15
|
+
memories: SearchResult[];
|
|
16
|
+
keywords: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function isLiteralDetailQuery(query: string): boolean;
|
|
19
|
+
export declare function extractLiteralQueryKeywords(query: string): string[];
|
|
20
|
+
export declare function expandLiteralQuery(repo: SearchStore, userId: string, query: string, queryEmbedding: number[], excludeIds: Set<string>, limit: number): Promise<LiteralQueryExpansionResult>;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic retrieval helpers for literal autobiographical lookups.
|
|
3
|
+
*
|
|
4
|
+
* These queries ask for exact titles, quotes, object details, pets, photos,
|
|
5
|
+
* posters, store details, or other concrete memory fragments. Pure semantic
|
|
6
|
+
* retrieval often under-ranks those rows because the query phrasing is broad
|
|
7
|
+
* while the target memory contains a short literal detail.
|
|
8
|
+
*
|
|
9
|
+
* This module extracts high-signal lexical anchors from the query, finds exact
|
|
10
|
+
* keyword candidates, and boosts them enough to survive later reranking.
|
|
11
|
+
*/
|
|
12
|
+
import { fetchAndBoostKeywordCandidates } from './keyword-expansion.js';
|
|
13
|
+
const DIRECT_LOOKUP_PREFIX = /^\s*(?:what|which|who|where|when)\b/i;
|
|
14
|
+
const ABSTRACT_BLOCKERS = [
|
|
15
|
+
'attitude',
|
|
16
|
+
'important',
|
|
17
|
+
'inspired',
|
|
18
|
+
'meaning',
|
|
19
|
+
'motivated',
|
|
20
|
+
'reaction',
|
|
21
|
+
'realize',
|
|
22
|
+
'reason',
|
|
23
|
+
'represent',
|
|
24
|
+
'symbol',
|
|
25
|
+
'take away',
|
|
26
|
+
'why',
|
|
27
|
+
];
|
|
28
|
+
const LITERAL_SIGNALS = [
|
|
29
|
+
'book',
|
|
30
|
+
'books',
|
|
31
|
+
'bowl',
|
|
32
|
+
'cat',
|
|
33
|
+
'cats',
|
|
34
|
+
'clothing store',
|
|
35
|
+
'concert',
|
|
36
|
+
'decor',
|
|
37
|
+
'dog',
|
|
38
|
+
'dogs',
|
|
39
|
+
'drawing',
|
|
40
|
+
'fan',
|
|
41
|
+
'festival',
|
|
42
|
+
'flooring',
|
|
43
|
+
'furniture',
|
|
44
|
+
'grand canyon',
|
|
45
|
+
'guinea pig',
|
|
46
|
+
'library',
|
|
47
|
+
'meteor shower',
|
|
48
|
+
'music',
|
|
49
|
+
'musician',
|
|
50
|
+
'musicians',
|
|
51
|
+
'painting',
|
|
52
|
+
'paintings',
|
|
53
|
+
'pet',
|
|
54
|
+
'pets',
|
|
55
|
+
'photo',
|
|
56
|
+
'photos',
|
|
57
|
+
'poetry reading',
|
|
58
|
+
'poster',
|
|
59
|
+
'posters',
|
|
60
|
+
'pottery',
|
|
61
|
+
'road trip',
|
|
62
|
+
'shoe',
|
|
63
|
+
'shoes',
|
|
64
|
+
'sidewalk',
|
|
65
|
+
'sign',
|
|
66
|
+
'slipper',
|
|
67
|
+
'song',
|
|
68
|
+
'songs',
|
|
69
|
+
'store',
|
|
70
|
+
'title',
|
|
71
|
+
'workshop',
|
|
72
|
+
];
|
|
73
|
+
const SIGNAL_WINDOW_RADIUS = 2;
|
|
74
|
+
const MAX_KEYWORDS = 8;
|
|
75
|
+
const LITERAL_SCORE_BOOST = 0.75;
|
|
76
|
+
const WORD_BOUNDARY = /\b[\w'’.-]+\b/g;
|
|
77
|
+
const QUOTED_LITERAL = /["“”']([^"“”']{2,80})["“”']/g;
|
|
78
|
+
const YEAR_PATTERN = /\b(?:19|20)\d{2}\b/g;
|
|
79
|
+
const DATE_PATTERN = /\b\d{1,2}\s+(?:January|February|March|April|May|June|July|August|September|October|November|December)\b/gi;
|
|
80
|
+
const MULTI_WORD_PROPER_NOUN = /\b[A-Z][A-Za-z'’.-]+(?:\s+[A-Z][A-Za-z'’.-]+)+\b/g;
|
|
81
|
+
const STOP_WORDS = new Set([
|
|
82
|
+
'a', 'an', 'at', 'did', 'do', 'does', 'for', 'from', 'her', 'his', 'in',
|
|
83
|
+
'is', 'kind', 'of', 'on', 'say', 'the', 'their', 'type', 'was', 'were',
|
|
84
|
+
'what', 'when', 'where', 'which', 'who',
|
|
85
|
+
]);
|
|
86
|
+
export function isLiteralDetailQuery(query) {
|
|
87
|
+
const normalized = query.trim().toLowerCase();
|
|
88
|
+
if (!normalized || !DIRECT_LOOKUP_PREFIX.test(normalized))
|
|
89
|
+
return false;
|
|
90
|
+
if (ABSTRACT_BLOCKERS.some((signal) => normalized.includes(signal)))
|
|
91
|
+
return false;
|
|
92
|
+
return extractLiteralQueryKeywords(query).length > 0;
|
|
93
|
+
}
|
|
94
|
+
export function extractLiteralQueryKeywords(query) {
|
|
95
|
+
const candidates = new Set();
|
|
96
|
+
const normalized = query.trim();
|
|
97
|
+
if (!normalized)
|
|
98
|
+
return [];
|
|
99
|
+
addMatches(candidates, extractQuotedLiterals(normalized));
|
|
100
|
+
addMatches(candidates, extractNamedLiteralCandidates(normalized));
|
|
101
|
+
addMatches(candidates, extractTemporalAnchors(normalized));
|
|
102
|
+
addMatches(candidates, extractSignalWindows(normalized));
|
|
103
|
+
return [...candidates]
|
|
104
|
+
.map(cleanKeyword)
|
|
105
|
+
.filter((keyword) => keyword.length >= 2)
|
|
106
|
+
.slice(0, MAX_KEYWORDS);
|
|
107
|
+
}
|
|
108
|
+
export async function expandLiteralQuery(repo, userId, query, queryEmbedding, excludeIds, limit) {
|
|
109
|
+
const keywords = extractLiteralQueryKeywords(query);
|
|
110
|
+
if (keywords.length === 0)
|
|
111
|
+
return { memories: [], keywords: [] };
|
|
112
|
+
const boosted = await fetchAndBoostKeywordCandidates(repo, userId, keywords, queryEmbedding, excludeIds, limit, LITERAL_SCORE_BOOST);
|
|
113
|
+
return { memories: boosted, keywords };
|
|
114
|
+
}
|
|
115
|
+
function extractQuotedLiterals(query) {
|
|
116
|
+
const matches = [];
|
|
117
|
+
let match;
|
|
118
|
+
while ((match = QUOTED_LITERAL.exec(query)) !== null) {
|
|
119
|
+
matches.push(match[1]);
|
|
120
|
+
}
|
|
121
|
+
return matches;
|
|
122
|
+
}
|
|
123
|
+
function extractNamedLiteralCandidates(query) {
|
|
124
|
+
const candidates = new Set();
|
|
125
|
+
const multiWord = query.match(MULTI_WORD_PROPER_NOUN) ?? [];
|
|
126
|
+
for (const phrase of multiWord) {
|
|
127
|
+
candidates.add(phrase.trim());
|
|
128
|
+
}
|
|
129
|
+
const words = query.match(WORD_BOUNDARY) ?? [];
|
|
130
|
+
for (let i = 1; i < words.length; i++) {
|
|
131
|
+
const word = words[i];
|
|
132
|
+
if (/^[A-Z][A-Za-z'’.-]+$/.test(word) && !STOP_WORDS.has(word.toLowerCase())) {
|
|
133
|
+
candidates.add(word);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return [...candidates];
|
|
137
|
+
}
|
|
138
|
+
function extractTemporalAnchors(query) {
|
|
139
|
+
return [
|
|
140
|
+
...(query.match(DATE_PATTERN) ?? []),
|
|
141
|
+
...(query.match(YEAR_PATTERN) ?? []),
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
function extractSignalWindows(query) {
|
|
145
|
+
const lowerWords = (query.toLowerCase().match(WORD_BOUNDARY) ?? []);
|
|
146
|
+
const originalWords = (query.match(WORD_BOUNDARY) ?? []);
|
|
147
|
+
const windows = new Set();
|
|
148
|
+
for (let i = 0; i < lowerWords.length; i++) {
|
|
149
|
+
const signalLength = matchedSignalLength(lowerWords, i);
|
|
150
|
+
if (signalLength === 0)
|
|
151
|
+
continue;
|
|
152
|
+
const start = Math.max(0, i - SIGNAL_WINDOW_RADIUS);
|
|
153
|
+
const end = Math.min(originalWords.length, i + signalLength + SIGNAL_WINDOW_RADIUS);
|
|
154
|
+
const window = originalWords.slice(start, end).join(' ');
|
|
155
|
+
windows.add(window);
|
|
156
|
+
windows.add(originalWords.slice(i, i + signalLength).join(' '));
|
|
157
|
+
}
|
|
158
|
+
return [...windows];
|
|
159
|
+
}
|
|
160
|
+
function matchedSignalLength(words, start) {
|
|
161
|
+
for (const signal of LITERAL_SIGNALS) {
|
|
162
|
+
const signalWords = signal.split(' ');
|
|
163
|
+
const candidate = words.slice(start, start + signalWords.length);
|
|
164
|
+
if (candidate.join(' ') === signal) {
|
|
165
|
+
return signalWords.length;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return 0;
|
|
169
|
+
}
|
|
170
|
+
function addMatches(target, values) {
|
|
171
|
+
for (const value of values)
|
|
172
|
+
target.add(value);
|
|
173
|
+
}
|
|
174
|
+
function cleanKeyword(keyword) {
|
|
175
|
+
return keyword
|
|
176
|
+
.trim()
|
|
177
|
+
.replace(/^[^\w"“”']+|[^\w"“”']+$/g, '')
|
|
178
|
+
.split(/\s+/)
|
|
179
|
+
.filter((word) => !STOP_WORDS.has(word.toLowerCase()))
|
|
180
|
+
.join(' ');
|
|
181
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM provider abstraction for chat completions.
|
|
3
|
+
* Supports OpenAI, Ollama, and any OpenAI-compatible API (LM Studio, etc).
|
|
4
|
+
* Provider is selected via PROVIDER_LLM env var.
|
|
5
|
+
*/
|
|
6
|
+
import { type WriteCostEventConfig } from './cost-telemetry.js';
|
|
7
|
+
import type { LLMProviderName } from '../config.js';
|
|
8
|
+
/**
|
|
9
|
+
* Config subset consumed by the LLM module. Same module-local-state
|
|
10
|
+
* pattern as embedding.ts: provider/model selection is startup-only
|
|
11
|
+
* (Phase 7 Step 3c), so holding the config as module state after init
|
|
12
|
+
* matches the effective contract.
|
|
13
|
+
*/
|
|
14
|
+
export interface LLMConfig extends WriteCostEventConfig {
|
|
15
|
+
llmProvider: LLMProviderName;
|
|
16
|
+
llmModel: string;
|
|
17
|
+
llmApiUrl?: string;
|
|
18
|
+
llmApiKey?: string;
|
|
19
|
+
openaiApiKey: string;
|
|
20
|
+
groqApiKey?: string;
|
|
21
|
+
anthropicApiKey?: string;
|
|
22
|
+
googleApiKey?: string;
|
|
23
|
+
ollamaBaseUrl: string;
|
|
24
|
+
llmSeed?: number;
|
|
25
|
+
}
|
|
26
|
+
/** Bind the LLM module's config. Called once by the composition root. */
|
|
27
|
+
export declare function initLlm(config: LLMConfig): void;
|
|
28
|
+
export interface ChatMessage {
|
|
29
|
+
role: 'system' | 'user' | 'assistant';
|
|
30
|
+
content: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ChatOptions {
|
|
33
|
+
temperature?: number;
|
|
34
|
+
maxTokens?: number;
|
|
35
|
+
jsonMode?: boolean;
|
|
36
|
+
seed?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface LLMProvider {
|
|
39
|
+
chat(messages: ChatMessage[], options?: ChatOptions): Promise<string>;
|
|
40
|
+
}
|
|
41
|
+
/** Create LLM provider from config. */
|
|
42
|
+
export declare function createLLMProvider(): LLMProvider;
|
|
43
|
+
/** Singleton-like LLM accessor that refreshes when runtime config changes. */
|
|
44
|
+
export declare const llm: LLMProvider;
|
|
45
|
+
/** Schema shape expected by callAnthropicTool. */
|
|
46
|
+
export interface AnthropicToolSchema {
|
|
47
|
+
name: string;
|
|
48
|
+
description: string;
|
|
49
|
+
input_schema: Record<string, unknown>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Invoke an Anthropic model in forced tool-use mode and return the parsed
|
|
53
|
+
* tool input. Uses the module-local config (set by initLlm) for the API key.
|
|
54
|
+
*
|
|
55
|
+
* @param model - Anthropic model ID (e.g. 'claude-sonnet-4-5').
|
|
56
|
+
* @param system - System prompt.
|
|
57
|
+
* @param user - User message.
|
|
58
|
+
* @param toolSchema - Tool definition; the model is forced to call this tool.
|
|
59
|
+
* @returns Parsed tool input cast to T.
|
|
60
|
+
*/
|
|
61
|
+
export declare function callAnthropicTool<T>(model: string, system: string, user: string, toolSchema: AnthropicToolSchema): Promise<T>;
|