openclaw-hybrid-memory 2026.5.310 → 2026.6.10
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/api/plugin-runtime.ts +2 -0
- package/backends/facts-db/contradictions.ts +1 -1
- package/cli/cmd-extract-directives.ts +225 -11
- package/cli/cmd-extract-proposals.ts +5 -6
- package/cli/cmd-extract-reinforcement.ts +71 -0
- package/cli/cmd-feedback.ts +15 -9
- package/cli/commands/manage/register-reflection-pipeline.ts +247 -13
- package/cli/commands/manage/register-storage-maintenance.ts +224 -15
- package/cli/commands/manage/storage-stats-helpers.ts +13 -2
- package/cli/context.ts +9 -19
- package/cli/distill.ts +31 -1
- package/cli/register.ts +28 -38
- package/dist/api/plugin-runtime.js.map +1 -1
- package/dist/backends/agent-health-store.js.map +1 -1
- package/dist/backends/apitap-store.js.map +1 -1
- package/dist/backends/audit-store.js.map +1 -1
- package/dist/backends/base-sqlite-store.js.map +1 -1
- package/dist/backends/cost-tracker.js.map +1 -1
- package/dist/backends/credentials-db.js +2 -3
- package/dist/backends/credentials-db.js.map +1 -1
- package/dist/backends/crystallization-store.js.map +1 -1
- package/dist/backends/edict-store.js.map +1 -1
- package/dist/backends/event-bus.js.map +1 -1
- package/dist/backends/event-log.js.map +1 -1
- package/dist/backends/facts-db/cache-manager.js.map +1 -1
- package/dist/backends/facts-db/clusters.js.map +1 -1
- package/dist/backends/facts-db/contradictions.js +1 -1
- package/dist/backends/facts-db/contradictions.js.map +1 -1
- package/dist/backends/facts-db/crud.js.map +1 -1
- package/dist/backends/facts-db/db-connection.js.map +1 -1
- package/dist/backends/facts-db/entity-autolink.js.map +1 -1
- package/dist/backends/facts-db/entity-layer.js.map +1 -1
- package/dist/backends/facts-db/episodes.js.map +1 -1
- package/dist/backends/facts-db/fact-queries.js.map +1 -1
- package/dist/backends/facts-db/fact-read-queries.js.map +1 -1
- package/dist/backends/facts-db/facts-db-layer1.js.map +1 -1
- package/dist/backends/facts-db/facts-db-layer2.js.map +1 -1
- package/dist/backends/facts-db/facts-db-layer3.js.map +1 -1
- package/dist/backends/facts-db/fts-text.js.map +1 -1
- package/dist/backends/facts-db/generated-skills/policy.js.map +1 -1
- package/dist/backends/facts-db/generated-skills.js.map +1 -1
- package/dist/backends/facts-db/housekeeping.js.map +1 -1
- package/dist/backends/facts-db/links.js.map +1 -1
- package/dist/backends/facts-db/maintenance.js.map +1 -1
- package/dist/backends/facts-db/procedures/crud.js.map +1 -1
- package/dist/backends/facts-db/procedures/internal.js.map +1 -1
- package/dist/backends/facts-db/procedures/promotion.js.map +1 -1
- package/dist/backends/facts-db/procedures/search.js.map +1 -1
- package/dist/backends/facts-db/procedures/stats.js.map +1 -1
- package/dist/backends/facts-db/reinforcement.js.map +1 -1
- package/dist/backends/facts-db/row-mapper.js.map +1 -1
- package/dist/backends/facts-db/scan-cursors.js.map +1 -1
- package/dist/backends/facts-db/schema-bootstrap.js.map +1 -1
- package/dist/backends/facts-db/scope-sql.js.map +1 -1
- package/dist/backends/facts-db/search.js.map +1 -1
- package/dist/backends/facts-db/stats.js.map +1 -1
- package/dist/backends/facts-db/types.js.map +1 -1
- package/dist/backends/facts-db/variants.js.map +1 -1
- package/dist/backends/identity-reflection-store.js.map +1 -1
- package/dist/backends/issue-store.js.map +1 -1
- package/dist/backends/learnings-db.js.map +1 -1
- package/dist/backends/migrations/facts-migrations.js.map +1 -1
- package/dist/backends/migrations/procedures.js.map +1 -1
- package/dist/backends/narratives-db.js.map +1 -1
- package/dist/backends/persona-state-store.js.map +1 -1
- package/dist/backends/proposals-db.js.map +1 -1
- package/dist/backends/scope-filter-sql.js.map +1 -1
- package/dist/backends/sqlite-schema-meta.js.map +1 -1
- package/dist/backends/tool-proposal-store.js.map +1 -1
- package/dist/backends/vector-db/constants.js.map +1 -1
- package/dist/backends/vector-db/path-utils.js.map +1 -1
- package/dist/backends/vector-db/runtime-locks.js.map +1 -1
- package/dist/backends/vector-db/vector-db-class.js.map +1 -1
- package/dist/backends/wal.js.map +1 -1
- package/dist/backends/workflow-store.js.map +1 -1
- package/dist/benchmark/shadow-eval.js.map +1 -1
- package/dist/cli/active-tasks.js.map +1 -1
- package/dist/cli/backup.js.map +1 -1
- package/dist/cli/benchmark.js.map +1 -1
- package/dist/cli/cmd-backfill.js.map +1 -1
- package/dist/cli/cmd-config.js.map +1 -1
- package/dist/cli/cmd-credentials.js.map +1 -1
- package/dist/cli/cmd-demo.js.map +1 -1
- package/dist/cli/cmd-distill.js.map +1 -1
- package/dist/cli/cmd-doctor.js.map +1 -1
- package/dist/cli/cmd-examples.js.map +1 -1
- package/dist/cli/cmd-extract-daily.js.map +1 -1
- package/dist/cli/cmd-extract-directives.js +141 -10
- package/dist/cli/cmd-extract-directives.js.map +1 -1
- package/dist/cli/cmd-extract-procedures.js.map +1 -1
- package/dist/cli/cmd-extract-proposals.js +3 -2
- package/dist/cli/cmd-extract-proposals.js.map +1 -1
- package/dist/cli/cmd-extract-reinforcement.js +39 -0
- package/dist/cli/cmd-extract-reinforcement.js.map +1 -1
- package/dist/cli/cmd-extract-sessions.js.map +1 -1
- package/dist/cli/cmd-feedback.js +9 -4
- package/dist/cli/cmd-feedback.js.map +1 -1
- package/dist/cli/cmd-health.js.map +1 -1
- package/dist/cli/cmd-providers.js.map +1 -1
- package/dist/cli/cmd-selfcorrection.js.map +1 -1
- package/dist/cli/cmd-setup.js.map +1 -1
- package/dist/cli/cmd-status.js.map +1 -1
- package/dist/cli/cmd-store.js.map +1 -1
- package/dist/cli/cmd-user-friendly.js.map +1 -1
- package/dist/cli/cmd-verify.js.map +1 -1
- package/dist/cli/commands/manage/bindings.js.map +1 -1
- package/dist/cli/commands/manage/dream-cycle-followup.js.map +1 -1
- package/dist/cli/commands/manage/maintenance-heartbeat.js.map +1 -1
- package/dist/cli/commands/manage/register-agents-audit-runall.js.map +1 -1
- package/dist/cli/commands/manage/register-analyze-maintenance-logs.js.map +1 -1
- package/dist/cli/commands/manage/register-budget-proposals.js.map +1 -1
- package/dist/cli/commands/manage/register-config-cli.js.map +1 -1
- package/dist/cli/commands/manage/register-corrections-and-pipeline.js.map +1 -1
- package/dist/cli/commands/manage/register-corrections.js.map +1 -1
- package/dist/cli/commands/manage/register-council.js.map +1 -1
- package/dist/cli/commands/manage/register-credentials-scope.js.map +1 -1
- package/dist/cli/commands/manage/register-digest.js.map +1 -1
- package/dist/cli/commands/manage/register-lifecycle.js.map +1 -1
- package/dist/cli/commands/manage/register-procedure-lifecycle.js.map +1 -1
- package/dist/cli/commands/manage/register-reconcile-cron-ledgers.js.map +1 -1
- package/dist/cli/commands/manage/register-reflection-pipeline.js +144 -7
- package/dist/cli/commands/manage/register-reflection-pipeline.js.map +1 -1
- package/dist/cli/commands/manage/register-self-correction-feedback.js.map +1 -1
- package/dist/cli/commands/manage/register-storage-and-stats.js.map +1 -1
- package/dist/cli/commands/manage/register-storage-entities-decay.js.map +1 -1
- package/dist/cli/commands/manage/register-storage-graph-audit.js.map +1 -1
- package/dist/cli/commands/manage/register-storage-maintenance.js +152 -9
- package/dist/cli/commands/manage/register-storage-maintenance.js.map +1 -1
- package/dist/cli/commands/manage/register-validate-cron-exit.js.map +1 -1
- package/dist/cli/commands/manage/storage-stats-helpers.js +10 -3
- package/dist/cli/commands/manage/storage-stats-helpers.js.map +1 -1
- package/dist/cli/commands/register-manage-commands.js.map +1 -1
- package/dist/cli/config-feature-summaries.js.map +1 -1
- package/dist/cli/config-output-sink.js.map +1 -1
- package/dist/cli/distill-session-jsonl.js.map +1 -1
- package/dist/cli/distill.js +10 -1
- package/dist/cli/distill.js.map +1 -1
- package/dist/cli/global-verbose.js.map +1 -1
- package/dist/cli/goals.js.map +1 -1
- package/dist/cli/hybrid-mem-commander-utils.js.map +1 -1
- package/dist/cli/install/config-merge.js.map +1 -1
- package/dist/cli/install/cron-jobs.js.map +1 -1
- package/dist/cli/install/embedding-detect.js.map +1 -1
- package/dist/cli/install/run-install.js.map +1 -1
- package/dist/cli/install/workspace.js.map +1 -1
- package/dist/cli/proposals.js.map +1 -1
- package/dist/cli/register.js.map +1 -1
- package/dist/cli/shared.js.map +1 -1
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/task-queue-status.js.map +1 -1
- package/dist/cli/verified.js.map +1 -1
- package/dist/cli/verify/fact-count.js.map +1 -1
- package/dist/cli/verify/openclaw-config.js.map +1 -1
- package/dist/cli/verify/plugin-config-credentials.js.map +1 -1
- package/dist/cli/verify/sections/config-cron.js.map +1 -1
- package/dist/cli/verify/sections/embeddings.js.map +1 -1
- package/dist/cli/verify/sections/infrastructure.js.map +1 -1
- package/dist/cli/verify/sections/llm-models.js.map +1 -1
- package/dist/cli/verify/sections/reconcile.js.map +1 -1
- package/dist/cli/verify/verify-run-state.js.map +1 -1
- package/dist/cli/verify-llm-azure-auth.js.map +1 -1
- package/dist/cli/verify.js.map +1 -1
- package/dist/config/hybrid-schema.js.map +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/maintenance-fallback-policy.js.map +1 -1
- package/dist/config/parsers/capture.js.map +1 -1
- package/dist/config/parsers/core.js.map +1 -1
- package/dist/config/parsers/features.js.map +1 -1
- package/dist/config/parsers/index.js.map +1 -1
- package/dist/config/parsers/maintenance.js.map +1 -1
- package/dist/config/parsers/retrieval.js.map +1 -1
- package/dist/config/parsers/sensors.js.map +1 -1
- package/dist/config/skill-sections.js.map +1 -1
- package/dist/config/skill-size-limits.js.map +1 -1
- package/dist/config/types/agents.js.map +1 -1
- package/dist/config/types/bootstrap.js.map +1 -1
- package/dist/config/types/core.js.map +1 -1
- package/dist/config/types/index.js.map +1 -1
- package/dist/config/utils.js.map +1 -1
- package/dist/index-help.js.map +1 -1
- package/dist/index-testing-exports.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/hook-resolution-api.js.map +1 -1
- package/dist/lifecycle/hooks.js +0 -1
- package/dist/lifecycle/hooks.js.map +1 -1
- package/dist/lifecycle/resolve-agent-id.js.map +1 -1
- package/dist/lifecycle/session-state.js.map +1 -1
- package/dist/lifecycle/stage-active-task.js.map +1 -1
- package/dist/lifecycle/stage-auth-failure.js.map +1 -1
- package/dist/lifecycle/stage-capture/run-capture.js.map +1 -1
- package/dist/lifecycle/stage-capture.js.map +1 -1
- package/dist/lifecycle/stage-cleanup.js.map +1 -1
- package/dist/lifecycle/stage-credential-hint.js.map +1 -1
- package/dist/lifecycle/stage-frustration.js.map +1 -1
- package/dist/lifecycle/stage-goal-stewardship.js.map +1 -1
- package/dist/lifecycle/stage-goal-subagent.js.map +1 -1
- package/dist/lifecycle/stage-injection.js +1 -1
- package/dist/lifecycle/stage-injection.js.map +1 -1
- package/dist/lifecycle/stage-recall/run-recall.js.map +1 -1
- package/dist/lifecycle/stage-recall.js.map +1 -1
- package/dist/lifecycle/stage-setup.js.map +1 -1
- package/dist/routes/dashboard/collectors.js.map +1 -1
- package/dist/routes/dashboard/html.js.map +1 -1
- package/dist/routes/dashboard/server.js.map +1 -1
- package/dist/routes/dashboard-graph.js.map +1 -1
- package/dist/routes/graphql-resolvers.js.map +1 -1
- package/dist/routes/graphql-server.js.map +1 -1
- package/dist/services/active-task-checkpoint.js.map +1 -1
- package/dist/services/active-task-injection.js.map +1 -1
- package/dist/services/active-task.js.map +1 -1
- package/dist/services/adaptive-catch-up-pacing.js +25 -0
- package/dist/services/adaptive-catch-up-pacing.js.map +1 -0
- package/dist/services/adaptive-maintenance-llm.js.map +1 -1
- package/dist/services/adaptive-model-limits.js.map +1 -1
- package/dist/services/ambient-retrieval.js.map +1 -1
- package/dist/services/apitap-service.js.map +1 -1
- package/dist/services/audit-health-exit-info.js.map +1 -1
- package/dist/services/audit-health-json.js.map +1 -1
- package/dist/services/auth-failure-detect.js.map +1 -1
- package/dist/services/auto-capture.js.map +1 -1
- package/dist/services/auto-classifier.js.map +1 -1
- package/dist/services/auto-skills-audit.js.map +1 -1
- package/dist/services/bootstrap-optional.js.map +1 -1
- package/dist/services/bootstrap-priority.js.map +1 -1
- package/dist/services/bootstrap.js.map +1 -1
- package/dist/services/capture-provenance.js.map +1 -1
- package/dist/services/capture-utils.js.map +1 -1
- package/dist/services/chat.js +22 -3
- package/dist/services/chat.js.map +1 -1
- package/dist/services/classification-scope.js.map +1 -1
- package/dist/services/classification.js.map +1 -1
- package/dist/services/cli-sql-dump.js.map +1 -1
- package/dist/services/consolidation.js.map +1 -1
- package/dist/services/context-audit.js +1 -1
- package/dist/services/context-audit.js.map +1 -1
- package/dist/services/context-budget.js.map +1 -1
- package/dist/services/context-engine.js.map +1 -1
- package/dist/services/contextual-variants.js.map +1 -1
- package/dist/services/continuous-verifier.js.map +1 -1
- package/dist/services/contradiction-adjudicator.js.map +1 -1
- package/dist/services/cost-context.js.map +1 -1
- package/dist/services/cost-feature-labels.js.map +1 -1
- package/dist/services/credential-migration.js.map +1 -1
- package/dist/services/credential-scanner.js.map +1 -1
- package/dist/services/credential-validation.js.map +1 -1
- package/dist/services/cron-exit-validator.js.map +1 -1
- package/dist/services/cron-guard.js.map +1 -1
- package/dist/services/cron-job-bash-harness.js +52 -5
- package/dist/services/cron-job-bash-harness.js.map +1 -1
- package/dist/services/cron-maintenance-reconciler.js +1 -3
- package/dist/services/cron-maintenance-reconciler.js.map +1 -1
- package/dist/services/cross-agent-learning.js.map +1 -1
- package/dist/services/crystallization-proposer.js.map +1 -1
- package/dist/services/dedupe-policy.js.map +1 -1
- package/dist/services/deprecated-cron-commands.js.map +1 -1
- package/dist/services/directive-extract.js.map +1 -1
- package/dist/services/document-chunker.js.map +1 -1
- package/dist/services/document-grader.js.map +1 -1
- package/dist/services/dream-cycle.js.map +1 -1
- package/dist/services/embedding-migration.js.map +1 -1
- package/dist/services/embedding-registry.js.map +1 -1
- package/dist/services/embeddings/chain-provider.js.map +1 -1
- package/dist/services/embeddings/factory.js.map +1 -1
- package/dist/services/embeddings/fallback-provider.js.map +1 -1
- package/dist/services/embeddings/ollama-provider.js.map +1 -1
- package/dist/services/embeddings/onnx-provider.js.map +1 -1
- package/dist/services/embeddings/openai-provider.js.map +1 -1
- package/dist/services/embeddings/shared.js +3 -3
- package/dist/services/embeddings/shared.js.map +1 -1
- package/dist/services/embeddings/types.js.map +1 -1
- package/dist/services/entity-enrichment-adaptive.js +128 -0
- package/dist/services/entity-enrichment-adaptive.js.map +1 -0
- package/dist/services/entity-enrichment-cli.js +389 -42
- package/dist/services/entity-enrichment-cli.js.map +1 -1
- package/dist/services/entity-enrichment.js +31 -5
- package/dist/services/entity-enrichment.js.map +1 -1
- package/dist/services/error-reporter/noisy-errors.js.map +1 -1
- package/dist/services/error-reporter/sanitize.js.map +1 -1
- package/dist/services/error-reporter.js.map +1 -1
- package/dist/services/event-hub-repair.js.map +1 -1
- package/dist/services/export-memory.js.map +1 -1
- package/dist/services/fact-extraction.js.map +1 -1
- package/dist/services/feedback-effectiveness.js.map +1 -1
- package/dist/services/find-duplicates.js.map +1 -1
- package/dist/services/frustration-detector.js.map +1 -1
- package/dist/services/fts-search.js.map +1 -1
- package/dist/services/gap-detector.js.map +1 -1
- package/dist/services/generated-skill-lifecycle.js.map +1 -1
- package/dist/services/generated-skill-validation.js.map +1 -1
- package/dist/services/goal-active-task-mirror.js.map +1 -1
- package/dist/services/goal-circuit-breaker.js.map +1 -1
- package/dist/services/goal-health.js.map +1 -1
- package/dist/services/goal-registry.js.map +1 -1
- package/dist/services/goal-stewardship-heartbeat.js.map +1 -1
- package/dist/services/goal-stewardship-llm-triage.js.map +1 -1
- package/dist/services/goal-stewardship-verify-cron.js.map +1 -1
- package/dist/services/goal-stewardship.js.map +1 -1
- package/dist/services/goal-subagent.js.map +1 -1
- package/dist/services/graph-retrieval.js.map +1 -1
- package/dist/services/humanizer-score.js.map +1 -1
- package/dist/services/hybrid-mem-cron-default-job-steps.js.map +1 -1
- package/dist/services/hyde-helper.js.map +1 -1
- package/dist/services/identity-reflection.js.map +1 -1
- package/dist/services/implicit-feedback-extract.js.map +1 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/ingest-utils.js.map +1 -1
- package/dist/services/intent-template.js.map +1 -1
- package/dist/services/json-array-parser.js.map +1 -1
- package/dist/services/knowledge-gaps.js.map +1 -1
- package/dist/services/language-keywords-build.js.map +1 -1
- package/dist/services/lifecycle/github-adapter.js.map +1 -1
- package/dist/services/llm-rate-limit-headers.js +1 -2
- package/dist/services/llm-rate-limit-headers.js.map +1 -1
- package/dist/services/maintenance-auto-fix.js.map +1 -1
- package/dist/services/maintenance-log-analyzer.js +7 -1
- package/dist/services/maintenance-log-analyzer.js.map +1 -1
- package/dist/services/maintenance-timestamp.js.map +1 -1
- package/dist/services/memory-diagnostics.js.map +1 -1
- package/dist/services/memory-index.js.map +1 -1
- package/dist/services/merge-results.js.map +1 -1
- package/dist/services/model-capabilities.js.map +1 -1
- package/dist/services/model-pricing.js.map +1 -1
- package/dist/services/narrative-recall.js.map +1 -1
- package/dist/services/openclaw-session-artifact.js.map +1 -1
- package/dist/services/passive-observer.js.map +1 -1
- package/dist/services/pattern-detector-hash.js.map +1 -1
- package/dist/services/pattern-detector.js.map +1 -1
- package/dist/services/pending-autopilot/foundation.js.map +1 -1
- package/dist/services/pending-autopilot/redaction.js.map +1 -1
- package/dist/services/pending-autopilot/store.js.map +1 -1
- package/dist/services/pending-autopilot/types.js.map +1 -1
- package/dist/services/pending-digest-autopilot-cron.js.map +1 -1
- package/dist/services/pending-digest-autopilot.js.map +1 -1
- package/dist/services/pending-review-digest.js.map +1 -1
- package/dist/services/persona-proposal-triage.js.map +1 -1
- package/dist/services/persona-state-promotion.js.map +1 -1
- package/dist/services/post-compaction-recall.js.map +1 -1
- package/dist/services/pre-consolidation-flush.js.map +1 -1
- package/dist/services/pre-finalization-guard.js.map +1 -1
- package/dist/services/procedure-cluster.js.map +1 -1
- package/dist/services/procedure-extractor.js.map +1 -1
- package/dist/services/procedure-promotion/duplicate-skill-cache.js.map +1 -1
- package/dist/services/procedure-promotion-policy.js.map +1 -1
- package/dist/services/procedure-selection-metrics.js.map +1 -1
- package/dist/services/procedure-skill-eval.js.map +1 -1
- package/dist/services/procedure-skill-generator.js.map +1 -1
- package/dist/services/procedure-skill-recipe.js.map +1 -1
- package/dist/services/procedure-skill-shrink.js.map +1 -1
- package/dist/services/procedure-skill-workflow.js.map +1 -1
- package/dist/services/provenance.js.map +1 -1
- package/dist/services/public-export-bundle.js.map +1 -1
- package/dist/services/python-bridge.js.map +1 -1
- package/dist/services/query-expander.js.map +1 -1
- package/dist/services/query-validator.js.map +1 -1
- package/dist/services/recall-pipeline.js.map +1 -1
- package/dist/services/recall-timing.js.map +1 -1
- package/dist/services/recent-http-attempts.js.map +1 -1
- package/dist/services/reflection/shared.js.map +1 -1
- package/dist/services/reflection.js.map +1 -1
- package/dist/services/reinforcement-extract.js.map +1 -1
- package/dist/services/reranker.js.map +1 -1
- package/dist/services/responses-adapter.js.map +1 -1
- package/dist/services/retrieval-aliases.js.map +1 -1
- package/dist/services/retrieval-mode-policy.js.map +1 -1
- package/dist/services/retrieval-orchestrator/packing.js.map +1 -1
- package/dist/services/retrieval-orchestrator.d.ts +2 -3
- package/dist/services/retrieval-orchestrator.js.map +1 -1
- package/dist/services/rrf-fusion.js.map +1 -1
- package/dist/services/self-correction-extract.js.map +1 -1
- package/dist/services/session-observability.js.map +1 -1
- package/dist/services/session-pre-filter.js.map +1 -1
- package/dist/services/shortest-path.js.map +1 -1
- package/dist/services/skill-allowed-tools.js.map +1 -1
- package/dist/services/skill-creator-validator.js.map +1 -1
- package/dist/services/skill-crystallizer-helpers.js.map +1 -1
- package/dist/services/skill-crystallizer.js.map +1 -1
- package/dist/services/skill-description-builder.js.map +1 -1
- package/dist/services/skill-eval-synthesizer.js.map +1 -1
- package/dist/services/skill-examples-builder.js.map +1 -1
- package/dist/services/skill-frontmatter.js.map +1 -1
- package/dist/services/skill-name-validator.js.map +1 -1
- package/dist/services/skill-prompt-injection.js.map +1 -1
- package/dist/services/skill-reference-sidecar.js.map +1 -1
- package/dist/services/skill-script-bundler.js.map +1 -1
- package/dist/services/skill-validator.js.map +1 -1
- package/dist/services/startup-memory-attribution.js.map +1 -1
- package/dist/services/task-hygiene.js.map +1 -1
- package/dist/services/task-ledger/canonical.js.map +1 -1
- package/dist/services/task-ledger-facts.js.map +1 -1
- package/dist/services/task-queue-leases.js.map +1 -1
- package/dist/services/task-queue-watchdog.js.map +1 -1
- package/dist/services/tool-effectiveness.js.map +1 -1
- package/dist/services/tool-proposer.js.map +1 -1
- package/dist/services/tools-md-section.js.map +1 -1
- package/dist/services/topic-clusters.js.map +1 -1
- package/dist/services/trajectory-tracker.js.map +1 -1
- package/dist/services/vector-backend-observability.js.map +1 -1
- package/dist/services/vector-lifecycle-audit.js.map +1 -1
- package/dist/services/vector-maintenance.js.map +1 -1
- package/dist/services/vector-search.js.map +1 -1
- package/dist/services/verification-store.js.map +1 -1
- package/dist/services/verified-fact-triage.js.map +1 -1
- package/dist/services/wal-helpers.js.map +1 -1
- package/dist/services/workflow-tracker.js.map +1 -1
- package/dist/setup/bootstrap-databases.js.map +1 -1
- package/dist/setup/cli-context/cli-services.js.map +1 -1
- package/dist/setup/cli-context/help-text.js.map +1 -1
- package/dist/setup/cli-context/metadata.js.map +1 -1
- package/dist/setup/cli-context/register-cli-with-help.js.map +1 -1
- package/dist/setup/cli-context/register-full.js.map +1 -1
- package/dist/setup/cli-context/register-help.js.map +1 -1
- package/dist/setup/cost-instrumentation.js.map +1 -1
- package/dist/setup/hybrid-memory-generation-state.js.map +1 -1
- package/dist/setup/hybrid-memory-reload-coordinator.js +13 -13
- package/dist/setup/hybrid-memory-reload-coordinator.js.map +1 -1
- package/dist/setup/plugin-service.js.map +1 -1
- package/dist/setup/provider-router.js.map +1 -1
- package/dist/setup/register-context-engine.js.map +1 -1
- package/dist/setup/register-hooks.js.map +1 -1
- package/dist/setup/register-plugin.js +25 -21
- package/dist/setup/register-plugin.js.map +1 -1
- package/dist/setup/register-tools.js.map +1 -1
- package/dist/setup/reregister-policy.js +2 -2
- package/dist/setup/reregister-policy.js.map +1 -1
- package/dist/setup/tool-installers.js.map +1 -1
- package/dist/setup/workspace-bootstrap.js.map +1 -1
- package/dist/src/worker/narratives.js.map +1 -1
- package/dist/tools/apitap-tools.js.map +1 -1
- package/dist/tools/credential-tools.js.map +1 -1
- package/dist/tools/crystallization-tools.js.map +1 -1
- package/dist/tools/dashboard-routes.js.map +1 -1
- package/dist/tools/document-tools.js.map +1 -1
- package/dist/tools/goal-tools.js.map +1 -1
- package/dist/tools/graph-tools.js.map +1 -1
- package/dist/tools/issue-tools.js.map +1 -1
- package/dist/tools/memory/build-runtime.js.map +1 -1
- package/dist/tools/memory/helpers.js.map +1 -1
- package/dist/tools/memory/register-checkpoint-tools.js.map +1 -1
- package/dist/tools/memory/register-directory-tools.js.map +1 -1
- package/dist/tools/memory/register-edict-tools.js.map +1 -1
- package/dist/tools/memory/register-episode-tools.js.map +1 -1
- package/dist/tools/memory/register-recall-tools.js.map +1 -1
- package/dist/tools/memory/register-store-tools.js.map +1 -1
- package/dist/tools/memory-tools.js.map +1 -1
- package/dist/tools/persona-tools.js.map +1 -1
- package/dist/tools/provenance-tools.js.map +1 -1
- package/dist/tools/public-api-routes.js.map +1 -1
- package/dist/tools/safe-register-http-route.js.map +1 -1
- package/dist/tools/self-extension-tools.js.map +1 -1
- package/dist/tools/task-hygiene-tools.js.map +1 -1
- package/dist/tools/utility-tools.js.map +1 -1
- package/dist/tools/verification-tools.js.map +1 -1
- package/dist/tools/workflow-tools.js.map +1 -1
- package/dist/types/issue-types.js.map +1 -1
- package/dist/types/learnings-types.js.map +1 -1
- package/dist/types/memory.js.map +1 -1
- package/dist/utils/apim-gateway-fetch.js.map +1 -1
- package/dist/utils/atomic-write.js.map +1 -1
- package/dist/utils/auth-failover.js.map +1 -1
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/compaction-model-watchdog.js.map +1 -1
- package/dist/utils/consolidation-controls.js.map +1 -1
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/date-detector.js.map +1 -1
- package/dist/utils/dates.js.map +1 -1
- package/dist/utils/decay.js.map +1 -1
- package/dist/utils/duration.js.map +1 -1
- package/dist/utils/embed-call.js.map +1 -1
- package/dist/utils/entity-lookup-resolve.js.map +1 -1
- package/dist/utils/entity-mention-quality.js.map +1 -1
- package/dist/utils/entity-stopwords.js.map +1 -1
- package/dist/utils/env-manager.js.map +1 -1
- package/dist/utils/error-tracking.js.map +1 -1
- package/dist/utils/event-loop-yield.js.map +1 -1
- package/dist/utils/extract-last-user-message.js.map +1 -1
- package/dist/utils/extraction-from-template.js.map +1 -1
- package/dist/utils/fact-embeddings.js.map +1 -1
- package/dist/utils/file-snapshot.js.map +1 -1
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/gh-repo-arg.js.map +1 -1
- package/dist/utils/hybrid-mem-json-cli.js.map +1 -1
- package/dist/utils/language-keywords.js.map +1 -1
- package/dist/utils/lifecycle-generation.js.map +1 -1
- package/dist/utils/llm-json-array.js.map +1 -1
- package/dist/utils/llm-selection.js.map +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/model-provider-family.js.map +1 -1
- package/dist/utils/model-tier.js.map +1 -1
- package/dist/utils/openclaw-agent-defaults.js.map +1 -1
- package/dist/utils/path.js.map +1 -1
- package/dist/utils/plugin-root.js.map +1 -1
- package/dist/utils/plugin-update-check.js.map +1 -1
- package/dist/utils/procedure-risk.js.map +1 -1
- package/dist/utils/progress-indicators.js.map +1 -1
- package/dist/utils/prompt-loader.js.map +1 -1
- package/dist/utils/provenance.js.map +1 -1
- package/dist/utils/provider-detection.js.map +1 -1
- package/dist/utils/registration-superseded.js.map +1 -1
- package/dist/utils/salience.js.map +1 -1
- package/dist/utils/sanitize-messages.js.map +1 -1
- package/dist/utils/scope-filter.js.map +1 -1
- package/dist/utils/skill-discovery.js.map +1 -1
- package/dist/utils/sqlite-file-perms.js.map +1 -1
- package/dist/utils/sqlite-outcome-compat.js.map +1 -1
- package/dist/utils/sqlite-transaction.js.map +1 -1
- package/dist/utils/stable-stringify.js.map +1 -1
- package/dist/utils/subagent-ended-utils.js.map +1 -1
- package/dist/utils/tags.js.map +1 -1
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/timeout.js.map +1 -1
- package/dist/utils/typebox.js.map +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/wal-replay.js.map +1 -1
- package/dist/versionInfo.js.map +1 -1
- package/index.ts +2 -2
- package/lifecycle/hooks.ts +0 -1
- package/npm-shrinkwrap.json +487 -186
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
- package/services/adaptive-catch-up-pacing.ts +28 -0
- package/services/chat.ts +34 -1
- package/services/cron-job-bash-harness.ts +52 -5
- package/services/embeddings/shared.ts +5 -2
- package/services/entity-enrichment-adaptive.ts +245 -0
- package/services/entity-enrichment-cli.ts +553 -47
- package/services/entity-enrichment.ts +43 -2
- package/services/llm-rate-limit-headers.ts +1 -4
- package/services/maintenance-log-analyzer.ts +13 -9
- package/services/reinforcement-extract.ts +19 -0
- package/setup/hybrid-memory-reload-coordinator.ts +26 -0
- package/setup/register-plugin.ts +62 -32
- package/setup/reregister-policy.ts +10 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-edict-tools.js","names":[],"sources":["../../../tools/memory/register-edict-tools.ts"],"sourcesContent":["/**\n * Memory Tool Registrations\n *\n * Tool definitions for memory recall, storage, promotion, and deletion.\n * Extracted from index.ts for better modularity.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport { capturePluginError } from \"../../services/error-reporter.js\";\n\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerEdictTools(runtime: MemoryToolRuntime): void {\n const { edictStore, api, isEdictWriteToolEnabled } = runtime;\n // Edict tools — verified ground-truth facts with forced prompt injection (#791)\n // ---------------------------------------------------------------------------\n\n /** memory_add_edict — create a verified ground-truth fact (human-only; agents propose via GitHub). */\n {\n const _addEdictLabel = \"Add Edict\";\n const _addEdictParams = Type.Object({\n text: Type.String({ description: \"The verified statement of fact to store\" }),\n source: Type.Optional(\n Type.String({\n description: \"Who or what verified this edict (e.g. 'human:markus', 'ops:runbook')\",\n }),\n ),\n tags: Type.Optional(\n Type.Array(Type.String(), { description: \"Labels for filtering (e.g. ['operations', 'ssh'])\" }),\n ),\n ttl: Type.Optional(\n Type.String({\n description: \"TTL mode: 'never' (permanent), 'event' (use expiresAt date), or seconds as number\",\n }),\n ),\n expiresAt: Type.Optional(\n Type.String({\n description: \"ISO 8601 date when this edict expires (for ttl='event')\",\n }),\n ),\n });\n const _addEdictDesc =\n \"Add a verified ground-truth fact (edict) to memory. Edicts are always injected verbatim into system prompts — the agent does NOT reason about them.\\n\\n\" +\n 'NOTE: Agents should NOT create edicts directly. To propose an edict, add a GitHub comment: [EDICT CANDIDATE] text=\"...\" reason=\"...\" tags=[...]. ' +\n \"Only Markus (the human) should use this tool directly.\";\n const _execAddEdict = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n if (!isEdictWriteToolEnabled()) {\n return {\n content: [\n {\n type: \"text\",\n text: 'memory_add_edict is disabled. Propose edicts via GitHub comment: [EDICT CANDIDATE] text=\"...\" reason=\"...\" tags=[...].',\n },\n ],\n details: { error: \"forbidden\", reason: \"edict_write_disabled\" },\n };\n }\n\n const { text, source, tags, ttl, expiresAt } = params as {\n text: string;\n source?: string;\n tags?: string[];\n ttl?: string;\n expiresAt?: string;\n };\n\n if (!text || text.trim().length === 0) {\n return {\n content: [{ type: \"text\", text: \"Provide the 'text' parameter: the verified statement to store.\" }],\n details: { error: \"missing_text\" },\n };\n }\n\n let ttlValue: \"never\" | \"event\" | number = \"never\";\n if (ttl !== undefined) {\n if (ttl === \"never\") ttlValue = \"never\";\n else if (ttl === \"event\") ttlValue = \"event\";\n else if (!Number.isNaN(Number(ttl))) ttlValue = Number(ttl);\n else {\n return {\n content: [\n {\n type: \"text\",\n text: \"Invalid 'ttl' parameter: must be a positive integer number of seconds, 'never', or 'event'.\",\n },\n ],\n details: { error: \"invalid_ttl\" },\n };\n }\n }\n if (\n typeof ttlValue === \"number\" &&\n (!Number.isFinite(ttlValue) || ttlValue <= 0 || !Number.isInteger(ttlValue))\n ) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Invalid 'ttl' parameter: must be a positive integer number of seconds, 'never', or 'event'.\",\n },\n ],\n details: { error: \"invalid_ttl\" },\n };\n }\n if (ttlValue === \"event\" && !expiresAt?.trim()) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Provide the 'expiresAt' parameter (ISO 8601) when ttl='event'.\",\n },\n ],\n details: { error: \"missing_expiresAt\" },\n };\n }\n\n const edict = edictStore.add({\n text: text.trim(),\n source,\n tags,\n ttl: ttlValue,\n expiresAt,\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `Edict added: \"${edict.text.slice(0, 80)}${edict.text.length > 80 ? \"...\" : \"\"}\" (id: ${edict.id})`,\n },\n ],\n details: { edict },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"add_edict\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_add_edict\",\n label: _addEdictLabel,\n description: _addEdictDesc,\n parameters: _addEdictParams,\n execute: _execAddEdict,\n },\n { name: \"memory_add_edict\" },\n );\n }\n\n /** memory_list_edicts — list edicts, optionally filtered by tags. */\n {\n const _listEdictsLabel = \"List Edicts\";\n const _listEdictsParams = Type.Object({\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Filter to edicts with any of these tags\" })),\n limit: Type.Optional(Type.Number({ description: \"Max results (default 100)\" })),\n });\n const _listEdictsDesc = \"List all non-expired edicts, optionally filtered by tags.\";\n const _execListEdicts = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const { tags, limit } = params as { tags?: string[]; limit?: number };\n const edicts = edictStore.list({ tags, limit });\n if (edicts.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No edicts found.\" }],\n details: { count: 0, edicts: [] },\n };\n }\n const lines = edicts.map((e) => {\n const tagStr = e.tags.length > 0 ? `[${e.tags[0]}] ` : \"\";\n return `- ${tagStr}${e.text}${e.expiresAt ? ` (expires: ${e.expiresAt})` : \"\"} (id: ${e.id})`;\n });\n return {\n content: [\n {\n type: \"text\",\n text: `Edicts (${edicts.length}):\\n${lines.join(\"\\n\")}`,\n },\n ],\n details: { count: edicts.length, edicts },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"list_edicts\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_list_edicts\",\n label: _listEdictsLabel,\n description: _listEdictsDesc,\n parameters: _listEdictsParams,\n execute: _execListEdicts,\n },\n { name: \"memory_list_edicts\" },\n );\n }\n\n /** memory_get_edicts — get edicts formatted for system prompt injection. */\n {\n const _getEdictsLabel = \"Get Edicts for Prompt\";\n const _getEdictsParams = Type.Object({\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Filter to edicts with any of these tags\" })),\n format: Type.Optional(\n Type.String({ description: \"Output format: 'prompt' (Markdown block, default) or 'full' (structured)\" }),\n ),\n limit: Type.Optional(Type.Number({ description: \"Max results (default 100)\" })),\n });\n const _getEdictsDesc =\n \"Get all non-expired edicts as a pre-formatted Markdown block for system prompt injection. \" +\n \"This is called automatically during context compaction — prefer using this tool when you need edicts explicitly.\";\n const _execGetEdicts = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const { tags, format, limit } = params as { tags?: string[]; format?: string; limit?: number };\n const result = edictStore.getEdicts({ tags, format: format as \"prompt\" | \"full\", limit });\n if (result.edicts.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No edicts found.\" }],\n details: { count: 0, edicts: [], renderForPrompt: \"\" },\n };\n }\n return {\n content: [{ type: \"text\", text: result.renderForPrompt || JSON.stringify(result.edicts, null, 2) }],\n details: { count: result.edicts.length, edicts: result.edicts, renderForPrompt: result.renderForPrompt },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"get_edicts\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_get_edicts\",\n label: _getEdictsLabel,\n description: _getEdictsDesc,\n parameters: _getEdictsParams,\n execute: _execGetEdicts,\n },\n { name: \"memory_get_edicts\" },\n );\n }\n\n /** memory_update_edict — update an existing edict's text, tags, source, or expiry. */\n {\n const _updateEdictLabel = \"Update Edict\";\n const _updateEdictParams = Type.Object({\n id: Type.String({ description: \"The edict id to update\" }),\n text: Type.Optional(Type.String({ description: \"New verified statement text\" })),\n source: Type.Optional(Type.String({ description: \"New or updated source\" })),\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Replacement tags array\" })),\n ttl: Type.Optional(Type.String({ description: \"New TTL mode: 'never', 'event', or seconds as number\" })),\n expiresAt: Type.Optional(Type.String({ description: \"ISO 8601 expiry date for ttl='event'\" })),\n });\n const _updateEdictDesc = \"Update the text, tags, source, or expiry of an existing edict.\";\n const _execUpdateEdict = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n if (!isEdictWriteToolEnabled()) {\n return {\n content: [\n {\n type: \"text\",\n text: 'memory_update_edict is disabled. Propose edicts via GitHub comment: [EDICT CANDIDATE] text=\"...\" reason=\"...\" tags=[...].',\n },\n ],\n details: { error: \"forbidden\", reason: \"edict_write_disabled\" },\n };\n }\n\n const { id, text, source, tags, ttl, expiresAt } = params as {\n id: string;\n text?: string;\n source?: string;\n tags?: string[];\n ttl?: string;\n expiresAt?: string;\n };\n\n let ttlValue: \"never\" | \"event\" | number | undefined;\n if (ttl !== undefined) {\n if (ttl === \"never\") ttlValue = \"never\";\n else if (ttl === \"event\") ttlValue = \"event\";\n else if (!Number.isNaN(Number(ttl))) ttlValue = Number(ttl);\n else {\n return {\n content: [\n {\n type: \"text\",\n text: \"Invalid 'ttl' parameter: must be a positive integer number of seconds, 'never', or 'event'.\",\n },\n ],\n details: { error: \"invalid_ttl\" },\n };\n }\n }\n if (\n typeof ttlValue === \"number\" &&\n (!Number.isFinite(ttlValue) || ttlValue <= 0 || !Number.isInteger(ttlValue))\n ) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Invalid 'ttl' parameter: must be a positive integer number of seconds, 'never', or 'event'.\",\n },\n ],\n details: { error: \"invalid_ttl\" },\n };\n }\n if (ttlValue === \"event\" && !expiresAt?.trim()) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Provide the 'expiresAt' parameter (ISO 8601) when ttl='event'.\",\n },\n ],\n details: { error: \"missing_expiresAt\" },\n };\n }\n\n const updated = edictStore.update({\n id,\n text,\n source,\n tags,\n ttl: ttlValue,\n expiresAt,\n });\n\n if (!updated) {\n return {\n content: [{ type: \"text\", text: `Edict not found: ${id}` }],\n details: { error: \"not_found\" },\n };\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `Edict updated: \"${updated.text.slice(0, 80)}${updated.text.length > 80 ? \"...\" : \"\"}\" (id: ${updated.id})`,\n },\n ],\n details: { edict: updated },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"update_edict\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_update_edict\",\n label: _updateEdictLabel,\n description: _updateEdictDesc,\n parameters: _updateEdictParams,\n execute: _execUpdateEdict,\n },\n { name: \"memory_update_edict\" },\n );\n }\n\n /** memory_remove_edict — delete an edict by id. */\n {\n const _removeEdictLabel = \"Remove Edict\";\n const _removeEdictParams = Type.Object({\n id: Type.String({ description: \"The edict id to delete\" }),\n });\n const _removeEdictDesc = \"Delete an edict from memory by its id.\";\n const _execRemoveEdict = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n if (!isEdictWriteToolEnabled()) {\n return {\n content: [\n {\n type: \"text\",\n text: 'memory_remove_edict is disabled. Propose edicts via GitHub comment: [EDICT CANDIDATE] text=\"...\" reason=\"...\" tags=[...].',\n },\n ],\n details: { error: \"forbidden\", reason: \"edict_write_disabled\" },\n };\n }\n\n const { id } = params as { id: string };\n const removed = edictStore.remove(id);\n return {\n content: [\n {\n type: \"text\",\n text: removed ? `Edict removed: ${id}` : `Edict not found: ${id}`,\n },\n ],\n details: { removed },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"remove_edict\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_remove_edict\",\n label: _removeEdictLabel,\n description: _removeEdictDesc,\n parameters: _removeEdictParams,\n execute: _execRemoveEdict,\n },\n { name: \"memory_remove_edict\" },\n );\n }\n\n /** memory_edict_stats — get statistics about the edict store. */\n {\n const _edictStatsLabel = \"Edict Stats\";\n const _edictStatsParams = Type.Object({});\n const _edictStatsDesc = \"Get statistics about the edict store: total, by-tag counts, expired, and expiring soon.\";\n const _execEdictStats = async (_toolCallId: string) => {\n try {\n const stats = edictStore.stats();\n const lines = [\n `Total edicts: ${stats.total}`,\n `Expired: ${stats.expired}`,\n `Expiring in 7 days: ${stats.expiringIn7Days}`,\n `By tag: ${\n Object.entries(stats.byTag)\n .map(([k, v]) => `${k}=${v}`)\n .join(\", \") || \"none\"\n }`,\n ];\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n details: stats,\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"edict_stats\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_edict_stats\",\n label: _edictStatsLabel,\n description: _edictStatsDesc,\n parameters: _edictStatsParams,\n execute: _execEdictStats,\n },\n { name: \"memory_edict_stats\" },\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"register-edict-tools.js","names":[],"sources":["../../../tools/memory/register-edict-tools.ts"],"sourcesContent":["/**\n * Memory Tool Registrations\n *\n * Tool definitions for memory recall, storage, promotion, and deletion.\n * Extracted from index.ts for better modularity.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport { capturePluginError } from \"../../services/error-reporter.js\";\n\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerEdictTools(runtime: MemoryToolRuntime): void {\n const { edictStore, api, isEdictWriteToolEnabled } = runtime;\n // Edict tools — verified ground-truth facts with forced prompt injection (#791)\n // ---------------------------------------------------------------------------\n\n /** memory_add_edict — create a verified ground-truth fact (human-only; agents propose via GitHub). */\n {\n const _addEdictLabel = \"Add Edict\";\n const _addEdictParams = Type.Object({\n text: Type.String({ description: \"The verified statement of fact to store\" }),\n source: Type.Optional(\n Type.String({\n description: \"Who or what verified this edict (e.g. 'human:markus', 'ops:runbook')\",\n }),\n ),\n tags: Type.Optional(\n Type.Array(Type.String(), { description: \"Labels for filtering (e.g. ['operations', 'ssh'])\" }),\n ),\n ttl: Type.Optional(\n Type.String({\n description: \"TTL mode: 'never' (permanent), 'event' (use expiresAt date), or seconds as number\",\n }),\n ),\n expiresAt: Type.Optional(\n Type.String({\n description: \"ISO 8601 date when this edict expires (for ttl='event')\",\n }),\n ),\n });\n const _addEdictDesc =\n \"Add a verified ground-truth fact (edict) to memory. Edicts are always injected verbatim into system prompts — the agent does NOT reason about them.\\n\\n\" +\n 'NOTE: Agents should NOT create edicts directly. To propose an edict, add a GitHub comment: [EDICT CANDIDATE] text=\"...\" reason=\"...\" tags=[...]. ' +\n \"Only Markus (the human) should use this tool directly.\";\n const _execAddEdict = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n if (!isEdictWriteToolEnabled()) {\n return {\n content: [\n {\n type: \"text\",\n text: 'memory_add_edict is disabled. Propose edicts via GitHub comment: [EDICT CANDIDATE] text=\"...\" reason=\"...\" tags=[...].',\n },\n ],\n details: { error: \"forbidden\", reason: \"edict_write_disabled\" },\n };\n }\n\n const { text, source, tags, ttl, expiresAt } = params as {\n text: string;\n source?: string;\n tags?: string[];\n ttl?: string;\n expiresAt?: string;\n };\n\n if (!text || text.trim().length === 0) {\n return {\n content: [{ type: \"text\", text: \"Provide the 'text' parameter: the verified statement to store.\" }],\n details: { error: \"missing_text\" },\n };\n }\n\n let ttlValue: \"never\" | \"event\" | number = \"never\";\n if (ttl !== undefined) {\n if (ttl === \"never\") ttlValue = \"never\";\n else if (ttl === \"event\") ttlValue = \"event\";\n else if (!Number.isNaN(Number(ttl))) ttlValue = Number(ttl);\n else {\n return {\n content: [\n {\n type: \"text\",\n text: \"Invalid 'ttl' parameter: must be a positive integer number of seconds, 'never', or 'event'.\",\n },\n ],\n details: { error: \"invalid_ttl\" },\n };\n }\n }\n if (\n typeof ttlValue === \"number\" &&\n (!Number.isFinite(ttlValue) || ttlValue <= 0 || !Number.isInteger(ttlValue))\n ) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Invalid 'ttl' parameter: must be a positive integer number of seconds, 'never', or 'event'.\",\n },\n ],\n details: { error: \"invalid_ttl\" },\n };\n }\n if (ttlValue === \"event\" && !expiresAt?.trim()) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Provide the 'expiresAt' parameter (ISO 8601) when ttl='event'.\",\n },\n ],\n details: { error: \"missing_expiresAt\" },\n };\n }\n\n const edict = edictStore.add({\n text: text.trim(),\n source,\n tags,\n ttl: ttlValue,\n expiresAt,\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `Edict added: \"${edict.text.slice(0, 80)}${edict.text.length > 80 ? \"...\" : \"\"}\" (id: ${edict.id})`,\n },\n ],\n details: { edict },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"add_edict\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_add_edict\",\n label: _addEdictLabel,\n description: _addEdictDesc,\n parameters: _addEdictParams,\n execute: _execAddEdict,\n },\n { name: \"memory_add_edict\" },\n );\n }\n\n /** memory_list_edicts — list edicts, optionally filtered by tags. */\n {\n const _listEdictsLabel = \"List Edicts\";\n const _listEdictsParams = Type.Object({\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Filter to edicts with any of these tags\" })),\n limit: Type.Optional(Type.Number({ description: \"Max results (default 100)\" })),\n });\n const _listEdictsDesc = \"List all non-expired edicts, optionally filtered by tags.\";\n const _execListEdicts = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const { tags, limit } = params as { tags?: string[]; limit?: number };\n const edicts = edictStore.list({ tags, limit });\n if (edicts.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No edicts found.\" }],\n details: { count: 0, edicts: [] },\n };\n }\n const lines = edicts.map((e) => {\n const tagStr = e.tags.length > 0 ? `[${e.tags[0]}] ` : \"\";\n return `- ${tagStr}${e.text}${e.expiresAt ? ` (expires: ${e.expiresAt})` : \"\"} (id: ${e.id})`;\n });\n return {\n content: [\n {\n type: \"text\",\n text: `Edicts (${edicts.length}):\\n${lines.join(\"\\n\")}`,\n },\n ],\n details: { count: edicts.length, edicts },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"list_edicts\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_list_edicts\",\n label: _listEdictsLabel,\n description: _listEdictsDesc,\n parameters: _listEdictsParams,\n execute: _execListEdicts,\n },\n { name: \"memory_list_edicts\" },\n );\n }\n\n /** memory_get_edicts — get edicts formatted for system prompt injection. */\n {\n const _getEdictsLabel = \"Get Edicts for Prompt\";\n const _getEdictsParams = Type.Object({\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Filter to edicts with any of these tags\" })),\n format: Type.Optional(\n Type.String({ description: \"Output format: 'prompt' (Markdown block, default) or 'full' (structured)\" }),\n ),\n limit: Type.Optional(Type.Number({ description: \"Max results (default 100)\" })),\n });\n const _getEdictsDesc =\n \"Get all non-expired edicts as a pre-formatted Markdown block for system prompt injection. \" +\n \"This is called automatically during context compaction — prefer using this tool when you need edicts explicitly.\";\n const _execGetEdicts = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const { tags, format, limit } = params as { tags?: string[]; format?: string; limit?: number };\n const result = edictStore.getEdicts({ tags, format: format as \"prompt\" | \"full\", limit });\n if (result.edicts.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No edicts found.\" }],\n details: { count: 0, edicts: [], renderForPrompt: \"\" },\n };\n }\n return {\n content: [{ type: \"text\", text: result.renderForPrompt || JSON.stringify(result.edicts, null, 2) }],\n details: { count: result.edicts.length, edicts: result.edicts, renderForPrompt: result.renderForPrompt },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"get_edicts\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_get_edicts\",\n label: _getEdictsLabel,\n description: _getEdictsDesc,\n parameters: _getEdictsParams,\n execute: _execGetEdicts,\n },\n { name: \"memory_get_edicts\" },\n );\n }\n\n /** memory_update_edict — update an existing edict's text, tags, source, or expiry. */\n {\n const _updateEdictLabel = \"Update Edict\";\n const _updateEdictParams = Type.Object({\n id: Type.String({ description: \"The edict id to update\" }),\n text: Type.Optional(Type.String({ description: \"New verified statement text\" })),\n source: Type.Optional(Type.String({ description: \"New or updated source\" })),\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Replacement tags array\" })),\n ttl: Type.Optional(Type.String({ description: \"New TTL mode: 'never', 'event', or seconds as number\" })),\n expiresAt: Type.Optional(Type.String({ description: \"ISO 8601 expiry date for ttl='event'\" })),\n });\n const _updateEdictDesc = \"Update the text, tags, source, or expiry of an existing edict.\";\n const _execUpdateEdict = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n if (!isEdictWriteToolEnabled()) {\n return {\n content: [\n {\n type: \"text\",\n text: 'memory_update_edict is disabled. Propose edicts via GitHub comment: [EDICT CANDIDATE] text=\"...\" reason=\"...\" tags=[...].',\n },\n ],\n details: { error: \"forbidden\", reason: \"edict_write_disabled\" },\n };\n }\n\n const { id, text, source, tags, ttl, expiresAt } = params as {\n id: string;\n text?: string;\n source?: string;\n tags?: string[];\n ttl?: string;\n expiresAt?: string;\n };\n\n let ttlValue: \"never\" | \"event\" | number | undefined;\n if (ttl !== undefined) {\n if (ttl === \"never\") ttlValue = \"never\";\n else if (ttl === \"event\") ttlValue = \"event\";\n else if (!Number.isNaN(Number(ttl))) ttlValue = Number(ttl);\n else {\n return {\n content: [\n {\n type: \"text\",\n text: \"Invalid 'ttl' parameter: must be a positive integer number of seconds, 'never', or 'event'.\",\n },\n ],\n details: { error: \"invalid_ttl\" },\n };\n }\n }\n if (\n typeof ttlValue === \"number\" &&\n (!Number.isFinite(ttlValue) || ttlValue <= 0 || !Number.isInteger(ttlValue))\n ) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Invalid 'ttl' parameter: must be a positive integer number of seconds, 'never', or 'event'.\",\n },\n ],\n details: { error: \"invalid_ttl\" },\n };\n }\n if (ttlValue === \"event\" && !expiresAt?.trim()) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Provide the 'expiresAt' parameter (ISO 8601) when ttl='event'.\",\n },\n ],\n details: { error: \"missing_expiresAt\" },\n };\n }\n\n const updated = edictStore.update({\n id,\n text,\n source,\n tags,\n ttl: ttlValue,\n expiresAt,\n });\n\n if (!updated) {\n return {\n content: [{ type: \"text\", text: `Edict not found: ${id}` }],\n details: { error: \"not_found\" },\n };\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `Edict updated: \"${updated.text.slice(0, 80)}${updated.text.length > 80 ? \"...\" : \"\"}\" (id: ${updated.id})`,\n },\n ],\n details: { edict: updated },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"update_edict\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_update_edict\",\n label: _updateEdictLabel,\n description: _updateEdictDesc,\n parameters: _updateEdictParams,\n execute: _execUpdateEdict,\n },\n { name: \"memory_update_edict\" },\n );\n }\n\n /** memory_remove_edict — delete an edict by id. */\n {\n const _removeEdictLabel = \"Remove Edict\";\n const _removeEdictParams = Type.Object({\n id: Type.String({ description: \"The edict id to delete\" }),\n });\n const _removeEdictDesc = \"Delete an edict from memory by its id.\";\n const _execRemoveEdict = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n if (!isEdictWriteToolEnabled()) {\n return {\n content: [\n {\n type: \"text\",\n text: 'memory_remove_edict is disabled. Propose edicts via GitHub comment: [EDICT CANDIDATE] text=\"...\" reason=\"...\" tags=[...].',\n },\n ],\n details: { error: \"forbidden\", reason: \"edict_write_disabled\" },\n };\n }\n\n const { id } = params as { id: string };\n const removed = edictStore.remove(id);\n return {\n content: [\n {\n type: \"text\",\n text: removed ? `Edict removed: ${id}` : `Edict not found: ${id}`,\n },\n ],\n details: { removed },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"remove_edict\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_remove_edict\",\n label: _removeEdictLabel,\n description: _removeEdictDesc,\n parameters: _removeEdictParams,\n execute: _execRemoveEdict,\n },\n { name: \"memory_remove_edict\" },\n );\n }\n\n /** memory_edict_stats — get statistics about the edict store. */\n {\n const _edictStatsLabel = \"Edict Stats\";\n const _edictStatsParams = Type.Object({});\n const _edictStatsDesc = \"Get statistics about the edict store: total, by-tag counts, expired, and expiring soon.\";\n const _execEdictStats = async (_toolCallId: string) => {\n try {\n const stats = edictStore.stats();\n const lines = [\n `Total edicts: ${stats.total}`,\n `Expired: ${stats.expired}`,\n `Expiring in 7 days: ${stats.expiringIn7Days}`,\n `By tag: ${\n Object.entries(stats.byTag)\n .map(([k, v]) => `${k}=${v}`)\n .join(\", \") || \"none\"\n }`,\n ];\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n details: stats,\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"edict_stats\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_edict_stats\",\n label: _edictStatsLabel,\n description: _edictStatsDesc,\n parameters: _edictStatsParams,\n execute: _execEdictStats,\n },\n { name: \"memory_edict_stats\" },\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-episode-tools.js","names":[],"sources":["../../../tools/memory/register-episode-tools.ts"],"sourcesContent":["/**\n * Memory Tool Registrations\n *\n * Tool definitions for memory recall, storage, promotion, and deletion.\n * Extracted from index.ts for better modularity.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport { stringEnum } from \"../../utils/typebox.js\";\n\nimport { capturePluginError } from \"../../services/error-reporter.js\";\nimport type { EpisodeOutcome } from \"../../types/memory.js\";\n\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerEpisodeTools(runtime: MemoryToolRuntime): void {\n const { factsDb, cfg, currentAgentIdRef, buildToolScopeFilter, api } = runtime;\n // ---------------------------------------------------------------------------\n // Episodic Memory tools (#781)\n // ---------------------------------------------------------------------------\n\n /** memory_record_episode — store a structured event with explicit outcome. */\n {\n const _recordEpisodeParams = Type.Object({\n event: Type.String({ description: \"What happened (e.g. 'deployed openclaw to production').\" }),\n outcome: stringEnum([\"success\", \"failure\", \"partial\", \"unknown\"] as const, {\n description: \"Outcome of the event.\",\n }),\n timestamp: Type.Optional(\n Type.Number({ description: \"Unix epoch seconds when the event occurred. Defaults to now.\" }),\n ),\n duration: Type.Optional(\n Type.Number({ description: \"Duration in milliseconds (e.g. how long a deployment took).\" }),\n ),\n context: Type.Optional(Type.String({ description: \"Context: environment state, what led up to it, etc.\" })),\n relatedFactIds: Type.Optional(\n Type.Array(Type.String(), { description: \"IDs of related memory facts to link to this episode.\" }),\n ),\n procedureId: Type.Optional(\n Type.String({ description: \"ID of the procedure that triggered this episode, if any.\" }),\n ),\n importance: Type.Optional(\n Type.Number({ description: \"Importance 0–1 (default 0.5). Failures are auto-boosted to ≥0.8.\" }),\n ),\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Topic tags for filtering.\" })),\n scope: Type.Optional(\n stringEnum([\"global\", \"user\", \"agent\", \"session\"] as const, {\n description: \"Memory scope. Default: global.\",\n }),\n ),\n agentId: Type.Optional(Type.String()),\n userId: Type.Optional(Type.String()),\n sessionId: Type.Optional(Type.String()),\n });\n const _recordEpisodeDesc =\n \"Record a structured episodic memory: a significant event with an explicit outcome (success/failure/partial/unknown), timestamp, and optional context. Use after deployments, migrations, incidents, or other notable events to build a queryable history of what happened and how it turned out.\";\n const _execRecordEpisode = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const scopeFilter = buildToolScopeFilter({}, currentAgentIdRef.value, cfg);\n const episode = factsDb.recordEpisode({\n event: params.event as string,\n outcome: params.outcome as EpisodeOutcome,\n timestamp: params.timestamp as number | undefined,\n duration: params.duration as number | undefined,\n context: params.context as string | undefined,\n relatedFactIds: params.relatedFactIds as string[] | undefined,\n procedureId: params.procedureId as string | undefined,\n importance: params.importance as number | undefined,\n tags: params.tags as string[] | undefined,\n decayClass: \"normal\",\n scope: params.scope as \"global\" | \"user\" | \"agent\" | \"session\" | undefined,\n scopeTarget: scopeFilter?.sessionId ?? scopeFilter?.userId ?? scopeFilter?.agentId ?? null,\n agentId: (params.agentId as string | undefined) ?? scopeFilter?.agentId ?? undefined,\n userId: (params.userId as string | undefined) ?? scopeFilter?.userId ?? undefined,\n sessionId: (params.sessionId as string | undefined) ?? scopeFilter?.sessionId ?? undefined,\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `Episode recorded: [${episode.outcome}] \"${episode.event}\" at ${new Date(episode.timestamp * 1000).toISOString()} (id: ${episode.id})`,\n },\n ],\n details: { episode },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"record_episode\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_record_episode\",\n description: _recordEpisodeDesc,\n parameters: _recordEpisodeParams,\n execute: _execRecordEpisode,\n },\n { name: \"memory_record_episode\" },\n );\n }\n\n /** memory_search_episodes — search structured episodic memories with filters. */\n {\n const _searchEpisodesParams = Type.Object({\n query: Type.Optional(Type.String({ description: \"Full-text search over event and context fields.\" })),\n outcome: Type.Optional(Type.Array(stringEnum([\"success\", \"failure\", \"partial\", \"unknown\"] as const))),\n since: Type.Optional(Type.Number({ description: \"Unix epoch seconds — only events after this time.\" })),\n until: Type.Optional(Type.Number({ description: \"Unix epoch seconds — only events before this time.\" })),\n procedureId: Type.Optional(Type.String({ description: \"Filter to episodes linked to a specific procedure.\" })),\n limit: Type.Optional(Type.Number({ description: \"Max results to return (default 50, max 200).\" })),\n });\n const _searchEpisodesDesc =\n \"Search episodic memories — structured records of events with outcomes and timestamps. Filter by outcome (success/failure/partial/unknown), time range, or procedure. Returns events ordered by most recent first.\";\n const _execSearchEpisodes = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const scopeFilter = buildToolScopeFilter({}, currentAgentIdRef.value, cfg);\n const episodes = factsDb.searchEpisodes({\n query: params.query as string | undefined,\n outcome: params.outcome as EpisodeOutcome[] | undefined,\n since: params.since as number | undefined,\n until: params.until as number | undefined,\n procedureId: params.procedureId as string | undefined,\n limit: Math.min((params.limit as number | undefined) ?? 50, 200),\n scopeFilter,\n });\n\n if (episodes.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No episodes found matching the criteria.\" }],\n details: { found: 0, episodes: [] },\n };\n }\n\n const lines = episodes.map((e) => {\n const ts = new Date(e.timestamp * 1000).toLocaleString();\n const tagStr = e.tags.length > 0 ? ` #${e.tags.join(\" #\")}` : \"\";\n return `- [${e.outcome}] ${ts}: ${e.event}${tagStr} (id: ${e.id})`;\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${episodes.length} episode(s):\\n${lines.join(\"\\n\")}`,\n },\n ],\n details: { found: episodes.length, episodes },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"search_episodes\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_search_episodes\",\n description: _searchEpisodesDesc,\n parameters: _searchEpisodesParams,\n execute: _execSearchEpisodes,\n },\n { name: \"memory_search_episodes\" },\n );\n }\n\n // ---------------------------------------------------------------------------\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"register-episode-tools.js","names":[],"sources":["../../../tools/memory/register-episode-tools.ts"],"sourcesContent":["/**\n * Memory Tool Registrations\n *\n * Tool definitions for memory recall, storage, promotion, and deletion.\n * Extracted from index.ts for better modularity.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport { stringEnum } from \"../../utils/typebox.js\";\n\nimport { capturePluginError } from \"../../services/error-reporter.js\";\nimport type { EpisodeOutcome } from \"../../types/memory.js\";\n\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerEpisodeTools(runtime: MemoryToolRuntime): void {\n const { factsDb, cfg, currentAgentIdRef, buildToolScopeFilter, api } = runtime;\n // ---------------------------------------------------------------------------\n // Episodic Memory tools (#781)\n // ---------------------------------------------------------------------------\n\n /** memory_record_episode — store a structured event with explicit outcome. */\n {\n const _recordEpisodeParams = Type.Object({\n event: Type.String({ description: \"What happened (e.g. 'deployed openclaw to production').\" }),\n outcome: stringEnum([\"success\", \"failure\", \"partial\", \"unknown\"] as const, {\n description: \"Outcome of the event.\",\n }),\n timestamp: Type.Optional(\n Type.Number({ description: \"Unix epoch seconds when the event occurred. Defaults to now.\" }),\n ),\n duration: Type.Optional(\n Type.Number({ description: \"Duration in milliseconds (e.g. how long a deployment took).\" }),\n ),\n context: Type.Optional(Type.String({ description: \"Context: environment state, what led up to it, etc.\" })),\n relatedFactIds: Type.Optional(\n Type.Array(Type.String(), { description: \"IDs of related memory facts to link to this episode.\" }),\n ),\n procedureId: Type.Optional(\n Type.String({ description: \"ID of the procedure that triggered this episode, if any.\" }),\n ),\n importance: Type.Optional(\n Type.Number({ description: \"Importance 0–1 (default 0.5). Failures are auto-boosted to ≥0.8.\" }),\n ),\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Topic tags for filtering.\" })),\n scope: Type.Optional(\n stringEnum([\"global\", \"user\", \"agent\", \"session\"] as const, {\n description: \"Memory scope. Default: global.\",\n }),\n ),\n agentId: Type.Optional(Type.String()),\n userId: Type.Optional(Type.String()),\n sessionId: Type.Optional(Type.String()),\n });\n const _recordEpisodeDesc =\n \"Record a structured episodic memory: a significant event with an explicit outcome (success/failure/partial/unknown), timestamp, and optional context. Use after deployments, migrations, incidents, or other notable events to build a queryable history of what happened and how it turned out.\";\n const _execRecordEpisode = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const scopeFilter = buildToolScopeFilter({}, currentAgentIdRef.value, cfg);\n const episode = factsDb.recordEpisode({\n event: params.event as string,\n outcome: params.outcome as EpisodeOutcome,\n timestamp: params.timestamp as number | undefined,\n duration: params.duration as number | undefined,\n context: params.context as string | undefined,\n relatedFactIds: params.relatedFactIds as string[] | undefined,\n procedureId: params.procedureId as string | undefined,\n importance: params.importance as number | undefined,\n tags: params.tags as string[] | undefined,\n decayClass: \"normal\",\n scope: params.scope as \"global\" | \"user\" | \"agent\" | \"session\" | undefined,\n scopeTarget: scopeFilter?.sessionId ?? scopeFilter?.userId ?? scopeFilter?.agentId ?? null,\n agentId: (params.agentId as string | undefined) ?? scopeFilter?.agentId ?? undefined,\n userId: (params.userId as string | undefined) ?? scopeFilter?.userId ?? undefined,\n sessionId: (params.sessionId as string | undefined) ?? scopeFilter?.sessionId ?? undefined,\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `Episode recorded: [${episode.outcome}] \"${episode.event}\" at ${new Date(episode.timestamp * 1000).toISOString()} (id: ${episode.id})`,\n },\n ],\n details: { episode },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"record_episode\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_record_episode\",\n description: _recordEpisodeDesc,\n parameters: _recordEpisodeParams,\n execute: _execRecordEpisode,\n },\n { name: \"memory_record_episode\" },\n );\n }\n\n /** memory_search_episodes — search structured episodic memories with filters. */\n {\n const _searchEpisodesParams = Type.Object({\n query: Type.Optional(Type.String({ description: \"Full-text search over event and context fields.\" })),\n outcome: Type.Optional(Type.Array(stringEnum([\"success\", \"failure\", \"partial\", \"unknown\"] as const))),\n since: Type.Optional(Type.Number({ description: \"Unix epoch seconds — only events after this time.\" })),\n until: Type.Optional(Type.Number({ description: \"Unix epoch seconds — only events before this time.\" })),\n procedureId: Type.Optional(Type.String({ description: \"Filter to episodes linked to a specific procedure.\" })),\n limit: Type.Optional(Type.Number({ description: \"Max results to return (default 50, max 200).\" })),\n });\n const _searchEpisodesDesc =\n \"Search episodic memories — structured records of events with outcomes and timestamps. Filter by outcome (success/failure/partial/unknown), time range, or procedure. Returns events ordered by most recent first.\";\n const _execSearchEpisodes = async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const scopeFilter = buildToolScopeFilter({}, currentAgentIdRef.value, cfg);\n const episodes = factsDb.searchEpisodes({\n query: params.query as string | undefined,\n outcome: params.outcome as EpisodeOutcome[] | undefined,\n since: params.since as number | undefined,\n until: params.until as number | undefined,\n procedureId: params.procedureId as string | undefined,\n limit: Math.min((params.limit as number | undefined) ?? 50, 200),\n scopeFilter,\n });\n\n if (episodes.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No episodes found matching the criteria.\" }],\n details: { found: 0, episodes: [] },\n };\n }\n\n const lines = episodes.map((e) => {\n const ts = new Date(e.timestamp * 1000).toLocaleString();\n const tagStr = e.tags.length > 0 ? ` #${e.tags.join(\" #\")}` : \"\";\n return `- [${e.outcome}] ${ts}: ${e.event}${tagStr} (id: ${e.id})`;\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${episodes.length} episode(s):\\n${lines.join(\"\\n\")}`,\n },\n ],\n details: { found: episodes.length, episodes },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"search_episodes\",\n phase: \"runtime\",\n });\n throw err;\n }\n };\n api.registerTool(\n {\n name: \"memory_search_episodes\",\n description: _searchEpisodesDesc,\n parameters: _searchEpisodesParams,\n execute: _execSearchEpisodes,\n },\n { name: \"memory_search_episodes\" },\n );\n }\n\n // ---------------------------------------------------------------------------\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-recall-tools.js","names":[],"sources":["../../../tools/memory/register-recall-tools.ts"],"sourcesContent":["/**\n * Memory Tool Registrations\n *\n * Tool definitions for memory recall, storage, promotion, and deletion.\n * Extracted from index.ts for better modularity.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport { capturePluginError } from \"../../services/error-reporter.js\";\nimport { expandGraph, formatLinkPath } from \"../../services/graph-retrieval.js\";\nimport { filterByScope, mergeResults } from \"../../services/merge-results.js\";\nimport { formatNarrativeRange, recallNarrativeSummaries } from \"../../services/narrative-recall.js\";\nimport { QueryExpander } from \"../../services/query-expander.js\";\nimport {\n resolveConstrainedRetrievalPolicy,\n resolveExplicitDeepRetrievalPolicy,\n type ExplicitDeepRetrievalPolicy,\n} from \"../../services/retrieval-mode-policy.js\";\nimport { buildExplicitSemanticQueryVector, runExplicitDeepRetrieval } from \"../../services/retrieval-orchestrator.js\";\nimport type { MemoryEntry, ScopeFilter, SearchResult } from \"../../types/memory.js\";\nimport { getSessionLogFileSuffix } from \"../../utils/constants.js\";\nimport { parseSourceDate } from \"../../utils/dates.js\";\nimport { embedCallWithTimeoutAndRetry } from \"../../utils/embed-call.js\";\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerRecallTools(runtime: MemoryToolRuntime): void {\n const {\n factsDb,\n edictStore,\n vectorDb,\n cfg,\n embeddings,\n openai,\n credentialsDb,\n eventLog,\n narrativesDb,\n provenanceService,\n aliasDb,\n embeddingRegistry,\n verificationStore,\n lastProgressiveIndexIds,\n currentAgentIdRef,\n pendingLLMWarnings,\n variantQueue,\n buildToolScopeFilter,\n walWrite,\n walRemove,\n findSimilarByEmbedding,\n auditStore,\n api,\n auditAppend,\n agentIdForAudit,\n maybeRefreshProjectActiveTaskProjection,\n storeActiveCanonicalVector,\n storeRegistryEmbeddings,\n isEdictWriteToolEnabled,\n sanitizeScopeParam,\n } = runtime;\n\n api.registerTool(\n {\n name: \"memory_recall\",\n label: \"Memory Recall\",\n description: \"Search through long-term memories using both structured (exact) and semantic (fuzzy) search.\",\n parameters: Type.Object({\n query: Type.Optional(\n Type.String({\n description: \"Search query (omit when using id to fetch a specific memory)\",\n }),\n ),\n id: Type.Optional(\n Type.Union([Type.String(), Type.Number()], {\n description:\n \"Fetch a specific memory: fact id (UUID string) or 1-based index from the last progressive index (e.g. 1 for first listed memory).\",\n }),\n ),\n limit: Type.Optional(Type.Number({ description: \"Max results (default: 10)\" })),\n entity: Type.Optional(\n Type.String({\n description: \"Optional: filter by entity name for exact lookup\",\n }),\n ),\n tag: Type.Optional(\n Type.String({\n description: \"Optional: filter by topic tag (e.g. nibe, zigbee)\",\n }),\n ),\n category: Type.Optional(\n Type.String({\n description: \"Optional: constrain results to a specific category/type before ranking.\",\n }),\n ),\n source: Type.Optional(\n Type.String({\n description:\n \"Optional: constrain results to an exact fact source before ranking (e.g. conversation, ingest, reflection).\",\n }),\n ),\n verificationTier: Type.Optional(\n Type.String({\n description:\n \"Optional: constrain results to verified facts of a given tier before ranking (e.g. critical).\",\n }),\n ),\n validFromSec: Type.Optional(\n Type.Number({\n description:\n \"Optional: constrain results to facts whose valid_from is on/after this Unix timestamp before ranking.\",\n }),\n ),\n validUntilSec: Type.Optional(\n Type.Number({\n description:\n \"Optional: constrain results to facts whose validity extends past this Unix timestamp before ranking.\",\n }),\n ),\n sourceSession: Type.Optional(\n Type.String({\n description: \"Optional: constrain results to facts linked to a specific source session before ranking.\",\n }),\n ),\n retrievalMode: Type.Optional(\n Type.Union(\n [Type.Literal(\"interactive-recall\"), Type.Literal(\"explicit-deep\"), Type.Literal(\"constrained-recall\")],\n {\n description:\n 'Optional retrieval strategy selection. Use \"constrained-recall\" for filter → rank → hydrate searches inside a known boundary.',\n },\n ),\n ),\n includeSuperseded: Type.Optional(\n Type.Boolean({\n description: \"Include superseded (historical) facts in results. Default: only current facts.\",\n }),\n ),\n asOf: Type.Optional(\n Type.String({\n description:\n \"Point-in-time query: ISO date (YYYY-MM-DD) or epoch seconds. Return only facts valid at that time.\",\n }),\n ),\n userId: Type.Optional(\n Type.String({\n description:\n \"⚠️ SECURITY: Caller-controlled parameter. In multi-tenant environments, derive from authenticated identity instead. Include user-private memories for this user.\",\n }),\n ),\n agentId: Type.Optional(\n Type.String({\n description:\n \"⚠️ SECURITY: Caller-controlled parameter. In multi-tenant environments, derive from authenticated identity instead. Include agent-specific memories for this agent.\",\n }),\n ),\n sessionId: Type.Optional(\n Type.String({\n description:\n \"⚠️ SECURITY: Caller-controlled parameter. In multi-tenant environments, derive from authenticated identity instead. Include session-scoped memories for this session.\",\n }),\n ),\n confirmCrossTenantScope: Type.Optional(\n Type.Boolean({\n description:\n \"When multiAgent.trustToolScopeParams is true, set true to confirm intentional cross-tenant scope use of userId/agentId/sessionId (#874).\",\n }),\n ),\n includeCold: Type.Optional(\n Type.Boolean({\n description: \"Set true to include COLD tier (slower / deeper retrieval). Default: false (HOT + WARM only).\",\n }),\n ),\n expandGraph: Type.Optional(\n Type.Boolean({\n description:\n \"When true, run BFS graph expansion from the top results: related facts up to expandDepth hops are included. \" +\n \"Direct matches score higher than expanded ones. Default: false (or graphRetrieval.defaultExpand from config).\",\n }),\n ),\n expandDepth: Type.Optional(\n Type.Number({\n description:\n \"Number of BFS hops to expand when expandGraph=true (default: 2, max: graphRetrieval.maxExpandDepth from config).\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n return await memoryRecallImpl(params);\n } catch (err) {\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: undefined,\n outcome: \"failed\",\n error: err instanceof Error ? err.message : String(err),\n sessionId: api.context?.sessionId ?? undefined,\n });\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-recall\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_recall\" },\n );\n\n api.registerTool(\n {\n name: \"memory_recall_timeline\",\n label: \"Memory Recall Timeline\",\n description: \"Recall chronological summaries of recent sessions, decisions, and attempts.\",\n parameters: Type.Object({\n query: Type.Optional(\n Type.String({\n description: \"Optional topic or project query used to rank narrative summaries.\",\n }),\n ),\n sessionId: Type.Optional(\n Type.String({\n description:\n \"Optional session id to fetch a specific session narrative or event timeline. In multi-tenant environments, only pass a sessionId derived from the authenticated context; never accept arbitrary end-user input here, to avoid cross-session data exposure.\",\n }),\n ),\n limit: Type.Optional(\n Type.Number({\n description: \"Max summaries to return (default: 3).\",\n minimum: 1,\n maximum: 50,\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const MAX_SUMMARY_LIMIT = 50;\n const MIN_SUMMARY_LIMIT = 1;\n\n const query = typeof params.query === \"string\" && params.query.trim().length > 0 ? params.query.trim() : null;\n const requestedSessionId =\n typeof params.sessionId === \"string\" && params.sessionId.trim().length > 0 ? params.sessionId.trim() : null;\n const contextSessionId =\n typeof api.context?.sessionId === \"string\" && api.context.sessionId.trim().length > 0\n ? api.context.sessionId.trim()\n : null;\n if (!contextSessionId) {\n throw new Error(\"memory_recall_timeline requires an authenticated session context\");\n }\n if (requestedSessionId && requestedSessionId !== contextSessionId) {\n throw new Error(\"memory_recall_timeline sessionId must match the authenticated session context\");\n }\n const sessionId = contextSessionId;\n\n let limit = typeof params.limit === \"number\" && params.limit > 0 ? Math.floor(params.limit) : 3;\n limit = Math.min(MAX_SUMMARY_LIMIT, Math.max(MIN_SUMMARY_LIMIT, limit));\n const nowSec = Math.floor(Date.now() / 1000);\n const summaries = recallNarrativeSummaries({\n narrativesDb: narrativesDb ?? null,\n eventLog,\n query,\n sessionId,\n limit,\n nowSec,\n sinceSec: undefined,\n });\n\n if (summaries.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `No narrative summary found for session ${sessionId}.`,\n },\n ],\n details: { count: 0, narratives: [] },\n };\n }\n\n const lines = summaries.map((summary, index) => {\n const agentDir = currentAgentIdRef.value || \"main\";\n const logPath = `~/.openclaw/agents/${agentDir}/sessions/${summary.sessionId}${getSessionLogFileSuffix()}`;\n return (\n `${index + 1}. [${summary.source}] ${formatNarrativeRange(summary.periodStart, summary.periodEnd)} ` +\n `(sessionKey: ${summary.sessionId}, sessionLogPath: ${logPath})\\n${summary.text}`\n );\n });\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Found ${summaries.length} narrative summar${summaries.length === 1 ? \"y\" : \"ies\"}:\\n\\n${lines.join(\"\\n\\n\")}`,\n },\n ],\n details: {\n count: summaries.length,\n narratives: summaries.map((summary) => ({\n id: summary.id,\n source: summary.source,\n sessionId: summary.sessionId,\n sessionKey: summary.sessionId,\n sessionLogPath: `~/.openclaw/agents/${currentAgentIdRef.value || \"main\"}/sessions/${summary.sessionId}${getSessionLogFileSuffix()}`,\n periodStart: new Date(summary.periodStart * 1000).toISOString(),\n periodEnd: new Date(summary.periodEnd * 1000).toISOString(),\n tag: summary.tag,\n text: summary.text,\n score: Number(summary.score.toFixed(3)),\n })),\n },\n };\n },\n },\n { name: \"memory_recall_timeline\" },\n {\n name: \"memory_session_observability\",\n label: \"Memory Session Observability\",\n description:\n \"Get a unified session observability report: timeline of capture, recall, injection, suppressions, and used-vs-stored analysis. Use sessionId from the session context or pass a specific session id.\",\n parameters: Type.Object({\n sessionId: Type.Optional(\n Type.String({\n description: \"Session id to report on. Defaults to the current session from context.\",\n }),\n ),\n agentId: Type.Optional(\n Type.String({\n description: \"Agent id to scope the report to (optional).\",\n }),\n ),\n limit: Type.Optional(\n Type.Number({\n description: \"Max timeline entries per section (default: 50, max: 200).\",\n minimum: 1,\n maximum: 200,\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const sessionId =\n typeof params.sessionId === \"string\" && params.sessionId.trim().length > 0 ? params.sessionId.trim() : null;\n const agentId =\n typeof params.agentId === \"string\" && params.agentId.trim().length > 0 ? params.agentId.trim() : null;\n const limit =\n typeof params.limit === \"number\" && params.limit > 0 ? Math.min(200, Math.floor(params.limit)) : 50;\n\n // Build report synchronously (factsDb / auditStore are sync interfaces)\n let report;\n try {\n const { buildSessionObservabilityReport } = await import(\"../../services/session-observability.js\");\n report = await buildSessionObservabilityReport({\n factsDb: factsDb as import(\"../../backends/facts-db.js\").FactsDB,\n eventLog: eventLog as import(\"../../backends/event-log.js\").EventLog | null,\n narrativesDb: narrativesDb as import(\"../../backends/narratives-db.js\").NarrativesDB | null,\n auditStore: auditStore ?? null,\n sessionId,\n agentId,\n limit,\n });\n } catch (err) {\n return {\n content: [{ type: \"text\" as const, text: `Failed to build session report: ${String(err)}` }],\n details: { error: String(err) },\n };\n }\n\n // Human-readable summary line\n const summaryText =\n report.summary ||\n `Session ${sessionId ?? \"unknown\"}: ${report.timeline.length} timeline entries, ` +\n `${report.capture.factsStored} stored, ${report.capture.duplicatesSuppressed} suppressed, ` +\n `${report.recall.injectedCount} injected.`;\n\n const detail = {\n sessionId: report.sessionId,\n agentId: report.agentId,\n windowStart: report.windowStart,\n windowEnd: report.windowEnd,\n timelineCount: report.timeline.length,\n capture: {\n factsStored: report.capture.factsStored,\n factsUpdated: report.capture.factsUpdated,\n duplicatesSuppressed: report.capture.duplicatesSuppressed,\n noopSkipped: report.capture.noopSkipped,\n errorsEncountered: report.capture.errorsEncountered,\n entitiesExtracted: report.capture.entitiesExtracted,\n episodesRecorded: report.capture.episodesRecorded,\n proceduresLearned: report.capture.proceduresLearned,\n },\n recall: {\n candidatesFound: report.recall.candidatesFound,\n injectedCount: report.recall.injectedCount,\n omittedCount: report.recall.omittedCount,\n strategies: report.recall.strategies,\n directiveMatches: report.recall.directiveMatches,\n suppressionReasons: report.recall.suppressionReasons,\n },\n injection: {\n totalChars: report.injection.totalChars,\n totalTokensEstimate: report.injection.totalTokensEstimate,\n blocksInjected: report.injection.blocksInjected,\n budgetTokens: report.injection.budgetTokens,\n budgetUsedFraction: Math.round(report.injection.budgetUsedFraction * 100) / 100,\n },\n suppressions: report.suppressions,\n timeline: report.timeline.slice(0, limit).map((e) => ({\n timestamp: e.timestamp,\n kind: e.kind,\n label: e.label,\n description: e.description,\n outcome: e.outcome,\n score: e.score,\n })),\n };\n\n return {\n content: [{ type: \"text\" as const, text: summaryText }],\n details: detail,\n };\n },\n },\n );\n\n // Internal implementation so we can return from the try block\n async function memoryRecallImpl(params: Record<string, unknown>) {\n const recallStartedAt = Date.now();\n const {\n query: queryParam,\n id: idParam,\n limit = 10,\n entity: entityParam,\n tag: tagParam,\n category: categoryParam,\n source: sourceParam,\n verificationTier: verificationTierParam,\n validFromSec,\n validUntilSec,\n sourceSession: sourceSessionParam,\n retrievalMode,\n includeSuperseded = false,\n asOf: asOfParam,\n includeCold = false,\n userId,\n agentId,\n sessionId,\n confirmCrossTenantScope,\n expandGraph: expandGraphParam,\n expandDepth: expandDepthParam,\n } = params as {\n query?: string;\n id?: string | number;\n limit?: number;\n entity?: string;\n tag?: string;\n category?: string;\n source?: string;\n verificationTier?: string;\n validFromSec?: number;\n validUntilSec?: number;\n sourceSession?: string;\n retrievalMode?: \"interactive-recall\" | \"explicit-deep\" | \"constrained-recall\";\n includeSuperseded?: boolean;\n asOf?: string;\n includeCold?: boolean;\n userId?: string;\n agentId?: string;\n sessionId?: string;\n confirmCrossTenantScope?: boolean;\n expandGraph?: boolean;\n expandDepth?: number;\n };\n const normalizeOptionalString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n };\n const entity = normalizeOptionalString(entityParam);\n const tag = normalizeOptionalString(tagParam);\n const category = normalizeOptionalString(categoryParam);\n const source = normalizeOptionalString(sourceParam);\n const verificationTier = normalizeOptionalString(verificationTierParam);\n const sourceSession = normalizeOptionalString(sourceSessionParam);\n const asOfSec = asOfParam != null && asOfParam !== \"\" ? parseSourceDate(asOfParam) : undefined;\n\n // Scope filtering with auto-detection\n // ⚠️ SECURITY WARNING: userId/agentId/sessionId are caller-controlled parameters.\n // In multi-tenant production environments, these should be derived from authenticated\n // identity (via autoRecall.scopeFilter config) rather than accepted as tool parameters.\n // Accepting arbitrary scope filters allows users to access other users' private memories.\n // See docs/MEMORY-SCOPING.md \"Secure Multi-Tenant Setup\" for proper implementation.\n const scopeFilter = buildToolScopeFilter(\n {\n userId: sanitizeScopeParam(\"userId\", userId),\n agentId: sanitizeScopeParam(\"agentId\", agentId),\n sessionId: sanitizeScopeParam(\"sessionId\", sessionId),\n confirmCrossTenantScope,\n },\n currentAgentIdRef.value,\n cfg,\n );\n const logRecall = (hit: boolean) => {\n const maybeFactsDb = factsDb as { logRecall?: (hit: boolean) => void };\n if (typeof maybeFactsDb.logRecall === \"function\") {\n try {\n maybeFactsDb.logRecall(hit);\n } catch {\n // Non-fatal: recall logging should never break recall\n }\n }\n };\n\n // Fetch by id (fact id or 1-based index from last progressive index)\n if (idParam !== undefined && idParam !== null && idParam !== \"\") {\n let factId: string | null = null;\n if (typeof idParam === \"number\") {\n const idx = Math.floor(idParam);\n if (idx >= 1 && idx <= lastProgressiveIndexIds.length) {\n factId = lastProgressiveIndexIds[idx - 1] ?? null;\n }\n } else if (typeof idParam === \"string\" && idParam.trim().length > 0) {\n const trimmed = idParam.trim();\n // Check if it's a numeric string (progressive index position)\n if (/^\\d+$/.test(trimmed)) {\n const idx = Number.parseInt(trimmed, 10);\n if (idx >= 1 && idx <= lastProgressiveIndexIds.length) {\n factId = lastProgressiveIndexIds[idx - 1] ?? null;\n }\n } else {\n // Treat as fact ID\n factId = trimmed;\n }\n }\n if (factId) {\n const getByIdOpts = { asOf: asOfSec, scopeFilter };\n const entry = factsDb.getById(\n factId,\n asOfSec != null || scopeFilter ? (getByIdOpts as { asOf?: number; scopeFilter?: ScopeFilter }) : undefined,\n );\n if (entry) {\n // Access boost — update recall_count and last_accessed on fetch by id\n factsDb.refreshAccessedFacts([entry.id]);\n logRecall(true);\n const text = `[${entry.category}] ${entry.text}`;\n const whyLine = entry.why ? `\\nWhy: ${entry.why}` : \"\";\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: `memory #${entry.id}`,\n outcome: \"success\",\n durationMs: Date.now() - recallStartedAt,\n sessionId: api.context?.sessionId ?? undefined,\n });\n return {\n content: [\n {\n type: \"text\",\n text: `Memory (id: ${entry.id}):\\n\\n${text}${whyLine}`,\n },\n ],\n details: {\n count: 1,\n memories: [\n {\n id: entry.id,\n text: entry.text,\n why: entry.why ?? undefined,\n category: entry.category,\n entity: entry.entity,\n importance: entry.importance,\n score: 1,\n backend: \"sqlite\" as const,\n tags: entry.tags?.length ? entry.tags : undefined,\n sourceDate: entry.sourceDate\n ? new Date(entry.sourceDate * 1000).toISOString().slice(0, 10)\n : undefined,\n },\n ],\n },\n };\n }\n }\n logRecall(false);\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: typeof idParam === \"number\" ? `index ${idParam}` : `id ${idParam}`,\n outcome: \"partial\",\n durationMs: Date.now() - recallStartedAt,\n sessionId: api.context?.sessionId ?? undefined,\n });\n return {\n content: [\n {\n type: \"text\",\n text:\n typeof idParam === \"number\"\n ? `No memory at index ${idParam}. Use a number between 1 and ${lastProgressiveIndexIds.length} from the index, or provide a fact id.`\n : `No memory found with id: ${idParam}.`,\n },\n ],\n details: { count: 0 },\n };\n }\n\n const query = typeof queryParam === \"string\" && queryParam.trim().length > 0 ? queryParam.trim() : null;\n if (!query) {\n logRecall(false);\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: undefined,\n outcome: \"partial\",\n durationMs: Date.now() - recallStartedAt,\n sessionId: api.context?.sessionId ?? undefined,\n });\n return {\n content: [\n {\n type: \"text\",\n text: \"Provide a search query or an id (fact id or index from the memory index) to recall memories.\",\n },\n ],\n details: { count: 0 },\n };\n }\n\n const tierFilter: \"warm\" | \"all\" = includeCold ? \"all\" : \"warm\";\n const recallOpts = {\n tag,\n includeSuperseded,\n tierFilter,\n scopeFilter,\n ...(asOfSec != null ? { asOf: asOfSec } : {}),\n };\n\n const hasAdditionalConstrainedFilters = Boolean(\n category || source || verificationTier || validFromSec != null || validUntilSec != null || sourceSession,\n );\n const shouldUseConstrainedMode =\n retrievalMode === \"constrained-recall\" || (!retrievalMode && hasAdditionalConstrainedFilters);\n const effectiveMode = shouldUseConstrainedMode ? \"constrained-recall\" : retrievalMode;\n const constrainedFilters = shouldUseConstrainedMode\n ? {\n ...(entity ? { entity } : {}),\n ...(tag ? { tag } : {}),\n ...(category ? { category } : {}),\n ...(source ? { source } : {}),\n ...(verificationTier ? { verificationTier } : {}),\n ...(typeof validFromSec === \"number\" ? { validFromSec: Math.floor(validFromSec) } : {}),\n ...(typeof validUntilSec === \"number\" ? { validUntilSec: Math.floor(validUntilSec) } : {}),\n ...(sourceSession ? { sourceSession } : {}),\n }\n : undefined;\n\n // Entity-targeted lookup is useful for legacy explicit recall, but it bypasses\n // filter → rank → hydrate semantics, so disable it in constrained mode.\n let entityResults: SearchResult[] = [];\n if (entity && !shouldUseConstrainedMode) {\n entityResults = factsDb.lookup(entity, undefined, tag, { ...recallOpts, limit: 100 });\n }\n\n // Explicit/deep retrieval owns richer semantic prep, including optional HyDE.\n let queryVector: number[] | null = null;\n let semanticWarning: string | null = null;\n\n // RRF multi-strategy retrieval pipeline (Issue #152)\n // Legacy tag-only recall skips semantic search; constrained mode keeps semantic ranking\n // because tag/entity/category/etc. are applied before ranking inside the candidate set.\n let results: SearchResult[] = [];\n try {\n const useLegacyTagShortcut = Boolean(tag && !shouldUseConstrainedMode);\n const rrfStrategies = useLegacyTagShortcut\n ? cfg.retrieval.strategies.filter((s) => s !== \"semantic\")\n : cfg.retrieval.strategies;\n const rrfConfig = { ...cfg.retrieval, strategies: rrfStrategies };\n // interactive-recall uses a different policy with its own vector prep; skip for other modes\n const effectivePolicy =\n effectiveMode !== \"interactive-recall\"\n ? effectiveMode === \"constrained-recall\"\n ? resolveConstrainedRetrievalPolicy(rrfConfig)\n : resolveExplicitDeepRetrievalPolicy(rrfConfig)\n : undefined;\n if (!useLegacyTagShortcut && effectivePolicy !== undefined) {\n const vectorPrep = await buildExplicitSemanticQueryVector({\n query,\n cfg,\n embeddings,\n openai,\n pendingLLMWarnings,\n logger: api.logger,\n policy: effectivePolicy as ExplicitDeepRetrievalPolicy,\n });\n queryVector = vectorPrep.queryVector;\n semanticWarning = vectorPrep.warning;\n }\n const queryExpander =\n cfg.queryExpansion?.enabled && rrfStrategies.includes(\"semantic\")\n ? new QueryExpander(cfg.queryExpansion, openai)\n : null;\n const embedFn =\n queryVector != null\n ? (text: string) =>\n embedCallWithTimeoutAndRetry(() => embeddings.embed(text), \"memory-tools:rrf-deep-retrieval\")\n : null;\n const rrfOutput = await runExplicitDeepRetrieval(query, queryVector, factsDb.getRawDb(), vectorDb, factsDb, {\n config: rrfConfig,\n ...(effectiveMode !== \"interactive-recall\" && effectivePolicy\n ? { policy: effectivePolicy }\n : effectiveMode === \"interactive-recall\"\n ? { mode: effectiveMode as \"interactive-recall\" }\n : {}),\n ...(useLegacyTagShortcut ? { tagFilter: tag ?? undefined } : {}),\n ...(constrainedFilters ? { constrainedFilters } : {}),\n includeSuperseded,\n scopeFilter,\n asOf: asOfSec ?? undefined,\n graphHubDegreeCap: cfg.graph.hubDegreeCap,\n graphHubScorePenalty: cfg.graph.hubScorePenalty,\n aliasDb: cfg.aliases?.enabled ? aliasDb : null,\n clustersConfig: cfg.clusters,\n embeddingRegistry: embeddingRegistry ?? null,\n factsDbForEmbeddings: factsDb,\n queryExpander: queryExpander ?? null,\n embedFn,\n rerankingConfig: cfg.reranking,\n rerankingOpenai: openai,\n adaptiveOpenai: cfg.documentGrading?.enabled ? openai : undefined,\n documentGradingConfig: cfg.documentGrading,\n });\n\n // Merge entity-lookup results first, then append RRF results (deduped).\n // When packed is non-empty, only include fused results whose factId was packed\n // (avoids including items beyond the token budget). Fall back to the full fused\n // list when packed is empty (e.g. budget too small to pack any).\n // Use a factId→entry Map so entry lookup never depends on loop index alignment.\n const seenIds = new Set<string>(entityResults.map((r) => r.entry.id));\n results = [...entityResults];\n const entryByFactId = new Map<string, MemoryEntry>();\n for (let i = 0; i < rrfOutput.fused.length; i++) {\n const e = rrfOutput.entries[i];\n if (e) entryByFactId.set(rrfOutput.fused[i].factId, e);\n }\n const packedFactIdSet = rrfOutput.packed.length > 0 ? new Set(rrfOutput.packedFactIds) : null;\n for (const fusedResult of rrfOutput.fused) {\n if (packedFactIdSet && !packedFactIdSet.has(fusedResult.factId)) continue;\n if (seenIds.has(fusedResult.factId)) continue;\n const entry = entryByFactId.get(fusedResult.factId);\n if (entry) {\n results.push({ entry, score: fusedResult.finalScore, backend: \"sqlite\" });\n seenIds.add(fusedResult.factId);\n }\n }\n results.sort((a, b) => b.score - a.score);\n results = results.slice(0, limit);\n } catch (err) {\n // Fallback: use legacy FTS + vector merge if RRF pipeline fails\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"search\",\n operation: \"rrf-pipeline\",\n phase: \"runtime\",\n });\n api.logger.warn(`memory-hybrid: RRF pipeline failed, falling back to legacy merge: ${err}`);\n const ftsResults = factsDb.search(query, limit, {\n ...recallOpts,\n reinforcementBoost: cfg.distill?.reinforcementBoost ?? 0.1,\n diversityWeight: cfg.reinforcement?.diversityWeight ?? 1.0,\n });\n let lanceResults: SearchResult[] = [];\n if (queryVector) {\n lanceResults = await vectorDb.search(queryVector, limit * 3, 0.3);\n lanceResults = filterByScope(lanceResults, (id, opts) => factsDb.getById(id, opts), scopeFilter);\n }\n results = mergeResults([...entityResults, ...ftsResults], lanceResults, limit, factsDb);\n }\n\n // Exclude COLD tier when includeCold is false (Lance results may include cold facts)\n if (!includeCold && results.length > 0) {\n const filtered: SearchResult[] = [];\n for (const r of results) {\n const full = factsDb.getById(r.entry.id);\n if (full && full.tier !== \"cold\") filtered.push({ ...r, entry: full });\n }\n results = filtered.slice(0, limit);\n }\n\n // When asOf is set, filter so only facts valid at that time (Lance results lack temporal filter)\n if (asOfSec != null && results.length > 0) {\n const filtered: SearchResult[] = [];\n for (const r of results) {\n const full = factsDb.getById(r.entry.id, { asOf: asOfSec });\n if (full) filtered.push({ ...r, entry: full });\n }\n results = filtered.slice(0, limit);\n }\n\n // Resolve whether to run GraphRAG expansion for this call.\n const useExpandGraph =\n cfg.graphRetrieval.enabled &&\n cfg.graph.enabled &&\n results.length > 0 &&\n (expandGraphParam ?? cfg.graphRetrieval.defaultExpand);\n\n // GraphRAG expansion — BFS from seed results with path tracking and ranked scoring.\n // When expandGraph=true, replaces the legacy flat-score graph traversal.\n type ExpandedMeta = { expansionSource: \"direct\" | \"graph\"; hopCount: number; linkPath: string } | undefined;\n const expansionMeta = new Map<string, ExpandedMeta>();\n\n if (useExpandGraph) {\n const rawDepth = typeof expandDepthParam === \"number\" ? expandDepthParam : cfg.retrieval.graphWalkDepth;\n const depth = Math.min(Math.max(0, rawDepth), cfg.graphRetrieval.maxExpandDepth);\n const seedInputs = results.map((r) => ({ factId: r.entry.id, score: r.score, entry: r.entry }));\n const originalBackendMap = new Map<string, \"sqlite\" | \"lancedb\">();\n for (const r of results) {\n originalBackendMap.set(r.entry.id, r.backend);\n }\n const { results: expanded } = expandGraph(factsDb, seedInputs, {\n maxDepth: depth,\n maxExpandedResults: cfg.graphRetrieval.maxExpandedResults,\n scopeFilter: scopeFilter ?? undefined,\n asOf: asOfSec ?? undefined,\n hubDegreeCap: cfg.graph.hubDegreeCap,\n hubScorePenalty: cfg.graph.hubScorePenalty,\n });\n\n // Re-build results from expanded output (preserves scores and dedup).\n const newResults: SearchResult[] = [];\n for (const e of expanded) {\n const backend = e.expansionSource === \"direct\" ? (originalBackendMap.get(e.factId) ?? \"sqlite\") : \"sqlite\";\n newResults.push({ entry: e.entry, score: e.score, backend });\n expansionMeta.set(e.factId, {\n expansionSource: e.expansionSource,\n hopCount: e.hopCount,\n linkPath: formatLinkPath(e.linkPath),\n });\n }\n newResults.sort((a, b) => b.score - a.score);\n results = newResults.slice(0, limit);\n } else if (cfg.graph.enabled && cfg.graph.useInRecall && results.length > 0) {\n // Legacy flat-score graph traversal (backward compatible, no path annotation).\n const initialIds = new Set(results.map((r) => r.entry.id));\n const connectedIds = factsDb.getConnectedFactIds([...initialIds], cfg.graph.maxTraversalDepth, {\n hubDegreeCap: cfg.graph.hubDegreeCap,\n });\n const extraIds = connectedIds.filter((id) => !initialIds.has(id));\n const getByIdOpts = asOfSec != null || scopeFilter ? { asOf: asOfSec, scopeFilter } : undefined;\n for (const id of extraIds) {\n const entry = factsDb.getById(id, getByIdOpts as { asOf?: number; scopeFilter?: ScopeFilter });\n if (entry) {\n results.push({ entry, score: 0.45, backend: \"sqlite\" });\n }\n }\n results.sort((a, b) => b.score - a.score);\n results = results.slice(0, limit);\n }\n\n const retrievalExplanation = (() => {\n if (!shouldUseConstrainedMode || !constrainedFilters) return undefined;\n const filterPairs = Object.entries(constrainedFilters)\n .filter(([, value]) => value !== undefined && value !== null && value !== \"\")\n .map(([key, value]) => `${key}=${String(value)}`);\n return {\n mode: \"constrained-recall\" as const,\n contract: \"filter → rank → hydrate\",\n filterBasis: filterPairs,\n rankBasis:\n \"semantic rank inside the structured candidate set (with hydrated provenance/context in the final result)\",\n };\n })();\n const retrievalExplanationText = retrievalExplanation\n ? `Retrieval: constrained-recall (filter → rank → hydrate)\\nFilter basis: ${retrievalExplanation.filterBasis.join(\", \")}\\nRank basis: ${retrievalExplanation.rankBasis}`\n : undefined;\n\n if (results.length === 0) {\n logRecall(false);\n const noResultsText = semanticWarning\n ? `No relevant memories found.\\n\\n⚠️ ${semanticWarning}`\n : \"No relevant memories found.\";\n return {\n content: [\n {\n type: \"text\",\n text: retrievalExplanationText ? `${retrievalExplanationText}\\n\\n${noResultsText}` : noResultsText,\n },\n ],\n details: {\n count: 0,\n warning: semanticWarning ?? undefined,\n retrieval: retrievalExplanation,\n },\n };\n }\n\n const contradictionStatus = new Map<string, boolean>();\n for (const r of results) {\n contradictionStatus.set(r.entry.id, factsDb.isContradicted(r.entry.id));\n }\n\n // Check integrity for verified facts (Issue #162): flag tampered results.\n const tamperStatus = new Map<string, boolean>();\n if (verificationStore && cfg.verification.enabled) {\n for (const r of results) {\n try {\n const report = verificationStore.checkIntegrity(r.entry.id);\n if (report.checked > 0 && !report.valid) {\n tamperStatus.set(r.entry.id, true);\n }\n } catch {\n // Don't block retrieval on integrity check failure\n }\n }\n }\n\n logRecall(true);\n const text = results\n .map((r, i) => {\n const contradicted = contradictionStatus.get(r.entry.id) ?? false;\n const contradictedPrefix = contradicted ? \"[⚠️ CONTRADICTED] \" : \"\";\n const tampered = tamperStatus.get(r.entry.id) ?? false;\n const tamperedPrefix = tampered ? \"[⚠️ TAMPERED] \" : \"\";\n const meta = expansionMeta.get(r.entry.id);\n const expansionSuffix =\n meta && meta.expansionSource === \"graph\"\n ? ` [graph+${meta.hopCount}hop${meta.linkPath ? `: ${meta.linkPath}` : \"\"}]`\n : \"\";\n const whySuffix = r.entry.why ? `\\n Why: ${r.entry.why}` : \"\";\n return `${i + 1}. [${r.backend}/${r.entry.category}] ${contradictedPrefix}${tamperedPrefix}${r.entry.text} (${(r.score * 100).toFixed(0)}%)${expansionSuffix}${whySuffix}`;\n })\n .join(\"\\n\");\n\n const sanitized = results.map((r) => {\n const meta = expansionMeta.get(r.entry.id);\n return {\n id: r.entry.id,\n text: r.entry.text,\n why: r.entry.why ?? undefined,\n category: r.entry.category,\n entity: r.entry.entity,\n importance: r.entry.importance,\n score: r.score,\n backend: r.backend,\n tags: r.entry.tags?.length ? r.entry.tags : undefined,\n sourceDate: r.entry.sourceDate ? new Date(r.entry.sourceDate * 1000).toISOString().slice(0, 10) : undefined,\n contradicted: contradictionStatus.get(r.entry.id) || undefined,\n accessCount: r.entry.accessCount ?? 0,\n lastAccessedAt: r.entry.lastAccessedAt ?? null,\n ...(meta\n ? {\n expansionSource: meta.expansionSource,\n hopCount: meta.hopCount,\n linkPath: meta.linkPath || undefined,\n }\n : {}),\n };\n });\n\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: query ? `query=\"${query.slice(0, 160)}\"` : undefined,\n outcome: \"success\",\n durationMs: Date.now() - recallStartedAt,\n sessionId: api.context?.sessionId ?? undefined,\n context: { count: results.length },\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `${retrievalExplanationText ? `${retrievalExplanationText}\\n\\n` : \"\"}Found ${results.length} memories:\\n\\n${text}${semanticWarning ? `\\n\\n⚠️ ${semanticWarning}` : \"\"}`,\n },\n ],\n details: {\n count: results.length,\n memories: sanitized,\n warning: semanticWarning ?? undefined,\n retrieval: retrievalExplanation,\n },\n };\n }\n\n if (cfg.procedures.enabled) {\n api.registerTool(\n {\n name: \"memory_recall_procedures\",\n label: \"Recall Procedures\",\n description:\n \"Search for learned procedures (positive: what worked; negative: known failures) matching a task description.\",\n parameters: Type.Object({\n taskDescription: Type.String({\n description: \"What you are trying to do (e.g. 'check Moltbook', 'HA health checks')\",\n }),\n limit: Type.Optional(Type.Number({ description: \"Max procedures to return (default: 5)\" })),\n agentId: Type.Optional(\n Type.String({\n description: \"⚠️ SECURITY: Caller-controlled parameter. Filter procedures for specific agent.\",\n }),\n ),\n userId: Type.Optional(\n Type.String({\n description: \"⚠️ SECURITY: Caller-controlled parameter. Filter procedures for specific user.\",\n }),\n ),\n sessionId: Type.Optional(\n Type.String({\n description: \"⚠️ SECURITY: Caller-controlled parameter. Filter procedures for specific session.\",\n }),\n ),\n confirmCrossTenantScope: Type.Optional(\n Type.Boolean({\n description:\n \"When multiAgent.trustToolScopeParams is true, set true to confirm intentional cross-tenant scope use of userId/agentId/sessionId (#874).\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const {\n taskDescription,\n limit = 5,\n agentId,\n userId,\n sessionId,\n confirmCrossTenantScope,\n } = params as {\n taskDescription: string;\n limit?: number;\n agentId?: string;\n userId?: string;\n sessionId?: string;\n confirmCrossTenantScope?: boolean;\n };\n const q =\n typeof taskDescription === \"string\" && taskDescription.trim().length > 0 ? taskDescription.trim() : null;\n if (!q) {\n return {\n content: [{ type: \"text\" as const, text: \"Provide a task description to recall procedures.\" }],\n details: { count: 0 },\n };\n }\n\n // Build scope filter (same logic as memory_recall)\n const scopeFilter = buildToolScopeFilter(\n {\n userId: sanitizeScopeParam(\"userId\", userId),\n agentId: sanitizeScopeParam(\"agentId\", agentId),\n sessionId: sanitizeScopeParam(\"sessionId\", sessionId),\n confirmCrossTenantScope,\n },\n currentAgentIdRef.value,\n cfg,\n );\n\n const procedures = factsDb.searchProcedures(\n q,\n limit,\n cfg.distill?.reinforcementProcedureBoost ?? 0.1,\n scopeFilter,\n );\n const negatives = factsDb.getNegativeProceduresMatching(q, 3, scopeFilter);\n const lines: string[] = [];\n const positiveList = procedures.filter((p) => p.procedureType === \"positive\");\n if (positiveList.length > 0) {\n lines.push(\"Last time this worked:\");\n for (const p of positiveList) {\n let recipe: unknown;\n try {\n recipe = JSON.parse(p.recipeJson);\n } catch (err) {\n capturePluginError(err as Error, {\n operation: \"parse-recipe\",\n severity: \"info\",\n subsystem: \"tools\",\n });\n recipe = [];\n }\n const steps = Array.isArray(recipe)\n ? (recipe as Array<{ tool?: string; args?: Record<string, unknown> }>)\n .map(\n (s) =>\n s.tool +\n (s.args && Object.keys(s.args).length > 0 ? `(${JSON.stringify(s.args).slice(0, 80)}…)` : \"\"),\n )\n .join(\" → \")\n : p.recipeJson.slice(0, 200);\n const rate = p.successRate !== undefined ? `, rate ${(p.successRate * 100).toFixed(0)}%` : \"\";\n const ver = p.version !== undefined ? `, v${p.version}` : \"\";\n const outcome = p.lastOutcome === \"failure\" ? \" ⚠️\" : p.lastOutcome === \"success\" ? \" ✅\" : \"\";\n lines.push(\n `- ${p.taskPattern.slice(0, 80)}…: ${steps} (validated ${p.successCount}x${rate}${ver}${outcome})`,\n );\n if (p.avoidanceNotes && p.avoidanceNotes.length > 0) {\n for (const note of p.avoidanceNotes.slice(0, 2)) {\n lines.push(` ⚠ ${note}`);\n }\n }\n }\n }\n if (negatives.length > 0) {\n lines.push(\"\");\n lines.push(\"⚠️ Known issues (avoid):\");\n for (const p of negatives) {\n let recipe: unknown;\n try {\n recipe = JSON.parse(p.recipeJson);\n } catch (err) {\n capturePluginError(err as Error, {\n operation: \"parse-recipe\",\n severity: \"info\",\n subsystem: \"tools\",\n });\n recipe = [];\n }\n const steps = Array.isArray(recipe)\n ? (recipe as Array<{ tool?: string }>)\n .map((s) => s.tool)\n .filter(Boolean)\n .join(\" → \")\n : \"\";\n const ver = p.version !== undefined ? ` (v${p.version})` : \"\";\n lines.push(`- ${p.taskPattern.slice(0, 80)}… ${steps ? `(${steps})` : \"\"}${ver}`);\n if (p.avoidanceNotes && p.avoidanceNotes.length > 0) {\n for (const note of p.avoidanceNotes.slice(0, 2)) {\n lines.push(` ⚠ ${note}`);\n }\n }\n }\n }\n if (lines.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: \"No procedures found for this task.\" }],\n details: { count: 0 },\n };\n }\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n details: {\n count: positiveList.length + negatives.length,\n procedures: positiveList.length,\n warnings: negatives.length,\n },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-recall-procedures\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_recall_procedures\" },\n );\n\n // Procedure feedback loop (#782)\n api.registerTool(\n {\n name: \"memory_procedure_feedback\",\n label: \"Procedure Feedback\",\n description:\n \"Record the outcome of using a procedure — success or failure. On failure, bumps the procedure version, logs the failure context, and creates an episode record. On success, records the validation. Use this whenever a procedure from memory_recall_procedures is attempted.\",\n parameters: Type.Object({\n procedureId: Type.String({ description: \"ID of the procedure that was used\" }),\n success: Type.Boolean({ description: \"true if the procedure succeeded, false if it failed\" }),\n context: Type.Optional(\n Type.String({\n description: \"What happened — error message, environment notes, or a summary of the outcome.\",\n }),\n ),\n failedAtStep: Type.Optional(\n Type.Number({\n description: \"If failure: which step number failed (1-based).\",\n }),\n ),\n duration: Type.Optional(\n Type.Number({\n description: \"Optional: how long the procedure took in milliseconds.\",\n }),\n ),\n tags: Type.Optional(\n Type.Array(Type.String(), {\n description: \"Optional tags to associate with the episode (e.g. 'production', 'doris').\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const { procedureId, success, context, failedAtStep, duration, tags } = params as {\n procedureId: string;\n success: boolean;\n context?: string;\n failedAtStep?: number;\n duration?: number;\n tags?: string[];\n };\n\n const result = factsDb.procedureFeedback({\n procedureId,\n success,\n context,\n failedAtStep,\n duration,\n tags,\n });\n\n if (!result) {\n return {\n content: [{ type: \"text\" as const, text: `Procedure not found: ${procedureId}` }],\n details: { success: false, error: \"procedure_not_found\" },\n };\n }\n\n const lines: string[] = [];\n if (success) {\n lines.push(\n `✅ Procedure validated (now ${result.successCount} successes, confidence: ${(result.confidence ?? 0).toFixed(2)})`,\n );\n } else {\n lines.push(\n `❌ Procedure failure recorded (now ${result.failureCount} failures, version ${result.version ?? 1}, confidence: ${(result.confidence ?? 0).toFixed(2)})`,\n );\n if (context) lines.push(` Context: ${context}`);\n if (result.avoidanceNotes && result.avoidanceNotes.length > 0) {\n lines.push(` Avoidance notes: ${result.avoidanceNotes.join(\"; \")}`);\n }\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n details: {\n success: true,\n procedureId: result.id,\n version: result.version,\n outcome: success ? \"success\" : \"failure\",\n successCount: result.successCount,\n failureCount: result.failureCount,\n successRate: result.successRate,\n },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-procedure-feedback\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_procedure_feedback\" },\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"register-recall-tools.js","names":[],"sources":["../../../tools/memory/register-recall-tools.ts"],"sourcesContent":["/**\n * Memory Tool Registrations\n *\n * Tool definitions for memory recall, storage, promotion, and deletion.\n * Extracted from index.ts for better modularity.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport { capturePluginError } from \"../../services/error-reporter.js\";\nimport { expandGraph, formatLinkPath } from \"../../services/graph-retrieval.js\";\nimport { filterByScope, mergeResults } from \"../../services/merge-results.js\";\nimport { formatNarrativeRange, recallNarrativeSummaries } from \"../../services/narrative-recall.js\";\nimport { QueryExpander } from \"../../services/query-expander.js\";\nimport {\n resolveConstrainedRetrievalPolicy,\n resolveExplicitDeepRetrievalPolicy,\n type ExplicitDeepRetrievalPolicy,\n} from \"../../services/retrieval-mode-policy.js\";\nimport { buildExplicitSemanticQueryVector, runExplicitDeepRetrieval } from \"../../services/retrieval-orchestrator.js\";\nimport type { MemoryEntry, ScopeFilter, SearchResult } from \"../../types/memory.js\";\nimport { getSessionLogFileSuffix } from \"../../utils/constants.js\";\nimport { parseSourceDate } from \"../../utils/dates.js\";\nimport { embedCallWithTimeoutAndRetry } from \"../../utils/embed-call.js\";\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerRecallTools(runtime: MemoryToolRuntime): void {\n const {\n factsDb,\n edictStore,\n vectorDb,\n cfg,\n embeddings,\n openai,\n credentialsDb,\n eventLog,\n narrativesDb,\n provenanceService,\n aliasDb,\n embeddingRegistry,\n verificationStore,\n lastProgressiveIndexIds,\n currentAgentIdRef,\n pendingLLMWarnings,\n variantQueue,\n buildToolScopeFilter,\n walWrite,\n walRemove,\n findSimilarByEmbedding,\n auditStore,\n api,\n auditAppend,\n agentIdForAudit,\n maybeRefreshProjectActiveTaskProjection,\n storeActiveCanonicalVector,\n storeRegistryEmbeddings,\n isEdictWriteToolEnabled,\n sanitizeScopeParam,\n } = runtime;\n\n api.registerTool(\n {\n name: \"memory_recall\",\n label: \"Memory Recall\",\n description: \"Search through long-term memories using both structured (exact) and semantic (fuzzy) search.\",\n parameters: Type.Object({\n query: Type.Optional(\n Type.String({\n description: \"Search query (omit when using id to fetch a specific memory)\",\n }),\n ),\n id: Type.Optional(\n Type.Union([Type.String(), Type.Number()], {\n description:\n \"Fetch a specific memory: fact id (UUID string) or 1-based index from the last progressive index (e.g. 1 for first listed memory).\",\n }),\n ),\n limit: Type.Optional(Type.Number({ description: \"Max results (default: 10)\" })),\n entity: Type.Optional(\n Type.String({\n description: \"Optional: filter by entity name for exact lookup\",\n }),\n ),\n tag: Type.Optional(\n Type.String({\n description: \"Optional: filter by topic tag (e.g. nibe, zigbee)\",\n }),\n ),\n category: Type.Optional(\n Type.String({\n description: \"Optional: constrain results to a specific category/type before ranking.\",\n }),\n ),\n source: Type.Optional(\n Type.String({\n description:\n \"Optional: constrain results to an exact fact source before ranking (e.g. conversation, ingest, reflection).\",\n }),\n ),\n verificationTier: Type.Optional(\n Type.String({\n description:\n \"Optional: constrain results to verified facts of a given tier before ranking (e.g. critical).\",\n }),\n ),\n validFromSec: Type.Optional(\n Type.Number({\n description:\n \"Optional: constrain results to facts whose valid_from is on/after this Unix timestamp before ranking.\",\n }),\n ),\n validUntilSec: Type.Optional(\n Type.Number({\n description:\n \"Optional: constrain results to facts whose validity extends past this Unix timestamp before ranking.\",\n }),\n ),\n sourceSession: Type.Optional(\n Type.String({\n description: \"Optional: constrain results to facts linked to a specific source session before ranking.\",\n }),\n ),\n retrievalMode: Type.Optional(\n Type.Union(\n [Type.Literal(\"interactive-recall\"), Type.Literal(\"explicit-deep\"), Type.Literal(\"constrained-recall\")],\n {\n description:\n 'Optional retrieval strategy selection. Use \"constrained-recall\" for filter → rank → hydrate searches inside a known boundary.',\n },\n ),\n ),\n includeSuperseded: Type.Optional(\n Type.Boolean({\n description: \"Include superseded (historical) facts in results. Default: only current facts.\",\n }),\n ),\n asOf: Type.Optional(\n Type.String({\n description:\n \"Point-in-time query: ISO date (YYYY-MM-DD) or epoch seconds. Return only facts valid at that time.\",\n }),\n ),\n userId: Type.Optional(\n Type.String({\n description:\n \"⚠️ SECURITY: Caller-controlled parameter. In multi-tenant environments, derive from authenticated identity instead. Include user-private memories for this user.\",\n }),\n ),\n agentId: Type.Optional(\n Type.String({\n description:\n \"⚠️ SECURITY: Caller-controlled parameter. In multi-tenant environments, derive from authenticated identity instead. Include agent-specific memories for this agent.\",\n }),\n ),\n sessionId: Type.Optional(\n Type.String({\n description:\n \"⚠️ SECURITY: Caller-controlled parameter. In multi-tenant environments, derive from authenticated identity instead. Include session-scoped memories for this session.\",\n }),\n ),\n confirmCrossTenantScope: Type.Optional(\n Type.Boolean({\n description:\n \"When multiAgent.trustToolScopeParams is true, set true to confirm intentional cross-tenant scope use of userId/agentId/sessionId (#874).\",\n }),\n ),\n includeCold: Type.Optional(\n Type.Boolean({\n description: \"Set true to include COLD tier (slower / deeper retrieval). Default: false (HOT + WARM only).\",\n }),\n ),\n expandGraph: Type.Optional(\n Type.Boolean({\n description:\n \"When true, run BFS graph expansion from the top results: related facts up to expandDepth hops are included. \" +\n \"Direct matches score higher than expanded ones. Default: false (or graphRetrieval.defaultExpand from config).\",\n }),\n ),\n expandDepth: Type.Optional(\n Type.Number({\n description:\n \"Number of BFS hops to expand when expandGraph=true (default: 2, max: graphRetrieval.maxExpandDepth from config).\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n return await memoryRecallImpl(params);\n } catch (err) {\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: undefined,\n outcome: \"failed\",\n error: err instanceof Error ? err.message : String(err),\n sessionId: api.context?.sessionId ?? undefined,\n });\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-recall\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_recall\" },\n );\n\n api.registerTool(\n {\n name: \"memory_recall_timeline\",\n label: \"Memory Recall Timeline\",\n description: \"Recall chronological summaries of recent sessions, decisions, and attempts.\",\n parameters: Type.Object({\n query: Type.Optional(\n Type.String({\n description: \"Optional topic or project query used to rank narrative summaries.\",\n }),\n ),\n sessionId: Type.Optional(\n Type.String({\n description:\n \"Optional session id to fetch a specific session narrative or event timeline. In multi-tenant environments, only pass a sessionId derived from the authenticated context; never accept arbitrary end-user input here, to avoid cross-session data exposure.\",\n }),\n ),\n limit: Type.Optional(\n Type.Number({\n description: \"Max summaries to return (default: 3).\",\n minimum: 1,\n maximum: 50,\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const MAX_SUMMARY_LIMIT = 50;\n const MIN_SUMMARY_LIMIT = 1;\n\n const query = typeof params.query === \"string\" && params.query.trim().length > 0 ? params.query.trim() : null;\n const requestedSessionId =\n typeof params.sessionId === \"string\" && params.sessionId.trim().length > 0 ? params.sessionId.trim() : null;\n const contextSessionId =\n typeof api.context?.sessionId === \"string\" && api.context.sessionId.trim().length > 0\n ? api.context.sessionId.trim()\n : null;\n if (!contextSessionId) {\n throw new Error(\"memory_recall_timeline requires an authenticated session context\");\n }\n if (requestedSessionId && requestedSessionId !== contextSessionId) {\n throw new Error(\"memory_recall_timeline sessionId must match the authenticated session context\");\n }\n const sessionId = contextSessionId;\n\n let limit = typeof params.limit === \"number\" && params.limit > 0 ? Math.floor(params.limit) : 3;\n limit = Math.min(MAX_SUMMARY_LIMIT, Math.max(MIN_SUMMARY_LIMIT, limit));\n const nowSec = Math.floor(Date.now() / 1000);\n const summaries = recallNarrativeSummaries({\n narrativesDb: narrativesDb ?? null,\n eventLog,\n query,\n sessionId,\n limit,\n nowSec,\n sinceSec: undefined,\n });\n\n if (summaries.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `No narrative summary found for session ${sessionId}.`,\n },\n ],\n details: { count: 0, narratives: [] },\n };\n }\n\n const lines = summaries.map((summary, index) => {\n const agentDir = currentAgentIdRef.value || \"main\";\n const logPath = `~/.openclaw/agents/${agentDir}/sessions/${summary.sessionId}${getSessionLogFileSuffix()}`;\n return (\n `${index + 1}. [${summary.source}] ${formatNarrativeRange(summary.periodStart, summary.periodEnd)} ` +\n `(sessionKey: ${summary.sessionId}, sessionLogPath: ${logPath})\\n${summary.text}`\n );\n });\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Found ${summaries.length} narrative summar${summaries.length === 1 ? \"y\" : \"ies\"}:\\n\\n${lines.join(\"\\n\\n\")}`,\n },\n ],\n details: {\n count: summaries.length,\n narratives: summaries.map((summary) => ({\n id: summary.id,\n source: summary.source,\n sessionId: summary.sessionId,\n sessionKey: summary.sessionId,\n sessionLogPath: `~/.openclaw/agents/${currentAgentIdRef.value || \"main\"}/sessions/${summary.sessionId}${getSessionLogFileSuffix()}`,\n periodStart: new Date(summary.periodStart * 1000).toISOString(),\n periodEnd: new Date(summary.periodEnd * 1000).toISOString(),\n tag: summary.tag,\n text: summary.text,\n score: Number(summary.score.toFixed(3)),\n })),\n },\n };\n },\n },\n { name: \"memory_recall_timeline\" },\n {\n name: \"memory_session_observability\",\n label: \"Memory Session Observability\",\n description:\n \"Get a unified session observability report: timeline of capture, recall, injection, suppressions, and used-vs-stored analysis. Use sessionId from the session context or pass a specific session id.\",\n parameters: Type.Object({\n sessionId: Type.Optional(\n Type.String({\n description: \"Session id to report on. Defaults to the current session from context.\",\n }),\n ),\n agentId: Type.Optional(\n Type.String({\n description: \"Agent id to scope the report to (optional).\",\n }),\n ),\n limit: Type.Optional(\n Type.Number({\n description: \"Max timeline entries per section (default: 50, max: 200).\",\n minimum: 1,\n maximum: 200,\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const sessionId =\n typeof params.sessionId === \"string\" && params.sessionId.trim().length > 0 ? params.sessionId.trim() : null;\n const agentId =\n typeof params.agentId === \"string\" && params.agentId.trim().length > 0 ? params.agentId.trim() : null;\n const limit =\n typeof params.limit === \"number\" && params.limit > 0 ? Math.min(200, Math.floor(params.limit)) : 50;\n\n // Build report synchronously (factsDb / auditStore are sync interfaces)\n let report;\n try {\n const { buildSessionObservabilityReport } = await import(\"../../services/session-observability.js\");\n report = await buildSessionObservabilityReport({\n factsDb: factsDb as import(\"../../backends/facts-db.js\").FactsDB,\n eventLog: eventLog as import(\"../../backends/event-log.js\").EventLog | null,\n narrativesDb: narrativesDb as import(\"../../backends/narratives-db.js\").NarrativesDB | null,\n auditStore: auditStore ?? null,\n sessionId,\n agentId,\n limit,\n });\n } catch (err) {\n return {\n content: [{ type: \"text\" as const, text: `Failed to build session report: ${String(err)}` }],\n details: { error: String(err) },\n };\n }\n\n // Human-readable summary line\n const summaryText =\n report.summary ||\n `Session ${sessionId ?? \"unknown\"}: ${report.timeline.length} timeline entries, ` +\n `${report.capture.factsStored} stored, ${report.capture.duplicatesSuppressed} suppressed, ` +\n `${report.recall.injectedCount} injected.`;\n\n const detail = {\n sessionId: report.sessionId,\n agentId: report.agentId,\n windowStart: report.windowStart,\n windowEnd: report.windowEnd,\n timelineCount: report.timeline.length,\n capture: {\n factsStored: report.capture.factsStored,\n factsUpdated: report.capture.factsUpdated,\n duplicatesSuppressed: report.capture.duplicatesSuppressed,\n noopSkipped: report.capture.noopSkipped,\n errorsEncountered: report.capture.errorsEncountered,\n entitiesExtracted: report.capture.entitiesExtracted,\n episodesRecorded: report.capture.episodesRecorded,\n proceduresLearned: report.capture.proceduresLearned,\n },\n recall: {\n candidatesFound: report.recall.candidatesFound,\n injectedCount: report.recall.injectedCount,\n omittedCount: report.recall.omittedCount,\n strategies: report.recall.strategies,\n directiveMatches: report.recall.directiveMatches,\n suppressionReasons: report.recall.suppressionReasons,\n },\n injection: {\n totalChars: report.injection.totalChars,\n totalTokensEstimate: report.injection.totalTokensEstimate,\n blocksInjected: report.injection.blocksInjected,\n budgetTokens: report.injection.budgetTokens,\n budgetUsedFraction: Math.round(report.injection.budgetUsedFraction * 100) / 100,\n },\n suppressions: report.suppressions,\n timeline: report.timeline.slice(0, limit).map((e) => ({\n timestamp: e.timestamp,\n kind: e.kind,\n label: e.label,\n description: e.description,\n outcome: e.outcome,\n score: e.score,\n })),\n };\n\n return {\n content: [{ type: \"text\" as const, text: summaryText }],\n details: detail,\n };\n },\n },\n );\n\n // Internal implementation so we can return from the try block\n async function memoryRecallImpl(params: Record<string, unknown>) {\n const recallStartedAt = Date.now();\n const {\n query: queryParam,\n id: idParam,\n limit = 10,\n entity: entityParam,\n tag: tagParam,\n category: categoryParam,\n source: sourceParam,\n verificationTier: verificationTierParam,\n validFromSec,\n validUntilSec,\n sourceSession: sourceSessionParam,\n retrievalMode,\n includeSuperseded = false,\n asOf: asOfParam,\n includeCold = false,\n userId,\n agentId,\n sessionId,\n confirmCrossTenantScope,\n expandGraph: expandGraphParam,\n expandDepth: expandDepthParam,\n } = params as {\n query?: string;\n id?: string | number;\n limit?: number;\n entity?: string;\n tag?: string;\n category?: string;\n source?: string;\n verificationTier?: string;\n validFromSec?: number;\n validUntilSec?: number;\n sourceSession?: string;\n retrievalMode?: \"interactive-recall\" | \"explicit-deep\" | \"constrained-recall\";\n includeSuperseded?: boolean;\n asOf?: string;\n includeCold?: boolean;\n userId?: string;\n agentId?: string;\n sessionId?: string;\n confirmCrossTenantScope?: boolean;\n expandGraph?: boolean;\n expandDepth?: number;\n };\n const normalizeOptionalString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n };\n const entity = normalizeOptionalString(entityParam);\n const tag = normalizeOptionalString(tagParam);\n const category = normalizeOptionalString(categoryParam);\n const source = normalizeOptionalString(sourceParam);\n const verificationTier = normalizeOptionalString(verificationTierParam);\n const sourceSession = normalizeOptionalString(sourceSessionParam);\n const asOfSec = asOfParam != null && asOfParam !== \"\" ? parseSourceDate(asOfParam) : undefined;\n\n // Scope filtering with auto-detection\n // ⚠️ SECURITY WARNING: userId/agentId/sessionId are caller-controlled parameters.\n // In multi-tenant production environments, these should be derived from authenticated\n // identity (via autoRecall.scopeFilter config) rather than accepted as tool parameters.\n // Accepting arbitrary scope filters allows users to access other users' private memories.\n // See docs/MEMORY-SCOPING.md \"Secure Multi-Tenant Setup\" for proper implementation.\n const scopeFilter = buildToolScopeFilter(\n {\n userId: sanitizeScopeParam(\"userId\", userId),\n agentId: sanitizeScopeParam(\"agentId\", agentId),\n sessionId: sanitizeScopeParam(\"sessionId\", sessionId),\n confirmCrossTenantScope,\n },\n currentAgentIdRef.value,\n cfg,\n );\n const logRecall = (hit: boolean) => {\n const maybeFactsDb = factsDb as { logRecall?: (hit: boolean) => void };\n if (typeof maybeFactsDb.logRecall === \"function\") {\n try {\n maybeFactsDb.logRecall(hit);\n } catch {\n // Non-fatal: recall logging should never break recall\n }\n }\n };\n\n // Fetch by id (fact id or 1-based index from last progressive index)\n if (idParam !== undefined && idParam !== null && idParam !== \"\") {\n let factId: string | null = null;\n if (typeof idParam === \"number\") {\n const idx = Math.floor(idParam);\n if (idx >= 1 && idx <= lastProgressiveIndexIds.length) {\n factId = lastProgressiveIndexIds[idx - 1] ?? null;\n }\n } else if (typeof idParam === \"string\" && idParam.trim().length > 0) {\n const trimmed = idParam.trim();\n // Check if it's a numeric string (progressive index position)\n if (/^\\d+$/.test(trimmed)) {\n const idx = Number.parseInt(trimmed, 10);\n if (idx >= 1 && idx <= lastProgressiveIndexIds.length) {\n factId = lastProgressiveIndexIds[idx - 1] ?? null;\n }\n } else {\n // Treat as fact ID\n factId = trimmed;\n }\n }\n if (factId) {\n const getByIdOpts = { asOf: asOfSec, scopeFilter };\n const entry = factsDb.getById(\n factId,\n asOfSec != null || scopeFilter ? (getByIdOpts as { asOf?: number; scopeFilter?: ScopeFilter }) : undefined,\n );\n if (entry) {\n // Access boost — update recall_count and last_accessed on fetch by id\n factsDb.refreshAccessedFacts([entry.id]);\n logRecall(true);\n const text = `[${entry.category}] ${entry.text}`;\n const whyLine = entry.why ? `\\nWhy: ${entry.why}` : \"\";\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: `memory #${entry.id}`,\n outcome: \"success\",\n durationMs: Date.now() - recallStartedAt,\n sessionId: api.context?.sessionId ?? undefined,\n });\n return {\n content: [\n {\n type: \"text\",\n text: `Memory (id: ${entry.id}):\\n\\n${text}${whyLine}`,\n },\n ],\n details: {\n count: 1,\n memories: [\n {\n id: entry.id,\n text: entry.text,\n why: entry.why ?? undefined,\n category: entry.category,\n entity: entry.entity,\n importance: entry.importance,\n score: 1,\n backend: \"sqlite\" as const,\n tags: entry.tags?.length ? entry.tags : undefined,\n sourceDate: entry.sourceDate\n ? new Date(entry.sourceDate * 1000).toISOString().slice(0, 10)\n : undefined,\n },\n ],\n },\n };\n }\n }\n logRecall(false);\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: typeof idParam === \"number\" ? `index ${idParam}` : `id ${idParam}`,\n outcome: \"partial\",\n durationMs: Date.now() - recallStartedAt,\n sessionId: api.context?.sessionId ?? undefined,\n });\n return {\n content: [\n {\n type: \"text\",\n text:\n typeof idParam === \"number\"\n ? `No memory at index ${idParam}. Use a number between 1 and ${lastProgressiveIndexIds.length} from the index, or provide a fact id.`\n : `No memory found with id: ${idParam}.`,\n },\n ],\n details: { count: 0 },\n };\n }\n\n const query = typeof queryParam === \"string\" && queryParam.trim().length > 0 ? queryParam.trim() : null;\n if (!query) {\n logRecall(false);\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: undefined,\n outcome: \"partial\",\n durationMs: Date.now() - recallStartedAt,\n sessionId: api.context?.sessionId ?? undefined,\n });\n return {\n content: [\n {\n type: \"text\",\n text: \"Provide a search query or an id (fact id or index from the memory index) to recall memories.\",\n },\n ],\n details: { count: 0 },\n };\n }\n\n const tierFilter: \"warm\" | \"all\" = includeCold ? \"all\" : \"warm\";\n const recallOpts = {\n tag,\n includeSuperseded,\n tierFilter,\n scopeFilter,\n ...(asOfSec != null ? { asOf: asOfSec } : {}),\n };\n\n const hasAdditionalConstrainedFilters = Boolean(\n category || source || verificationTier || validFromSec != null || validUntilSec != null || sourceSession,\n );\n const shouldUseConstrainedMode =\n retrievalMode === \"constrained-recall\" || (!retrievalMode && hasAdditionalConstrainedFilters);\n const effectiveMode = shouldUseConstrainedMode ? \"constrained-recall\" : retrievalMode;\n const constrainedFilters = shouldUseConstrainedMode\n ? {\n ...(entity ? { entity } : {}),\n ...(tag ? { tag } : {}),\n ...(category ? { category } : {}),\n ...(source ? { source } : {}),\n ...(verificationTier ? { verificationTier } : {}),\n ...(typeof validFromSec === \"number\" ? { validFromSec: Math.floor(validFromSec) } : {}),\n ...(typeof validUntilSec === \"number\" ? { validUntilSec: Math.floor(validUntilSec) } : {}),\n ...(sourceSession ? { sourceSession } : {}),\n }\n : undefined;\n\n // Entity-targeted lookup is useful for legacy explicit recall, but it bypasses\n // filter → rank → hydrate semantics, so disable it in constrained mode.\n let entityResults: SearchResult[] = [];\n if (entity && !shouldUseConstrainedMode) {\n entityResults = factsDb.lookup(entity, undefined, tag, { ...recallOpts, limit: 100 });\n }\n\n // Explicit/deep retrieval owns richer semantic prep, including optional HyDE.\n let queryVector: number[] | null = null;\n let semanticWarning: string | null = null;\n\n // RRF multi-strategy retrieval pipeline (Issue #152)\n // Legacy tag-only recall skips semantic search; constrained mode keeps semantic ranking\n // because tag/entity/category/etc. are applied before ranking inside the candidate set.\n let results: SearchResult[] = [];\n try {\n const useLegacyTagShortcut = Boolean(tag && !shouldUseConstrainedMode);\n const rrfStrategies = useLegacyTagShortcut\n ? cfg.retrieval.strategies.filter((s) => s !== \"semantic\")\n : cfg.retrieval.strategies;\n const rrfConfig = { ...cfg.retrieval, strategies: rrfStrategies };\n // interactive-recall uses a different policy with its own vector prep; skip for other modes\n const effectivePolicy =\n effectiveMode !== \"interactive-recall\"\n ? effectiveMode === \"constrained-recall\"\n ? resolveConstrainedRetrievalPolicy(rrfConfig)\n : resolveExplicitDeepRetrievalPolicy(rrfConfig)\n : undefined;\n if (!useLegacyTagShortcut && effectivePolicy !== undefined) {\n const vectorPrep = await buildExplicitSemanticQueryVector({\n query,\n cfg,\n embeddings,\n openai,\n pendingLLMWarnings,\n logger: api.logger,\n policy: effectivePolicy as ExplicitDeepRetrievalPolicy,\n });\n queryVector = vectorPrep.queryVector;\n semanticWarning = vectorPrep.warning;\n }\n const queryExpander =\n cfg.queryExpansion?.enabled && rrfStrategies.includes(\"semantic\")\n ? new QueryExpander(cfg.queryExpansion, openai)\n : null;\n const embedFn =\n queryVector != null\n ? (text: string) =>\n embedCallWithTimeoutAndRetry(() => embeddings.embed(text), \"memory-tools:rrf-deep-retrieval\")\n : null;\n const rrfOutput = await runExplicitDeepRetrieval(query, queryVector, factsDb.getRawDb(), vectorDb, factsDb, {\n config: rrfConfig,\n ...(effectiveMode !== \"interactive-recall\" && effectivePolicy\n ? { policy: effectivePolicy }\n : effectiveMode === \"interactive-recall\"\n ? { mode: effectiveMode as \"interactive-recall\" }\n : {}),\n ...(useLegacyTagShortcut ? { tagFilter: tag ?? undefined } : {}),\n ...(constrainedFilters ? { constrainedFilters } : {}),\n includeSuperseded,\n scopeFilter,\n asOf: asOfSec ?? undefined,\n graphHubDegreeCap: cfg.graph.hubDegreeCap,\n graphHubScorePenalty: cfg.graph.hubScorePenalty,\n aliasDb: cfg.aliases?.enabled ? aliasDb : null,\n clustersConfig: cfg.clusters,\n embeddingRegistry: embeddingRegistry ?? null,\n factsDbForEmbeddings: factsDb,\n queryExpander: queryExpander ?? null,\n embedFn,\n rerankingConfig: cfg.reranking,\n rerankingOpenai: openai,\n adaptiveOpenai: cfg.documentGrading?.enabled ? openai : undefined,\n documentGradingConfig: cfg.documentGrading,\n });\n\n // Merge entity-lookup results first, then append RRF results (deduped).\n // When packed is non-empty, only include fused results whose factId was packed\n // (avoids including items beyond the token budget). Fall back to the full fused\n // list when packed is empty (e.g. budget too small to pack any).\n // Use a factId→entry Map so entry lookup never depends on loop index alignment.\n const seenIds = new Set<string>(entityResults.map((r) => r.entry.id));\n results = [...entityResults];\n const entryByFactId = new Map<string, MemoryEntry>();\n for (let i = 0; i < rrfOutput.fused.length; i++) {\n const e = rrfOutput.entries[i];\n if (e) entryByFactId.set(rrfOutput.fused[i].factId, e);\n }\n const packedFactIdSet = rrfOutput.packed.length > 0 ? new Set(rrfOutput.packedFactIds) : null;\n for (const fusedResult of rrfOutput.fused) {\n if (packedFactIdSet && !packedFactIdSet.has(fusedResult.factId)) continue;\n if (seenIds.has(fusedResult.factId)) continue;\n const entry = entryByFactId.get(fusedResult.factId);\n if (entry) {\n results.push({ entry, score: fusedResult.finalScore, backend: \"sqlite\" });\n seenIds.add(fusedResult.factId);\n }\n }\n results.sort((a, b) => b.score - a.score);\n results = results.slice(0, limit);\n } catch (err) {\n // Fallback: use legacy FTS + vector merge if RRF pipeline fails\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"search\",\n operation: \"rrf-pipeline\",\n phase: \"runtime\",\n });\n api.logger.warn(`memory-hybrid: RRF pipeline failed, falling back to legacy merge: ${err}`);\n const ftsResults = factsDb.search(query, limit, {\n ...recallOpts,\n reinforcementBoost: cfg.distill?.reinforcementBoost ?? 0.1,\n diversityWeight: cfg.reinforcement?.diversityWeight ?? 1.0,\n });\n let lanceResults: SearchResult[] = [];\n if (queryVector) {\n lanceResults = await vectorDb.search(queryVector, limit * 3, 0.3);\n lanceResults = filterByScope(lanceResults, (id, opts) => factsDb.getById(id, opts), scopeFilter);\n }\n results = mergeResults([...entityResults, ...ftsResults], lanceResults, limit, factsDb);\n }\n\n // Exclude COLD tier when includeCold is false (Lance results may include cold facts)\n if (!includeCold && results.length > 0) {\n const filtered: SearchResult[] = [];\n for (const r of results) {\n const full = factsDb.getById(r.entry.id);\n if (full && full.tier !== \"cold\") filtered.push({ ...r, entry: full });\n }\n results = filtered.slice(0, limit);\n }\n\n // When asOf is set, filter so only facts valid at that time (Lance results lack temporal filter)\n if (asOfSec != null && results.length > 0) {\n const filtered: SearchResult[] = [];\n for (const r of results) {\n const full = factsDb.getById(r.entry.id, { asOf: asOfSec });\n if (full) filtered.push({ ...r, entry: full });\n }\n results = filtered.slice(0, limit);\n }\n\n // Resolve whether to run GraphRAG expansion for this call.\n const useExpandGraph =\n cfg.graphRetrieval.enabled &&\n cfg.graph.enabled &&\n results.length > 0 &&\n (expandGraphParam ?? cfg.graphRetrieval.defaultExpand);\n\n // GraphRAG expansion — BFS from seed results with path tracking and ranked scoring.\n // When expandGraph=true, replaces the legacy flat-score graph traversal.\n type ExpandedMeta = { expansionSource: \"direct\" | \"graph\"; hopCount: number; linkPath: string } | undefined;\n const expansionMeta = new Map<string, ExpandedMeta>();\n\n if (useExpandGraph) {\n const rawDepth = typeof expandDepthParam === \"number\" ? expandDepthParam : cfg.retrieval.graphWalkDepth;\n const depth = Math.min(Math.max(0, rawDepth), cfg.graphRetrieval.maxExpandDepth);\n const seedInputs = results.map((r) => ({ factId: r.entry.id, score: r.score, entry: r.entry }));\n const originalBackendMap = new Map<string, \"sqlite\" | \"lancedb\">();\n for (const r of results) {\n originalBackendMap.set(r.entry.id, r.backend);\n }\n const { results: expanded } = expandGraph(factsDb, seedInputs, {\n maxDepth: depth,\n maxExpandedResults: cfg.graphRetrieval.maxExpandedResults,\n scopeFilter: scopeFilter ?? undefined,\n asOf: asOfSec ?? undefined,\n hubDegreeCap: cfg.graph.hubDegreeCap,\n hubScorePenalty: cfg.graph.hubScorePenalty,\n });\n\n // Re-build results from expanded output (preserves scores and dedup).\n const newResults: SearchResult[] = [];\n for (const e of expanded) {\n const backend = e.expansionSource === \"direct\" ? (originalBackendMap.get(e.factId) ?? \"sqlite\") : \"sqlite\";\n newResults.push({ entry: e.entry, score: e.score, backend });\n expansionMeta.set(e.factId, {\n expansionSource: e.expansionSource,\n hopCount: e.hopCount,\n linkPath: formatLinkPath(e.linkPath),\n });\n }\n newResults.sort((a, b) => b.score - a.score);\n results = newResults.slice(0, limit);\n } else if (cfg.graph.enabled && cfg.graph.useInRecall && results.length > 0) {\n // Legacy flat-score graph traversal (backward compatible, no path annotation).\n const initialIds = new Set(results.map((r) => r.entry.id));\n const connectedIds = factsDb.getConnectedFactIds([...initialIds], cfg.graph.maxTraversalDepth, {\n hubDegreeCap: cfg.graph.hubDegreeCap,\n });\n const extraIds = connectedIds.filter((id) => !initialIds.has(id));\n const getByIdOpts = asOfSec != null || scopeFilter ? { asOf: asOfSec, scopeFilter } : undefined;\n for (const id of extraIds) {\n const entry = factsDb.getById(id, getByIdOpts as { asOf?: number; scopeFilter?: ScopeFilter });\n if (entry) {\n results.push({ entry, score: 0.45, backend: \"sqlite\" });\n }\n }\n results.sort((a, b) => b.score - a.score);\n results = results.slice(0, limit);\n }\n\n const retrievalExplanation = (() => {\n if (!shouldUseConstrainedMode || !constrainedFilters) return undefined;\n const filterPairs = Object.entries(constrainedFilters)\n .filter(([, value]) => value !== undefined && value !== null && value !== \"\")\n .map(([key, value]) => `${key}=${String(value)}`);\n return {\n mode: \"constrained-recall\" as const,\n contract: \"filter → rank → hydrate\",\n filterBasis: filterPairs,\n rankBasis:\n \"semantic rank inside the structured candidate set (with hydrated provenance/context in the final result)\",\n };\n })();\n const retrievalExplanationText = retrievalExplanation\n ? `Retrieval: constrained-recall (filter → rank → hydrate)\\nFilter basis: ${retrievalExplanation.filterBasis.join(\", \")}\\nRank basis: ${retrievalExplanation.rankBasis}`\n : undefined;\n\n if (results.length === 0) {\n logRecall(false);\n const noResultsText = semanticWarning\n ? `No relevant memories found.\\n\\n⚠️ ${semanticWarning}`\n : \"No relevant memories found.\";\n return {\n content: [\n {\n type: \"text\",\n text: retrievalExplanationText ? `${retrievalExplanationText}\\n\\n${noResultsText}` : noResultsText,\n },\n ],\n details: {\n count: 0,\n warning: semanticWarning ?? undefined,\n retrieval: retrievalExplanation,\n },\n };\n }\n\n const contradictionStatus = new Map<string, boolean>();\n for (const r of results) {\n contradictionStatus.set(r.entry.id, factsDb.isContradicted(r.entry.id));\n }\n\n // Check integrity for verified facts (Issue #162): flag tampered results.\n const tamperStatus = new Map<string, boolean>();\n if (verificationStore && cfg.verification.enabled) {\n for (const r of results) {\n try {\n const report = verificationStore.checkIntegrity(r.entry.id);\n if (report.checked > 0 && !report.valid) {\n tamperStatus.set(r.entry.id, true);\n }\n } catch {\n // Don't block retrieval on integrity check failure\n }\n }\n }\n\n logRecall(true);\n const text = results\n .map((r, i) => {\n const contradicted = contradictionStatus.get(r.entry.id) ?? false;\n const contradictedPrefix = contradicted ? \"[⚠️ CONTRADICTED] \" : \"\";\n const tampered = tamperStatus.get(r.entry.id) ?? false;\n const tamperedPrefix = tampered ? \"[⚠️ TAMPERED] \" : \"\";\n const meta = expansionMeta.get(r.entry.id);\n const expansionSuffix =\n meta && meta.expansionSource === \"graph\"\n ? ` [graph+${meta.hopCount}hop${meta.linkPath ? `: ${meta.linkPath}` : \"\"}]`\n : \"\";\n const whySuffix = r.entry.why ? `\\n Why: ${r.entry.why}` : \"\";\n return `${i + 1}. [${r.backend}/${r.entry.category}] ${contradictedPrefix}${tamperedPrefix}${r.entry.text} (${(r.score * 100).toFixed(0)}%)${expansionSuffix}${whySuffix}`;\n })\n .join(\"\\n\");\n\n const sanitized = results.map((r) => {\n const meta = expansionMeta.get(r.entry.id);\n return {\n id: r.entry.id,\n text: r.entry.text,\n why: r.entry.why ?? undefined,\n category: r.entry.category,\n entity: r.entry.entity,\n importance: r.entry.importance,\n score: r.score,\n backend: r.backend,\n tags: r.entry.tags?.length ? r.entry.tags : undefined,\n sourceDate: r.entry.sourceDate ? new Date(r.entry.sourceDate * 1000).toISOString().slice(0, 10) : undefined,\n contradicted: contradictionStatus.get(r.entry.id) || undefined,\n accessCount: r.entry.accessCount ?? 0,\n lastAccessedAt: r.entry.lastAccessedAt ?? null,\n ...(meta\n ? {\n expansionSource: meta.expansionSource,\n hopCount: meta.hopCount,\n linkPath: meta.linkPath || undefined,\n }\n : {}),\n };\n });\n\n auditAppend({\n agentId: agentIdForAudit(),\n action: \"memory_recall\",\n target: query ? `query=\"${query.slice(0, 160)}\"` : undefined,\n outcome: \"success\",\n durationMs: Date.now() - recallStartedAt,\n sessionId: api.context?.sessionId ?? undefined,\n context: { count: results.length },\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `${retrievalExplanationText ? `${retrievalExplanationText}\\n\\n` : \"\"}Found ${results.length} memories:\\n\\n${text}${semanticWarning ? `\\n\\n⚠️ ${semanticWarning}` : \"\"}`,\n },\n ],\n details: {\n count: results.length,\n memories: sanitized,\n warning: semanticWarning ?? undefined,\n retrieval: retrievalExplanation,\n },\n };\n }\n\n if (cfg.procedures.enabled) {\n api.registerTool(\n {\n name: \"memory_recall_procedures\",\n label: \"Recall Procedures\",\n description:\n \"Search for learned procedures (positive: what worked; negative: known failures) matching a task description.\",\n parameters: Type.Object({\n taskDescription: Type.String({\n description: \"What you are trying to do (e.g. 'check Moltbook', 'HA health checks')\",\n }),\n limit: Type.Optional(Type.Number({ description: \"Max procedures to return (default: 5)\" })),\n agentId: Type.Optional(\n Type.String({\n description: \"⚠️ SECURITY: Caller-controlled parameter. Filter procedures for specific agent.\",\n }),\n ),\n userId: Type.Optional(\n Type.String({\n description: \"⚠️ SECURITY: Caller-controlled parameter. Filter procedures for specific user.\",\n }),\n ),\n sessionId: Type.Optional(\n Type.String({\n description: \"⚠️ SECURITY: Caller-controlled parameter. Filter procedures for specific session.\",\n }),\n ),\n confirmCrossTenantScope: Type.Optional(\n Type.Boolean({\n description:\n \"When multiAgent.trustToolScopeParams is true, set true to confirm intentional cross-tenant scope use of userId/agentId/sessionId (#874).\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const {\n taskDescription,\n limit = 5,\n agentId,\n userId,\n sessionId,\n confirmCrossTenantScope,\n } = params as {\n taskDescription: string;\n limit?: number;\n agentId?: string;\n userId?: string;\n sessionId?: string;\n confirmCrossTenantScope?: boolean;\n };\n const q =\n typeof taskDescription === \"string\" && taskDescription.trim().length > 0 ? taskDescription.trim() : null;\n if (!q) {\n return {\n content: [{ type: \"text\" as const, text: \"Provide a task description to recall procedures.\" }],\n details: { count: 0 },\n };\n }\n\n // Build scope filter (same logic as memory_recall)\n const scopeFilter = buildToolScopeFilter(\n {\n userId: sanitizeScopeParam(\"userId\", userId),\n agentId: sanitizeScopeParam(\"agentId\", agentId),\n sessionId: sanitizeScopeParam(\"sessionId\", sessionId),\n confirmCrossTenantScope,\n },\n currentAgentIdRef.value,\n cfg,\n );\n\n const procedures = factsDb.searchProcedures(\n q,\n limit,\n cfg.distill?.reinforcementProcedureBoost ?? 0.1,\n scopeFilter,\n );\n const negatives = factsDb.getNegativeProceduresMatching(q, 3, scopeFilter);\n const lines: string[] = [];\n const positiveList = procedures.filter((p) => p.procedureType === \"positive\");\n if (positiveList.length > 0) {\n lines.push(\"Last time this worked:\");\n for (const p of positiveList) {\n let recipe: unknown;\n try {\n recipe = JSON.parse(p.recipeJson);\n } catch (err) {\n capturePluginError(err as Error, {\n operation: \"parse-recipe\",\n severity: \"info\",\n subsystem: \"tools\",\n });\n recipe = [];\n }\n const steps = Array.isArray(recipe)\n ? (recipe as Array<{ tool?: string; args?: Record<string, unknown> }>)\n .map(\n (s) =>\n s.tool +\n (s.args && Object.keys(s.args).length > 0 ? `(${JSON.stringify(s.args).slice(0, 80)}…)` : \"\"),\n )\n .join(\" → \")\n : p.recipeJson.slice(0, 200);\n const rate = p.successRate !== undefined ? `, rate ${(p.successRate * 100).toFixed(0)}%` : \"\";\n const ver = p.version !== undefined ? `, v${p.version}` : \"\";\n const outcome = p.lastOutcome === \"failure\" ? \" ⚠️\" : p.lastOutcome === \"success\" ? \" ✅\" : \"\";\n lines.push(\n `- ${p.taskPattern.slice(0, 80)}…: ${steps} (validated ${p.successCount}x${rate}${ver}${outcome})`,\n );\n if (p.avoidanceNotes && p.avoidanceNotes.length > 0) {\n for (const note of p.avoidanceNotes.slice(0, 2)) {\n lines.push(` ⚠ ${note}`);\n }\n }\n }\n }\n if (negatives.length > 0) {\n lines.push(\"\");\n lines.push(\"⚠️ Known issues (avoid):\");\n for (const p of negatives) {\n let recipe: unknown;\n try {\n recipe = JSON.parse(p.recipeJson);\n } catch (err) {\n capturePluginError(err as Error, {\n operation: \"parse-recipe\",\n severity: \"info\",\n subsystem: \"tools\",\n });\n recipe = [];\n }\n const steps = Array.isArray(recipe)\n ? (recipe as Array<{ tool?: string }>)\n .map((s) => s.tool)\n .filter(Boolean)\n .join(\" → \")\n : \"\";\n const ver = p.version !== undefined ? ` (v${p.version})` : \"\";\n lines.push(`- ${p.taskPattern.slice(0, 80)}… ${steps ? `(${steps})` : \"\"}${ver}`);\n if (p.avoidanceNotes && p.avoidanceNotes.length > 0) {\n for (const note of p.avoidanceNotes.slice(0, 2)) {\n lines.push(` ⚠ ${note}`);\n }\n }\n }\n }\n if (lines.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: \"No procedures found for this task.\" }],\n details: { count: 0 },\n };\n }\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n details: {\n count: positiveList.length + negatives.length,\n procedures: positiveList.length,\n warnings: negatives.length,\n },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-recall-procedures\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_recall_procedures\" },\n );\n\n // Procedure feedback loop (#782)\n api.registerTool(\n {\n name: \"memory_procedure_feedback\",\n label: \"Procedure Feedback\",\n description:\n \"Record the outcome of using a procedure — success or failure. On failure, bumps the procedure version, logs the failure context, and creates an episode record. On success, records the validation. Use this whenever a procedure from memory_recall_procedures is attempted.\",\n parameters: Type.Object({\n procedureId: Type.String({ description: \"ID of the procedure that was used\" }),\n success: Type.Boolean({ description: \"true if the procedure succeeded, false if it failed\" }),\n context: Type.Optional(\n Type.String({\n description: \"What happened — error message, environment notes, or a summary of the outcome.\",\n }),\n ),\n failedAtStep: Type.Optional(\n Type.Number({\n description: \"If failure: which step number failed (1-based).\",\n }),\n ),\n duration: Type.Optional(\n Type.Number({\n description: \"Optional: how long the procedure took in milliseconds.\",\n }),\n ),\n tags: Type.Optional(\n Type.Array(Type.String(), {\n description: \"Optional tags to associate with the episode (e.g. 'production', 'doris').\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const { procedureId, success, context, failedAtStep, duration, tags } = params as {\n procedureId: string;\n success: boolean;\n context?: string;\n failedAtStep?: number;\n duration?: number;\n tags?: string[];\n };\n\n const result = factsDb.procedureFeedback({\n procedureId,\n success,\n context,\n failedAtStep,\n duration,\n tags,\n });\n\n if (!result) {\n return {\n content: [{ type: \"text\" as const, text: `Procedure not found: ${procedureId}` }],\n details: { success: false, error: \"procedure_not_found\" },\n };\n }\n\n const lines: string[] = [];\n if (success) {\n lines.push(\n `✅ Procedure validated (now ${result.successCount} successes, confidence: ${(result.confidence ?? 0).toFixed(2)})`,\n );\n } else {\n lines.push(\n `❌ Procedure failure recorded (now ${result.failureCount} failures, version ${result.version ?? 1}, confidence: ${(result.confidence ?? 0).toFixed(2)})`,\n );\n if (context) lines.push(` Context: ${context}`);\n if (result.avoidanceNotes && result.avoidanceNotes.length > 0) {\n lines.push(` Avoidance notes: ${result.avoidanceNotes.join(\"; \")}`);\n }\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n details: {\n success: true,\n procedureId: result.id,\n version: result.version,\n outcome: success ? \"success\" : \"failure\",\n successCount: result.successCount,\n failureCount: result.failureCount,\n successRate: result.successRate,\n },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-procedure-feedback\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_procedure_feedback\" },\n );\n }\n}\n"],"mappings":"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"}
|