@snoai/memory 1.2.2 → 1.2.4
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/README.md +1 -1
- package/dist/{access-tracker-BNqlgChq.d.ts → access-tracker-D20cgP0X.d.ts} +3 -3
- package/dist/{adapter-CeQ7rViY.d.ts → adapter-Dx92oSuo.d.ts} +3 -2
- package/dist/{adapter-XaRHZWZ2.js → adapter-RxQ9CJ7f.js} +1 -1
- package/dist/{agent-llm-port-5oXgBpzJ.d.ts → agent-llm-port-DY2290EK.d.ts} +2 -0
- package/dist/{atomic-memory-extraction-By0axKHc.js → atomic-memory-extraction-BWYEdBhl.js} +4 -4
- package/dist/{atomic-memory-extraction-BT8lFE5t.d.ts → atomic-memory-extraction-Dz-fe3h0.d.ts} +4 -4
- package/dist/{b-profile-section-dictionary-provider-DGtF4dB7.d.ts → b-profile-section-dictionary-provider-D-VJRSOs.d.ts} +1 -1
- package/dist/{capture-policy-detector-CN3vfdNU.d.ts → capture-policy-detector-D7rPVLFp.d.ts} +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/{config-CyH1VuJc.js → config-D3Hc1__G.js} +60 -1
- package/dist/{derived-suppression-cache-BZdBZSdK.d.ts → derived-suppression-cache-BGcKAg2p.d.ts} +1 -1
- package/dist/diagnostic-encoder.js +1 -1
- package/dist/{embedding-provider-client-Q_hJonK9.js → embedding-provider-client-40tpzKou.js} +5 -1
- package/dist/{index-DtqgCT8u.d.ts → index-CgqHi0Rw.d.ts} +2 -2
- package/dist/index.d.ts +10 -10
- package/dist/index.js +6 -5
- package/dist/internal/config/plugin-config-schema.d.ts +1 -1
- package/dist/internal/config/plugin-config-schema.js +1 -1
- package/dist/internal/config/product-mode.d.ts +1 -1
- package/dist/internal/config/settings.d.ts +1 -1
- package/dist/internal/config/settings.js +1 -1
- package/dist/internal/config/skin-defaults.d.ts +1 -1
- package/dist/internal/contract/profile.d.ts +1 -1
- package/dist/internal/contract/routes.d.ts +1 -1
- package/dist/internal/engine/bindings/memory-cli-shared.d.ts +4 -4
- package/dist/internal/engine/bindings/memory-forget-tool.js +1 -1
- package/dist/internal/engine/bindings/memory-list-tool.js +1 -1
- package/dist/internal/engine/bindings/memory-recall-tool.js +1 -1
- package/dist/internal/engine/bindings/memory-reflection-resolve-tool.js +1 -1
- package/dist/internal/engine/bindings/memory-stats-tool.js +1 -1
- package/dist/internal/engine/bindings/memory-store-tool.js +3 -3
- package/dist/internal/engine/bindings/memory-tool-access.d.ts +1 -1
- package/dist/internal/engine/bindings/memory-tool-access.js +1 -1
- package/dist/internal/engine/bindings/memory-tool-results.d.ts +1 -1
- package/dist/internal/engine/bindings/memory-tool-results.js +1 -1
- package/dist/internal/engine/bindings/memory-tool-schemas.d.ts +5 -5
- package/dist/internal/engine/bindings/memory-tool-schemas.js +1 -1
- package/dist/internal/engine/bindings/memory-update-tool.js +2 -2
- package/dist/internal/engine/bindings/sno-station-mem-ambient-learning-hook.d.ts +4 -4
- package/dist/internal/engine/bindings/sno-station-mem-ambient-learning-hook.js +2 -2
- package/dist/internal/engine/bindings/sno-station-mem-auto-recall-hook.d.ts +4 -4
- package/dist/internal/engine/bindings/sno-station-mem-auto-recall-hook.js +1 -1
- package/dist/internal/engine/bindings/sno-station-mem-insight-distill-factory.d.ts +6 -6
- package/dist/internal/engine/bindings/sno-station-mem-insight-distill-factory.js +2 -2
- package/dist/internal/engine/bindings/sno-station-mem-message-transcript.js +2 -2
- package/dist/internal/engine/bindings/sno-station-mem-reset-hook.d.ts +3 -3
- package/dist/internal/engine/bindings/sno-station-mem-runtime-mode.d.ts +1 -1
- package/dist/internal/engine/extraction/atomic-memory-extraction.d.ts +1 -1
- package/dist/internal/engine/extraction/atomic-memory-extraction.js +1 -1
- package/dist/internal/engine/extraction/b-profile-section-dictionary-provider.d.ts +1 -1
- package/dist/internal/engine/extraction/b-profile-section-rekey.d.ts +5 -5
- package/dist/internal/engine/extraction/capture-policy-detector.d.ts +1 -1
- package/dist/internal/engine/extraction/embedding-provider-client.js +1 -1
- package/dist/internal/engine/extraction/memory-metadata-codec.d.ts +2 -2
- package/dist/internal/engine/extraction/memory-temporality-classifier.d.ts +1 -1
- package/dist/internal/engine/extraction/memory-temporality-classifier.js +1 -1
- package/dist/internal/engine/observability/adapter.d.ts +1 -1
- package/dist/internal/engine/observability/adapter.js +1 -1
- package/dist/internal/engine/observability/memory-snapshot.d.ts +1 -1
- package/dist/internal/engine/observability/observable-embedder.d.ts +1 -1
- package/dist/internal/engine/observability/observable-embedder.js +1 -1
- package/dist/internal/engine/observability/observable-llm-client.d.ts +1 -1
- package/dist/internal/engine/observability/observable-memory-store.d.ts +1 -1
- package/dist/internal/engine/observability/observable-memory-store.js +1 -1
- package/dist/internal/engine/observability/observable-retriever.d.ts +1 -1
- package/dist/internal/engine/observability/runtime-diagnostics.d.ts +1 -1
- package/dist/internal/engine/observability/runtime-diagnostics.js +1 -1
- package/dist/internal/engine/operations/memory-tier-promoter.d.ts +1 -1
- package/dist/internal/engine/operations/runtime-audit-log.d.ts +2 -2
- package/dist/internal/engine/provider/provider-registration.d.ts +4 -4
- package/dist/internal/engine/provider/provider-row-renderer.d.ts +1 -1
- package/dist/internal/engine/reflection/reflection-command-hooks.d.ts +1 -1
- package/dist/internal/engine/reflection/reflection-command-hooks.js +1 -1
- package/dist/internal/engine/reflection/reflection-deps.d.ts +1 -1
- package/dist/internal/engine/reflection/reflection-embedded-generator.d.ts +1 -1
- package/dist/internal/engine/reflection/reflection-embedded-generator.js +1 -1
- package/dist/internal/engine/reflection/reflection-injection-hooks.d.ts +1 -1
- package/dist/internal/engine/reflection/reflection-injection-hooks.js +1 -1
- package/dist/internal/engine/reflection/reflection-lifecycle-hooks.d.ts +1 -1
- package/dist/internal/engine/reflection/reflection-lifecycle-hooks.js +1 -1
- package/dist/internal/engine/reflection/strategy-hook-runner.d.ts +3 -3
- package/dist/internal/engine/reflection/strategy-hook-runner.js +2 -2
- package/dist/internal/engine/retrieval/access-tracker.d.ts +1 -1
- package/dist/internal/engine/retrieval/retriever.d.ts +1 -1
- package/dist/internal/engine/shared/memory-kind-policy.d.ts +1 -1
- package/dist/internal/engine/shared/paths.d.ts +2 -2
- package/dist/internal/engine/shared/types.d.ts +2 -2
- package/dist/internal/engine/shared/types.js +1 -1
- package/dist/internal/engine/telemetry/observe-ledger.d.ts +3 -2
- package/dist/internal/engine/telemetry/observe-ledger.js +3 -0
- package/dist/internal/model/agent-llm-port.d.ts +1 -1
- package/dist/internal/model/llm-client.d.ts +2 -2
- package/dist/internal/model/llm-client.js +1 -1
- package/dist/internal/model/llm-mode-routing.d.ts +1 -1
- package/dist/internal/store/maintenance.d.ts +2 -2
- package/dist/internal/store/maintenance.js +21 -7
- package/dist/internal/store/store.d.ts +2 -2
- package/dist/internal/store/store.js +1 -1
- package/dist/{llm-client-BhkzlTnH.js → llm-client-BOkokxti.js} +1 -0
- package/dist/{llm-client-PC0yQuCq.d.ts → llm-client-CtNzuoRc.d.ts} +2 -1
- package/dist/{log-site-catalog.generated-DTY6bcLM.js → log-site-catalog.generated-DoCYZhJF.js} +115 -115
- package/dist/log-site-catalog.json +1 -1
- package/dist/{memory-kind-policy-DnHY7l0n.d.ts → memory-kind-policy-iKHUsuwu.d.ts} +1 -1
- package/dist/{memory-metadata-codec-DbrRyhCg.d.ts → memory-metadata-codec-n-CFKYjn.d.ts} +1 -1
- package/dist/{memory-runtime-ChU1i-bO.js → memory-runtime-CVbnnCfB.js} +159 -120
- package/dist/{memory-snapshot-shzK-0C8.d.ts → memory-snapshot-DhtNqVPs.d.ts} +2 -2
- package/dist/{memory-store-base-Dx6oSqiv.d.ts → memory-store-base-QoyY3sxH.d.ts} +2 -2
- package/dist/{memory-temporality-classifier-D91grvZ3.d.ts → memory-temporality-classifier-Bon6IpEm.d.ts} +1 -1
- package/dist/{memory-temporality-classifier-AetVby94.js → memory-temporality-classifier-C6MW_0i4.js} +1 -1
- package/dist/{memory-tier-promoter-DzX7GMZ2.d.ts → memory-tier-promoter-DeJbiH1w.d.ts} +1 -1
- package/dist/memory-tool-dependencies-CDvVqE6_.d.ts +14 -0
- package/dist/{memory-tool-dependencies-4Vl4QwBY.js → memory-tool-dependencies-CiofG6Lj.js} +1 -1
- package/dist/{observable-embedder-CbFylzsx.d.ts → observable-embedder-B5ZLQv4-.d.ts} +1 -1
- package/dist/{observable-llm-client-BC6Bc8t3.d.ts → observable-llm-client-D65rHe8y.d.ts} +3 -3
- package/dist/{observable-memory-store-BykVMQXt.d.ts → observable-memory-store-CAdLg_OF.d.ts} +4 -4
- package/dist/{observable-retriever-C-c9O83s.d.ts → observable-retriever-DPPwzSY1.d.ts} +5 -5
- package/dist/paths-AoHWqjCM.d.ts +1 -0
- package/dist/plugin-config-observe-schema-BORZ9_7q.js +54 -0
- package/dist/{plugin-config-schema-CTLb-ChF.js → plugin-config-schema-CC-2N9Xw.js} +4 -49
- package/dist/{plugin-config-schema-CCwv_K7R.d.ts → plugin-config-schema-DmbzYMYe.d.ts} +1 -1
- package/dist/{profile-DbIDAmnc.d.ts → profile-C2e9mF3H.d.ts} +1 -1
- package/dist/{profile-section-writer-BV605K78.js → profile-section-writer-qPqgOH-a.js} +2 -2
- package/dist/{reflection-command-hooks-CTYkYqM3.js → reflection-command-hooks-Ctumt-yD.js} +3 -3
- package/dist/{reflection-command-hooks-h2CbYuXx.d.ts → reflection-command-hooks-xeMMA4Ik.d.ts} +4 -4
- package/dist/{reflection-deps-MWVeBZcs.d.ts → reflection-deps-Btr849dc.d.ts} +3 -3
- package/dist/{reflection-embedded-generator-D5OhLLVw.js → reflection-embedded-generator-B5K0O1sJ.js} +1 -1
- package/dist/{reflection-embedded-generator-Dk7sL8uy.d.ts → reflection-embedded-generator-W6MWE9e3.d.ts} +4 -4
- package/dist/{reflection-injection-hooks-B0fGkENX.d.ts → reflection-injection-hooks-BR-bvDmD.d.ts} +4 -4
- package/dist/{reflection-lifecycle-hooks-Bg_JBS6c.d.ts → reflection-lifecycle-hooks-DnQp5cvp.d.ts} +3 -3
- package/dist/rem-batch-executor-C7iItB5x.js +2 -0
- package/dist/{rem-batch-executor-Bdsf26tD.js → rem-trigger-BEIQodYk.js} +857 -138
- package/dist/{retriever-CXeB7-A2.d.ts → retriever-DgVRB1Zq.d.ts} +6 -6
- package/dist/{runtime-audit-log-CIYiNvwf.d.ts → runtime-audit-log-DNPzk6Wy.d.ts} +1 -1
- package/dist/{server-CDy9liZ-.js → server-DyWtDUHh.js} +11 -11
- package/dist/sidecar/main.js +2 -3
- package/dist/{sno-station-mem-runtime-dependencies-Bzfg4hGZ.js → sno-station-mem-runtime-dependencies-D47FAvbm.js} +6 -6
- package/dist/sno-station-mem-runtime-dependencies-EbtwfQh0.d.ts +31 -0
- package/dist/{store-D3n1P7Xn.js → store-ByUy8ukD.js} +1 -1
- package/dist/{store-Dbo7MIzt.d.ts → store-DmFEfRbK.d.ts} +1 -1
- package/dist/{strategy-hook-runner-C6qUCnzY.d.ts → strategy-hook-runner-BdG_ktbm.d.ts} +7 -7
- package/dist/{strategy-hook-runner-CHpG8vXD.js → strategy-hook-runner-CD5X8gs3.js} +1 -1
- package/dist/{types-DvQ6nTNC.d.ts → types-CCPXb_iJ.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/memory-tool-dependencies-BGFjBpkG.d.ts +0 -14
- package/dist/paths-DHU342hf.d.ts +0 -1
- package/dist/rem-batch-executor-DdgZBL5K.js +0 -2
- package/dist/rem-trigger-6dmOjIU_.js +0 -730
- package/dist/routes-DLHT__Ay.js +0 -60
- package/dist/sno-station-mem-runtime-dependencies-cFPSMqDD.d.ts +0 -31
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $ as FIXED_IDX_MEMORY_ACTIVE_TASK_EVIDENCE_INSTANCE, $n as MAX_CHUNK_FETCH_LIMIT, $t as FIXED_VEC_MEMORY, At as FIXED_MEMORY_PROVIDER_AGENT_MAPPINGS, B as FIXED_EXTERNAL_VALUE_51, C as getSnoStationMemStateDir, Cn as CHUNK_TARGET_TOKENS, Cr as LOCAL_EMBEDDING_CACHE_DIR_DEFAULT, Ct as FIXED_MEMORY_CHUNKS_MEM_IDX, D as settingsToPluginConfig, Dn as DEFAULT_RECALL_LIFECYCLE, Dr as ensureModelDownloaded, Dt as FIXED_MEMORY_MEMORIES_FACT_ID_UPDATE_GUARD, En as DEFAULT_IMPORTANCE, Er as LocalEmbedProvider, Et as FIXED_MEMORY_MEMORIES_FACT_ID_INSERT_GUARD, Fn as EMBEDDER_DIM, Ft as FIXED_MEMORY_SNO_EXTRACT_CHAT, G as FIXED_EXTERNAL_VALUE_56, Gt as FIXED_PROTOCOL_VALUE_69, H as FIXED_EXTERNAL_VALUE_53, Hn as HEAD_EXTRACT_OVERLAP_DROP_RATIO, In as EMBEDDER_MODEL_DEFAULT, J as FIXED_EXTERNAL_VALUE_62, Jn as LIGHTWEIGHT_FUSION_WEIGHT, K as FIXED_EXTERNAL_VALUE_57, Kn as INTRA_MEMORY_COSINE_THRESHOLD, Kt as FIXED_PROTOCOL_VALUE_73, Ln as EMBEDDER_PROVIDER_DEFAULT, Lt as FIXED_MEMORY_TASK_LIFECYCLE_COMMANDS, Mn as DEFAULT_RERANK_TIMEOUT_MS, Mt as FIXED_MEMORY_PROVIDER_PROJECT_MAPPINGS, O as MODEL_CALLS, Ot as FIXED_MEMORY_MIGRATION_MARKERS, Pn as DEFAULT_VECTOR_WEIGHT, Q as FIXED_IDX_MEMORY_ACTIVE_TASK_CURRENT_REVISION, Rn as EVAL_QA_TRACES_FILENAME, Rt as FIXED_MEMORY_UNPLACED_CANDIDATES, Sn as CHUNK_OVERLAP_TOKENS, Sr as CachedEmbeddingProvider, St as FIXED_MEMORY_CHUNKS_MEM_FACET_IDX, T as readSettings, Tn as DEFAULT_BM25_WEIGHT, Tt as FIXED_MEMORY_MEMORIES, U as FIXED_EXTERNAL_VALUE_54, Un as HEAD_EXTRACT_TOKEN_BUDGET, V as FIXED_EXTERNAL_VALUE_52, Vn as HEAD_EXTRACT_MIN_CONTENT_TOKENS, W as FIXED_EXTERNAL_VALUE_55, Wn as IMPORTANCE_WEIGHT_BASE, X as FIXED_EXTERNAL_VALUE_9, Y as FIXED_EXTERNAL_VALUE_8, Yn as LIGHTWEIGHT_RERANK_PENALTY, Z as FIXED_IDX_MEMORY, _n as BONUS_TOTAL_INVARIANT, _t as FIXED_MEMORY_CHUNKS_AD, a as REM_MODEL_OUTPUT_TOKEN_CAP, ar as MULTI_HIT_BONUS_CAP, at as FIXED_IDX_MEMORY_MEMORIES_PROJECT, bn as CHUNK_MAX_TOKENS, br as experimentMmrDisabled, bt as FIXED_MEMORY_CHUNKS_FTS, cr as RECENCY_WEIGHT, ct as FIXED_IDX_MEMORY_MEMORIES_PROJECT_TIMESTAMP, dr as RERANK_BLEND_CROSS, dt as FIXED_MEMORY_ACTIVE_TASK_INSTANCES, en as FIXED_VEC_MEMORY_CHUNKS, er as MAX_LIST_LIMIT, et as FIXED_IDX_MEMORY_ACTIVE_TASK_INSTANCES_PROJECTION, fr as RERANK_BLEND_VECTOR, ft as FIXED_MEMORY_ACTIVE_TASK_MIGRATION_EVIDENCE, g as readRemOperationalConfig, gt as FIXED_MEMORY_CHUNKS, hr as TIME_DECAY_FLOOR, ht as FIXED_MEMORY_ACTIVE_TASK_TRANSITIONS, in as PERSISTED_PROVIDER_SYSTEM, ir as MMR_LAMBDA, it as FIXED_IDX_MEMORY_MEMORIES_LANE_PROJECT, jn as DEFAULT_RERANK_MODEL, jt as FIXED_MEMORY_PROVIDER_PROJECT_AGENTS, k as modelCallDestination, kt as FIXED_MEMORY_PROFILE_RECOVERY_ENTRIES, ln as ADJACENCY_BONUS_CAP, lt as FIXED_MEMORY, mt as FIXED_MEMORY_ACTIVE_TASK_REVISIONS, nn as PERSISTED_CONTENT_HASH_V1, nt as FIXED_IDX_MEMORY_MEMORIES_CONTENT_HASH, on as llmRoutingConfigSchema, or as MULTI_HIT_BONUS_PER_HIT, ot as FIXED_IDX_MEMORY_MEMORIES_PROJECT_CONTENT_HASH, pr as RETRIEVAL_STORAGE_CHUNK_PROFILE, pt as FIXED_MEMORY_ACTIVE_TASK_MIGRATION_MANIFESTS, q as FIXED_EXTERNAL_VALUE_58, qn as LIGHTWEIGHT_COSINE_WEIGHT, rn as PERSISTED_CONTENT_HASH_V3, rt as FIXED_IDX_MEMORY_MEMORIES_FACT_ID, sn as SUPPORTED_LOCALES, st as FIXED_IDX_MEMORY_MEMORIES_PROJECT_FACT_KEY_ACTIVE, tn as PERSISTED_CANDIDATE_HASH_V1, tt as FIXED_IDX_MEMORY_MEMORIES_CATEGORY, un as ADJACENCY_BONUS_PER_PAIR, ut as FIXED_MEMORY_ACTIVE_TASK_EVIDENCE, vn as CACHE_TTL_MS, vt as FIXED_MEMORY_CHUNKS_AI, wn as CHUNK_TOKENIZER_MODE, wr as LOCAL_EMBEDDING_MODEL, wt as FIXED_MEMORY_EXTRACTION_TIMESTAMPS, xn as CHUNK_MIN_TOKENS, xt as FIXED_MEMORY_CHUNKS_MEMORY_ID_IDX, yn as CHUNKING_VERSION$1, yr as experimentCandidatePoolOverride, yt as FIXED_MEMORY_CHUNKS_AU, z as FIXED_EXTERNAL_VALUE_49 } from "./config-
|
|
1
|
+
import { $ as FIXED_IDX_MEMORY_ACTIVE_TASK_EVIDENCE_INSTANCE, $n as MAX_CHUNK_FETCH_LIMIT, $t as FIXED_VEC_MEMORY, At as FIXED_MEMORY_PROVIDER_AGENT_MAPPINGS, B as FIXED_EXTERNAL_VALUE_51, C as getSnoStationMemStateDir, Cn as CHUNK_TARGET_TOKENS, Cr as LOCAL_EMBEDDING_CACHE_DIR_DEFAULT, Ct as FIXED_MEMORY_CHUNKS_MEM_IDX, D as settingsToPluginConfig, Dn as DEFAULT_RECALL_LIFECYCLE, Dr as ensureModelDownloaded, Dt as FIXED_MEMORY_MEMORIES_FACT_ID_UPDATE_GUARD, En as DEFAULT_IMPORTANCE, Er as LocalEmbedProvider, Et as FIXED_MEMORY_MEMORIES_FACT_ID_INSERT_GUARD, Fn as EMBEDDER_DIM, Ft as FIXED_MEMORY_SNO_EXTRACT_CHAT, G as FIXED_EXTERNAL_VALUE_56, Gt as FIXED_PROTOCOL_VALUE_69, H as FIXED_EXTERNAL_VALUE_53, Hn as HEAD_EXTRACT_OVERLAP_DROP_RATIO, In as EMBEDDER_MODEL_DEFAULT, J as FIXED_EXTERNAL_VALUE_62, Jn as LIGHTWEIGHT_FUSION_WEIGHT, K as FIXED_EXTERNAL_VALUE_57, Kn as INTRA_MEMORY_COSINE_THRESHOLD, Kt as FIXED_PROTOCOL_VALUE_73, Ln as EMBEDDER_PROVIDER_DEFAULT, Lt as FIXED_MEMORY_TASK_LIFECYCLE_COMMANDS, Mn as DEFAULT_RERANK_TIMEOUT_MS, Mt as FIXED_MEMORY_PROVIDER_PROJECT_MAPPINGS, N as observeAgentId, O as MODEL_CALLS, Ot as FIXED_MEMORY_MIGRATION_MARKERS, Pn as DEFAULT_VECTOR_WEIGHT, Pr as REM_SIDECAR_TOKEN_HEADER, Q as FIXED_IDX_MEMORY_ACTIVE_TASK_CURRENT_REVISION, Rn as EVAL_QA_TRACES_FILENAME, Rt as FIXED_MEMORY_UNPLACED_CANDIDATES, Sn as CHUNK_OVERLAP_TOKENS, Sr as CachedEmbeddingProvider, St as FIXED_MEMORY_CHUNKS_MEM_FACET_IDX, T as readSettings, Tn as DEFAULT_BM25_WEIGHT, Tt as FIXED_MEMORY_MEMORIES, U as FIXED_EXTERNAL_VALUE_54, Un as HEAD_EXTRACT_TOKEN_BUDGET, V as FIXED_EXTERNAL_VALUE_52, Vn as HEAD_EXTRACT_MIN_CONTENT_TOKENS, W as FIXED_EXTERNAL_VALUE_55, Wn as IMPORTANCE_WEIGHT_BASE, X as FIXED_EXTERNAL_VALUE_9, Y as FIXED_EXTERNAL_VALUE_8, Yn as LIGHTWEIGHT_RERANK_PENALTY, Z as FIXED_IDX_MEMORY, _n as BONUS_TOTAL_INVARIANT, _t as FIXED_MEMORY_CHUNKS_AD, a as REM_MODEL_OUTPUT_TOKEN_CAP, ar as MULTI_HIT_BONUS_CAP, at as FIXED_IDX_MEMORY_MEMORIES_PROJECT, bn as CHUNK_MAX_TOKENS, br as experimentMmrDisabled, bt as FIXED_MEMORY_CHUNKS_FTS, cr as RECENCY_WEIGHT, ct as FIXED_IDX_MEMORY_MEMORIES_PROJECT_TIMESTAMP, d as getRemDiscoveryPath, dr as RERANK_BLEND_CROSS, dt as FIXED_MEMORY_ACTIVE_TASK_INSTANCES, en as FIXED_VEC_MEMORY_CHUNKS, er as MAX_LIST_LIMIT, et as FIXED_IDX_MEMORY_ACTIVE_TASK_INSTANCES_PROJECTION, fr as RERANK_BLEND_VECTOR, ft as FIXED_MEMORY_ACTIVE_TASK_MIGRATION_EVIDENCE, g as readRemOperationalConfig, gt as FIXED_MEMORY_CHUNKS, hr as TIME_DECAY_FLOOR, ht as FIXED_MEMORY_ACTIVE_TASK_TRANSITIONS, in as PERSISTED_PROVIDER_SYSTEM, ir as MMR_LAMBDA, it as FIXED_IDX_MEMORY_MEMORIES_LANE_PROJECT, jn as DEFAULT_RERANK_MODEL, jt as FIXED_MEMORY_PROVIDER_PROJECT_AGENTS, k as modelCallDestination, kt as FIXED_MEMORY_PROFILE_RECOVERY_ENTRIES, ln as ADJACENCY_BONUS_CAP, lt as FIXED_MEMORY, mt as FIXED_MEMORY_ACTIVE_TASK_REVISIONS, nn as PERSISTED_CONTENT_HASH_V1, nt as FIXED_IDX_MEMORY_MEMORIES_CONTENT_HASH, o as REM_RUN_PATH, on as llmRoutingConfigSchema, or as MULTI_HIT_BONUS_PER_HIT, ot as FIXED_IDX_MEMORY_MEMORIES_PROJECT_CONTENT_HASH, pr as RETRIEVAL_STORAGE_CHUNK_PROFILE, pt as FIXED_MEMORY_ACTIVE_TASK_MIGRATION_MANIFESTS, q as FIXED_EXTERNAL_VALUE_58, qn as LIGHTWEIGHT_COSINE_WEIGHT, r as REM_CORRELATION_ID_HEADER, rn as PERSISTED_CONTENT_HASH_V3, rt as FIXED_IDX_MEMORY_MEMORIES_FACT_ID, s as REM_SIDECAR_HOST, sn as SUPPORTED_LOCALES, st as FIXED_IDX_MEMORY_MEMORIES_PROJECT_FACT_KEY_ACTIVE, tn as PERSISTED_CANDIDATE_HASH_V1, tt as FIXED_IDX_MEMORY_MEMORIES_CATEGORY, un as ADJACENCY_BONUS_PER_PAIR, ut as FIXED_MEMORY_ACTIVE_TASK_EVIDENCE, vn as CACHE_TTL_MS, vt as FIXED_MEMORY_CHUNKS_AI, wn as CHUNK_TOKENIZER_MODE, wr as LOCAL_EMBEDDING_MODEL, wt as FIXED_MEMORY_EXTRACTION_TIMESTAMPS, xn as CHUNK_MIN_TOKENS, xt as FIXED_MEMORY_CHUNKS_MEMORY_ID_IDX, yn as CHUNKING_VERSION$1, yr as experimentCandidatePoolOverride, yt as FIXED_MEMORY_CHUNKS_AU, z as FIXED_EXTERNAL_VALUE_49 } from "./config-D3Hc1__G.js";
|
|
2
2
|
import { createLogger, createLogger as createLogger$1, currentLogContext, privateLogReference, withLogContext } from "@snoai/utils/logger";
|
|
3
3
|
import path, { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { appendFileSync, createReadStream, existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { arch, platform } from "node:os";
|
|
5
|
+
import { arch, availableParallelism, platform } from "node:os";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { LRUCache } from "lru-cache";
|
|
8
8
|
import { z } from "zod";
|
|
@@ -10,7 +10,7 @@ import { CHUNKING_VERSION, aggregateChunksToMemories, buildChunkId, buildDensePa
|
|
|
10
10
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
11
11
|
import { createHash, createHmac, createPublicKey, randomUUID, randomUUID as randomUUID$1, timingSafeEqual, verify } from "node:crypto";
|
|
12
12
|
import { getDek, openEncryptedDb, openEncryptedDbReadonly } from "@snoai/sqlite-crypto";
|
|
13
|
-
import { appendFile } from "node:fs/promises";
|
|
13
|
+
import { appendFile, mkdir, open, readFile, rename, rm } from "node:fs/promises";
|
|
14
14
|
import { Temporal } from "@js-temporal/polyfill";
|
|
15
15
|
import { redactForStorage, sanitizeContentIngress, sanitizeStructuredJsonForStorage } from "@snoai/content-sanitizer";
|
|
16
16
|
import { CallPipeline, ConfigRegistryManager, KeyPool, loadLlmixTrustManifest, registryRootOptionsFromTrustManifest } from "@snoai/llmix";
|
|
@@ -37,9 +37,10 @@ var __exportAll = (all, no_symbols) => {
|
|
|
37
37
|
};
|
|
38
38
|
//#endregion
|
|
39
39
|
//#region src/engine/telemetry/observe-ledger.ts
|
|
40
|
-
const log$
|
|
40
|
+
const log$23 = createLogger("sno-station-mem:observe-ledger");
|
|
41
41
|
const rowSchema = z.object({
|
|
42
42
|
ts_ms: z.number().int().nonnegative(),
|
|
43
|
+
agent_id: z.string().transform(observeAgentId).optional(),
|
|
43
44
|
event_type: z.string(),
|
|
44
45
|
lane: z.string(),
|
|
45
46
|
project_id: z.string().min(1).optional(),
|
|
@@ -53,7 +54,7 @@ function observeLedgerSyncedPath(profileDir) {
|
|
|
53
54
|
}
|
|
54
55
|
function warn(observe, message) {
|
|
55
56
|
if (observe.logger) observe.logger.warn(message);
|
|
56
|
-
else log$
|
|
57
|
+
else log$23.warn(message, void 0, {
|
|
57
58
|
event_name: "observe.ledger.failed",
|
|
58
59
|
file: "packages/memory/src/engine/telemetry/observe-ledger.ts",
|
|
59
60
|
function: "forwardObserveLedger",
|
|
@@ -117,6 +118,7 @@ async function forwardObserveLedger(options) {
|
|
|
117
118
|
try {
|
|
118
119
|
if (await observe.tryEmit({
|
|
119
120
|
eventType: row.event_type,
|
|
121
|
+
agentId: row.agent_id,
|
|
120
122
|
payload: row.payload,
|
|
121
123
|
tsEdgeMs: row.ts_ms,
|
|
122
124
|
...row.project_id ? { scope: { project_id: row.project_id } } : {}
|
|
@@ -139,7 +141,7 @@ async function forwardObserveLedgerUntilIdle(options) {
|
|
|
139
141
|
//#endregion
|
|
140
142
|
//#region src/engine/operation-cancellation.ts
|
|
141
143
|
const operations = new AsyncLocalStorage();
|
|
142
|
-
const log$
|
|
144
|
+
const log$22 = createLogger("sno-station-mem:cancellation");
|
|
143
145
|
/** Carries cancellation through the existing nested extraction and reflection writers. */
|
|
144
146
|
async function withMemoryOperation(method, signal, run) {
|
|
145
147
|
const operation = {
|
|
@@ -155,7 +157,7 @@ async function withMemoryOperation(method, signal, run) {
|
|
|
155
157
|
signal?.throwIfAborted();
|
|
156
158
|
return result;
|
|
157
159
|
} finally {
|
|
158
|
-
if (signal?.aborted) log$
|
|
160
|
+
if (signal?.aborted) log$22.error("memory.operation.aborted", {
|
|
159
161
|
method,
|
|
160
162
|
outcome: "aborted",
|
|
161
163
|
writes: operation.writes
|
|
@@ -6089,7 +6091,7 @@ async function resolveLlmEndpoint(input) {
|
|
|
6089
6091
|
}
|
|
6090
6092
|
//#endregion
|
|
6091
6093
|
//#region src/model/llm-provider-transport.ts
|
|
6092
|
-
const log$
|
|
6094
|
+
const log$21 = createLogger("sno-station-mem:llm-provider-transport");
|
|
6093
6095
|
const routeInFlight = /* @__PURE__ */ new Map();
|
|
6094
6096
|
const providerResponses = new AsyncLocalStorage();
|
|
6095
6097
|
/** Collect actual provider usage for the current sidecar request, without changing transport. */
|
|
@@ -6116,7 +6118,7 @@ async function observeRequest(input, run) {
|
|
|
6116
6118
|
const remaining = (routeInFlight.get(route) ?? 1) - 1;
|
|
6117
6119
|
if (remaining === 0) routeInFlight.delete(route);
|
|
6118
6120
|
else routeInFlight.set(route, remaining);
|
|
6119
|
-
log$
|
|
6121
|
+
log$21.info("Model request completed", {
|
|
6120
6122
|
outcome,
|
|
6121
6123
|
error: failure,
|
|
6122
6124
|
call_id: input.slot ?? "unavailable",
|
|
@@ -6508,7 +6510,7 @@ function resolveProviderApiKey(config, resolved, userBaseUrlOverride) {
|
|
|
6508
6510
|
}
|
|
6509
6511
|
//#endregion
|
|
6510
6512
|
//#region src/model/llm-client.ts
|
|
6511
|
-
const log$
|
|
6513
|
+
const log$20 = createLogger("sno-station-mem:llm-client");
|
|
6512
6514
|
let hostRequestsInFlight = 0;
|
|
6513
6515
|
/**
|
|
6514
6516
|
* Last-resort output cap for a raw-completion caller that set none. Every use is logged as an
|
|
@@ -6746,7 +6748,7 @@ function createLlmClient(config) {
|
|
|
6746
6748
|
config: config.routing
|
|
6747
6749
|
});
|
|
6748
6750
|
if ("off" in decision) {
|
|
6749
|
-
log$
|
|
6751
|
+
log$20.debug("Model client request diagnostic", {
|
|
6750
6752
|
call_id: request.callId,
|
|
6751
6753
|
destination: destinationFor(request),
|
|
6752
6754
|
error: `sno-station-mem: llm-client [${request.callId}] routed off (${decision.reason}); deterministic fallback applies`
|
|
@@ -6761,7 +6763,7 @@ function createLlmClient(config) {
|
|
|
6761
6763
|
if (decision.transport === "agent-host-seam") {
|
|
6762
6764
|
if (config.agentPort) return "agent-host-seam";
|
|
6763
6765
|
state.error = `sno-station-mem: llm-client [${request.callId}] routed to agent-host-seam but AgentLlmPort is unavailable`;
|
|
6764
|
-
log$
|
|
6766
|
+
log$20.warn("Model client request diagnostic", {
|
|
6765
6767
|
call_id: request.callId,
|
|
6766
6768
|
destination: destinationFor(request),
|
|
6767
6769
|
error: state.error
|
|
@@ -6811,7 +6813,7 @@ function createLlmClient(config) {
|
|
|
6811
6813
|
return completion;
|
|
6812
6814
|
} finally {
|
|
6813
6815
|
hostRequestsInFlight -= 1;
|
|
6814
|
-
log$
|
|
6816
|
+
log$20.info("Host model request completed", {
|
|
6815
6817
|
outcome,
|
|
6816
6818
|
transport: "agent-host-seam",
|
|
6817
6819
|
call_id: request.callId,
|
|
@@ -6850,7 +6852,7 @@ function createLlmClient(config) {
|
|
|
6850
6852
|
});
|
|
6851
6853
|
if (result.kind === "cancelled") {
|
|
6852
6854
|
state.error = `[${request.callId}] agent-llm cancelled (${result.reason})`;
|
|
6853
|
-
log$
|
|
6855
|
+
log$20.warn("Host model request cancelled", {
|
|
6854
6856
|
call_id: request.callId,
|
|
6855
6857
|
destination,
|
|
6856
6858
|
error: state.error
|
|
@@ -6871,7 +6873,7 @@ function createLlmClient(config) {
|
|
|
6871
6873
|
failure: `host_${result.category}`,
|
|
6872
6874
|
durationMs: performance.now() - hostStarted
|
|
6873
6875
|
});
|
|
6874
|
-
log$
|
|
6876
|
+
log$20.warn("Host model request failed", {
|
|
6875
6877
|
call_id: request.callId,
|
|
6876
6878
|
destination,
|
|
6877
6879
|
failure_category: result.category,
|
|
@@ -6897,6 +6899,7 @@ function createLlmClient(config) {
|
|
|
6897
6899
|
transport
|
|
6898
6900
|
};
|
|
6899
6901
|
}
|
|
6902
|
+
if (config.hostRequired && config.agentPort?.reachable && !await config.agentPort.reachable()) throw new ModelCallRefusedError(request.callId, "host", "no-agent-endpoint");
|
|
6900
6903
|
const endpoint = await getEndpoint(request.callId, transport);
|
|
6901
6904
|
checkMemoryOperation();
|
|
6902
6905
|
const preset = endpoint.preset;
|
|
@@ -6904,7 +6907,7 @@ function createLlmClient(config) {
|
|
|
6904
6907
|
const operationId = config.operationId ?? memoryOperationId();
|
|
6905
6908
|
if (transport === "raw-completions") {
|
|
6906
6909
|
if (preset.provider !== "sno-gpu") throw new Error("raw completion requires the sno-gpu provider");
|
|
6907
|
-
if (MODEL_CALLS[request.callId].replyParser.snoGpu !== "single-token-verdict" && !request.maxTokens) log$
|
|
6910
|
+
if (MODEL_CALLS[request.callId].replyParser.snoGpu !== "single-token-verdict" && !request.maxTokens) log$20.error("Model client request diagnostic", {
|
|
6908
6911
|
call_id: request.callId,
|
|
6909
6912
|
destination,
|
|
6910
6913
|
error: `sno-station-mem llm-client: raw completion [${request.callId}] set no maxTokens; sending ${RAW_COMPLETION_FALLBACK_MAX_TOKENS} so the call still runs. Fix the caller — without a cap the serving side truncates at 16 tokens.`
|
|
@@ -6939,7 +6942,7 @@ function createLlmClient(config) {
|
|
|
6939
6942
|
});
|
|
6940
6943
|
if (!response.success) {
|
|
6941
6944
|
state.error = `sno-station-mem: llm-client [${request.callId}] pipeline error: ${response.error}`;
|
|
6942
|
-
log$
|
|
6945
|
+
log$20.warn("Raw model request failed", {
|
|
6943
6946
|
call_id: request.callId,
|
|
6944
6947
|
destination,
|
|
6945
6948
|
error: state.error
|
|
@@ -6979,7 +6982,7 @@ function createLlmClient(config) {
|
|
|
6979
6982
|
});
|
|
6980
6983
|
if (!response.success) {
|
|
6981
6984
|
state.error = `sno-station-mem: llm-client [${request.callId}] pipeline error: ${response.error}`;
|
|
6982
|
-
log$
|
|
6985
|
+
log$20.warn("Chat model request failed", {
|
|
6983
6986
|
call_id: request.callId,
|
|
6984
6987
|
destination,
|
|
6985
6988
|
error: state.error
|
|
@@ -6998,7 +7001,7 @@ function createLlmClient(config) {
|
|
|
6998
7001
|
const raw = response.content;
|
|
6999
7002
|
if (!raw) {
|
|
7000
7003
|
state.error = `sno-station-mem: llm-client [${request.callId}] empty response from preset ${config.preset}`;
|
|
7001
|
-
log$
|
|
7004
|
+
log$20.warn("Model reply empty", {
|
|
7002
7005
|
call_id: request.callId,
|
|
7003
7006
|
destination,
|
|
7004
7007
|
error: state.error
|
|
@@ -7037,7 +7040,7 @@ function createLlmClient(config) {
|
|
|
7037
7040
|
if (content === null || content.raw.trim().length > 0) break;
|
|
7038
7041
|
const remainingMs = deadlineMs - performance.now();
|
|
7039
7042
|
if (remainingMs <= 0) break;
|
|
7040
|
-
log$
|
|
7043
|
+
log$20.debug("Retrying empty model reply", {
|
|
7041
7044
|
call_id: request.callId,
|
|
7042
7045
|
destination: destinationFor(request),
|
|
7043
7046
|
attempt,
|
|
@@ -7096,7 +7099,7 @@ function createLlmClient(config) {
|
|
|
7096
7099
|
else try {
|
|
7097
7100
|
const host = await requestContent(state, request, systemContent, request.hostPrompt ?? request.prompt, "host");
|
|
7098
7101
|
if (host?.raw.trim()) {
|
|
7099
|
-
log$
|
|
7102
|
+
log$20.info("Sno model call answered by host", {
|
|
7100
7103
|
call_id: request.callId,
|
|
7101
7104
|
operation_id: operationId,
|
|
7102
7105
|
sno_failure: snoFailure,
|
|
@@ -7118,7 +7121,7 @@ function createLlmClient(config) {
|
|
|
7118
7121
|
}
|
|
7119
7122
|
state.error = originalLastError;
|
|
7120
7123
|
state.usage = originalLastUsage;
|
|
7121
|
-
log$
|
|
7124
|
+
log$20.warn("Sno model call and host fallback failed", {
|
|
7122
7125
|
call_id: request.callId,
|
|
7123
7126
|
operation_id: operationId,
|
|
7124
7127
|
sno_failure: snoFailure,
|
|
@@ -7154,7 +7157,7 @@ function createLlmClient(config) {
|
|
|
7154
7157
|
const remainingTimeoutMs = Math.floor(deadlineMs - performance.now());
|
|
7155
7158
|
if (remainingTimeoutMs <= 0) {
|
|
7156
7159
|
state.error = `sno-station-mem: llm-client [${request.callId}] deadline exhausted before JSON repair`;
|
|
7157
|
-
log$
|
|
7160
|
+
log$20.warn("Model repair deadline exhausted", {
|
|
7158
7161
|
call_id: request.callId,
|
|
7159
7162
|
destination: destinationFor(request),
|
|
7160
7163
|
error: state.error
|
|
@@ -7175,7 +7178,7 @@ function createLlmClient(config) {
|
|
|
7175
7178
|
if (parsed.ok) return parsed.value;
|
|
7176
7179
|
}
|
|
7177
7180
|
state.error = `sno-station-mem: llm-client [${request.callId}] ${parsed.error}`;
|
|
7178
|
-
log$
|
|
7181
|
+
log$20.warn("Model client request diagnostic", {
|
|
7179
7182
|
operation: "completeJson",
|
|
7180
7183
|
call_id: request.callId,
|
|
7181
7184
|
destination: destinationFor(request),
|
|
@@ -7191,7 +7194,7 @@ function createLlmClient(config) {
|
|
|
7191
7194
|
checkMemoryOperation();
|
|
7192
7195
|
if (err instanceof LlmClientTerminalError || err instanceof ModelCallRefusedError) throw err;
|
|
7193
7196
|
state.error = `sno-station-mem: llm-client [${request.callId}] request failed for preset ${config.preset}: ${err instanceof Error ? err.message : String(err)}`;
|
|
7194
|
-
log$
|
|
7197
|
+
log$20.warn("Model request failed", {
|
|
7195
7198
|
call_id: request.callId,
|
|
7196
7199
|
destination: destinationFor(request),
|
|
7197
7200
|
error: state.error
|
|
@@ -7225,7 +7228,7 @@ function createLlmClient(config) {
|
|
|
7225
7228
|
checkMemoryOperation();
|
|
7226
7229
|
if (err instanceof LlmClientTerminalError || err instanceof ModelCallRefusedError) throw err;
|
|
7227
7230
|
state.error = `sno-station-mem: llm-client [${request.callId}] request failed for preset ${config.preset}: ${err instanceof Error ? err.message : String(err)}`;
|
|
7228
|
-
log$
|
|
7231
|
+
log$20.warn("Model client request diagnostic", {
|
|
7229
7232
|
call_id: request.callId,
|
|
7230
7233
|
destination: destinationFor(request),
|
|
7231
7234
|
error: state.error
|
|
@@ -7276,7 +7279,7 @@ const SCOPE_PATTERNS = {
|
|
|
7276
7279
|
* @purpose Normalizes agent identities and configured access lists for scope policy.
|
|
7277
7280
|
* @boundary Identity parsing, bypass detection, and config normalization only.
|
|
7278
7281
|
*/
|
|
7279
|
-
const log$
|
|
7282
|
+
const log$19 = createLogger("sno-station-mem:scopes");
|
|
7280
7283
|
const SYSTEM_BYPASS_IDS = /* @__PURE__ */ new Set(["system", "undefined"]);
|
|
7281
7284
|
const warnedLegacyStringBypassIds = /* @__PURE__ */ new Set();
|
|
7282
7285
|
function normalizeExtraAccessibleScopes(extraAccessibleScopes) {
|
|
@@ -7296,7 +7299,7 @@ function isSystemBypassId(agentId) {
|
|
|
7296
7299
|
if (typeof agentId !== "string") return false;
|
|
7297
7300
|
if (agentId === "undefined" && !warnedLegacyStringBypassIds.has(agentId)) {
|
|
7298
7301
|
warnedLegacyStringBypassIds.add(agentId);
|
|
7299
|
-
log$
|
|
7302
|
+
log$19.warn("legacy string agentId bypass detected", { reason_code: "legacy_undefined_string" }, {
|
|
7300
7303
|
event_name: "sno_station_mem.scope-identity.legacy.string.agentid.bypass.detected",
|
|
7301
7304
|
file: "packages/memory/src/engine/security/scope-identity.ts",
|
|
7302
7305
|
function: "isSystemBypassId",
|
|
@@ -14139,7 +14142,7 @@ function normalizeAmbientLearningText(role, text, shouldSkipMessage) {
|
|
|
14139
14142
|
* @purpose Normalize runtime payload text before it reaches memory extraction.
|
|
14140
14143
|
* @boundary Removes channel/runtime envelope metadata only; does not classify or persist memories.
|
|
14141
14144
|
*/
|
|
14142
|
-
const log$
|
|
14145
|
+
const log$18 = createLogger("sno-station-mem:extraction-text-sanitizer");
|
|
14143
14146
|
/**
|
|
14144
14147
|
* Keeps a section's clause list inside `DEFAULT_MAX_CONTEXT_TOKENS`, the repository-wide
|
|
14145
14148
|
* per-record ceiling the store refuses to write past.
|
|
@@ -14161,7 +14164,7 @@ function boundSectionContent(content, abstract, countRecordTokens) {
|
|
|
14161
14164
|
let first = 0;
|
|
14162
14165
|
while (first < clauses.length && countRecordTokens(buildIndexedText(abstract, clauses.slice(first).join("\n"))) > 512) first += 1;
|
|
14163
14166
|
const kept = clauses.slice(first).join("\n");
|
|
14164
|
-
log$
|
|
14167
|
+
log$18.warn("profile section trimmed to the record token ceiling", {
|
|
14165
14168
|
droppedClauses: first,
|
|
14166
14169
|
keptClauses: clauses.length - first,
|
|
14167
14170
|
maxTokens: 512
|
|
@@ -14244,7 +14247,7 @@ function stripEnvelopeMetadata(text) {
|
|
|
14244
14247
|
//#endregion
|
|
14245
14248
|
//#region src/engine/extraction/date-resolution.ts
|
|
14246
14249
|
/** Model-only time interpretation followed by deterministic calendar arithmetic. */
|
|
14247
|
-
const log$
|
|
14250
|
+
const log$17 = createLogger("sno-station-mem:date-resolution");
|
|
14248
14251
|
/** No model means no semantic decision. Preserve the text rather than interpreting it. */
|
|
14249
14252
|
function unresolvedMemoryDate(input) {
|
|
14250
14253
|
return {
|
|
@@ -14295,7 +14298,7 @@ async function resolveMemoryDate(input) {
|
|
|
14295
14298
|
}) : void 0;
|
|
14296
14299
|
if (!reply) {
|
|
14297
14300
|
const reason = raw === null ? "model-unavailable" : "invalid-model-instruction";
|
|
14298
|
-
log$
|
|
14301
|
+
log$17.warn("Memory time judgment failed; preserving unresolved time", {
|
|
14299
14302
|
model_called: true,
|
|
14300
14303
|
reason
|
|
14301
14304
|
}, {
|
|
@@ -14317,7 +14320,7 @@ async function resolveMemoryDate(input) {
|
|
|
14317
14320
|
reason: reply.reason
|
|
14318
14321
|
};
|
|
14319
14322
|
const calculated = calculateCalendarTime(reply.time, anchor, unresolved.timezone);
|
|
14320
|
-
log$
|
|
14323
|
+
log$17.info("Memory date resolution completed", {
|
|
14321
14324
|
model_called: true,
|
|
14322
14325
|
resolved: calculated !== null
|
|
14323
14326
|
}, {
|
|
@@ -14386,7 +14389,7 @@ function serializeIntervalMetadata(category, interval) {
|
|
|
14386
14389
|
}
|
|
14387
14390
|
//#endregion
|
|
14388
14391
|
//#region src/engine/operations/jsonl-lines.ts
|
|
14389
|
-
const log$
|
|
14392
|
+
const log$16 = createLogger("sno-station-mem:jsonl");
|
|
14390
14393
|
/** Preserve complete records without materializing an unbounded log as one string. */
|
|
14391
14394
|
async function* readJsonlLines(file) {
|
|
14392
14395
|
const stream = createReadStream(file, { encoding: "utf8" });
|
|
@@ -14398,7 +14401,7 @@ async function* readJsonlLines(file) {
|
|
|
14398
14401
|
for await (const line of lines) if (line.trim()) yield line;
|
|
14399
14402
|
} catch (error) {
|
|
14400
14403
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") return;
|
|
14401
|
-
log$
|
|
14404
|
+
log$16.error("jsonl.read.failed", {
|
|
14402
14405
|
file,
|
|
14403
14406
|
error
|
|
14404
14407
|
}, {
|
|
@@ -17829,7 +17832,7 @@ function loadSqliteVecExtension(database) {
|
|
|
17829
17832
|
* idempotent, so an interrupted move simply completes on the next boot.
|
|
17830
17833
|
* @boundary Reads and writes only those two tables through the caller's handle.
|
|
17831
17834
|
*/
|
|
17832
|
-
const log$
|
|
17835
|
+
const log$14 = createLogger("unplaced-candidate-migration");
|
|
17833
17836
|
/**
|
|
17834
17837
|
* Legacy rows are keyed on their own row id, not on the live writer's basis.
|
|
17835
17838
|
* Two legacy rows can carry byte-identical payloads and reasons and still be
|
|
@@ -17872,7 +17875,7 @@ function migrateUnplacedCandidates(sqlite) {
|
|
|
17872
17875
|
}
|
|
17873
17876
|
return moved;
|
|
17874
17877
|
})();
|
|
17875
|
-
log$
|
|
17878
|
+
log$14.warn("relocated non-active memory rows into the unplaced-candidate table", { moved }, {
|
|
17876
17879
|
event_name: FIXED_EXTERNAL_VALUE_62,
|
|
17877
17880
|
file: "packages/memory/src/store/unplaced-candidate-migration.ts",
|
|
17878
17881
|
function: "migrateUnplacedCandidates",
|
|
@@ -17887,7 +17890,7 @@ function migrateUnplacedCandidates(sqlite) {
|
|
|
17887
17890
|
* @boundary Filesystem safety, database pragmas, migrations, and runtime loading.
|
|
17888
17891
|
* @see sqlite-runtime.ts, schema.ts, store.ts.
|
|
17889
17892
|
*/
|
|
17890
|
-
const log$
|
|
17893
|
+
const log$13 = createLogger("sno-station-mem:db");
|
|
17891
17894
|
function parseVecTableDimension(sql) {
|
|
17892
17895
|
if (!/create\s+virtual\s+table/i.test(sql) || !/using\s+vec0/i.test(sql)) throw new StorageError(`nodix_memory_chunk_vectors exists but is not a sqlite-vec virtual table: ${sql}`);
|
|
17893
17896
|
const token = sql.match(/embedding\s+float\[(\d+)\]/i)?.[1];
|
|
@@ -17926,7 +17929,7 @@ function ensureChunkVecTable(db, vectorDim) {
|
|
|
17926
17929
|
const existing = readChunkVecTableState(db);
|
|
17927
17930
|
if (existing && (existing.dimension !== vectorDim || !existing.hasPartitionKey)) {
|
|
17928
17931
|
if (existing.rowCount > 0) {
|
|
17929
|
-
log$
|
|
17932
|
+
log$13.error("storage.vector.configuration.mismatch", {
|
|
17930
17933
|
vectorDim,
|
|
17931
17934
|
existing
|
|
17932
17935
|
}, {
|
|
@@ -17966,7 +17969,7 @@ function loadSimpleTokenizer(db) {
|
|
|
17966
17969
|
db.loadExtension(extensionPath);
|
|
17967
17970
|
db.prepare("SELECT jieba_dict(?)").get(dictPath);
|
|
17968
17971
|
db.exec("CREATE VIRTUAL TABLE temp.nodix_simple_tokenizer_smoke USING fts5(x, tokenize='simple 0'); DROP TABLE temp.nodix_simple_tokenizer_smoke;");
|
|
17969
|
-
log$
|
|
17972
|
+
log$13.info("simple-tokenizer loaded", {
|
|
17970
17973
|
platform,
|
|
17971
17974
|
extensionPath
|
|
17972
17975
|
}, {
|
|
@@ -17996,7 +17999,7 @@ function resolveMigrationsDir() {
|
|
|
17996
17999
|
const MIGRATIONS_DIR = resolveMigrationsDir();
|
|
17997
18000
|
/** Implements init db as the local SQLite connection setup operation. */
|
|
17998
18001
|
function initDb(dbPath, vectorDim) {
|
|
17999
|
-
log$
|
|
18002
|
+
log$13.info("initializing database", {
|
|
18000
18003
|
dbPath,
|
|
18001
18004
|
vectorDim
|
|
18002
18005
|
}, {
|
|
@@ -18013,7 +18016,7 @@ function initDb(dbPath, vectorDim) {
|
|
|
18013
18016
|
run();
|
|
18014
18017
|
pending.delete(step);
|
|
18015
18018
|
} catch (error) {
|
|
18016
|
-
log$
|
|
18019
|
+
log$13.error("storage.setup.failed", {
|
|
18017
18020
|
step,
|
|
18018
18021
|
error
|
|
18019
18022
|
}, {
|
|
@@ -18072,7 +18075,7 @@ function ensureColumn(database, tableName, columnName, declaration) {
|
|
|
18072
18075
|
* @boundary SQLite schema, embedding vectors, FTS, and metadata invariants.
|
|
18073
18076
|
* @see connection.ts, schema.ts, retriever.ts.
|
|
18074
18077
|
*/
|
|
18075
|
-
const log$
|
|
18078
|
+
const log$12 = createLogger("sno-station-mem:store");
|
|
18076
18079
|
/**
|
|
18077
18080
|
* Reflection v3: discriminator added to content-hash input when the
|
|
18078
18081
|
* row carries a `metadata.mappedKind`. Two rows with same projectId + same store
|
|
@@ -18339,7 +18342,7 @@ function verification(status, receipt) {
|
|
|
18339
18342
|
}
|
|
18340
18343
|
//#endregion
|
|
18341
18344
|
//#region src/engine/telemetry/memory-telemetry-events.ts
|
|
18342
|
-
const log$
|
|
18345
|
+
const log$11 = createLogger("sno-station-mem:memory-telemetry-events");
|
|
18343
18346
|
var MemoryTelemetryEventWriter = class {
|
|
18344
18347
|
sqlite;
|
|
18345
18348
|
enabled;
|
|
@@ -18374,7 +18377,7 @@ var MemoryTelemetryEventWriter = class {
|
|
|
18374
18377
|
});
|
|
18375
18378
|
this.receiptService = options.config?.receiptService ?? createMemoryTelemetryReceiptService(keySet);
|
|
18376
18379
|
} catch (error) {
|
|
18377
|
-
log$
|
|
18380
|
+
log$11.warn("memory telemetry disabled: receipt key unavailable", { error }, {
|
|
18378
18381
|
event_name: "sno_station_mem.memory-telemetry-events.memory.telemetry.disabled.receipt.key.unavailable",
|
|
18379
18382
|
file: "packages/memory/src/engine/telemetry/memory-telemetry-events.ts",
|
|
18380
18383
|
function: "<anonymous callback>",
|
|
@@ -18752,7 +18755,7 @@ var MemoryStore = class {
|
|
|
18752
18755
|
sqlite.close();
|
|
18753
18756
|
throw error;
|
|
18754
18757
|
}
|
|
18755
|
-
log$
|
|
18758
|
+
log$12.info("memory store initialized", {
|
|
18756
18759
|
dbPath: config.dbPath,
|
|
18757
18760
|
vectorDim: this.vectorDim,
|
|
18758
18761
|
hasFtsSupport: this.hasFtsSupport
|
|
@@ -18911,7 +18914,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
18911
18914
|
} catch (error) {
|
|
18912
18915
|
failedRows++;
|
|
18913
18916
|
if (firstFailure === void 0 && error instanceof Error) firstFailure = error;
|
|
18914
|
-
log$
|
|
18917
|
+
log$12.warn("legacy memory chunk backfill skipped row", {
|
|
18915
18918
|
memory_id: row.id,
|
|
18916
18919
|
error
|
|
18917
18920
|
}, {
|
|
@@ -18961,7 +18964,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
18961
18964
|
this.backfillFailureCount = 0;
|
|
18962
18965
|
this.backfillNextRetryAt = 0;
|
|
18963
18966
|
this.backfillLastFailureAt = 0;
|
|
18964
|
-
if (count > 0) log$
|
|
18967
|
+
if (count > 0) log$12.info("backfilled legacy memory chunks", { count }, {
|
|
18965
18968
|
event_name: "sno_station_mem.memory-store-backfill.backfilled.legacy.memory.chunks",
|
|
18966
18969
|
file: "packages/memory/src/store/memory-store-backfill.ts",
|
|
18967
18970
|
function: "<anonymous callback>",
|
|
@@ -18974,7 +18977,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
18974
18977
|
this.backfillLastFailureAt = failedAt;
|
|
18975
18978
|
const retryInMs = this.backfillFailureCount < 3 ? CHUNK_BACKFILL_RETRY_BASE_MS * 2 ** (this.backfillFailureCount - 1) : null;
|
|
18976
18979
|
this.backfillNextRetryAt = retryInMs === null ? Number.POSITIVE_INFINITY : failedAt + retryInMs;
|
|
18977
|
-
log$
|
|
18980
|
+
log$12.warn("legacy memory chunk backfill failed", {
|
|
18978
18981
|
attempt: this.backfillFailureCount,
|
|
18979
18982
|
maxAttempts: 3,
|
|
18980
18983
|
retryInMs,
|
|
@@ -19262,7 +19265,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
19262
19265
|
const entry = readEntry(this, key);
|
|
19263
19266
|
if (entry.state !== "pending_reprocess" || entry.reprocessReason === null) throw new StorageError(`Cannot reopen atomic extraction from state '${entry.state}'`);
|
|
19264
19267
|
if (entry.reprocessAttemptCount >= attemptCap) {
|
|
19265
|
-
log$
|
|
19268
|
+
log$12.error("atomic extraction chunk stuck at reprocess attempt cap", {
|
|
19266
19269
|
product_session_reference: privateLogReference(key.conversationId),
|
|
19267
19270
|
chunk_hash: key.chunkHash,
|
|
19268
19271
|
version: key.pipelineVersion,
|
|
@@ -21091,7 +21094,7 @@ function canTrustedWrite(kind) {
|
|
|
21091
21094
|
* @purpose Validates and normalizes memory-kind metadata before direct store writes.
|
|
21092
21095
|
* @boundary Storage write chokepoint only; extraction owns metadata semantics.
|
|
21093
21096
|
*/
|
|
21094
|
-
const log$
|
|
21097
|
+
const log$9 = createLogger("sno-station-mem:active-task-shape-alarm");
|
|
21095
21098
|
function validateAtomicCardWrite(input) {
|
|
21096
21099
|
if (input.category !== "state") return;
|
|
21097
21100
|
if (input.subject === null || !input.subject.startsWith("entity:") || input.subject.length === 7) throw new StorageError("state memory requires a non-empty entity subject");
|
|
@@ -21135,7 +21138,7 @@ function formatCause(error) {
|
|
|
21135
21138
|
return error instanceof Error ? error.message : String(error);
|
|
21136
21139
|
}
|
|
21137
21140
|
function shapeAlarm(operation, reason) {
|
|
21138
|
-
log$
|
|
21141
|
+
log$9.error("Active task shape validation failed", {
|
|
21139
21142
|
operation,
|
|
21140
21143
|
reason_code: reason.replace(/[^a-z0-9]+/gi, "_").toLowerCase()
|
|
21141
21144
|
}, {
|
|
@@ -23522,7 +23525,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
23522
23525
|
async store(entry) {
|
|
23523
23526
|
const safeEntry = sanitizeStoreInput(entry);
|
|
23524
23527
|
const lane = safeEntry.lane ?? "active";
|
|
23525
|
-
log$
|
|
23528
|
+
log$12.debug("storing memory", {
|
|
23526
23529
|
category: safeEntry.category,
|
|
23527
23530
|
projectId: safeEntry.projectId
|
|
23528
23531
|
}, {
|
|
@@ -23565,7 +23568,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
23565
23568
|
if (writeIdentity) {
|
|
23566
23569
|
const alreadyWritten = this.findByExtractionIdempotencyKey(projectId, writeIdentity);
|
|
23567
23570
|
if (alreadyWritten) {
|
|
23568
|
-
log$
|
|
23571
|
+
log$12.debug("idempotency key match, skipping store", {
|
|
23569
23572
|
projectId,
|
|
23570
23573
|
memory_id: alreadyWritten.id
|
|
23571
23574
|
}, {
|
|
@@ -23579,7 +23582,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
23579
23582
|
}
|
|
23580
23583
|
const earlyDup = this.readExistingByHash(projectId, hash, category);
|
|
23581
23584
|
if (earlyDup && !canRevive(earlyDup)) {
|
|
23582
|
-
log$
|
|
23585
|
+
log$12.debug("content hash match, skipping store", {
|
|
23583
23586
|
projectId,
|
|
23584
23587
|
memory_id: earlyDup.id
|
|
23585
23588
|
}, {
|
|
@@ -23596,7 +23599,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
23596
23599
|
if (writeIdentity) {
|
|
23597
23600
|
const alreadyWritten = this.findByExtractionIdempotencyKey(projectId, writeIdentity);
|
|
23598
23601
|
if (alreadyWritten) {
|
|
23599
|
-
log$
|
|
23602
|
+
log$12.debug("idempotency key match, skipping store", {
|
|
23600
23603
|
projectId,
|
|
23601
23604
|
memory_id: alreadyWritten.id
|
|
23602
23605
|
}, {
|
|
@@ -23610,7 +23613,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
23610
23613
|
}
|
|
23611
23614
|
const existing = this.readExistingByHash(projectId, hash, category);
|
|
23612
23615
|
if (existing && !canRevive(existing)) {
|
|
23613
|
-
log$
|
|
23616
|
+
log$12.debug("content hash match, skipping store", {
|
|
23614
23617
|
projectId,
|
|
23615
23618
|
memory_id: existing.id
|
|
23616
23619
|
}, {
|
|
@@ -23920,7 +23923,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
23920
23923
|
assertProfileRecoveryWrite(args.profileRecovery);
|
|
23921
23924
|
const { activeFactGuard, activeTaskProjectionGuard, closes, preserveExisting, reviveInvalidatedExisting } = args;
|
|
23922
23925
|
const create = sanitizeStoreInput(args.create);
|
|
23923
|
-
log$
|
|
23926
|
+
log$12.debug("supersede write", {
|
|
23924
23927
|
category: create.category,
|
|
23925
23928
|
projectId: create.projectId,
|
|
23926
23929
|
closes: closes.length
|
|
@@ -24700,7 +24703,7 @@ function mergeMetadata(current, patch) {
|
|
|
24700
24703
|
Object.assign(MemoryStore.prototype, {
|
|
24701
24704
|
async update(id, changes) {
|
|
24702
24705
|
const countRecordTokens = await recordTokenCounter(this.embedder);
|
|
24703
|
-
log$
|
|
24706
|
+
log$12.debug("updating memory", { memory_id: id }, {
|
|
24704
24707
|
event_name: "sno_station_mem.memory-store-update-api.updating.memory",
|
|
24705
24708
|
file: "packages/memory/src/store/memory-store-update-api.ts",
|
|
24706
24709
|
function: "update",
|
|
@@ -24825,7 +24828,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
24825
24828
|
});
|
|
24826
24829
|
},
|
|
24827
24830
|
async updateTier(memoryId, newTier, options) {
|
|
24828
|
-
log$
|
|
24831
|
+
log$12.debug("updating tier", {
|
|
24829
24832
|
memory_id: memoryId,
|
|
24830
24833
|
tier: newTier
|
|
24831
24834
|
}, {
|
|
@@ -24847,7 +24850,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
24847
24850
|
});
|
|
24848
24851
|
},
|
|
24849
24852
|
async updateMetadata(memoryId, patch) {
|
|
24850
|
-
log$
|
|
24853
|
+
log$12.debug("updating metadata", { memory_id: memoryId }, {
|
|
24851
24854
|
event_name: "sno_station_mem.memory-store-update-api.updating.metadata",
|
|
24852
24855
|
file: "packages/memory/src/store/memory-store-update-api.ts",
|
|
24853
24856
|
function: "updateMetadata",
|
|
@@ -24865,7 +24868,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
24865
24868
|
});
|
|
24866
24869
|
},
|
|
24867
24870
|
async resolveReflectionItem(memoryId, opts) {
|
|
24868
|
-
log$
|
|
24871
|
+
log$12.debug("resolving reflection item", { memory_id: memoryId }, {
|
|
24869
24872
|
event_name: "sno_station_mem.memory-store-update-api.resolving.reflection.item",
|
|
24870
24873
|
file: "packages/memory/src/store/memory-store-update-api.ts",
|
|
24871
24874
|
function: "resolveReflectionItem",
|
|
@@ -24900,7 +24903,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
24900
24903
|
*/
|
|
24901
24904
|
async applyMetadataDeltas(entries) {
|
|
24902
24905
|
if (entries.length === 0) return;
|
|
24903
|
-
log$
|
|
24906
|
+
log$12.debug("applying metadata deltas", { count: entries.length }, {
|
|
24904
24907
|
event_name: "sno_station_mem.memory-store-update-api.applying.metadata.deltas",
|
|
24905
24908
|
file: "packages/memory/src/store/memory-store-update-api.ts",
|
|
24906
24909
|
function: "applyMetadataDeltas",
|
|
@@ -24924,7 +24927,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
24924
24927
|
});
|
|
24925
24928
|
},
|
|
24926
24929
|
async applyMetadataDelta(memoryId, deltaFn) {
|
|
24927
|
-
log$
|
|
24930
|
+
log$12.debug("applying metadata delta", { memory_id: memoryId }, {
|
|
24928
24931
|
event_name: "sno_station_mem.memory-store-update-api.applying.metadata.delta",
|
|
24929
24932
|
file: "packages/memory/src/store/memory-store-update-api.ts",
|
|
24930
24933
|
function: "applyMetadataDelta",
|
|
@@ -24945,7 +24948,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
24945
24948
|
});
|
|
24946
24949
|
//#endregion
|
|
24947
24950
|
//#region src/store/memory-store-rem-api.ts
|
|
24948
|
-
const log$
|
|
24951
|
+
const log$7 = createLogger("sno-station-mem:rem-write");
|
|
24949
24952
|
Object.assign(MemoryStore.prototype, { async applyRemTextVersion(input) {
|
|
24950
24953
|
if (input.reason.trim().length === 0) throw new Error("mutation reason is required");
|
|
24951
24954
|
if (input.idempotencyKey !== void 0 && input.idempotencyKey.trim().length === 0) throw new Error("REM idempotency key must be non-empty");
|
|
@@ -24976,7 +24979,7 @@ Object.assign(MemoryStore.prototype, { async applyRemTextVersion(input) {
|
|
|
24976
24979
|
});
|
|
24977
24980
|
} catch (error) {
|
|
24978
24981
|
if (completedMutation === void 0) throw error;
|
|
24979
|
-
log$
|
|
24982
|
+
log$7.error("rem_write_completion_audit_failed", {
|
|
24980
24983
|
error,
|
|
24981
24984
|
row_id: input.rowId
|
|
24982
24985
|
}, {
|
|
@@ -25085,7 +25088,7 @@ async function applyTransaction(store, input, chunks) {
|
|
|
25085
25088
|
}
|
|
25086
25089
|
});
|
|
25087
25090
|
} catch (error) {
|
|
25088
|
-
log$
|
|
25091
|
+
log$7.error("rem_write_receipt_failed", {
|
|
25089
25092
|
error,
|
|
25090
25093
|
row_id: existing.id
|
|
25091
25094
|
}, {
|
|
@@ -25292,7 +25295,7 @@ function buildChunkSearchResults(vecRows, metaRows, limit, minScore) {
|
|
|
25292
25295
|
Object.assign(MemoryStore.prototype, {
|
|
25293
25296
|
async searchChunksSemantic(vector, opts = {}) {
|
|
25294
25297
|
if (!this.db.vectorSearchAvailable) {
|
|
25295
|
-
log$
|
|
25298
|
+
log$12.error("storage.vector.search.unavailable", { dbPath: this.dbPath }, {
|
|
25296
25299
|
event_name: "storage.vector.search.unavailable",
|
|
25297
25300
|
file: "packages/memory/src/store/memory-store-chunk-search.ts",
|
|
25298
25301
|
function: "searchChunksSemantic",
|
|
@@ -25315,7 +25318,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25315
25318
|
const metaRows = readSemanticMetaRows(this.sqlite, vecRows, opts);
|
|
25316
25319
|
const results = buildChunkSearchResults(vecRows, metaRows, limit, minScore);
|
|
25317
25320
|
if (results.length >= limit || vecRows.length < candidateBudget) {
|
|
25318
|
-
log$
|
|
25321
|
+
log$12.debug("chunk semantic search", {
|
|
25319
25322
|
limit,
|
|
25320
25323
|
projectIdFilter: opts.projectIdFilter,
|
|
25321
25324
|
vecCandidates: vecRows.length,
|
|
@@ -25335,7 +25338,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25335
25338
|
candidateBudget = Math.min(candidateBudget * SEMANTIC_CANDIDATE_GROWTH_FACTOR, vectorRowCount);
|
|
25336
25339
|
}
|
|
25337
25340
|
} catch (error) {
|
|
25338
|
-
log$
|
|
25341
|
+
log$12.error("chunk semantic search failed", {
|
|
25339
25342
|
error,
|
|
25340
25343
|
limit,
|
|
25341
25344
|
projectIdFilter: opts.projectIdFilter,
|
|
@@ -25400,7 +25403,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25400
25403
|
rank: index + 1
|
|
25401
25404
|
});
|
|
25402
25405
|
});
|
|
25403
|
-
log$
|
|
25406
|
+
log$12.debug("chunk keyword search", {
|
|
25404
25407
|
query_length: safeQuery?.length ?? "unavailable",
|
|
25405
25408
|
limit,
|
|
25406
25409
|
minScore,
|
|
@@ -25413,7 +25416,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25413
25416
|
});
|
|
25414
25417
|
return results;
|
|
25415
25418
|
} catch (error) {
|
|
25416
|
-
log$
|
|
25419
|
+
log$12.error("chunk keyword search failed", {
|
|
25417
25420
|
error,
|
|
25418
25421
|
query_length: safeQuery?.length ?? "unavailable",
|
|
25419
25422
|
limit,
|
|
@@ -25589,7 +25592,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25589
25592
|
if (results.length >= limit) break;
|
|
25590
25593
|
}
|
|
25591
25594
|
this.attachSnippets(results, opts.facetPolicy);
|
|
25592
|
-
log$
|
|
25595
|
+
log$12.debug("semantic search (memory-level wrapper)", {
|
|
25593
25596
|
limit,
|
|
25594
25597
|
chunkLimit,
|
|
25595
25598
|
projectIdFilter: opts.projectIdFilter,
|
|
@@ -25635,7 +25638,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25635
25638
|
if (results.length >= limit) break;
|
|
25636
25639
|
}
|
|
25637
25640
|
this.attachSnippets(results, opts.facetPolicy);
|
|
25638
|
-
log$
|
|
25641
|
+
log$12.debug("keyword search (memory-level wrapper)", {
|
|
25639
25642
|
limit,
|
|
25640
25643
|
chunkLimit,
|
|
25641
25644
|
projectIdFilter: opts.projectIdFilter,
|
|
@@ -25666,7 +25669,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25666
25669
|
neighborAfter: 2
|
|
25667
25670
|
});
|
|
25668
25671
|
} catch (err) {
|
|
25669
|
-
log$
|
|
25672
|
+
log$12.warn("snippet expand window failed; falling back to entry text", {
|
|
25670
25673
|
memory_id: result.entry.id,
|
|
25671
25674
|
chunkIndex: result.chunkIndex,
|
|
25672
25675
|
totalChunks,
|
|
@@ -25806,7 +25809,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25806
25809
|
}
|
|
25807
25810
|
return metadata;
|
|
25808
25811
|
} catch (e) {
|
|
25809
|
-
log$
|
|
25812
|
+
log$12.warn("malformed metadata JSON", {
|
|
25810
25813
|
memory_id: memoryId,
|
|
25811
25814
|
error: e
|
|
25812
25815
|
}, {
|
|
@@ -25870,7 +25873,7 @@ function writeDeleteEvents(internals, rows, reason) {
|
|
|
25870
25873
|
}
|
|
25871
25874
|
Object.assign(MemoryStore.prototype, {
|
|
25872
25875
|
async delete(idOrPrefix, options) {
|
|
25873
|
-
log$
|
|
25876
|
+
log$12.info("deleting memories", { idOrPrefix }, {
|
|
25874
25877
|
event_name: "sno_station_mem.memory-store-admin-api.deleting.memories",
|
|
25875
25878
|
file: "packages/memory/src/store/memory-store-admin-api.ts",
|
|
25876
25879
|
function: "delete",
|
|
@@ -25895,7 +25898,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25895
25898
|
async deleteMany(ids, options) {
|
|
25896
25899
|
const uniqueIds = Array.from(new Set(ids));
|
|
25897
25900
|
if (uniqueIds.length === 0) return 0;
|
|
25898
|
-
log$
|
|
25901
|
+
log$12.info("deleting many memories", { count: uniqueIds.length }, {
|
|
25899
25902
|
event_name: "sno_station_mem.memory-store-admin-api.deleting.many.memories",
|
|
25900
25903
|
file: "packages/memory/src/store/memory-store-admin-api.ts",
|
|
25901
25904
|
function: "deleteMany",
|
|
@@ -25929,7 +25932,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
25929
25932
|
}).immediate();
|
|
25930
25933
|
},
|
|
25931
25934
|
async bulkDelete(filter, options) {
|
|
25932
|
-
log$
|
|
25935
|
+
log$12.info("bulk delete", {
|
|
25933
25936
|
projectId: filter.projectId,
|
|
25934
25937
|
category: filter.category
|
|
25935
25938
|
}, {
|
|
@@ -26000,7 +26003,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
26000
26003
|
unplacedParams.push(filter.category);
|
|
26001
26004
|
}
|
|
26002
26005
|
this.sqlite.prepare(`DELETE FROM nodix_unplaced_memory_candidates${unplacedWhere.length > 0 ? ` WHERE ${unplacedWhere.join(" AND ")}` : ""}`).run(...unplacedParams);
|
|
26003
|
-
if (truncated) log$
|
|
26006
|
+
if (truncated) log$12.warn("bulk delete reached safety iteration cap", {
|
|
26004
26007
|
projectId: filter.projectId,
|
|
26005
26008
|
category: filter.category,
|
|
26006
26009
|
deleted,
|
|
@@ -26043,7 +26046,7 @@ Object.assign(MemoryStore.prototype, {
|
|
|
26043
26046
|
this.sqlite.exec("PRAGMA optimize");
|
|
26044
26047
|
this.sqlite.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
26045
26048
|
} catch (error) {
|
|
26046
|
-
log$
|
|
26049
|
+
log$12.warn("sqlite close-time maintenance failed", { error }, {
|
|
26047
26050
|
event_name: "sno_station_mem.memory-store-admin-api.sqlite.close.time.maintenance.failed",
|
|
26048
26051
|
file: "packages/memory/src/store/memory-store-admin-api.ts",
|
|
26049
26052
|
function: "closeSqlite",
|
|
@@ -26066,7 +26069,10 @@ function buildProvider(config) {
|
|
|
26066
26069
|
offline: config.offline,
|
|
26067
26070
|
mirror: config.mirror,
|
|
26068
26071
|
dtype: config.dtype,
|
|
26069
|
-
sessionOptions:
|
|
26072
|
+
sessionOptions: {
|
|
26073
|
+
...config.sessionOptions,
|
|
26074
|
+
intraOpNumThreads: config.sessionOptions?.intraOpNumThreads ?? Math.max(1, Math.min(4, Math.floor(availableParallelism() / 2)))
|
|
26075
|
+
},
|
|
26070
26076
|
...config.model !== void 0 ? { model: config.model } : {},
|
|
26071
26077
|
...config.revision !== void 0 ? { revision: config.revision } : {},
|
|
26072
26078
|
...config.nativeDim !== void 0 ? { nativeDim: config.nativeDim } : {},
|
|
@@ -26136,7 +26142,7 @@ function truncateToTokens(text, maxTokens, countTokens) {
|
|
|
26136
26142
|
* @see store.ts, retriever.ts.
|
|
26137
26143
|
*/
|
|
26138
26144
|
/** Local ONNX embedding with an LRU cache and oversized-text chunking. */
|
|
26139
|
-
const log$
|
|
26145
|
+
const log$6 = createLogger("sno-station-mem:embed");
|
|
26140
26146
|
var Embedder = class {
|
|
26141
26147
|
provider;
|
|
26142
26148
|
chunkingEnabled;
|
|
@@ -26166,7 +26172,7 @@ var Embedder = class {
|
|
|
26166
26172
|
maxSize: 256,
|
|
26167
26173
|
ttlMs: CACHE_TTL_MS
|
|
26168
26174
|
});
|
|
26169
|
-
log$
|
|
26175
|
+
log$6.info("embedder initialized", {
|
|
26170
26176
|
provider: providerKind,
|
|
26171
26177
|
model: this.model,
|
|
26172
26178
|
dimensions: this.dimensions,
|
|
@@ -26226,7 +26232,7 @@ var Embedder = class {
|
|
|
26226
26232
|
if (pieceTokens > 512) throw new EmbeddingError(`Embedder chunk of ${pieceTokens} tokens exceeds DEFAULT_MAX_CONTEXT_TOKENS (512)`);
|
|
26227
26233
|
}
|
|
26228
26234
|
if (chunks.length <= 1) return this.embedDirect(chunks[0] ?? text);
|
|
26229
|
-
log$
|
|
26235
|
+
log$6.warn("legacy chunker invoked (embedding-API safety net)", {
|
|
26230
26236
|
chunks: chunks.length,
|
|
26231
26237
|
totalTokens: tokens,
|
|
26232
26238
|
maxTokens: 512
|
|
@@ -26244,7 +26250,7 @@ var Embedder = class {
|
|
|
26244
26250
|
const vector = await this.provider.embed(text);
|
|
26245
26251
|
return this.toFloat32(vector);
|
|
26246
26252
|
} catch (error) {
|
|
26247
|
-
log$
|
|
26253
|
+
log$6.error("passage embedding failed", {
|
|
26248
26254
|
textLength: text.length,
|
|
26249
26255
|
error
|
|
26250
26256
|
}, {
|
|
@@ -26259,7 +26265,7 @@ var Embedder = class {
|
|
|
26259
26265
|
/** Implements embed many as the local embedding generation operation. */
|
|
26260
26266
|
async embedMany(values) {
|
|
26261
26267
|
await this.awaitWarmup();
|
|
26262
|
-
log$
|
|
26268
|
+
log$6.debug("batch embedding", { count: values.length }, {
|
|
26263
26269
|
event_name: "sno_station_mem.embedding-provider-client.batch.embedding",
|
|
26264
26270
|
file: "packages/memory/src/engine/extraction/embedding-provider-client.ts",
|
|
26265
26271
|
function: "embedMany",
|
|
@@ -26270,7 +26276,7 @@ var Embedder = class {
|
|
|
26270
26276
|
if (vectors.length !== values.length) throw new EmbeddingError(`Embedding provider returned ${vectors.length} vectors for ${values.length} inputs`);
|
|
26271
26277
|
return vectors.map((v) => this.toFloat32(v));
|
|
26272
26278
|
} catch (error) {
|
|
26273
|
-
log$
|
|
26279
|
+
log$6.error("batch embedding failed", {
|
|
26274
26280
|
count: values.length,
|
|
26275
26281
|
error
|
|
26276
26282
|
}, {
|
|
@@ -26309,14 +26315,14 @@ var Embedder = class {
|
|
|
26309
26315
|
if (this.modelDownload) await ensureModelDownloaded(this.modelDownload);
|
|
26310
26316
|
const vector = await this.provider.embed("warmup");
|
|
26311
26317
|
if (vector.length !== this.dimensions) throw new EmbeddingError(`Embedder warmup dimension mismatch: expected ${this.dimensions}, got ${vector.length}`);
|
|
26312
|
-
log$
|
|
26318
|
+
log$6.info("embedder warmup ok", { dimensions: this.dimensions }, {
|
|
26313
26319
|
event_name: "sno_station_mem.embedding-provider-client.embedder.warmup.ok",
|
|
26314
26320
|
file: "packages/memory/src/engine/extraction/embedding-provider-client.ts",
|
|
26315
26321
|
function: "<anonymous callback>",
|
|
26316
26322
|
site_id: "embedding-provider-client.<anonymous callback>.32cc9ec43e"
|
|
26317
26323
|
});
|
|
26318
26324
|
} catch (error) {
|
|
26319
|
-
log$
|
|
26325
|
+
log$6.error("embedder warmup failed", { error }, {
|
|
26320
26326
|
event_name: "sno_station_mem.embedding-provider-client.embedder.warmup.failed",
|
|
26321
26327
|
file: "packages/memory/src/engine/extraction/embedding-provider-client.ts",
|
|
26322
26328
|
function: "<anonymous callback>",
|
|
@@ -26354,7 +26360,7 @@ function createEmbedder(config, stateDir) {
|
|
|
26354
26360
|
* run-dir provided via `EVAL_TRACE_DIR` (env). Phase 0 instrumentation
|
|
26355
26361
|
* (MRR/Recall, gold-rank, miss classification) remains explicitly waived.
|
|
26356
26362
|
*/
|
|
26357
|
-
const log$
|
|
26363
|
+
const log$5 = createLogger("sno-station-mem:eval-trace");
|
|
26358
26364
|
/**
|
|
26359
26365
|
* Returns true when the eval-trace surface should write. Reads the env var at
|
|
26360
26366
|
* call time so harness-flipped values take effect without a re-import.
|
|
@@ -26389,7 +26395,7 @@ function appendQaTrace(trace, traceDirOverride) {
|
|
|
26389
26395
|
context: currentLogContext()
|
|
26390
26396
|
})}\n`, "utf8");
|
|
26391
26397
|
} catch (err) {
|
|
26392
|
-
log$
|
|
26398
|
+
log$5.warn("failed to append qa trace", { error: err }, {
|
|
26393
26399
|
event_name: "sno_station_mem.trace.failed.to.append.qa.trace",
|
|
26394
26400
|
file: "packages/memory/src/engine/eval/trace.ts",
|
|
26395
26401
|
function: "appendQaTrace",
|
|
@@ -26459,7 +26465,7 @@ function sha256Hex(input) {
|
|
|
26459
26465
|
* Tracks memory access patterns to support reinforcement-based decay.
|
|
26460
26466
|
* Frequently accessed memories decay more slowly (longer effective half-life).
|
|
26461
26467
|
*/
|
|
26462
|
-
const log$
|
|
26468
|
+
const log$4 = createLogger("sno-station-mem:access-tracker");
|
|
26463
26469
|
const MIN_ACCESS_COUNT = 0;
|
|
26464
26470
|
const LEGACY_MAX_ACCESS_COUNT = 1e4;
|
|
26465
26471
|
/** Default debounce interval before flushing pending writes (5 seconds) */
|
|
@@ -26608,7 +26614,7 @@ var AccessTracker = class {
|
|
|
26608
26614
|
this.clearTimer();
|
|
26609
26615
|
if (this.flushPromise) await this.flushPromise;
|
|
26610
26616
|
if (this.pending.size > 0) await this.doFlush();
|
|
26611
|
-
if (this.pending.size > 0) log$
|
|
26617
|
+
if (this.pending.size > 0) log$4.warn("destroying with pending writes", { pendingCount: this.pending.size }, {
|
|
26612
26618
|
event_name: "sno_station_mem.access-tracker.destroying.with.pending.writes",
|
|
26613
26619
|
file: "packages/memory/src/engine/retrieval/access-tracker.ts",
|
|
26614
26620
|
function: "destroy",
|
|
@@ -26643,7 +26649,7 @@ var AccessTracker = class {
|
|
|
26643
26649
|
const failures = (this.writeFailures.get(id) ?? 0) + 1;
|
|
26644
26650
|
if (failures >= MAX_WRITE_FAILURES_PER_ID) {
|
|
26645
26651
|
this.writeFailures.delete(id);
|
|
26646
|
-
log$
|
|
26652
|
+
log$4.warn("dropping access delta after repeated write failures", {
|
|
26647
26653
|
memory_id: id,
|
|
26648
26654
|
failures,
|
|
26649
26655
|
error: err
|
|
@@ -26658,7 +26664,7 @@ var AccessTracker = class {
|
|
|
26658
26664
|
this.writeFailures.set(id, failures);
|
|
26659
26665
|
this.pending.set(id, (this.pending.get(id) ?? 0) + delta);
|
|
26660
26666
|
}
|
|
26661
|
-
log$
|
|
26667
|
+
log$4.warn("access flush batch failed", {
|
|
26662
26668
|
batchSize: batch.size,
|
|
26663
26669
|
error: err,
|
|
26664
26670
|
committed_count: 0
|
|
@@ -26690,7 +26696,7 @@ var AccessTracker = class {
|
|
|
26690
26696
|
if (prevLast > 0 && now - prevLast < this.recallLifecycle.accessRateLimitMs) return void 0;
|
|
26691
26697
|
if (prevCount > ceiling && !this.clampedOnce.has(id)) {
|
|
26692
26698
|
this.clampedOnce.add(id);
|
|
26693
|
-
log$
|
|
26699
|
+
log$4.warn("legacy access count clamped to ceiling", {
|
|
26694
26700
|
memory_id: id,
|
|
26695
26701
|
previousCount: prevCount,
|
|
26696
26702
|
ceiling
|
|
@@ -27048,7 +27054,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27048
27054
|
});
|
|
27049
27055
|
//#endregion
|
|
27050
27056
|
//#region src/engine/retrieval/retrieval-scoring-utils.ts
|
|
27051
|
-
const log$
|
|
27057
|
+
const log$3 = createLogger$1("sno-station-mem:retriever");
|
|
27052
27058
|
function dotProduct(a, b) {
|
|
27053
27059
|
let sum = 0;
|
|
27054
27060
|
const len = a.length;
|
|
@@ -27103,7 +27109,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27103
27109
|
aggregationIncomplete: result.aggregationIncomplete
|
|
27104
27110
|
}));
|
|
27105
27111
|
trace?.endStage(mapped.map((result) => result.entry.id), mapped.map((result) => result.score));
|
|
27106
|
-
log$
|
|
27112
|
+
log$3.info("aggregation evidence served", {
|
|
27107
27113
|
rows: mapped.length,
|
|
27108
27114
|
scopeRows: mapped[0]?.scopeRowCount ?? 0,
|
|
27109
27115
|
readingBudget: context.limit,
|
|
@@ -27195,14 +27201,14 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27195
27201
|
throw new RetrievalError("Both vector and keyword search failed", vectorSettled.reason);
|
|
27196
27202
|
}
|
|
27197
27203
|
let vectorResults = vectorSettled.status === "fulfilled" ? vectorSettled.value : [];
|
|
27198
|
-
if (vectorSettled.status === "rejected") log$
|
|
27204
|
+
if (vectorSettled.status === "rejected") log$3.warn("vector search branch failed, using keyword-only", { error: vectorError }, {
|
|
27199
27205
|
event_name: "memory.retriever_search_modes.diagnostic",
|
|
27200
27206
|
file: "packages/memory/src/engine/retrieval/retriever-search-modes.ts",
|
|
27201
27207
|
function: "precisionRecall",
|
|
27202
27208
|
site_id: "retrieval.retriever-search-modes.precisionRecall.97b8770f50"
|
|
27203
27209
|
});
|
|
27204
27210
|
let keywordResults = keywordSettled.status === "fulfilled" ? keywordSettled.value : [];
|
|
27205
|
-
if (keywordSettled.status === "rejected") log$
|
|
27211
|
+
if (keywordSettled.status === "rejected") log$3.warn("keyword search branch failed, using vector-only", { error: keywordError }, {
|
|
27206
27212
|
event_name: "memory.retriever_search_modes.diagnostic",
|
|
27207
27213
|
file: "packages/memory/src/engine/retrieval/retriever-search-modes.ts",
|
|
27208
27214
|
function: "precisionRecall",
|
|
@@ -27220,7 +27226,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27220
27226
|
trace?.startStage("rrf_fusion", [...vectorResults.map((r) => r.entry.id), ...keywordResults.map((r) => r.entry.id)]);
|
|
27221
27227
|
let fused = this.rrfFuse(vectorResults, keywordResults);
|
|
27222
27228
|
trace?.endStage(fused.map((r) => r.entry.id), fused.map((r) => r.score));
|
|
27223
|
-
log$
|
|
27229
|
+
log$3.debug("precision recall search", {
|
|
27224
27230
|
vectorCount: vectorResults.length,
|
|
27225
27231
|
keywordCount: keywordResults.length,
|
|
27226
27232
|
fusedCount: fused.length,
|
|
@@ -27522,7 +27528,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27522
27528
|
if (this.config.rerank === "lightweight" || !this.config.rerankApiKey) return { candidates: this.rerankLightweight(candidates, queryVector) };
|
|
27523
27529
|
const rerankEndpoint = this.config.rerankEndpoint ?? RERANK_DEFAULT_ENDPOINTS[provider];
|
|
27524
27530
|
if (!rerankEndpoint) {
|
|
27525
|
-
log$
|
|
27531
|
+
log$3.warn("rerank skipped: no endpoint for provider", { provider }, {
|
|
27526
27532
|
event_name: "memory.retriever_rerank.diagnostic",
|
|
27527
27533
|
file: "packages/memory/src/engine/retrieval/retriever-rerank.ts",
|
|
27528
27534
|
function: "rerank",
|
|
@@ -27546,7 +27552,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27546
27552
|
const queryTokens = this.embedder.countTokens(query);
|
|
27547
27553
|
const documentTokenBudget = 509 - queryTokens;
|
|
27548
27554
|
if (documentTokenBudget <= 0) {
|
|
27549
|
-
log$
|
|
27555
|
+
log$3.warn("rerank skipped: the query alone fills the reranker token window", {
|
|
27550
27556
|
queryTokens,
|
|
27551
27557
|
window: 512,
|
|
27552
27558
|
templateTokens: 3
|
|
@@ -27570,7 +27576,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27570
27576
|
if (bounded !== c.entry.text) truncatedCandidates += 1;
|
|
27571
27577
|
return bounded;
|
|
27572
27578
|
});
|
|
27573
|
-
if (truncatedCandidates > 0) log$
|
|
27579
|
+
if (truncatedCandidates > 0) log$3.warn("rerank candidates were cut to the document budget the query left", {
|
|
27574
27580
|
truncatedCandidates,
|
|
27575
27581
|
documentTokenBudget,
|
|
27576
27582
|
queryTokens
|
|
@@ -27607,7 +27613,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27607
27613
|
const target = Math.max(1, Math.floor(allowed * localPairTokens / named.inputTokens) - queryTokens);
|
|
27608
27614
|
return this.embedder.truncateToTokens(text, target);
|
|
27609
27615
|
});
|
|
27610
|
-
log$
|
|
27616
|
+
log$3.warn("rerank batch refused over its token window; resending the named texts cut to fit", {
|
|
27611
27617
|
status: response.status,
|
|
27612
27618
|
overLongCount: refusal.overLong.length,
|
|
27613
27619
|
maxInputTokens: refusal.maxInputTokens,
|
|
@@ -27621,7 +27627,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27621
27627
|
});
|
|
27622
27628
|
continue;
|
|
27623
27629
|
}
|
|
27624
|
-
log$
|
|
27630
|
+
log$3.warn("rerank API failed, using pre-rerank results", {
|
|
27625
27631
|
status: response.status,
|
|
27626
27632
|
endpoint_hash: createHash("sha256").update(rerankEndpoint).digest("hex"),
|
|
27627
27633
|
retryAfter,
|
|
@@ -27638,7 +27644,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27638
27644
|
}
|
|
27639
27645
|
const parsed = parseRerankResponse(provider, data);
|
|
27640
27646
|
if (!parsed) {
|
|
27641
|
-
log$
|
|
27647
|
+
log$3.warn("rerank API returned unparseable response", {
|
|
27642
27648
|
provider,
|
|
27643
27649
|
endpoint_hash: createHash("sha256").update(rerankEndpoint).digest("hex"),
|
|
27644
27650
|
batchStart: start
|
|
@@ -27706,7 +27712,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27706
27712
|
score: clamp01(this.getRerankSourceScore(r) * LIGHTWEIGHT_RERANK_PENALTY, 0)
|
|
27707
27713
|
}));
|
|
27708
27714
|
const merged = [...reranked, ...unreturned].sort((a, b) => b.score - a.score);
|
|
27709
|
-
log$
|
|
27715
|
+
log$3.debug("reranked", {
|
|
27710
27716
|
totalCandidateCount: candidates.length,
|
|
27711
27717
|
sentToRerankCount: toRerank.length,
|
|
27712
27718
|
returnedCount: reranked.length,
|
|
@@ -27730,7 +27736,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27730
27736
|
let reason;
|
|
27731
27737
|
if (isRerankTimeout(error)) {
|
|
27732
27738
|
reason = "timeout";
|
|
27733
|
-
log$
|
|
27739
|
+
log$3.warn("rerank API timed out, using pre-rerank results", {
|
|
27734
27740
|
timeoutMs: rerankTimeoutMs,
|
|
27735
27741
|
attempts: RERANK_TRANSIENT_ATTEMPTS
|
|
27736
27742
|
}, {
|
|
@@ -27741,7 +27747,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27741
27747
|
});
|
|
27742
27748
|
} else {
|
|
27743
27749
|
reason = "request_error";
|
|
27744
|
-
log$
|
|
27750
|
+
log$3.warn("rerank error, using pre-rerank results", {
|
|
27745
27751
|
error,
|
|
27746
27752
|
attempts: RERANK_TRANSIENT_ATTEMPTS
|
|
27747
27753
|
}, {
|
|
@@ -27800,7 +27806,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27800
27806
|
}
|
|
27801
27807
|
};
|
|
27802
27808
|
});
|
|
27803
|
-
if (dimMismatchCount > 0) log$
|
|
27809
|
+
if (dimMismatchCount > 0) log$3.warn("lightweight rerank: chunk vector dim mismatch on some candidates", {
|
|
27804
27810
|
dimMismatchCount,
|
|
27805
27811
|
queryDim: queryVector.length
|
|
27806
27812
|
}, {
|
|
@@ -27809,7 +27815,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
27809
27815
|
function: "rerankLightweight",
|
|
27810
27816
|
site_id: "retrieval.retriever-rerank.rerankLightweight.70eb2031f1"
|
|
27811
27817
|
});
|
|
27812
|
-
log$
|
|
27818
|
+
log$3.debug("lightweight rerank applied", {
|
|
27813
27819
|
candidateCount: candidates.length,
|
|
27814
27820
|
blendedCount,
|
|
27815
27821
|
fusionWeight: wF,
|
|
@@ -28207,7 +28213,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
28207
28213
|
...input,
|
|
28208
28214
|
signal: memoryOperationSignal(input.signal)
|
|
28209
28215
|
});
|
|
28210
|
-
log$
|
|
28216
|
+
log$3.info("retrieval started", {
|
|
28211
28217
|
queryLength: context.query.length,
|
|
28212
28218
|
limit: context.limit,
|
|
28213
28219
|
mode: this.config.mode,
|
|
@@ -28281,7 +28287,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
28281
28287
|
...traceMetadata && { traceMetadata }
|
|
28282
28288
|
});
|
|
28283
28289
|
}
|
|
28284
|
-
log$
|
|
28290
|
+
log$3.info("Memory retrieval completed", {
|
|
28285
28291
|
store_reference: privateLogReference(this.store.dbPath),
|
|
28286
28292
|
outcome: results.length ? "success" : "empty_success",
|
|
28287
28293
|
duration_ms: performance.now() - started,
|
|
@@ -28308,7 +28314,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
28308
28314
|
});
|
|
28309
28315
|
return results;
|
|
28310
28316
|
} catch (error) {
|
|
28311
|
-
log$
|
|
28317
|
+
log$3.error("Memory retrieval failed", {
|
|
28312
28318
|
outcome: "failed",
|
|
28313
28319
|
error,
|
|
28314
28320
|
duration_ms: performance.now() - started
|
|
@@ -28350,7 +28356,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
28350
28356
|
if (!isExplicitAggregation && this._accessTracker && (this._recallLifecycle?.autoRecallAccessTracking === true || context.source === "manual") && results.length > 0) this._accessTracker.recordAccess(results.map((r) => r.entry.id));
|
|
28351
28357
|
if (!isExplicitAggregation && this._recallLifecycle?.tierPromoter && this._tierPromoter && results.length > 0) await this.evaluateTopKTierTransitions(results);
|
|
28352
28358
|
if (this._statsCollector) this._statsCollector.recordQuery(finalTrace, context.source ?? "debug");
|
|
28353
|
-
log$
|
|
28359
|
+
log$3.info("Traced memory retrieval completed", {
|
|
28354
28360
|
outcome: results.length ? "success" : "empty_success",
|
|
28355
28361
|
store_reference: privateLogReference(this.store.dbPath),
|
|
28356
28362
|
duration_ms: performance.now() - started,
|
|
@@ -28375,7 +28381,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
28375
28381
|
trace: finalTrace
|
|
28376
28382
|
};
|
|
28377
28383
|
} catch (error) {
|
|
28378
|
-
log$
|
|
28384
|
+
log$3.error("Traced memory retrieval failed", {
|
|
28379
28385
|
outcome: "failed",
|
|
28380
28386
|
error,
|
|
28381
28387
|
duration_ms: performance.now() - started
|
|
@@ -28438,7 +28444,7 @@ Object.assign(MemoryRetriever.prototype, {
|
|
|
28438
28444
|
if (!transition || transition.toTier === tier) continue;
|
|
28439
28445
|
await this.store.updateTier(entry.id, transition.toTier, { writerAuthority: "offline-family" });
|
|
28440
28446
|
} catch (error) {
|
|
28441
|
-
log$
|
|
28447
|
+
log$3.warn("tier evaluation failed for memory", {
|
|
28442
28448
|
memoryId: r.entry.id,
|
|
28443
28449
|
error
|
|
28444
28450
|
}, {
|
|
@@ -28570,7 +28576,7 @@ const REM_UPDATE_JUDGMENT_SKILL = {
|
|
|
28570
28576
|
* @purpose Binds capability-safe REM mutation and recovery ports to encrypted sno-station-mem SQLite.
|
|
28571
28577
|
* @boundary Additive REM tables and recoverable memory-row updates; no deletion or compaction.
|
|
28572
28578
|
*/
|
|
28573
|
-
const log$
|
|
28579
|
+
const log$2 = createLogger("sno-station-mem:rem-sqlite-adapter");
|
|
28574
28580
|
const verifiedWriteAuthorizationBrand = Symbol("verifiedWriteAuthorization");
|
|
28575
28581
|
const verifiedWriteAuthorization = new AsyncLocalStorage();
|
|
28576
28582
|
const replaceCoverageAllowBrand = Symbol("replaceCoverageAllow");
|
|
@@ -28694,7 +28700,7 @@ function createSnoStationMemRemMutationExecutor(input) {
|
|
|
28694
28700
|
reasonCode: mutation.applied ? null : "mutation_refused"
|
|
28695
28701
|
};
|
|
28696
28702
|
} catch (error) {
|
|
28697
|
-
log$
|
|
28703
|
+
log$2.warn("rem mutation failed", {
|
|
28698
28704
|
attempt_id: attempt.attempt_id,
|
|
28699
28705
|
attemptOrdinal: ordinal,
|
|
28700
28706
|
error,
|
|
@@ -29262,7 +29268,7 @@ function hashMemoryRow(row) {
|
|
|
29262
29268
|
function createRemModelStageResponsePort(input) {
|
|
29263
29269
|
return input;
|
|
29264
29270
|
}
|
|
29265
|
-
const log = createLogger("sno-station-mem:rem-sidecar:batch");
|
|
29271
|
+
const log$1 = createLogger("sno-station-mem:rem-sidecar:batch");
|
|
29266
29272
|
const canonicalStoreWriteQueues = /* @__PURE__ */ new Map();
|
|
29267
29273
|
const retirementAttributeConfigSchema = z.object({ slugs: z.array(z.object({
|
|
29268
29274
|
slug: z.string(),
|
|
@@ -29307,7 +29313,7 @@ async function runRemProductionOrderedWave(input) {
|
|
|
29307
29313
|
config: { stages: resolved.configuration.operations },
|
|
29308
29314
|
onStageError: ({ stage, error }) => {
|
|
29309
29315
|
if (error instanceof ModelCallRefusedError) refusal = error;
|
|
29310
|
-
log.warn("ordered_wave_stage_failed", {
|
|
29316
|
+
log$1.warn("ordered_wave_stage_failed", {
|
|
29311
29317
|
error: describeRemStageError(error),
|
|
29312
29318
|
job_id: waveId,
|
|
29313
29319
|
job_type: jobType,
|
|
@@ -29435,7 +29441,7 @@ async function runRemBatchJobUnlocked(input) {
|
|
|
29435
29441
|
const rows = readCandidates(runtime.database, input.scope);
|
|
29436
29442
|
const repository = createRemRepository(runtime.database);
|
|
29437
29443
|
const candidates = classifyCandidates(repository, rows);
|
|
29438
|
-
log.info("scan_started", {
|
|
29444
|
+
log$1.info("scan_started", {
|
|
29439
29445
|
job_id: input.jobId,
|
|
29440
29446
|
job_type: input.jobType,
|
|
29441
29447
|
candidates: candidates.length
|
|
@@ -29492,7 +29498,7 @@ async function runRemBatchJobUnlocked(input) {
|
|
|
29492
29498
|
outcome = completed.actionsApplied > 0 ? "success" : "empty-success";
|
|
29493
29499
|
if (!cleanupCompleted) outcome = "partial";
|
|
29494
29500
|
}
|
|
29495
|
-
log[completed && cleanupCompleted ? "info" : "error"]("REM batch completed", {
|
|
29501
|
+
log$1[completed && cleanupCompleted ? "info" : "error"]("REM batch completed", {
|
|
29496
29502
|
outcome,
|
|
29497
29503
|
job_id: input.jobId,
|
|
29498
29504
|
job_type: input.jobType,
|
|
@@ -29545,7 +29551,7 @@ async function openBatchRuntime(input) {
|
|
|
29545
29551
|
memoryTelemetry: pluginConfig.memoryTelemetry
|
|
29546
29552
|
});
|
|
29547
29553
|
database = openSqliteDatabase(dbPath, { fileMustExist: true });
|
|
29548
|
-
log.info("database_opened", {
|
|
29554
|
+
log$1.info("database_opened", {
|
|
29549
29555
|
event: "database_opened",
|
|
29550
29556
|
job_id: input.jobId,
|
|
29551
29557
|
job_type: input.jobType,
|
|
@@ -29565,12 +29571,13 @@ async function openBatchRuntime(input) {
|
|
|
29565
29571
|
timeoutMs: Math.max(12e4, CODING_SKIN_CHILD_DEADLINE_MS),
|
|
29566
29572
|
agentPort: input.agentPort,
|
|
29567
29573
|
refuseOnUnavailable: true,
|
|
29574
|
+
hostRequired: remNeedsHost(input.mode ?? pluginConfig.mode, settings.modelCalls),
|
|
29568
29575
|
routing: pickLlmRoutingConfig({
|
|
29569
29576
|
mode: input.mode ?? pluginConfig.mode,
|
|
29570
29577
|
modelCalls: settings.modelCalls
|
|
29571
29578
|
}),
|
|
29572
29579
|
onProviderResponse: ({ callId, destination, provider, requestId, model, usage }) => {
|
|
29573
|
-
log.info("llm_provider_response", {
|
|
29580
|
+
log$1.info("llm_provider_response", {
|
|
29574
29581
|
event: "llm_provider_response",
|
|
29575
29582
|
job_id: input.jobId,
|
|
29576
29583
|
job_type: input.jobType,
|
|
@@ -29761,7 +29768,7 @@ async function runUpdate(input) {
|
|
|
29761
29768
|
for (const [index, candidate] of owned.entries()) {
|
|
29762
29769
|
const claimed = claimCandidate(input.repository, candidate, "restate");
|
|
29763
29770
|
if (!claimed) continue;
|
|
29764
|
-
log.info("update_progress", {
|
|
29771
|
+
log$1.info("update_progress", {
|
|
29765
29772
|
job_id: input.jobId,
|
|
29766
29773
|
current: index + 1,
|
|
29767
29774
|
total: owned.length,
|
|
@@ -29801,7 +29808,7 @@ async function runUpdate(input) {
|
|
|
29801
29808
|
llmCalls += 1;
|
|
29802
29809
|
const reply = await completeJsonStage(input.runtime, "rem-update-judgment", prompt);
|
|
29803
29810
|
const decision = decideRemUpdateFromReply(typeof reply === "string" ? reply : JSON.stringify(reply) ?? "");
|
|
29804
|
-
log.info("update_decision_evaluated", {
|
|
29811
|
+
log$1.info("update_decision_evaluated", {
|
|
29805
29812
|
job_id: input.jobId,
|
|
29806
29813
|
row_id: candidate.id,
|
|
29807
29814
|
outcome: decision.outcome,
|
|
@@ -29833,7 +29840,7 @@ async function runUpdate(input) {
|
|
|
29833
29840
|
llmCalls += 1;
|
|
29834
29841
|
const verificationReply = await completeJsonStage(input.runtime, "rem-update-verification", verificationPrompt);
|
|
29835
29842
|
const verification = decideRemUpdateVerification(typeof verificationReply === "string" ? verificationReply : JSON.stringify(verificationReply) ?? "");
|
|
29836
|
-
log.info("update_verification_evaluated", {
|
|
29843
|
+
log$1.info("update_verification_evaluated", {
|
|
29837
29844
|
job_id: input.jobId,
|
|
29838
29845
|
row_id: candidate.id,
|
|
29839
29846
|
outcome: verification.outcome,
|
|
@@ -30707,7 +30714,7 @@ async function runReplace(input) {
|
|
|
30707
30714
|
refusePairOutcome(input.repository, input.jobId, generationId, pairClaim.pairId, invocationId, "row_closed_by_prior_pair");
|
|
30708
30715
|
continue;
|
|
30709
30716
|
}
|
|
30710
|
-
log.info("replace_progress", {
|
|
30717
|
+
log$1.info("replace_progress", {
|
|
30711
30718
|
job_id: input.jobId,
|
|
30712
30719
|
current: index + 1,
|
|
30713
30720
|
total: pairs.length,
|
|
@@ -30860,7 +30867,7 @@ async function runReplace(input) {
|
|
|
30860
30867
|
reason: coverageReason,
|
|
30861
30868
|
throughRefusePair: false
|
|
30862
30869
|
});
|
|
30863
|
-
log.info("replace_coverage_refused", {
|
|
30870
|
+
log$1.info("replace_coverage_refused", {
|
|
30864
30871
|
job_id: input.jobId,
|
|
30865
30872
|
pair_id: pairClaim.pairId,
|
|
30866
30873
|
older_row_id: ordered.older.id,
|
|
@@ -31006,7 +31013,7 @@ async function runReplace(input) {
|
|
|
31006
31013
|
const clause = clauses[clauseIndex];
|
|
31007
31014
|
return clause?.origin === "older" ? [clause.value] : [];
|
|
31008
31015
|
});
|
|
31009
|
-
if (retiredFactAtoms.length !== arbitration.retiringClauseIndices.length) log.info("replace_retiring_index_unresolved", {
|
|
31016
|
+
if (retiredFactAtoms.length !== arbitration.retiringClauseIndices.length) log$1.info("replace_retiring_index_unresolved", {
|
|
31010
31017
|
job_id: input.jobId,
|
|
31011
31018
|
pair_id: pairClaim.pairId,
|
|
31012
31019
|
named: arbitration.retiringClauseIndices.length,
|
|
@@ -31098,7 +31105,7 @@ async function runReplace(input) {
|
|
|
31098
31105
|
try {
|
|
31099
31106
|
run();
|
|
31100
31107
|
} catch (releaseError) {
|
|
31101
|
-
log.error("REM claim release failed after a host refusal", {
|
|
31108
|
+
log$1.error("REM claim release failed after a host refusal", {
|
|
31102
31109
|
target,
|
|
31103
31110
|
error: releaseError
|
|
31104
31111
|
}, {
|
|
@@ -31247,7 +31254,7 @@ async function buildRemReplaceCandidateQueue(input) {
|
|
|
31247
31254
|
}
|
|
31248
31255
|
let failedLookups = 0;
|
|
31249
31256
|
for (const [index, candidate] of candidates.entries()) {
|
|
31250
|
-
log.info("replace_candidate_progress", {
|
|
31257
|
+
log$1.info("replace_candidate_progress", {
|
|
31251
31258
|
current: index + 1,
|
|
31252
31259
|
total: candidates.length,
|
|
31253
31260
|
row_id: candidate.id
|
|
@@ -31314,7 +31321,7 @@ async function buildRemReplaceCandidateQueue(input) {
|
|
|
31314
31321
|
recordedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
31315
31322
|
});
|
|
31316
31323
|
}
|
|
31317
|
-
if (failedLookups > 0) log.warn("replace_candidate_lookup_failed", {
|
|
31324
|
+
if (failedLookups > 0) log$1.warn("replace_candidate_lookup_failed", {
|
|
31318
31325
|
failed_lookups: failedLookups,
|
|
31319
31326
|
total: candidates.length
|
|
31320
31327
|
}, {
|
|
@@ -31629,7 +31636,7 @@ function reserveReplaceStage(repository, generationId, pairId, invocationId, sta
|
|
|
31629
31636
|
countTokens
|
|
31630
31637
|
});
|
|
31631
31638
|
if (reservation.status === "reserved") return reservation.tokens;
|
|
31632
|
-
log.warn("replace_stage_unmeasured", {
|
|
31639
|
+
log$1.warn("replace_stage_unmeasured", {
|
|
31633
31640
|
job_id: jobId,
|
|
31634
31641
|
pair_id: pairId,
|
|
31635
31642
|
stage,
|
|
@@ -31649,4 +31656,716 @@ function compareTuple(left, right) {
|
|
|
31649
31656
|
return JSON.stringify(left).localeCompare(JSON.stringify(right));
|
|
31650
31657
|
}
|
|
31651
31658
|
//#endregion
|
|
31652
|
-
|
|
31659
|
+
//#region src/sidecar/rem-trigger-state.ts
|
|
31660
|
+
/** @file rem-trigger-state.ts
|
|
31661
|
+
* @purpose Persists the automatic REM scheduler's strict per-scope state.
|
|
31662
|
+
* @boundary One atomically replaced JSON file under the sno-station-mem state directory.
|
|
31663
|
+
*/
|
|
31664
|
+
const remTriggerScopeStateSchema = z.object({
|
|
31665
|
+
last_pass_at: z.string().datetime(),
|
|
31666
|
+
schedule_zone: z.string().min(1).refine(isValidScheduleZone, "invalid IANA time zone"),
|
|
31667
|
+
last_covered_count: z.number().int().nonnegative(),
|
|
31668
|
+
last_volume_pass_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/u).nullable(),
|
|
31669
|
+
missed_window: z.object({
|
|
31670
|
+
due_at: z.string().datetime(),
|
|
31671
|
+
trigger: z.enum(["daily", "volume"]),
|
|
31672
|
+
recorded_at: z.string().datetime()
|
|
31673
|
+
}).strict().nullable().default(null),
|
|
31674
|
+
attempts: z.object({
|
|
31675
|
+
identity: z.string().min(1).nullable(),
|
|
31676
|
+
count: z.number().int().min(0).max(3)
|
|
31677
|
+
}).strict()
|
|
31678
|
+
}).strict();
|
|
31679
|
+
const remTriggerStateDocumentSchema = z.object({
|
|
31680
|
+
version: z.literal(1),
|
|
31681
|
+
scopes: z.record(z.string().min(1), remTriggerScopeStateSchema)
|
|
31682
|
+
}).strict();
|
|
31683
|
+
var RemTriggerStateError = class extends Error {
|
|
31684
|
+
statePath;
|
|
31685
|
+
constructor(statePath, cause) {
|
|
31686
|
+
super(`REM trigger state at ${statePath} is invalid or unreadable: ${errorMessage$1(cause)}`, { cause: cause instanceof Error ? cause : void 0 });
|
|
31687
|
+
this.statePath = statePath;
|
|
31688
|
+
this.name = "RemTriggerStateError";
|
|
31689
|
+
}
|
|
31690
|
+
};
|
|
31691
|
+
function remTriggerStatePath(stateDir) {
|
|
31692
|
+
return path.join(stateDir, "rem-trigger-state.json");
|
|
31693
|
+
}
|
|
31694
|
+
async function loadRemTriggerState(stateDir) {
|
|
31695
|
+
const statePath = remTriggerStatePath(stateDir);
|
|
31696
|
+
let raw;
|
|
31697
|
+
try {
|
|
31698
|
+
raw = await readFile(statePath, "utf8");
|
|
31699
|
+
} catch (error) {
|
|
31700
|
+
if (isNodeError$1(error) && error.code === "ENOENT") return {
|
|
31701
|
+
version: 1,
|
|
31702
|
+
scopes: {}
|
|
31703
|
+
};
|
|
31704
|
+
throw new RemTriggerStateError(statePath, error);
|
|
31705
|
+
}
|
|
31706
|
+
try {
|
|
31707
|
+
return remTriggerStateDocumentSchema.parse(JSON.parse(raw));
|
|
31708
|
+
} catch (error) {
|
|
31709
|
+
throw new RemTriggerStateError(statePath, error);
|
|
31710
|
+
}
|
|
31711
|
+
}
|
|
31712
|
+
function ensureRemTriggerScope(state, input) {
|
|
31713
|
+
const existing = state.scopes[input.scope];
|
|
31714
|
+
if (existing !== void 0) return {
|
|
31715
|
+
state,
|
|
31716
|
+
scopeState: existing,
|
|
31717
|
+
initialized: false
|
|
31718
|
+
};
|
|
31719
|
+
if (input.scope.trim().length === 0) throw new Error("REM trigger scope is required");
|
|
31720
|
+
if (!Number.isInteger(input.candidateCount) || input.candidateCount < 0) throw new Error("REM trigger candidate count must be a nonnegative integer");
|
|
31721
|
+
if (Number.isNaN(input.now.getTime())) throw new Error("REM trigger initialization time is invalid");
|
|
31722
|
+
const scheduleZone = (input.resolveScheduleZone ?? resolveHostScheduleZone)();
|
|
31723
|
+
if (!isValidScheduleZone(scheduleZone)) throw new Error(`invalid REM schedule zone: ${scheduleZone}`);
|
|
31724
|
+
const scopeState = {
|
|
31725
|
+
last_pass_at: input.now.toISOString(),
|
|
31726
|
+
schedule_zone: scheduleZone,
|
|
31727
|
+
last_covered_count: input.candidateCount,
|
|
31728
|
+
last_volume_pass_date: null,
|
|
31729
|
+
missed_window: null,
|
|
31730
|
+
attempts: {
|
|
31731
|
+
identity: null,
|
|
31732
|
+
count: 0
|
|
31733
|
+
}
|
|
31734
|
+
};
|
|
31735
|
+
return {
|
|
31736
|
+
state: {
|
|
31737
|
+
version: 1,
|
|
31738
|
+
scopes: {
|
|
31739
|
+
...state.scopes,
|
|
31740
|
+
[input.scope]: scopeState
|
|
31741
|
+
}
|
|
31742
|
+
},
|
|
31743
|
+
scopeState,
|
|
31744
|
+
initialized: true
|
|
31745
|
+
};
|
|
31746
|
+
}
|
|
31747
|
+
async function writeRemTriggerStateAtomic$1(stateDir, state) {
|
|
31748
|
+
const validated = remTriggerStateDocumentSchema.parse(state);
|
|
31749
|
+
await mkdir(stateDir, {
|
|
31750
|
+
recursive: true,
|
|
31751
|
+
mode: 448
|
|
31752
|
+
});
|
|
31753
|
+
const statePath = remTriggerStatePath(stateDir);
|
|
31754
|
+
const temporaryPath = `${statePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
31755
|
+
try {
|
|
31756
|
+
const handle = await open(temporaryPath, "wx", 384);
|
|
31757
|
+
try {
|
|
31758
|
+
await handle.writeFile(JSON.stringify(validated), "utf8");
|
|
31759
|
+
await handle.sync();
|
|
31760
|
+
} finally {
|
|
31761
|
+
await handle.close();
|
|
31762
|
+
}
|
|
31763
|
+
await rename(temporaryPath, statePath);
|
|
31764
|
+
await syncDirectory(stateDir);
|
|
31765
|
+
} catch (error) {
|
|
31766
|
+
await rm(temporaryPath, { force: true });
|
|
31767
|
+
throw error;
|
|
31768
|
+
}
|
|
31769
|
+
}
|
|
31770
|
+
function resolveHostScheduleZone() {
|
|
31771
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
31772
|
+
}
|
|
31773
|
+
function isValidScheduleZone(value) {
|
|
31774
|
+
if (value.trim().length === 0) return false;
|
|
31775
|
+
try {
|
|
31776
|
+
new Intl.DateTimeFormat("en-US", { timeZone: value }).format(0);
|
|
31777
|
+
return true;
|
|
31778
|
+
} catch {
|
|
31779
|
+
return false;
|
|
31780
|
+
}
|
|
31781
|
+
}
|
|
31782
|
+
async function syncDirectory(directory) {
|
|
31783
|
+
if (process.platform === "win32") return;
|
|
31784
|
+
const handle = await open(directory, "r");
|
|
31785
|
+
try {
|
|
31786
|
+
await handle.sync();
|
|
31787
|
+
} finally {
|
|
31788
|
+
await handle.close();
|
|
31789
|
+
}
|
|
31790
|
+
}
|
|
31791
|
+
function isNodeError$1(error) {
|
|
31792
|
+
return error instanceof Error && "code" in error;
|
|
31793
|
+
}
|
|
31794
|
+
function errorMessage$1(error) {
|
|
31795
|
+
return error instanceof Error ? error.message : String(error);
|
|
31796
|
+
}
|
|
31797
|
+
const REM_COMPLETION_AUDIT_TAIL_BYTES = 16777216;
|
|
31798
|
+
const log = createLogger("sno-station-mem:rem-trigger");
|
|
31799
|
+
function remNeedsHost(mode, modelCalls) {
|
|
31800
|
+
return Object.keys(modelCalls).some((id) => id.startsWith("REM") && modelCalls[id][mode] === "host");
|
|
31801
|
+
}
|
|
31802
|
+
const discoverySchema = z.object({
|
|
31803
|
+
pid: z.number().int().positive(),
|
|
31804
|
+
port: z.number().int().min(1).max(65535),
|
|
31805
|
+
token: z.string().min(1)
|
|
31806
|
+
}).strict();
|
|
31807
|
+
const idleEvaluations = /* @__PURE__ */ new Map();
|
|
31808
|
+
async function evaluateRemAutomaticTriggers(input) {
|
|
31809
|
+
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
31810
|
+
if (!Number.isInteger(input.volumeThreshold ?? 100) || (input.volumeThreshold ?? 100) < 1) throw new Error("REM volume threshold must be a positive integer");
|
|
31811
|
+
const auditStateDir = input.auditStateDir ?? input.stateDir;
|
|
31812
|
+
if (Number.isNaN(now.getTime())) throw new Error("REM trigger evaluation time is invalid");
|
|
31813
|
+
if (input.requestedOperations.length === 0) {
|
|
31814
|
+
await recordDecision(auditStateDir, void 0, "skipped", {
|
|
31815
|
+
row: "automatic-trigger-skipped",
|
|
31816
|
+
reason: "product-mode-disabled"
|
|
31817
|
+
});
|
|
31818
|
+
return {
|
|
31819
|
+
evaluations: 0,
|
|
31820
|
+
dispatches: 0
|
|
31821
|
+
};
|
|
31822
|
+
}
|
|
31823
|
+
if (input.mode && remNeedsHost(input.mode, input.modelCalls) && !input.hasConnectedHost?.()) {
|
|
31824
|
+
await recordDecision(auditStateDir, void 0, "skipped", {
|
|
31825
|
+
row: "automatic-trigger-skipped",
|
|
31826
|
+
reason: "skipped: no host model connected"
|
|
31827
|
+
});
|
|
31828
|
+
return {
|
|
31829
|
+
evaluations: 0,
|
|
31830
|
+
dispatches: 0
|
|
31831
|
+
};
|
|
31832
|
+
}
|
|
31833
|
+
let scopes;
|
|
31834
|
+
try {
|
|
31835
|
+
scopes = enumerateRemCandidateScopes(input.database);
|
|
31836
|
+
} catch (error) {
|
|
31837
|
+
await recordDecision(auditStateDir, void 0, "error", {
|
|
31838
|
+
row: "enumeration-failed",
|
|
31839
|
+
cause: errorMessage(error)
|
|
31840
|
+
});
|
|
31841
|
+
return {
|
|
31842
|
+
evaluations: 1,
|
|
31843
|
+
dispatches: 0
|
|
31844
|
+
};
|
|
31845
|
+
}
|
|
31846
|
+
if (scopes.length === 0) {
|
|
31847
|
+
await recordDecision(auditStateDir, void 0, "ok", { row: "no-scopes" });
|
|
31848
|
+
return {
|
|
31849
|
+
evaluations: 1,
|
|
31850
|
+
dispatches: 0
|
|
31851
|
+
};
|
|
31852
|
+
}
|
|
31853
|
+
let state;
|
|
31854
|
+
let lostState = false;
|
|
31855
|
+
try {
|
|
31856
|
+
state = await loadRemTriggerState(input.stateDir);
|
|
31857
|
+
} catch (error) {
|
|
31858
|
+
for (const { scope, candidateCount } of scopes) {
|
|
31859
|
+
const consecutiveIdle = (idleEvaluations.get(scope) ?? 0) + 1;
|
|
31860
|
+
idleEvaluations.set(scope, consecutiveIdle);
|
|
31861
|
+
await recordDecision(auditStateDir, scope, "error", {
|
|
31862
|
+
row: "state-unreadable",
|
|
31863
|
+
candidate_count: candidateCount,
|
|
31864
|
+
cause: errorMessage(error),
|
|
31865
|
+
consecutive_idle: consecutiveIdle
|
|
31866
|
+
});
|
|
31867
|
+
}
|
|
31868
|
+
log.error("REM trigger state unavailable; continuing with due work", { cause: errorMessage(error) }, {
|
|
31869
|
+
event_name: "memory.rem.trigger.state.unavailable",
|
|
31870
|
+
file: "packages/memory/src/sidecar/rem-trigger.ts",
|
|
31871
|
+
function: "evaluateRemAutomaticTriggers",
|
|
31872
|
+
site_id: "memory.rem.trigger.state.unavailable"
|
|
31873
|
+
});
|
|
31874
|
+
state = {
|
|
31875
|
+
version: 1,
|
|
31876
|
+
scopes: {}
|
|
31877
|
+
};
|
|
31878
|
+
lostState = true;
|
|
31879
|
+
}
|
|
31880
|
+
state = await applyCompletedBaselines(auditStateDir, input.stateDir, state);
|
|
31881
|
+
let dispatches = 0;
|
|
31882
|
+
for (const { scope, candidateCount } of scopes) try {
|
|
31883
|
+
const ensured = ensureRemTriggerScope(state, {
|
|
31884
|
+
scope,
|
|
31885
|
+
now: lostState ? previousDay(now) : now,
|
|
31886
|
+
candidateCount,
|
|
31887
|
+
resolveScheduleZone: input.resolveScheduleZone
|
|
31888
|
+
});
|
|
31889
|
+
state = ensured.state;
|
|
31890
|
+
if (ensured.initialized) await writeRemTriggerStateAtomic(input.stateDir, state);
|
|
31891
|
+
const scopeResult = await evaluateScope(input, auditStateDir, state, scope, candidateCount, now);
|
|
31892
|
+
state = scopeResult.state;
|
|
31893
|
+
dispatches += scopeResult.dispatched ? 1 : 0;
|
|
31894
|
+
} catch (error) {
|
|
31895
|
+
log.error("REM automatic scope evaluation failed", {
|
|
31896
|
+
scope,
|
|
31897
|
+
error
|
|
31898
|
+
}, {
|
|
31899
|
+
event_name: "sno_station_mem.rem-trigger.rem.automatic.scope.evaluation.failed",
|
|
31900
|
+
file: "packages/memory/src/sidecar/rem-trigger.ts",
|
|
31901
|
+
function: "evaluateRemAutomaticTriggers",
|
|
31902
|
+
site_id: "rem-trigger.evaluateRemAutomaticTriggers.1d59077a5c"
|
|
31903
|
+
});
|
|
31904
|
+
try {
|
|
31905
|
+
await recordDecision(auditStateDir, scope, "error", {
|
|
31906
|
+
row: "scope-evaluation-failed",
|
|
31907
|
+
cause: errorMessage(error)
|
|
31908
|
+
});
|
|
31909
|
+
} catch (auditError) {
|
|
31910
|
+
log.warn("REM automatic scope failure audit failed", {
|
|
31911
|
+
scope,
|
|
31912
|
+
error: auditError
|
|
31913
|
+
}, {
|
|
31914
|
+
event_name: "sno_station_mem.rem-trigger.rem.automatic.scope.failure.audit.failed",
|
|
31915
|
+
file: "packages/memory/src/sidecar/rem-trigger.ts",
|
|
31916
|
+
function: "evaluateRemAutomaticTriggers",
|
|
31917
|
+
site_id: "rem-trigger.evaluateRemAutomaticTriggers.ebe1cdd204"
|
|
31918
|
+
});
|
|
31919
|
+
}
|
|
31920
|
+
try {
|
|
31921
|
+
state = await loadRemTriggerState(input.stateDir);
|
|
31922
|
+
} catch (stateError) {
|
|
31923
|
+
log.warn("REM automatic trigger state reload failed", {
|
|
31924
|
+
scope,
|
|
31925
|
+
error: stateError
|
|
31926
|
+
}, {
|
|
31927
|
+
event_name: "sno_station_mem.rem-trigger.rem.automatic.trigger.state.reload.failed",
|
|
31928
|
+
file: "packages/memory/src/sidecar/rem-trigger.ts",
|
|
31929
|
+
function: "evaluateRemAutomaticTriggers",
|
|
31930
|
+
site_id: "rem-trigger.evaluateRemAutomaticTriggers.46669e66ff"
|
|
31931
|
+
});
|
|
31932
|
+
break;
|
|
31933
|
+
}
|
|
31934
|
+
}
|
|
31935
|
+
return {
|
|
31936
|
+
evaluations: scopes.length,
|
|
31937
|
+
dispatches
|
|
31938
|
+
};
|
|
31939
|
+
}
|
|
31940
|
+
function previousDay(now) {
|
|
31941
|
+
const day = new Date(now);
|
|
31942
|
+
day.setUTCDate(day.getUTCDate() - 1);
|
|
31943
|
+
return day;
|
|
31944
|
+
}
|
|
31945
|
+
async function writeRemTriggerStateAtomic(stateDir, state) {
|
|
31946
|
+
try {
|
|
31947
|
+
await writeRemTriggerStateAtomic$1(stateDir, state);
|
|
31948
|
+
} catch (error) {
|
|
31949
|
+
log.error("REM trigger state write failed; continuing dispatch", { cause: errorMessage(error) }, {
|
|
31950
|
+
event_name: "memory.rem.trigger.state.write.failed",
|
|
31951
|
+
file: "packages/memory/src/sidecar/rem-trigger.ts",
|
|
31952
|
+
function: "evaluateRemAutomaticTriggers",
|
|
31953
|
+
site_id: "memory.rem.trigger.state.write.failed"
|
|
31954
|
+
});
|
|
31955
|
+
}
|
|
31956
|
+
}
|
|
31957
|
+
async function evaluateScope(input, auditStateDir, state, scope, candidateCount, now) {
|
|
31958
|
+
const scopeState = requiredScopeState(state, scope);
|
|
31959
|
+
const zone = scopeState.schedule_zone;
|
|
31960
|
+
const nextDue = nextDailyDue(scopeState);
|
|
31961
|
+
const localDate = localDateAt(now, zone);
|
|
31962
|
+
const growth = candidateCount - scopeState.last_covered_count;
|
|
31963
|
+
const scheduledDue = computeRemDailyDue(scopeState.last_pass_at, zone);
|
|
31964
|
+
const pendingVolumeToday = scopeState.attempts.identity === remAutomaticCorrelationId("volume", scope, localDate);
|
|
31965
|
+
const pendingDailyToday = localDateAt(scheduledDue, zone) === localDate && scopeState.attempts.identity === remAutomaticCorrelationId("daily", scope, scheduledDue.toISOString());
|
|
31966
|
+
const dailyDue = now.getTime() >= nextDue.getTime() && !pendingVolumeToday;
|
|
31967
|
+
const volumeDue = growth >= (input.volumeThreshold ?? 100) && scopeState.last_volume_pass_date !== localDate && !pendingDailyToday;
|
|
31968
|
+
if (!dailyDue && !volumeDue) {
|
|
31969
|
+
const consecutiveIdle = (idleEvaluations.get(scope) ?? 0) + 1;
|
|
31970
|
+
idleEvaluations.set(scope, consecutiveIdle);
|
|
31971
|
+
await recordDecision(auditStateDir, scope, "ok", {
|
|
31972
|
+
row: "waiting-for-schedule",
|
|
31973
|
+
next_due: nextDue.toISOString(),
|
|
31974
|
+
milliseconds_until_due: Math.max(0, nextDue.getTime() - now.getTime()),
|
|
31975
|
+
growth: growthDetails(candidateCount, scopeState.last_covered_count, input.volumeThreshold ?? 100),
|
|
31976
|
+
consecutive_idle: consecutiveIdle
|
|
31977
|
+
});
|
|
31978
|
+
return {
|
|
31979
|
+
state,
|
|
31980
|
+
dispatched: false
|
|
31981
|
+
};
|
|
31982
|
+
}
|
|
31983
|
+
const trigger = dailyDue ? "daily" : "volume";
|
|
31984
|
+
if (input.tickEnabled === false) {
|
|
31985
|
+
const nextState = replaceScopeState(state, scope, {
|
|
31986
|
+
...scopeState,
|
|
31987
|
+
missed_window: {
|
|
31988
|
+
due_at: dailyDue ? nextDue.toISOString() : now.toISOString(),
|
|
31989
|
+
trigger,
|
|
31990
|
+
recorded_at: now.toISOString()
|
|
31991
|
+
}
|
|
31992
|
+
});
|
|
31993
|
+
await writeRemTriggerStateAtomic(input.stateDir, nextState);
|
|
31994
|
+
return {
|
|
31995
|
+
state: nextState,
|
|
31996
|
+
dispatched: false
|
|
31997
|
+
};
|
|
31998
|
+
}
|
|
31999
|
+
const correlationId = remAutomaticCorrelationId(trigger, scope, trigger === "daily" ? nextDue.toISOString() : localDate);
|
|
32000
|
+
const priorAttempts = scopeState.attempts.identity === correlationId ? scopeState.attempts.count : 0;
|
|
32001
|
+
await recordDecision(auditStateDir, scope, "ok", {
|
|
32002
|
+
row: "dispatch",
|
|
32003
|
+
trigger,
|
|
32004
|
+
next_due: nextDue.toISOString(),
|
|
32005
|
+
pass_at: now.toISOString(),
|
|
32006
|
+
local_date: localDate,
|
|
32007
|
+
growth: growthDetails(candidateCount, scopeState.last_covered_count, input.volumeThreshold ?? 100),
|
|
32008
|
+
correlation_id: correlationId,
|
|
32009
|
+
consecutive_idle: 0
|
|
32010
|
+
});
|
|
32011
|
+
idleEvaluations.set(scope, 0);
|
|
32012
|
+
let nextState = replaceScopeState(state, scope, {
|
|
32013
|
+
...scopeState,
|
|
32014
|
+
attempts: {
|
|
32015
|
+
identity: correlationId,
|
|
32016
|
+
count: Math.min(priorAttempts + 1, 3)
|
|
32017
|
+
}
|
|
32018
|
+
});
|
|
32019
|
+
await writeRemTriggerStateAtomic(input.stateDir, nextState);
|
|
32020
|
+
let cause;
|
|
32021
|
+
try {
|
|
32022
|
+
await dispatchRemWave(input, scope, correlationId);
|
|
32023
|
+
} catch (error) {
|
|
32024
|
+
cause = errorMessage(error);
|
|
32025
|
+
}
|
|
32026
|
+
if (cause === void 0) {
|
|
32027
|
+
nextState = replaceScopeState(nextState, scope, {
|
|
32028
|
+
...requiredScopeState(nextState, scope),
|
|
32029
|
+
missed_window: null
|
|
32030
|
+
});
|
|
32031
|
+
await writeRemTriggerStateAtomic(input.stateDir, nextState);
|
|
32032
|
+
return {
|
|
32033
|
+
state: nextState,
|
|
32034
|
+
dispatched: true
|
|
32035
|
+
};
|
|
32036
|
+
}
|
|
32037
|
+
await appendAuditEntryStrict(auditStateDir, {
|
|
32038
|
+
event: "rem_failed",
|
|
32039
|
+
resultStatus: "error",
|
|
32040
|
+
scope,
|
|
32041
|
+
details: {
|
|
32042
|
+
outcome: "dispatch-failed",
|
|
32043
|
+
cause,
|
|
32044
|
+
correlation_id: correlationId,
|
|
32045
|
+
source: "gateway-trigger"
|
|
32046
|
+
}
|
|
32047
|
+
});
|
|
32048
|
+
return {
|
|
32049
|
+
state: nextState,
|
|
32050
|
+
dispatched: true
|
|
32051
|
+
};
|
|
32052
|
+
}
|
|
32053
|
+
async function dispatchRemWave(input, scope, correlationId) {
|
|
32054
|
+
const started = performance.now();
|
|
32055
|
+
const discovery = discoverySchema.parse(JSON.parse(await readFile(input.discoveryPath ?? getRemDiscoveryPath(), "utf8")));
|
|
32056
|
+
const response = await fetch(`http://${REM_SIDECAR_HOST}:${discovery.port}${REM_RUN_PATH}`, {
|
|
32057
|
+
method: "POST",
|
|
32058
|
+
headers: {
|
|
32059
|
+
"content-type": "application/json",
|
|
32060
|
+
[REM_SIDECAR_TOKEN_HEADER]: discovery.token,
|
|
32061
|
+
[REM_CORRELATION_ID_HEADER]: correlationId
|
|
32062
|
+
},
|
|
32063
|
+
body: JSON.stringify({
|
|
32064
|
+
types: input.requestedOperations,
|
|
32065
|
+
scope
|
|
32066
|
+
}),
|
|
32067
|
+
signal: AbortSignal.timeout(input.dispatchTimeoutMs ?? 1e4)
|
|
32068
|
+
});
|
|
32069
|
+
if (response.status !== 202) throw new Error(`REM sidecar returned HTTP ${response.status}`);
|
|
32070
|
+
const body = z.object({
|
|
32071
|
+
job_id: z.string().min(1),
|
|
32072
|
+
waveId: z.string().min(1)
|
|
32073
|
+
}).passthrough().parse(await response.json());
|
|
32074
|
+
if (body.job_id !== body.waveId) throw new Error("REM sidecar confirmation identities disagree");
|
|
32075
|
+
withLogContext$1({
|
|
32076
|
+
operation_id: body.job_id,
|
|
32077
|
+
job_id: body.job_id,
|
|
32078
|
+
session_reference: scope,
|
|
32079
|
+
external_reference: correlationId
|
|
32080
|
+
}, () => {
|
|
32081
|
+
log.info("REM dispatch accepted", {
|
|
32082
|
+
outcome: "success",
|
|
32083
|
+
job_id: body.job_id,
|
|
32084
|
+
status: response.status,
|
|
32085
|
+
duration_ms: performance.now() - started
|
|
32086
|
+
}, {
|
|
32087
|
+
event_name: "sidecar.trigger.dispatch.accepted",
|
|
32088
|
+
file: "packages/memory/src/sidecar/rem-trigger.ts",
|
|
32089
|
+
function: "dispatchRemWave",
|
|
32090
|
+
site_id: "sidecar.trigger.dispatch.accepted"
|
|
32091
|
+
});
|
|
32092
|
+
});
|
|
32093
|
+
}
|
|
32094
|
+
async function applyCompletedBaselines(auditStateDir, triggerStateDir, state) {
|
|
32095
|
+
let content;
|
|
32096
|
+
try {
|
|
32097
|
+
content = await readAuditTail(getAuditPath(auditStateDir));
|
|
32098
|
+
} catch (error) {
|
|
32099
|
+
if (isNodeError(error) && error.code === "ENOENT") return state;
|
|
32100
|
+
log.warn("REM completion audit could not be read", {
|
|
32101
|
+
error,
|
|
32102
|
+
outcome: "skipped",
|
|
32103
|
+
reason_code: "audit_read_failed"
|
|
32104
|
+
}, {
|
|
32105
|
+
event_name: "sidecar.trigger.audit_read.failed",
|
|
32106
|
+
file: "packages/memory/src/sidecar/rem-trigger.ts",
|
|
32107
|
+
function: "applyCompletedBaselines",
|
|
32108
|
+
site_id: "sidecar.trigger.audit_read.failed"
|
|
32109
|
+
});
|
|
32110
|
+
return state;
|
|
32111
|
+
}
|
|
32112
|
+
const dispatched = /* @__PURE__ */ new Map();
|
|
32113
|
+
const triesByCorrelation = /* @__PURE__ */ new Map();
|
|
32114
|
+
let nextState = state;
|
|
32115
|
+
let malformedCount = 0;
|
|
32116
|
+
for (const line of content.split("\n")) {
|
|
32117
|
+
if (line.trim() === "") continue;
|
|
32118
|
+
try {
|
|
32119
|
+
const entry = JSON.parse(line);
|
|
32120
|
+
const details = asRecord(entry["details"]);
|
|
32121
|
+
const correlationId = details?.["correlation_id"];
|
|
32122
|
+
const scope = entry["scope"];
|
|
32123
|
+
if (entry["event"] === "rem_trigger_evaluated" && details?.["row"] === "dispatch" && typeof correlationId === "string" && typeof scope === "string") {
|
|
32124
|
+
const trigger = details["trigger"];
|
|
32125
|
+
const passAt = details["pass_at"];
|
|
32126
|
+
const localDate = details["local_date"];
|
|
32127
|
+
dispatched.set(correlationId, {
|
|
32128
|
+
scope,
|
|
32129
|
+
...trigger === "daily" || trigger === "volume" ? { trigger } : {},
|
|
32130
|
+
...typeof passAt === "string" ? { passAt } : {},
|
|
32131
|
+
...typeof localDate === "string" ? { localDate } : {}
|
|
32132
|
+
});
|
|
32133
|
+
continue;
|
|
32134
|
+
}
|
|
32135
|
+
const failed = entry["event"] === "rem_failed";
|
|
32136
|
+
if ((entry["event"] === "rem_skipped" || failed) && typeof correlationId === "string") {
|
|
32137
|
+
const stopped = dispatched.get(correlationId);
|
|
32138
|
+
const spent = failed ? details?.["source"] === "sidecar" && details["error"] !== "sidecar_restart" : typeof details?.["destination"] === "string";
|
|
32139
|
+
const tries = (triesByCorrelation.get(correlationId) ?? 0) + (spent ? 1 : 0);
|
|
32140
|
+
triesByCorrelation.set(correlationId, tries);
|
|
32141
|
+
const stoppedScopeState = stopped ? nextState.scopes[stopped.scope] : void 0;
|
|
32142
|
+
if (stopped && stoppedScopeState && tries >= 3 && isLocalDate(stopped.localDate) && (stoppedScopeState.last_volume_pass_date ?? "") < stopped.localDate) nextState = replaceScopeState(nextState, stopped.scope, {
|
|
32143
|
+
...stoppedScopeState,
|
|
32144
|
+
last_volume_pass_date: stopped.localDate,
|
|
32145
|
+
attempts: {
|
|
32146
|
+
identity: null,
|
|
32147
|
+
count: 0
|
|
32148
|
+
}
|
|
32149
|
+
});
|
|
32150
|
+
else if (!failed && stopped && stoppedScopeState?.attempts.identity === correlationId) nextState = replaceScopeState(nextState, stopped.scope, {
|
|
32151
|
+
...stoppedScopeState,
|
|
32152
|
+
attempts: {
|
|
32153
|
+
identity: null,
|
|
32154
|
+
count: 0
|
|
32155
|
+
}
|
|
32156
|
+
});
|
|
32157
|
+
continue;
|
|
32158
|
+
}
|
|
32159
|
+
if (entry["event"] !== "rem_completed" || typeof correlationId !== "string") continue;
|
|
32160
|
+
const dispatch = dispatched.get(correlationId);
|
|
32161
|
+
if (dispatch === void 0 || state.scopes[dispatch.scope] === void 0 || entry["scope"] !== dispatch.scope) continue;
|
|
32162
|
+
const currentScopeState = requiredScopeState(nextState, dispatch.scope);
|
|
32163
|
+
let completedScopeState = {
|
|
32164
|
+
...currentScopeState,
|
|
32165
|
+
...dispatch.trigger === "daily" && isValidInstant(dispatch.passAt) ? { last_pass_at: dispatch.passAt } : {},
|
|
32166
|
+
...dispatch.trigger === "daily" && isLocalDate(dispatch.localDate) ? { last_volume_pass_date: dispatch.localDate } : {},
|
|
32167
|
+
...dispatch.trigger === "volume" && isLocalDate(dispatch.localDate) ? { last_volume_pass_date: dispatch.localDate } : {},
|
|
32168
|
+
...currentScopeState.attempts.identity === correlationId ? { attempts: {
|
|
32169
|
+
identity: null,
|
|
32170
|
+
count: 0
|
|
32171
|
+
} } : {}
|
|
32172
|
+
};
|
|
32173
|
+
const measured = asRecord(asRecord(details?.["stats"])?.["measured"]);
|
|
32174
|
+
const rowsConsidered = measured?.["rows_considered"];
|
|
32175
|
+
if (measured?.["pair_cap_binding"] === false && Number.isInteger(rowsConsidered) && Number(rowsConsidered) >= 0) completedScopeState = {
|
|
32176
|
+
...completedScopeState,
|
|
32177
|
+
last_covered_count: Number(rowsConsidered)
|
|
32178
|
+
};
|
|
32179
|
+
if (JSON.stringify(completedScopeState) === JSON.stringify(currentScopeState)) continue;
|
|
32180
|
+
nextState = replaceScopeState(nextState, dispatch.scope, completedScopeState);
|
|
32181
|
+
} catch {
|
|
32182
|
+
malformedCount += 1;
|
|
32183
|
+
}
|
|
32184
|
+
}
|
|
32185
|
+
if (malformedCount > 0) log.warn("Malformed REM audit records skipped", {
|
|
32186
|
+
malformed_count: malformedCount,
|
|
32187
|
+
outcome: "partial"
|
|
32188
|
+
}, {
|
|
32189
|
+
event_name: "sidecar.trigger.audit_records.skipped",
|
|
32190
|
+
file: "packages/memory/src/sidecar/rem-trigger.ts",
|
|
32191
|
+
function: "applyCompletedBaselines",
|
|
32192
|
+
site_id: "sidecar.trigger.audit_records.skipped"
|
|
32193
|
+
});
|
|
32194
|
+
if (nextState !== state) await writeRemTriggerStateAtomic(triggerStateDir, nextState);
|
|
32195
|
+
return nextState;
|
|
32196
|
+
}
|
|
32197
|
+
async function readAuditTail(auditPath) {
|
|
32198
|
+
const handle = await open(auditPath, "r");
|
|
32199
|
+
try {
|
|
32200
|
+
const size = (await handle.stat()).size;
|
|
32201
|
+
const bytesToRead = Math.min(size, REM_COMPLETION_AUDIT_TAIL_BYTES);
|
|
32202
|
+
if (bytesToRead === 0) return "";
|
|
32203
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
32204
|
+
const { bytesRead } = await handle.read(buffer, 0, bytesToRead, size - bytesToRead);
|
|
32205
|
+
let content = buffer.subarray(0, bytesRead).toString("utf8");
|
|
32206
|
+
if (size > bytesToRead) {
|
|
32207
|
+
const firstLineEnd = content.indexOf("\n");
|
|
32208
|
+
content = firstLineEnd === -1 ? "" : content.slice(firstLineEnd + 1);
|
|
32209
|
+
}
|
|
32210
|
+
return content;
|
|
32211
|
+
} finally {
|
|
32212
|
+
await handle.close();
|
|
32213
|
+
}
|
|
32214
|
+
}
|
|
32215
|
+
function remAutomaticCorrelationId(trigger, scope, triggerKey) {
|
|
32216
|
+
return `rem-auto-${trigger}-${createHash("sha256").update(JSON.stringify([
|
|
32217
|
+
"rem-automatic-v1",
|
|
32218
|
+
trigger,
|
|
32219
|
+
scope,
|
|
32220
|
+
triggerKey
|
|
32221
|
+
])).digest("hex")}`;
|
|
32222
|
+
}
|
|
32223
|
+
/** The daily due time, pushed to the schedule after the last used-up local day. */
|
|
32224
|
+
function nextDailyDue(scopeState) {
|
|
32225
|
+
const scheduled = computeRemDailyDue(scopeState.last_pass_at, scopeState.schedule_zone);
|
|
32226
|
+
const volumeDate = scopeState.last_volume_pass_date;
|
|
32227
|
+
if (volumeDate === null) return scheduled;
|
|
32228
|
+
const parsed = /^(\d{4})-(\d{2})-(\d{2})$/u.exec(volumeDate);
|
|
32229
|
+
if (parsed === null) return scheduled;
|
|
32230
|
+
const following = addCalendarDays({
|
|
32231
|
+
year: Number(parsed[1]),
|
|
32232
|
+
month: Number(parsed[2]),
|
|
32233
|
+
day: Number(parsed[3])
|
|
32234
|
+
}, 1);
|
|
32235
|
+
const afterVolume = zonedInstant(scopeState.schedule_zone, following.year, following.month, following.day);
|
|
32236
|
+
return afterVolume.getTime() > scheduled.getTime() ? afterVolume : scheduled;
|
|
32237
|
+
}
|
|
32238
|
+
function computeRemDailyDue(lastPassAt, scheduleZone) {
|
|
32239
|
+
const lastPass = new Date(lastPassAt);
|
|
32240
|
+
if (Number.isNaN(lastPass.getTime())) throw new Error("REM last pass time is invalid");
|
|
32241
|
+
const localDate = localDateParts(lastPass, scheduleZone);
|
|
32242
|
+
let due = zonedInstant(scheduleZone, localDate.year, localDate.month, localDate.day);
|
|
32243
|
+
if (due.getTime() <= lastPass.getTime()) {
|
|
32244
|
+
const nextDate = addCalendarDays(localDate, 1);
|
|
32245
|
+
due = zonedInstant(scheduleZone, nextDate.year, nextDate.month, nextDate.day);
|
|
32246
|
+
}
|
|
32247
|
+
return due;
|
|
32248
|
+
}
|
|
32249
|
+
function zonedInstant(zone, year, month, day) {
|
|
32250
|
+
const target = Date.UTC(year, month - 1, day, 3, 0, 0, 0);
|
|
32251
|
+
let instant = target;
|
|
32252
|
+
let firstExistingAfter;
|
|
32253
|
+
for (let iteration = 0; iteration < 5; iteration++) {
|
|
32254
|
+
const parts = zonedDateTimeParts(new Date(instant), zone);
|
|
32255
|
+
const represented = Date.UTC(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second);
|
|
32256
|
+
const adjustment = target - represented;
|
|
32257
|
+
if (adjustment === 0) return new Date(instant);
|
|
32258
|
+
if (represented > target && represented < (firstExistingAfter?.represented ?? Number.POSITIVE_INFINITY)) firstExistingAfter = {
|
|
32259
|
+
instant,
|
|
32260
|
+
represented
|
|
32261
|
+
};
|
|
32262
|
+
instant += adjustment;
|
|
32263
|
+
}
|
|
32264
|
+
if (firstExistingAfter !== void 0) return new Date(firstExistingAfter.instant);
|
|
32265
|
+
throw new Error(`REM scheduled instant cannot be resolved in zone ${zone}`);
|
|
32266
|
+
}
|
|
32267
|
+
function localDateAt(instant, zone) {
|
|
32268
|
+
const parts = localDateParts(instant, zone);
|
|
32269
|
+
return `${parts.year.toString().padStart(4, "0")}-${parts.month.toString().padStart(2, "0")}-${parts.day.toString().padStart(2, "0")}`;
|
|
32270
|
+
}
|
|
32271
|
+
function localDateParts(instant, zone) {
|
|
32272
|
+
const parts = zonedDateTimeParts(instant, zone);
|
|
32273
|
+
return {
|
|
32274
|
+
year: parts.year,
|
|
32275
|
+
month: parts.month,
|
|
32276
|
+
day: parts.day
|
|
32277
|
+
};
|
|
32278
|
+
}
|
|
32279
|
+
function zonedDateTimeParts(instant, zone) {
|
|
32280
|
+
const values = {};
|
|
32281
|
+
const formatter = new Intl.DateTimeFormat("en-CA", {
|
|
32282
|
+
timeZone: zone,
|
|
32283
|
+
year: "numeric",
|
|
32284
|
+
month: "2-digit",
|
|
32285
|
+
day: "2-digit",
|
|
32286
|
+
hour: "2-digit",
|
|
32287
|
+
minute: "2-digit",
|
|
32288
|
+
second: "2-digit",
|
|
32289
|
+
hourCycle: "h23"
|
|
32290
|
+
});
|
|
32291
|
+
for (const part of formatter.formatToParts(instant)) if (part.type !== "literal") values[part.type] = Number(part.value);
|
|
32292
|
+
const year = values["year"];
|
|
32293
|
+
const month = values["month"];
|
|
32294
|
+
const day = values["day"];
|
|
32295
|
+
const hour = values["hour"];
|
|
32296
|
+
const minute = values["minute"];
|
|
32297
|
+
const second = values["second"];
|
|
32298
|
+
if ([
|
|
32299
|
+
year,
|
|
32300
|
+
month,
|
|
32301
|
+
day,
|
|
32302
|
+
hour,
|
|
32303
|
+
minute,
|
|
32304
|
+
second
|
|
32305
|
+
].some((value) => value === void 0)) throw new Error(`REM schedule zone ${zone} did not produce complete date parts`);
|
|
32306
|
+
return {
|
|
32307
|
+
year: Number(year),
|
|
32308
|
+
month: Number(month),
|
|
32309
|
+
day: Number(day),
|
|
32310
|
+
hour: Number(hour),
|
|
32311
|
+
minute: Number(minute),
|
|
32312
|
+
second: Number(second)
|
|
32313
|
+
};
|
|
32314
|
+
}
|
|
32315
|
+
function addCalendarDays(date, days) {
|
|
32316
|
+
const instant = new Date(Date.UTC(date.year, date.month - 1, date.day + days));
|
|
32317
|
+
return {
|
|
32318
|
+
year: instant.getUTCFullYear(),
|
|
32319
|
+
month: instant.getUTCMonth() + 1,
|
|
32320
|
+
day: instant.getUTCDate()
|
|
32321
|
+
};
|
|
32322
|
+
}
|
|
32323
|
+
function growthDetails(candidateCount, coveredCount, threshold) {
|
|
32324
|
+
const growth = candidateCount - coveredCount;
|
|
32325
|
+
return {
|
|
32326
|
+
candidate_count: candidateCount,
|
|
32327
|
+
last_covered_count: coveredCount,
|
|
32328
|
+
delta: growth,
|
|
32329
|
+
threshold,
|
|
32330
|
+
remaining: Math.max(0, threshold - growth)
|
|
32331
|
+
};
|
|
32332
|
+
}
|
|
32333
|
+
async function recordDecision(stateDir, scope, resultStatus, details) {
|
|
32334
|
+
await appendAuditEntryStrict(stateDir, {
|
|
32335
|
+
event: "rem_trigger_evaluated",
|
|
32336
|
+
resultStatus,
|
|
32337
|
+
...scope === void 0 ? {} : { scope },
|
|
32338
|
+
details
|
|
32339
|
+
});
|
|
32340
|
+
}
|
|
32341
|
+
function requiredScopeState(state, scope) {
|
|
32342
|
+
const scopeState = state.scopes[scope];
|
|
32343
|
+
if (scopeState === void 0) throw new Error(`REM trigger state missing scope ${scope}`);
|
|
32344
|
+
return scopeState;
|
|
32345
|
+
}
|
|
32346
|
+
function replaceScopeState(state, scope, scopeState) {
|
|
32347
|
+
return {
|
|
32348
|
+
version: 1,
|
|
32349
|
+
scopes: {
|
|
32350
|
+
...state.scopes,
|
|
32351
|
+
[scope]: scopeState
|
|
32352
|
+
}
|
|
32353
|
+
};
|
|
32354
|
+
}
|
|
32355
|
+
function asRecord(value) {
|
|
32356
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
32357
|
+
}
|
|
32358
|
+
function isValidInstant(value) {
|
|
32359
|
+
return value !== void 0 && !Number.isNaN(new Date(value).getTime());
|
|
32360
|
+
}
|
|
32361
|
+
function isLocalDate(value) {
|
|
32362
|
+
return value !== void 0 && /^\d{4}-\d{2}-\d{2}$/u.test(value);
|
|
32363
|
+
}
|
|
32364
|
+
function isNodeError(error) {
|
|
32365
|
+
return error instanceof Error && "code" in error;
|
|
32366
|
+
}
|
|
32367
|
+
function errorMessage(error) {
|
|
32368
|
+
return error instanceof Error ? error.message : String(error);
|
|
32369
|
+
}
|
|
32370
|
+
//#endregion
|
|
32371
|
+
export { readMemorySourceOrderOrOldest as $, atomicExtractionSkillReference as $t, recordTokenCounter as A, isTerminalLlmFailure$1 as At, randomUUID$1 as B, buildInsightMetadata as Bt, resolveHookAgentId as C, parseAgentIdFromSessionKey$1 as Ct, closeAtomicArrivalRetirementTargets as D, isTerminalLlmFailure as Dt, recordAtomicEntityIdentityJournal as E, createLlmClient as Et, normalizeMemoryRelationPredicate as F, stableHash as Ft, adapterAViewFromRecord as G, deriveFactKey as Gt, loadSqliteVecExtension as H, stringifyInsightMetadata as Ht, MemoryStore as I, stripHtmlTags as It, parseAdapterAChatVerdict as J, normalizeCategory as Jt, isAdapterAVerdictReply as K, AGGREGATION_OPERATIONS as Kt, StaleSupersedeTargetError as L, stripRoleLabelPrefix as Lt, canonicalizeProfileSectionName as M, CODING_SKIN_SESSION_QUERY as Mt, normalizeTopicToSectionName as N, clamp01 as Nt, journalAtomicArrivalRetirementRefusal as O, withProviderResponses as Ot, getSnoStationMemDataDir as P, clampInt as Pt, compareMemorySourceOrder as Q, ATOMIC_EXTRACTION_SKILL_HASH as Qt, TaskLifecycleStaleResolutionError as R, truncateGraphemes as Rt, resolveTaskLifecycleEffectiveTime as S, createScopePolicy as St, normalizeEntityName as T, ModelCallRefusedError as Tt, REM_BUILT_OPERATION_TYPES as U, normalizeIsoDateTimeString as Ut, readChunkVecTableState as V, parseInsightMetadata as Vt, parseRemOperationType as W, parseIsoDateTimeMs as Wt, renderAdapterAChatPrompt as X, resolveLlmRoute as Xt, prospectiveProfileView as Y, pickLlmRoutingConfig as Yt, renderAdapterAPrompt as Z, ATOMIC_EXTRACTION_SKILL as Zt, findUniqueActiveTaskByDescription as _, withMemoryOperation as _n, RESOURCES_BY_LOCALE as _t, enumerateRemCandidateScopes as a, calendarInstructionSchema as an, runWithMemoryAuditSync as at, admitTaskLifecycleAssertion as b, StorageError as bt, runRemProductionOrderedWave as c, attribute_dictionary_default as cn, parseSessionTimestamp as ct, MemoryRetriever as d, initSqliteRuntime as dn, unresolvedMemoryDate as dt, modelReplyJsonCandidates as en, appendAuditEntry as et, DEFAULT_RETRIEVAL_CONFIG as f, openSqliteDatabase as fn, boundSectionContent as ft, buildTaskLifecycleCandidateSet as g, memoryOperationSignal as gn, ALL_RESOURCES as gt, acceptsTaskLifecycleJudgment as h, memoryFileWrite as hn, normalizeAmbientLearningText as ht, createRemModelStageResponsePort as i, calculateCalendarTime as in, runWithMemoryAudit as it, canExtractorWrite as j, CODING_SKIN_LEDGER_MAX_CHARS as jt, readAtomicArrivalRetirementCandidateSet as k, classifyLlmFailure as kt, runWithCanonicalStoreWriteMutex as l, MEMORY_TELEMETRY_DELETE_REASONS as ln, serializeIntervalMetadata as lt, Embedder as m, checkMemoryOperation as mn, stripEnvelopeMetadata as mt, remNeedsHost as n, state_vocabulary_default as nn, currentMutationAttemptId as nt, readCandidates as o, isCalendarLabel as on, runWithMutationAttempt as ot, AccessTracker as p, openSqliteDatabaseReadonly as pn, buildIndexedText as pt, orderAdapterAPair as q, MEMORY_CATEGORIES as qt, buildRemReplaceCandidateQueue as r, relations as rn, getAuditPath as rt, runRemBatchJob as s, sessionZoneCarriedBy as sn, readJsonlLines as st, evaluateRemAutomaticTriggers as t, readModelReplyJson as tn, appendAuditEntryStrict as tt, selectRemUpdateRelationCandidates as u, isMemoryTelemetryEventType as un, resolveMemoryDate as ut, resolveTaskLifecycle as v, forwardObserveLedgerUntilIdle as vn, RetrievalError as vt, listAtomicMemoryEntityCandidates as w, LlmClientTerminalError as wt, buildTaskLifecycleCommandClaim as x, MemoryScopePolicy as xt, taskLifecycleCandidateSetVersion as y, SnoStationMemError as yt, validateMemoryTelemetryMetadata as z, redactSecrets as zt };
|