@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,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduler wrapper around `runOnce`. Owns the `setInterval` handle,
|
|
3
|
+
* prevents overlapping runs, and exposes an
|
|
4
|
+
* explicit `stop()` that awaits any in-flight tick before resolving.
|
|
5
|
+
*
|
|
6
|
+
* NOT auto-started from `createCoreRuntime` — tests never want a
|
|
7
|
+
* background timer firing in the middle of seeded-row assertions.
|
|
8
|
+
* Production composition (a separate boot path) explicitly calls
|
|
9
|
+
* `startReconciler(deps)` when the runtime container hands back a
|
|
10
|
+
* non-null `reconcilerDeps` bundle and adds `scheduler.stop` to the
|
|
11
|
+
* graceful-shutdown hook.
|
|
12
|
+
*/
|
|
13
|
+
import { type ReconcilerDeps } from './raw-storage-reconciler.js';
|
|
14
|
+
export interface ReconcilerScheduler {
|
|
15
|
+
/** Clears the interval and awaits the in-flight `runOnce()`. */
|
|
16
|
+
stop(): Promise<void>;
|
|
17
|
+
/** True while a `runOnce()` invocation is in flight. */
|
|
18
|
+
readonly isRunning: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface SchedulerOptions extends ReconcilerDeps {
|
|
21
|
+
/** Polling interval — `setInterval(tick, intervalMs)`. */
|
|
22
|
+
intervalMs: number;
|
|
23
|
+
/**
|
|
24
|
+
* Called with the error if `runOnce()` rejects. Sanitization is
|
|
25
|
+
* the caller's responsibility.
|
|
26
|
+
*/
|
|
27
|
+
onError?: (err: unknown) => void;
|
|
28
|
+
}
|
|
29
|
+
export declare function startReconciler(options: SchedulerOptions): ReconcilerScheduler;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduler wrapper around `runOnce`. Owns the `setInterval` handle,
|
|
3
|
+
* prevents overlapping runs, and exposes an
|
|
4
|
+
* explicit `stop()` that awaits any in-flight tick before resolving.
|
|
5
|
+
*
|
|
6
|
+
* NOT auto-started from `createCoreRuntime` — tests never want a
|
|
7
|
+
* background timer firing in the middle of seeded-row assertions.
|
|
8
|
+
* Production composition (a separate boot path) explicitly calls
|
|
9
|
+
* `startReconciler(deps)` when the runtime container hands back a
|
|
10
|
+
* non-null `reconcilerDeps` bundle and adds `scheduler.stop` to the
|
|
11
|
+
* graceful-shutdown hook.
|
|
12
|
+
*/
|
|
13
|
+
import { runOnce } from './raw-storage-reconciler.js';
|
|
14
|
+
export function startReconciler(options) {
|
|
15
|
+
let isRunning = false;
|
|
16
|
+
let stopped = false;
|
|
17
|
+
let inFlight = Promise.resolve();
|
|
18
|
+
const tick = () => {
|
|
19
|
+
if (stopped || isRunning)
|
|
20
|
+
return;
|
|
21
|
+
isRunning = true;
|
|
22
|
+
inFlight = runOnce(options)
|
|
23
|
+
.then(() => undefined)
|
|
24
|
+
.catch((err) => {
|
|
25
|
+
if (options.onError)
|
|
26
|
+
options.onError(err);
|
|
27
|
+
})
|
|
28
|
+
.finally(() => {
|
|
29
|
+
isRunning = false;
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
const handle = setInterval(tick, options.intervalMs);
|
|
33
|
+
return {
|
|
34
|
+
get isRunning() {
|
|
35
|
+
return isRunning;
|
|
36
|
+
},
|
|
37
|
+
async stop() {
|
|
38
|
+
stopped = true;
|
|
39
|
+
clearInterval(handle);
|
|
40
|
+
await inFlight;
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw-storage reconciler — promotes `blob_pending` Filecoin
|
|
3
|
+
* rows to `blob_available` once gateway retrievability is confirmed,
|
|
4
|
+
* or marks them `blob_archival_failed` after retry exhaustion.
|
|
5
|
+
*
|
|
6
|
+
* `runOnce(deps)` is the deterministic, side-effect-bounded entry
|
|
7
|
+
* point tests call directly. The scheduler (a separate module) wraps
|
|
8
|
+
* it in a timer-driven loop for production use. NEVER calls
|
|
9
|
+
* setTimeout/setInterval internally — backoff scheduling lives on
|
|
10
|
+
* the row's `raw_storage_next_check_at` column, not in process memory.
|
|
11
|
+
*/
|
|
12
|
+
import pg from 'pg';
|
|
13
|
+
import type { RawContentStore } from '../storage/raw-content-store.js';
|
|
14
|
+
import type { RawContentCodec } from '../storage/raw-content-codec.js';
|
|
15
|
+
export { computeBackoffMs } from './raw-storage-reconciler-backoff.js';
|
|
16
|
+
export interface ReconcilerDeps {
|
|
17
|
+
pool: pg.Pool;
|
|
18
|
+
/**
|
|
19
|
+
* Active Filecoin adapter (or any adapter whose capabilities map
|
|
20
|
+
* cleanly onto `head()`-returns-retrievability). The reconciler
|
|
21
|
+
* calls `store.head(storage_uri)` for each claimed row outside
|
|
22
|
+
* any DB tx; in `hash_verify` mode it additionally calls `get()`.
|
|
23
|
+
*/
|
|
24
|
+
store: RawContentStore;
|
|
25
|
+
/**
|
|
26
|
+
* Content codec the upload service wrapped around the adapter's
|
|
27
|
+
* `put()`. The reconciler's `hash_verify` mode uses
|
|
28
|
+
* `codec.decode()` to reverse the encoding before sha256-comparing
|
|
29
|
+
* the bytes to the row's `content_hash`. Ignored in `head_only`
|
|
30
|
+
* mode; supplied unconditionally by `createCoreRuntime` so the
|
|
31
|
+
* dep bundle stays the same shape across modes.
|
|
32
|
+
*/
|
|
33
|
+
codec: RawContentCodec;
|
|
34
|
+
/**
|
|
35
|
+
* Verification depth before promoting `blob_pending` →
|
|
36
|
+
* `blob_available`:
|
|
37
|
+
*
|
|
38
|
+
* - `'head_only'`: trust the adapter's `head()` exists-check.
|
|
39
|
+
* Confirms retrievability but does NOT decode the bytes.
|
|
40
|
+
* - `'hash_verify'`: after `head()` confirms retrievability,
|
|
41
|
+
* `get()` the bytes, decode with the active codec, sha256 the
|
|
42
|
+
* plaintext, and compare to the row's `content_hash`. A
|
|
43
|
+
* mismatch routes the row to `blob_archival_failed` with
|
|
44
|
+
* code `content_hash_mismatch`.
|
|
45
|
+
*
|
|
46
|
+
* Runtime config may surface this knob later; the reconciler takes
|
|
47
|
+
* the resolved value directly.
|
|
48
|
+
*/
|
|
49
|
+
verifyMode: 'head_only' | 'hash_verify';
|
|
50
|
+
batchSize: number;
|
|
51
|
+
staleAfterMs: number;
|
|
52
|
+
baseIntervalMs: number;
|
|
53
|
+
backoffMaxMs: number;
|
|
54
|
+
maxAttempts: number;
|
|
55
|
+
/**
|
|
56
|
+
* Injectable clock for `pendingAgeSeconds` math. Defaults to `new Date()` in
|
|
57
|
+
* production; tests pass a fixed `Date` so the integration
|
|
58
|
+
* assertions can lock the exact age the event carries instead
|
|
59
|
+
* of a wall-clock range. Pure deterministic substitution; no
|
|
60
|
+
* timing-dependent test logic.
|
|
61
|
+
*/
|
|
62
|
+
now?: () => Date;
|
|
63
|
+
}
|
|
64
|
+
export interface ReconcilerRunSummary {
|
|
65
|
+
claimed: number;
|
|
66
|
+
promoted: number;
|
|
67
|
+
stillPending: number;
|
|
68
|
+
archivalFailed: number;
|
|
69
|
+
lostClaim: number;
|
|
70
|
+
}
|
|
71
|
+
export declare function runOnce(deps: ReconcilerDeps): Promise<ReconcilerRunSummary>;
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw-storage reconciler — promotes `blob_pending` Filecoin
|
|
3
|
+
* rows to `blob_available` once gateway retrievability is confirmed,
|
|
4
|
+
* or marks them `blob_archival_failed` after retry exhaustion.
|
|
5
|
+
*
|
|
6
|
+
* `runOnce(deps)` is the deterministic, side-effect-bounded entry
|
|
7
|
+
* point tests call directly. The scheduler (a separate module) wraps
|
|
8
|
+
* it in a timer-driven loop for production use. NEVER calls
|
|
9
|
+
* setTimeout/setInterval internally — backoff scheduling lives on
|
|
10
|
+
* the row's `raw_storage_next_check_at` column, not in process memory.
|
|
11
|
+
*/
|
|
12
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
13
|
+
import { buildLastError } from '../db/raw-document-status-repository.js';
|
|
14
|
+
import { claimReconcileBatch, markStillPendingWithClient, } from '../db/raw-storage-reconciliation-repository.js';
|
|
15
|
+
import { markArchivalFailedAndSyncArtifact, promoteAndSyncArtifact, } from '../db/raw-doc-artifact-sync.js';
|
|
16
|
+
import { computePendingAgeSeconds, emitFilecoinEvent, } from './filecoin-observability.js';
|
|
17
|
+
import { computeBackoffMs } from './raw-storage-reconciler-backoff.js';
|
|
18
|
+
export { computeBackoffMs } from './raw-storage-reconciler-backoff.js';
|
|
19
|
+
function clockNow(deps) {
|
|
20
|
+
return deps.now ? deps.now() : new Date();
|
|
21
|
+
}
|
|
22
|
+
export async function runOnce(deps) {
|
|
23
|
+
const claimId = randomUUID();
|
|
24
|
+
const rows = await claimReconcileBatch(deps.pool, {
|
|
25
|
+
claimId,
|
|
26
|
+
batchSize: deps.batchSize,
|
|
27
|
+
staleAfterMs: deps.staleAfterMs,
|
|
28
|
+
provider: deps.store.provider,
|
|
29
|
+
});
|
|
30
|
+
if (rows.length > 0) {
|
|
31
|
+
emitFilecoinEvent('filecoin.reconcile.claimed', {
|
|
32
|
+
provider: deps.store.provider,
|
|
33
|
+
claimId,
|
|
34
|
+
batchSize: rows.length,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
for (const row of rows) {
|
|
38
|
+
if (row.recoveredStaleClaim) {
|
|
39
|
+
emitFilecoinEvent('filecoin.reconcile.stale_claim_recovered', {
|
|
40
|
+
documentId: row.id,
|
|
41
|
+
userId: row.userId,
|
|
42
|
+
provider: row.storageProvider,
|
|
43
|
+
claimId,
|
|
44
|
+
reconcileAttempts: row.rawStorageReconcileAttempts,
|
|
45
|
+
pendingAgeSeconds: computePendingAgeSeconds(row.rawStoragePendingSince, clockNow(deps)) ?? undefined,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const summary = {
|
|
50
|
+
claimed: rows.length, promoted: 0, stillPending: 0, archivalFailed: 0, lostClaim: 0,
|
|
51
|
+
};
|
|
52
|
+
for (const row of rows) {
|
|
53
|
+
const outcome = await processOneRow(deps, row, claimId);
|
|
54
|
+
if (outcome === 'promoted')
|
|
55
|
+
summary.promoted += 1;
|
|
56
|
+
else if (outcome === 'still_pending')
|
|
57
|
+
summary.stillPending += 1;
|
|
58
|
+
else if (outcome === 'archival_failed')
|
|
59
|
+
summary.archivalFailed += 1;
|
|
60
|
+
else
|
|
61
|
+
summary.lostClaim += 1;
|
|
62
|
+
}
|
|
63
|
+
return summary;
|
|
64
|
+
}
|
|
65
|
+
async function processOneRow(deps, row, claimId) {
|
|
66
|
+
// Hand the row's `raw_storage_metadata` to the adapter so an
|
|
67
|
+
// eventual-consistency provider (Filecoin) can short-circuit
|
|
68
|
+
// its lookup using the provider-specific sidecar it wrote at
|
|
69
|
+
// `put` time (e.g. `data_set_id`). The adapter validates +
|
|
70
|
+
// ignores malformed entries; non-Filecoin adapters ignore the
|
|
71
|
+
// argument entirely.
|
|
72
|
+
const hints = row.rawStorageMetadata;
|
|
73
|
+
const probe = await probeHead(deps.store, row.storageUri, hints);
|
|
74
|
+
if (probe.kind === 'retrievable') {
|
|
75
|
+
return handleRetrievable(deps, row, claimId, probe);
|
|
76
|
+
}
|
|
77
|
+
if (probe.kind === 'permanent_failure') {
|
|
78
|
+
return archivalFailFromProbe(deps, row, claimId, probe.code, probe.message);
|
|
79
|
+
}
|
|
80
|
+
// Transient/pending outcomes. A late retrievable from a
|
|
81
|
+
// high-attempt-count row must still promote — we never fail on
|
|
82
|
+
// top of a successful probe (rev-7 §7).
|
|
83
|
+
return persistPendingOutcome(deps, row, claimId, probe);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* `retrievable` branch. In `head_only` mode the promotion is
|
|
87
|
+
* unconditional; in `hash_verify` mode we first `get()` the bytes,
|
|
88
|
+
* decode through the codec, sha256 the plaintext, and compare to
|
|
89
|
+
* the row's `content_hash`. Mismatch → permanent failure; transport/
|
|
90
|
+
* decode errors stay transient.
|
|
91
|
+
*/
|
|
92
|
+
async function handleRetrievable(deps, row, claimId, probe) {
|
|
93
|
+
if (deps.verifyMode === 'hash_verify') {
|
|
94
|
+
const verify = await verifyContentHash(deps, row);
|
|
95
|
+
if (verify.kind === 'mismatch') {
|
|
96
|
+
emitFilecoinEvent('filecoin.retrieval.verification_failed', {
|
|
97
|
+
documentId: row.id,
|
|
98
|
+
userId: row.userId,
|
|
99
|
+
provider: row.storageProvider,
|
|
100
|
+
claimId,
|
|
101
|
+
errorCode: 'content_hash_mismatch',
|
|
102
|
+
errorMessage: verify.message,
|
|
103
|
+
});
|
|
104
|
+
return archivalFailFromProbe(deps, row, claimId, 'content_hash_mismatch', verify.message);
|
|
105
|
+
}
|
|
106
|
+
if (verify.kind === 'error') {
|
|
107
|
+
emitFilecoinEvent('filecoin.retrieval.verification_failed', {
|
|
108
|
+
documentId: row.id,
|
|
109
|
+
userId: row.userId,
|
|
110
|
+
provider: row.storageProvider,
|
|
111
|
+
claimId,
|
|
112
|
+
errorCode: 'verify_transport_error',
|
|
113
|
+
errorMessage: verify.message,
|
|
114
|
+
});
|
|
115
|
+
return persistPendingOutcome(deps, row, claimId, { kind: 'error', message: verify.message });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const rowCount = await promoteAndSyncArtifact(deps.pool, {
|
|
119
|
+
rowId: row.id,
|
|
120
|
+
claimId,
|
|
121
|
+
provider: row.storageProvider,
|
|
122
|
+
providerFields: extractProviderHeadMetadata(row.storageProvider, probe.providerMetadata),
|
|
123
|
+
});
|
|
124
|
+
if (rowCount === 1) {
|
|
125
|
+
emitFilecoinEvent('filecoin.reconcile.promoted', {
|
|
126
|
+
documentId: row.id,
|
|
127
|
+
userId: row.userId,
|
|
128
|
+
provider: row.storageProvider,
|
|
129
|
+
claimId,
|
|
130
|
+
statusBefore: 'blob_pending',
|
|
131
|
+
statusAfter: 'blob_available',
|
|
132
|
+
reconcileAttempts: row.rawStorageReconcileAttempts,
|
|
133
|
+
pendingAgeSeconds: computePendingAgeSeconds(row.rawStoragePendingSince, clockNow(deps)) ?? undefined,
|
|
134
|
+
});
|
|
135
|
+
return 'promoted';
|
|
136
|
+
}
|
|
137
|
+
return 'lost_claim';
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Per-row permanent failure — skip
|
|
141
|
+
* straight to terminal `blob_archival_failed` without burning
|
|
142
|
+
* retries. Caller categorizes the failure (`content_hash_mismatch`,
|
|
143
|
+
* `onramp_reported_failed`, `malformed_storage_uri`, …) via `code`.
|
|
144
|
+
*/
|
|
145
|
+
async function archivalFailFromProbe(deps, row, claimId, code, message) {
|
|
146
|
+
const rowCount = await markArchivalFailedAndSyncArtifact(deps.pool, {
|
|
147
|
+
rowId: row.id,
|
|
148
|
+
claimId,
|
|
149
|
+
lastError: buildLastError('raw_storage', code, message),
|
|
150
|
+
provider: row.storageProvider,
|
|
151
|
+
});
|
|
152
|
+
if (rowCount === 1) {
|
|
153
|
+
emitFilecoinEvent('filecoin.reconcile.archival_failed', {
|
|
154
|
+
documentId: row.id,
|
|
155
|
+
userId: row.userId,
|
|
156
|
+
provider: row.storageProvider,
|
|
157
|
+
claimId,
|
|
158
|
+
statusBefore: 'blob_pending',
|
|
159
|
+
statusAfter: 'blob_archival_failed',
|
|
160
|
+
errorCode: code,
|
|
161
|
+
errorMessage: message,
|
|
162
|
+
reconcileAttempts: row.rawStorageReconcileAttempts,
|
|
163
|
+
pendingAgeSeconds: computePendingAgeSeconds(row.rawStoragePendingSince, clockNow(deps)) ?? undefined,
|
|
164
|
+
});
|
|
165
|
+
return 'archival_failed';
|
|
166
|
+
}
|
|
167
|
+
return 'lost_claim';
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* `hash_verify` integrity check: `get()` + `decode()` + sha256 +
|
|
171
|
+
* compare against `row.contentHash`. Categorizes failures:
|
|
172
|
+
*
|
|
173
|
+
* - `'match'` → bytes decode to the registered plaintext hash.
|
|
174
|
+
* - `'mismatch'` → bytes decoded fine but hash disagrees. This
|
|
175
|
+
* is a per-row terminal failure; the row cannot satisfy the
|
|
176
|
+
* integrity contract no matter how many retries.
|
|
177
|
+
* - `'error'` → transport or decode threw. Likely a global
|
|
178
|
+
* infra/config problem (gateway 5xx, missing codec key, codec
|
|
179
|
+
* metadata sidecar absent on the row). Stays transient so a
|
|
180
|
+
* misconfigured deployment doesn't permanently fail every row.
|
|
181
|
+
*
|
|
182
|
+
* A row with `content_hash === null` is treated as `'error'`: it
|
|
183
|
+
* shouldn't happen for a Phase-5 Filecoin `blob_pending` row (Phase
|
|
184
|
+
* α writes the plaintext hash), and if it does, we want the
|
|
185
|
+
* operator to debug it, not flip the row to terminal.
|
|
186
|
+
*/
|
|
187
|
+
async function verifyContentHash(deps, row) {
|
|
188
|
+
if (!row.contentHash) {
|
|
189
|
+
return { kind: 'error', message: 'row has no content_hash; cannot verify' };
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const got = await deps.store.get(row.storageUri);
|
|
193
|
+
const codecMetadata = extractCodecMetadata(row.rawStorageMetadata);
|
|
194
|
+
const decoded = await deps.codec.decode({ body: got.body, metadata: codecMetadata });
|
|
195
|
+
const observed = sha256Hex(decoded.body);
|
|
196
|
+
if (observed === row.contentHash)
|
|
197
|
+
return { kind: 'match' };
|
|
198
|
+
return {
|
|
199
|
+
kind: 'mismatch',
|
|
200
|
+
message: `expected content_hash ${row.contentHash}, decoded bytes hash to ${observed}`,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
return { kind: 'error', message: err instanceof Error ? err.message : String(err) };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Read the codec sidecar the durable URI-write step wrote into `raw_storage_metadata.codec`.
|
|
209
|
+
* Falls back to a `{ name: 'none', version: 1 }` shape so a row missing
|
|
210
|
+
* the sidecar (e.g. legacy / hand-seeded) decodes through the noop
|
|
211
|
+
* path instead of throwing on shape mismatch.
|
|
212
|
+
*/
|
|
213
|
+
function extractCodecMetadata(metadata) {
|
|
214
|
+
const codec = metadata['codec'];
|
|
215
|
+
if (codec && typeof codec === 'object' && 'name' in codec && 'version' in codec) {
|
|
216
|
+
return codec;
|
|
217
|
+
}
|
|
218
|
+
return { name: 'none', version: 1 };
|
|
219
|
+
}
|
|
220
|
+
function sha256Hex(buf) {
|
|
221
|
+
return createHash('sha256').update(buf).digest('hex');
|
|
222
|
+
}
|
|
223
|
+
async function probeHead(store, storageUri, hints) {
|
|
224
|
+
try {
|
|
225
|
+
const result = await store.head(storageUri, hints);
|
|
226
|
+
if (result.exists) {
|
|
227
|
+
const providerMetadata = result.metadata?.providerMetadata ?? {};
|
|
228
|
+
return { kind: 'retrievable', providerMetadata };
|
|
229
|
+
}
|
|
230
|
+
if (result.failure) {
|
|
231
|
+
return {
|
|
232
|
+
kind: 'permanent_failure',
|
|
233
|
+
code: result.failure.code,
|
|
234
|
+
message: result.failure.message,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
return { kind: 'pending' };
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
// Thrown errors are transient by default — global infra failures
|
|
241
|
+
// (auth, rate-limit, gateway 5xx) affect every row, and we must
|
|
242
|
+
// NOT flip every pending row to `blob_archival_failed` on a
|
|
243
|
+
// misconfigured deployment. Adapters that want to signal a
|
|
244
|
+
// per-row permanent failure return `{ exists: false, failure }`
|
|
245
|
+
// explicitly.
|
|
246
|
+
return {
|
|
247
|
+
kind: 'error',
|
|
248
|
+
message: err instanceof Error ? err.message : String(err),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Pull just the active provider sibling out of the adapter's head
|
|
254
|
+
* metadata. Eventual providers return `{ [provider]: {...} }`;
|
|
255
|
+
* unknown or malformed siblings merge as `{}`.
|
|
256
|
+
*/
|
|
257
|
+
function extractProviderHeadMetadata(provider, providerMetadata) {
|
|
258
|
+
const providerFields = providerMetadata[provider];
|
|
259
|
+
if (providerFields && typeof providerFields === 'object' && !Array.isArray(providerFields)) {
|
|
260
|
+
return providerFields;
|
|
261
|
+
}
|
|
262
|
+
return {};
|
|
263
|
+
}
|
|
264
|
+
async function persistPendingOutcome(deps, row, claimId, probe) {
|
|
265
|
+
const nextAttempts = row.rawStorageReconcileAttempts + 1;
|
|
266
|
+
if (nextAttempts >= deps.maxAttempts) {
|
|
267
|
+
const code = probe.kind === 'error' ? 'reconcile_probe_error' : 'reconcile_attempts_exhausted';
|
|
268
|
+
const message = probe.kind === 'error'
|
|
269
|
+
? `probe failed after ${nextAttempts} attempts: ${probe.message}`
|
|
270
|
+
: `pending after ${nextAttempts} reconciliation attempts`;
|
|
271
|
+
return archivalFailFromProbe(deps, row, claimId, code, message);
|
|
272
|
+
}
|
|
273
|
+
const nextCheckAtMs = computeBackoffMs(nextAttempts, deps.baseIntervalMs, deps.backoffMaxMs);
|
|
274
|
+
const rowCount = await markStillPendingWithClient(deps.pool, {
|
|
275
|
+
rowId: row.id, claimId, nextCheckAtMs, provider: row.storageProvider,
|
|
276
|
+
});
|
|
277
|
+
return rowCount === 1 ? 'still_pending' : 'lost_claim';
|
|
278
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recap layer (Sprint 3 v1) — pre-computed cross-session synthesis.
|
|
3
|
+
*
|
|
4
|
+
* For each cluster of N+ memories that share a conceptual topic, generate
|
|
5
|
+
* an LLM-synthesized narrative ("Episode") and store it as a separate
|
|
6
|
+
* retrievable unit with its own embedding. Cross-session questions ("how
|
|
7
|
+
* did the auth design evolve across sessions?") retrieve the Recap
|
|
8
|
+
* directly instead of re-synthesizing N raw facts at query time.
|
|
9
|
+
*
|
|
10
|
+
* Cog-sci analogue: hippocampal consolidation. Three of the four next-gen
|
|
11
|
+
* memory systems converge on this primitive (Hindsight observations,
|
|
12
|
+
* Honcho dreaming, X-Mem Episodes, EverMemOS multi-pass restructuring).
|
|
13
|
+
*
|
|
14
|
+
* Cluster pivot: `topic_abstraction` field. Requires topic-abstraction
|
|
15
|
+
* layer to be ON during ingest so memories carry topic tags. The clustering
|
|
16
|
+
* is simple grouping by exact topic string + user; embedding-based nearest-
|
|
17
|
+
* neighbor clustering is a v1.1 enhancement.
|
|
18
|
+
*
|
|
19
|
+
* Trigger: post-write hook checks if any topic for the user crosses
|
|
20
|
+
* recapMinClusterSize un-consolidated memories. Builder fires async
|
|
21
|
+
* (no await) so ingest latency is unaffected.
|
|
22
|
+
*
|
|
23
|
+
* Feature flag: recapLayerEnabled (default OFF).
|
|
24
|
+
*
|
|
25
|
+
* See benchmarks-sprint3/2026-05-10-am-baseline-and-rerank-design.md.
|
|
26
|
+
*/
|
|
27
|
+
import type { LLMProvider } from './llm.js';
|
|
28
|
+
import type { MemoryServiceDeps } from './memory-service-types.js';
|
|
29
|
+
export interface RecapContent {
|
|
30
|
+
narrative: string;
|
|
31
|
+
}
|
|
32
|
+
export declare class RecapBuilderError extends Error {
|
|
33
|
+
readonly cause?: unknown | undefined;
|
|
34
|
+
constructor(message: string, cause?: unknown | undefined);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Synthesize an episode narrative from a cluster of memory contents.
|
|
38
|
+
* Fail-closed: throws RecapBuilderError. Caller decides whether to fail
|
|
39
|
+
* the post-write step or just log.
|
|
40
|
+
*/
|
|
41
|
+
export declare function synthesizeRecap(topic: string, memberContents: string[], llmClient?: LLMProvider): Promise<RecapContent>;
|
|
42
|
+
/**
|
|
43
|
+
* Background trigger for episode building. Checks each user-topic pair for
|
|
44
|
+
* un-consolidated clusters meeting the size threshold; for each qualifying
|
|
45
|
+
* cluster, synthesizes + stores a Recap.
|
|
46
|
+
*
|
|
47
|
+
* Fire-and-forget from post-write — never throws to caller.
|
|
48
|
+
*/
|
|
49
|
+
export declare function maybeBuildRecapsForUser(deps: MemoryServiceDeps, userId: string): Promise<number>;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recap layer (Sprint 3 v1) — pre-computed cross-session synthesis.
|
|
3
|
+
*
|
|
4
|
+
* For each cluster of N+ memories that share a conceptual topic, generate
|
|
5
|
+
* an LLM-synthesized narrative ("Episode") and store it as a separate
|
|
6
|
+
* retrievable unit with its own embedding. Cross-session questions ("how
|
|
7
|
+
* did the auth design evolve across sessions?") retrieve the Recap
|
|
8
|
+
* directly instead of re-synthesizing N raw facts at query time.
|
|
9
|
+
*
|
|
10
|
+
* Cog-sci analogue: hippocampal consolidation. Three of the four next-gen
|
|
11
|
+
* memory systems converge on this primitive (Hindsight observations,
|
|
12
|
+
* Honcho dreaming, X-Mem Episodes, EverMemOS multi-pass restructuring).
|
|
13
|
+
*
|
|
14
|
+
* Cluster pivot: `topic_abstraction` field. Requires topic-abstraction
|
|
15
|
+
* layer to be ON during ingest so memories carry topic tags. The clustering
|
|
16
|
+
* is simple grouping by exact topic string + user; embedding-based nearest-
|
|
17
|
+
* neighbor clustering is a v1.1 enhancement.
|
|
18
|
+
*
|
|
19
|
+
* Trigger: post-write hook checks if any topic for the user crosses
|
|
20
|
+
* recapMinClusterSize un-consolidated memories. Builder fires async
|
|
21
|
+
* (no await) so ingest latency is unaffected.
|
|
22
|
+
*
|
|
23
|
+
* Feature flag: recapLayerEnabled (default OFF).
|
|
24
|
+
*
|
|
25
|
+
* See benchmarks-sprint3/2026-05-10-am-baseline-and-rerank-design.md.
|
|
26
|
+
*/
|
|
27
|
+
import { llm as defaultLlm } from './llm.js';
|
|
28
|
+
import { extractFirstJsonObject } from './extraction.js';
|
|
29
|
+
import { embedText } from './embedding.js';
|
|
30
|
+
const RECAP_MAX_TOKENS = 1024;
|
|
31
|
+
const RECAP_MAX_MEMBER_CONTENT_CHARS = 600;
|
|
32
|
+
const RECAP_TARGET_WORD_COUNT = 200;
|
|
33
|
+
const RECAP_SYSTEM_PROMPT = [
|
|
34
|
+
'You synthesize a coherent narrative from a cluster of related memories.',
|
|
35
|
+
'',
|
|
36
|
+
'Rules:',
|
|
37
|
+
'- The cluster shares a conceptual topic (given). Combine the memories into',
|
|
38
|
+
` a single narrative of ~${RECAP_TARGET_WORD_COUNT} words capturing how the`,
|
|
39
|
+
' topic evolved across the cluster.',
|
|
40
|
+
'- Preserve specific facts (names, dates, numbers, decisions).',
|
|
41
|
+
'- Use temporal connectives ("first ... then ... after ... by") so the order',
|
|
42
|
+
' is explicit.',
|
|
43
|
+
'- Do NOT speculate or add information not in the source memories.',
|
|
44
|
+
'- Output a JSON object: {"narrative": "<200-word narrative>"}.',
|
|
45
|
+
'- No markdown fences. No prose around the JSON.',
|
|
46
|
+
].join('\n');
|
|
47
|
+
export class RecapBuilderError extends Error {
|
|
48
|
+
cause;
|
|
49
|
+
constructor(message, cause) {
|
|
50
|
+
super(message);
|
|
51
|
+
this.cause = cause;
|
|
52
|
+
this.name = 'RecapBuilderError';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Synthesize an episode narrative from a cluster of memory contents.
|
|
57
|
+
* Fail-closed: throws RecapBuilderError. Caller decides whether to fail
|
|
58
|
+
* the post-write step or just log.
|
|
59
|
+
*/
|
|
60
|
+
export async function synthesizeRecap(topic, memberContents, llmClient = defaultLlm) {
|
|
61
|
+
if (memberContents.length === 0) {
|
|
62
|
+
throw new RecapBuilderError('cannot synthesize recap from zero members');
|
|
63
|
+
}
|
|
64
|
+
const messages = [
|
|
65
|
+
{ role: 'system', content: RECAP_SYSTEM_PROMPT },
|
|
66
|
+
{ role: 'user', content: buildEpisodeUserMessage(topic, memberContents) },
|
|
67
|
+
];
|
|
68
|
+
let raw;
|
|
69
|
+
try {
|
|
70
|
+
raw = await llmClient.chat(messages, {
|
|
71
|
+
temperature: 0,
|
|
72
|
+
jsonMode: true,
|
|
73
|
+
maxTokens: RECAP_MAX_TOKENS,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
throw new RecapBuilderError(`recap synthesis LLM call failed: ${err.message}`, err);
|
|
78
|
+
}
|
|
79
|
+
if (!raw)
|
|
80
|
+
throw new RecapBuilderError('recap synthesis returned empty content');
|
|
81
|
+
const cleaned = extractFirstJsonObject(raw);
|
|
82
|
+
let parsed;
|
|
83
|
+
try {
|
|
84
|
+
parsed = JSON.parse(cleaned);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
throw new RecapBuilderError(`recap synthesis returned non-JSON: ${cleaned.slice(0, 200)}`, err);
|
|
88
|
+
}
|
|
89
|
+
return validateEpisode(parsed);
|
|
90
|
+
}
|
|
91
|
+
function buildEpisodeUserMessage(topic, memberContents) {
|
|
92
|
+
const truncated = memberContents.map((c, i) => `[${i + 1}] ${c.trim().slice(0, RECAP_MAX_MEMBER_CONTENT_CHARS)}`);
|
|
93
|
+
return [
|
|
94
|
+
`TOPIC: ${topic}`,
|
|
95
|
+
'',
|
|
96
|
+
`MEMORIES (${memberContents.length}):`,
|
|
97
|
+
truncated.join('\n\n'),
|
|
98
|
+
'',
|
|
99
|
+
'Return JSON: {"narrative": "<200-word narrative weaving the memories together>"}',
|
|
100
|
+
].join('\n');
|
|
101
|
+
}
|
|
102
|
+
function validateEpisode(parsed) {
|
|
103
|
+
const narrative = typeof parsed.narrative === 'string' ? parsed.narrative.trim() : null;
|
|
104
|
+
if (!narrative) {
|
|
105
|
+
throw new RecapBuilderError(`recap response missing narrative: ${JSON.stringify(parsed).slice(0, 200)}`);
|
|
106
|
+
}
|
|
107
|
+
if (narrative.split(/\s+/).filter(Boolean).length < 20) {
|
|
108
|
+
throw new RecapBuilderError(`episode narrative too short: "${narrative.slice(0, 100)}"`);
|
|
109
|
+
}
|
|
110
|
+
return { narrative };
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Background trigger for episode building. Checks each user-topic pair for
|
|
114
|
+
* un-consolidated clusters meeting the size threshold; for each qualifying
|
|
115
|
+
* cluster, synthesizes + stores a Recap.
|
|
116
|
+
*
|
|
117
|
+
* Fire-and-forget from post-write — never throws to caller.
|
|
118
|
+
*/
|
|
119
|
+
export async function maybeBuildRecapsForUser(deps, userId) {
|
|
120
|
+
if (!deps.config.recapLayerEnabled)
|
|
121
|
+
return 0;
|
|
122
|
+
const recap = deps.stores.recap;
|
|
123
|
+
if (!recap)
|
|
124
|
+
return 0;
|
|
125
|
+
const minSize = deps.config.recapMinClusterSize;
|
|
126
|
+
const pivot = deps.config.recapClusterPivot ?? 'topic';
|
|
127
|
+
let created = 0;
|
|
128
|
+
try {
|
|
129
|
+
const clusters = await recap.findUnconsolidatedClusters(userId, minSize, pivot);
|
|
130
|
+
for (const cluster of clusters) {
|
|
131
|
+
try {
|
|
132
|
+
const { narrative } = await synthesizeRecap(cluster.topic, cluster.member_contents);
|
|
133
|
+
const embedding = await embedText(narrative, 'document');
|
|
134
|
+
await recap.storeRecap({
|
|
135
|
+
userId,
|
|
136
|
+
recapText: narrative,
|
|
137
|
+
recapEmbedding: embedding,
|
|
138
|
+
topic: cluster.topic,
|
|
139
|
+
memberMemoryIds: cluster.member_ids,
|
|
140
|
+
timeRangeStart: cluster.time_range_start,
|
|
141
|
+
timeRangeEnd: cluster.time_range_end,
|
|
142
|
+
});
|
|
143
|
+
created += 1;
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
// Per-cluster fail-soft: log and continue with the next cluster.
|
|
147
|
+
// The cluster will be retried on the next post-write trigger if the
|
|
148
|
+
// member count still meets threshold.
|
|
149
|
+
console.warn(`[episode] synthesis failed for topic="${cluster.topic}" (${cluster.member_ids.length} members): ${err.message}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
console.warn(`[episode] background pass failed for user=${userId}: ${err.message}`);
|
|
155
|
+
}
|
|
156
|
+
return created;
|
|
157
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reflect worker. Pulls one pending job at a time from reflection_jobs,
|
|
3
|
+
* marks it in_progress, invokes the Reflect orchestrator, and records the
|
|
4
|
+
* outcome on the job row.
|
|
5
|
+
*
|
|
6
|
+
* Mutations fail closed: if Reflect throws, the job is marked failed with
|
|
7
|
+
* the error message — the loop continues with the next job. The worker never
|
|
8
|
+
* silently swallows errors.
|
|
9
|
+
*
|
|
10
|
+
* Designed for single-instance deployment; multi-instance leasing is out of
|
|
11
|
+
* scope for v1.
|
|
12
|
+
*/
|
|
13
|
+
import type { ReflectionJobsRepository } from '../db/reflection-jobs-repository.js';
|
|
14
|
+
import type { ReflectResult } from './reflect.js';
|
|
15
|
+
export interface JobsWorkerDeps {
|
|
16
|
+
jobs: Pick<ReflectionJobsRepository, 'fetchPending' | 'markInProgress' | 'markCompleted' | 'markFailed'>;
|
|
17
|
+
runReflect: (userId: string, conversationId: string) => Promise<ReflectResult>;
|
|
18
|
+
}
|
|
19
|
+
export declare function processOnePendingJob(deps: JobsWorkerDeps): Promise<boolean>;
|
|
20
|
+
export interface WorkerHandle {
|
|
21
|
+
stop: () => void;
|
|
22
|
+
}
|
|
23
|
+
export declare function startReflectWorker(deps: JobsWorkerDeps, pollMs: number): WorkerHandle;
|