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":"goal-tools.js","names":[],"sources":["../../tools/goal-tools.ts"],"sourcesContent":["import { appendFile, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n/**\n * Goal stewardship tools — see docs/GOAL-STEWARDSHIP-DESIGN.md\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ClawdbotPluginApi } from \"openclaw/plugin-sdk/core\";\nimport type { EventLog } from \"../backends/event-log.js\";\nimport type { FactsDB } from \"../backends/facts-db.js\";\nimport type { HybridMemoryConfig } from \"../config.js\";\nimport { capturePluginError } from \"../services/error-reporter.js\";\nimport {\n circuitBreakerShortBlocker,\n composeCircuitBreakerHumanSummary,\n computeCircuitBreakerStateAfterAssess,\n evaluateCircuitBreakerTrip,\n} from \"../services/goal-circuit-breaker.js\";\nimport type { GoalHistoryEntry } from \"../services/goal-stewardship-types.js\";\nimport {\n type GoalVerification,\n createGoal,\n goalStewardshipDefaultsFromConfig,\n isGlobalRateLimited,\n isTerminalStatus,\n listActiveGoals,\n recordGoalDispatch,\n resolveGoalId,\n terminateGoal,\n updateGoal,\n} from \"../services/goal-stewardship.js\";\nimport { stringEnum } from \"../utils/typebox.js\";\n\nexport interface GoalToolsContext {\n cfg: HybridMemoryConfig;\n goalsDir: string;\n workspaceRoot: string;\n /** Absolute path to ACTIVE-TASKS.md (for task hygiene tools). */\n resolvedActiveTaskPath: string;\n factsDb: FactsDB | null;\n eventLog: EventLog | null;\n memoryDir: string;\n}\n\nconst PRIORITIES = [\"critical\", \"high\", \"normal\", \"low\"] as const;\n\nasync function flushGoalOutcomeToMemory(memoryDir: string, title: string, lines: string[]): Promise<void> {\n const date = new Date().toISOString().slice(0, 10);\n const filePath = join(memoryDir, `${date}.md`);\n await mkdir(memoryDir, { recursive: true });\n const block = [\"\", `## ${title} — ${date}`, \"\", ...lines, \"\"].join(\"\\n\");\n await appendFile(filePath, block, \"utf-8\").catch((err) => {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"goal-tools\",\n operation: \"flushGoalOutcomeToMemory\",\n });\n });\n}\n\nexport function registerGoalTools(ctx: GoalToolsContext, api: ClawdbotPluginApi): void {\n const { cfg, goalsDir, factsDb, eventLog, memoryDir } = ctx;\n const gs = cfg.goalStewardship;\n const defaults = goalStewardshipDefaultsFromConfig(gs);\n const notEnabled = () => ({\n content: [\n {\n type: \"text\" as const,\n text: \"Goal stewardship is disabled. Set goalStewardship.enabled: true in plugin config.\",\n },\n ],\n details: { error: \"goal_stewardship_disabled\" },\n });\n\n api.registerTool(\n {\n name: \"goal_register\",\n label: \"Register Goal\",\n description: \"Register a long-running goal with acceptance criteria.\",\n parameters: Type.Object({\n label: Type.String(),\n description: Type.String(),\n acceptance_criteria: Type.Array(Type.String(), { minItems: 1 }),\n priority: Type.Optional(stringEnum(PRIORITIES as unknown as readonly string[])),\n verification_type: Type.Optional(\n stringEnum([\"manual\", \"file_exists\", \"command_exit_zero\", \"pr_merged\", \"http_ok\"] as const),\n ),\n verification_target: Type.Optional(Type.String()),\n max_dispatches: Type.Optional(Type.Number()),\n max_assessments: Type.Optional(Type.Number()),\n cooldown_minutes: Type.Optional(Type.Number()),\n confirmed: Type.Optional(Type.Boolean()),\n }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n try {\n const active = await listActiveGoals(goalsDir);\n if (active.length >= gs.globalLimits.maxActiveGoals) {\n return {\n content: [{ type: \"text\", text: `Max active goals (${gs.globalLimits.maxActiveGoals}) reached.` }],\n details: { error: \"max_active_goals\" },\n };\n }\n const p = params as {\n label: string;\n description: string;\n acceptance_criteria: string[];\n priority?: (typeof PRIORITIES)[number];\n verification_type?: GoalVerification[\"type\"];\n verification_target?: string;\n max_dispatches?: number;\n max_assessments?: number;\n cooldown_minutes?: number;\n confirmed?: boolean;\n };\n const effectivePriority = p.priority ?? defaults.priority;\n if (\n gs.confirmationPolicy.requireRegisterAckForPriorities.includes(effectivePriority) &&\n p.confirmed !== true\n ) {\n return {\n content: [\n {\n type: \"text\",\n text: `Priority \"${effectivePriority}\" requires explicit human confirmation. Ask the user to approve these criteria, then call goal_register again with confirmed: true.`,\n },\n ],\n details: { error: \"confirmation_required\", priority: effectivePriority },\n };\n }\n let verification: GoalVerification | undefined;\n if (p.verification_type && p.verification_target) {\n verification = { type: p.verification_type, target: p.verification_target };\n }\n const goal = await createGoal(\n goalsDir,\n {\n label: p.label,\n description: p.description,\n acceptanceCriteria: p.acceptance_criteria,\n priority: p.priority,\n verification,\n maxDispatches: p.max_dispatches,\n maxAssessments: p.max_assessments,\n cooldownMinutes: p.cooldown_minutes,\n },\n defaults,\n eventLog,\n );\n return {\n content: [{ type: \"text\", text: `Goal registered: ${goal.label} (${goal.id})` }],\n details: { goal },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"goal-tools\",\n operation: \"goal_register\",\n });\n return { content: [{ type: \"text\", text: String(err) }], details: { error: String(err) } };\n }\n },\n },\n { name: \"goal_register\" },\n );\n\n api.registerTool(\n {\n name: \"goal_assess\",\n label: \"Assess Goal\",\n description: \"Record a stewardship assessment.\",\n parameters: Type.Object({\n goal_id: Type.String(),\n assessment: Type.String(),\n next_action: Type.String(),\n blockers: Type.Optional(Type.Array(Type.String())),\n dispatched: Type.Optional(Type.Boolean()),\n }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n try {\n const p = params as {\n goal_id: string;\n assessment: string;\n next_action: string;\n blockers?: string[];\n dispatched?: boolean;\n };\n const goal = await resolveGoalId(goalsDir, p.goal_id);\n if (!goal) return { content: [{ type: \"text\", text: \"Goal not found.\" }], details: { error: \"not_found\" } };\n if (isTerminalStatus(goal.status)) {\n return { content: [{ type: \"text\", text: `Goal already ${goal.status}` }], details: { error: \"terminal\" } };\n }\n if (goal.assessmentCount >= goal.maxAssessments) {\n await updateGoal(\n goalsDir,\n goal.id,\n { status: \"blocked\", currentBlockers: [\"Assessment budget exhausted\"] },\n { timestamp: new Date().toISOString(), action: \"blocked\", detail: \"assessments\", actor: \"steward\" },\n );\n return { content: [{ type: \"text\", text: \"Assessment budget exhausted.\" }], details: { error: \"budget\" } };\n }\n const ts = new Date().toISOString();\n let dispatchCount = goal.dispatchCount;\n let lastDispatchedAt = goal.lastDispatchedAt;\n if (p.dispatched) {\n if (isGlobalRateLimited(gs.globalLimits.maxDispatchesPerHour, goalsDir)) {\n return {\n content: [{ type: \"text\", text: \"Global dispatch rate limit reached.\" }],\n details: { error: \"rate_limited\" },\n };\n }\n if (goal.dispatchCount >= goal.maxDispatches) {\n return {\n content: [{ type: \"text\", text: \"Dispatch budget exhausted.\" }],\n details: { error: \"dispatch_budget\" },\n };\n }\n recordGoalDispatch(goalsDir);\n dispatchCount += 1;\n lastDispatchedAt = ts;\n }\n const blockersExplicitlyProvided = p.blockers !== undefined;\n const newBlockers = blockersExplicitlyProvided ? p.blockers! : goal.currentBlockers;\n const newAssessmentCount = goal.assessmentCount + 1;\n const cbState = blockersExplicitlyProvided\n ? computeCircuitBreakerStateAfterAssess(goal, newBlockers, newAssessmentCount)\n : {\n lastBlockerFingerprint: goal.lastBlockerFingerprint,\n sameBlockerStreak: goal.sameBlockerStreak,\n circuitBreakerLastProgressAssessmentCount: goal.circuitBreakerLastProgressAssessmentCount,\n };\n const tripEval = evaluateCircuitBreakerTrip(gs.circuitBreaker, cbState, newAssessmentCount);\n\n const basePatch = {\n assessmentCount: newAssessmentCount,\n lastAssessedAt: ts,\n dispatchCount,\n lastDispatchedAt,\n lastOutcome: `${p.assessment.slice(0, 400)} | next: ${p.next_action.slice(0, 200)}`,\n currentBlockers: newBlockers,\n ...cbState,\n };\n\n const assessEntry: GoalHistoryEntry = {\n timestamp: ts,\n action: \"assessed\",\n detail: `${p.assessment.slice(0, 400)} | next: ${p.next_action.slice(0, 100)}`,\n actor: \"steward\",\n };\n\n if (tripEval.trip) {\n const goalPreview = {\n ...goal,\n ...basePatch,\n currentBlockers: newBlockers,\n };\n const summary = composeCircuitBreakerHumanSummary(goalPreview, tripEval.reason, gs.circuitBreaker);\n const blockedPatch = {\n ...basePatch,\n status: \"blocked\" as const,\n currentBlockers: [circuitBreakerShortBlocker(tripEval.reason)],\n humanEscalationSummary: summary,\n escalationKind: \"circuit_breaker\" as const,\n lastOutcome: circuitBreakerShortBlocker(tripEval.reason),\n };\n const cbEntry: GoalHistoryEntry = {\n timestamp: ts,\n action: \"circuit_breaker\",\n detail: summary.slice(0, 8000),\n actor: \"watchdog\",\n };\n const updated = await updateGoal(goalsDir, goal.id, blockedPatch, [assessEntry, cbEntry]);\n try {\n eventLog?.append({\n sessionId: \"goal-stewardship\",\n timestamp: ts,\n eventType: \"action_taken\",\n content: {\n kind: \"goal.circuit_breaker\",\n goalId: updated.id,\n label: updated.label,\n reason: tripEval.reason,\n },\n });\n } catch {\n /* */\n }\n if (gs.circuitBreaker.appendMemoryEscalation) {\n await flushGoalOutcomeToMemory(memoryDir, `Circuit breaker: ${updated.label}`, [\n \"**Summary:**\",\n \"\",\n ...summary.split(\"\\n\"),\n ]);\n }\n return {\n content: [\n {\n type: \"text\",\n text: `Circuit breaker: ${updated.label} is blocked — human escalation required. See goal JSON (humanEscalationSummary) or workspace memory/.`,\n },\n ],\n details: { goal: updated, circuitBreaker: tripEval.reason },\n };\n }\n\n const updated = await updateGoal(goalsDir, goal.id, basePatch, assessEntry);\n try {\n eventLog?.append({\n sessionId: \"goal-stewardship\",\n timestamp: ts,\n eventType: \"action_taken\",\n content: { kind: \"goal.assessed\", goalId: updated.id, label: updated.label },\n });\n } catch {\n /* */\n }\n return {\n content: [{ type: \"text\", text: `Assessed ${updated.label}. Next: ${p.next_action}` }],\n details: { goal: updated },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"goal-tools\",\n operation: \"goal_assess\",\n });\n return { content: [{ type: \"text\", text: String(err) }], details: { error: String(err) } };\n }\n },\n },\n { name: \"goal_assess\" },\n );\n\n api.registerTool(\n {\n name: \"goal_update\",\n label: \"Update Goal\",\n parameters: Type.Object({\n goal_id: Type.String(),\n description: Type.Optional(Type.String()),\n acceptance_criteria: Type.Optional(Type.Array(Type.String())),\n priority: Type.Optional(stringEnum(PRIORITIES as unknown as readonly string[])),\n note: Type.Optional(Type.String()),\n }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n const p = params as {\n goal_id: string;\n description?: string;\n acceptance_criteria?: string[];\n priority?: (typeof PRIORITIES)[number];\n note?: string;\n };\n const goal = await resolveGoalId(goalsDir, p.goal_id);\n if (!goal) return { content: [{ type: \"text\", text: \"Goal not found.\" }], details: { error: \"not_found\" } };\n const patch: Parameters<typeof updateGoal>[2] = {};\n if (p.description !== undefined) patch.description = p.description;\n if (p.acceptance_criteria !== undefined) patch.acceptanceCriteria = p.acceptance_criteria;\n if (p.priority !== undefined) patch.priority = p.priority;\n const updated = await updateGoal(goalsDir, goal.id, patch, {\n timestamp: new Date().toISOString(),\n action: \"updated\",\n detail: p.note ?? \"update\",\n actor: \"agent\",\n });\n return { content: [{ type: \"text\", text: `Updated ${updated.label}` }], details: { goal: updated } };\n },\n },\n { name: \"goal_update\" },\n );\n\n api.registerTool(\n {\n name: \"goal_complete\",\n label: \"Complete Goal\",\n parameters: Type.Object({ goal_id: Type.String(), reason: Type.String() }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n const p = params as { goal_id: string; reason: string };\n const goal = await resolveGoalId(goalsDir, p.goal_id);\n if (!goal) return { content: [{ type: \"text\", text: \"Goal not found.\" }], details: { error: \"not_found\" } };\n if (isTerminalStatus(goal.status)) {\n return {\n content: [{ type: \"text\", text: `Goal ${goal.label} is already ${goal.status}.` }],\n details: { error: \"terminal\" },\n };\n }\n const completed = await terminateGoal(goalsDir, goal.id, \"completed\", p.reason, \"agent\", eventLog);\n if (cfg.activeTask.flushOnComplete !== false) {\n await flushGoalOutcomeToMemory(memoryDir, `Goal completed: ${completed.label}`, [`**Outcome:** ${p.reason}`]);\n }\n try {\n factsDb?.recordEpisode?.({\n event: `Goal completed: ${completed.label}`,\n outcome: \"success\",\n context: p.reason,\n importance: 0.7,\n });\n } catch {\n /* */\n }\n return { content: [{ type: \"text\", text: `Completed ${completed.label}` }], details: { goal: completed } };\n },\n },\n { name: \"goal_complete\" },\n );\n\n api.registerTool(\n {\n name: \"goal_abandon\",\n label: \"Abandon Goal\",\n parameters: Type.Object({ goal_id: Type.String(), reason: Type.String() }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n const p = params as { goal_id: string; reason: string };\n const goal = await resolveGoalId(goalsDir, p.goal_id);\n if (!goal) return { content: [{ type: \"text\", text: \"Goal not found.\" }], details: { error: \"not_found\" } };\n if (isTerminalStatus(goal.status)) {\n return {\n content: [{ type: \"text\", text: `Goal ${goal.label} is already ${goal.status}.` }],\n details: { error: \"terminal\" },\n };\n }\n const abandoned = await terminateGoal(goalsDir, goal.id, \"abandoned\", p.reason, \"agent\", eventLog);\n if (cfg.activeTask.flushOnComplete !== false) {\n await flushGoalOutcomeToMemory(memoryDir, `Goal abandoned: ${abandoned.label}`, [`**Reason:** ${p.reason}`]);\n }\n try {\n factsDb?.recordEpisode?.({\n event: `Goal abandoned: ${abandoned.label}`,\n outcome: \"failure\",\n context: p.reason,\n importance: 0.5,\n });\n } catch {\n /* */\n }\n return { content: [{ type: \"text\", text: `Abandoned ${abandoned.label}` }], details: { goal: abandoned } };\n },\n },\n { name: \"goal_abandon\" },\n );\n}\n"],"mappings":";;;;;;;;;;;;AA2CA,MAAM,aAAa;CAAC;CAAY;CAAQ;CAAU;CAAM;AAExD,eAAe,yBAAyB,WAAmB,OAAe,OAAgC;CACxG,MAAM,wBAAO,IAAI,MAAM,EAAC,aAAa,CAAC,MAAM,GAAG,GAAG;CAClD,MAAM,WAAW,KAAK,WAAW,GAAG,KAAK,KAAK;CAC9C,MAAM,MAAM,WAAW,EAAE,WAAW,MAAM,CAAC;CAE3C,MAAM,WAAW,UADH;EAAC;EAAI,MAAM,MAAM,KAAK;EAAQ;EAAI,GAAG;EAAO;EAAG,CAAC,KAAK,KACnC,EAAE,QAAQ,CAAC,OAAO,QAAQ;EACxD,mBAAmB,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,EAAE;GACtE,WAAW;GACX,WAAW;GACZ,CAAC;GACF;;AAGJ,SAAgB,kBAAkB,KAAuB,KAA8B;CACrF,MAAM,EAAE,KAAK,UAAU,SAAS,UAAU,cAAc;CACxD,MAAM,KAAK,IAAI;CACf,MAAM,WAAW,kCAAkC,GAAG;CACtD,MAAM,oBAAoB;EACxB,SAAS,CACP;GACE,MAAM;GACN,MAAM;GACP,CACF;EACD,SAAS,EAAE,OAAO,6BAA6B;EAChD;CAED,IAAI,aACF;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY,KAAK,OAAO;GACtB,OAAO,KAAK,QAAQ;GACpB,aAAa,KAAK,QAAQ;GAC1B,qBAAqB,KAAK,MAAM,KAAK,QAAQ,EAAE,EAAE,UAAU,GAAG,CAAC;GAC/D,UAAU,KAAK,SAAS,WAAW,WAA2C,CAAC;GAC/E,mBAAmB,KAAK,SACtB,WAAW;IAAC;IAAU;IAAe;IAAqB;IAAa;IAAU,CAAU,CAC5F;GACD,qBAAqB,KAAK,SAAS,KAAK,QAAQ,CAAC;GACjD,gBAAgB,KAAK,SAAS,KAAK,QAAQ,CAAC;GAC5C,iBAAiB,KAAK,SAAS,KAAK,QAAQ,CAAC;GAC7C,kBAAkB,KAAK,SAAS,KAAK,QAAQ,CAAC;GAC9C,WAAW,KAAK,SAAS,KAAK,SAAS,CAAC;GACzC,CAAC;EACF,MAAM,QAAQ,KAAa,QAAiC;GAC1D,IAAI,CAAC,GAAG,SAAS,OAAO,YAAY;GACpC,IAAI;IAEF,KAAI,MADiB,gBAAgB,SAAS,EACnC,UAAU,GAAG,aAAa,gBACnC,OAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,qBAAqB,GAAG,aAAa,eAAe;MAAa,CAAC;KAClG,SAAS,EAAE,OAAO,oBAAoB;KACvC;IAEH,MAAM,IAAI;IAYV,MAAM,oBAAoB,EAAE,YAAY,SAAS;IACjD,IACE,GAAG,mBAAmB,gCAAgC,SAAS,kBAAkB,IACjF,EAAE,cAAc,MAEhB,OAAO;KACL,SAAS,CACP;MACE,MAAM;MACN,MAAM,aAAa,kBAAkB;MACtC,CACF;KACD,SAAS;MAAE,OAAO;MAAyB,UAAU;MAAmB;KACzE;IAEH,IAAI;IACJ,IAAI,EAAE,qBAAqB,EAAE,qBAC3B,eAAe;KAAE,MAAM,EAAE;KAAmB,QAAQ,EAAE;KAAqB;IAE7E,MAAM,OAAO,MAAM,WACjB,UACA;KACE,OAAO,EAAE;KACT,aAAa,EAAE;KACf,oBAAoB,EAAE;KACtB,UAAU,EAAE;KACZ;KACA,eAAe,EAAE;KACjB,gBAAgB,EAAE;KAClB,iBAAiB,EAAE;KACpB,EACD,UACA,SACD;IACD,OAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,oBAAoB,KAAK,MAAM,IAAI,KAAK,GAAG;MAAI,CAAC;KAChF,SAAS,EAAE,MAAM;KAClB;YACM,KAAK;IACZ,mBAAmB,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,EAAE;KACtE,WAAW;KACX,WAAW;KACZ,CAAC;IACF,OAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,OAAO,IAAI;MAAE,CAAC;KAAE,SAAS,EAAE,OAAO,OAAO,IAAI,EAAE;KAAE;;;EAG/F,EACD,EAAE,MAAM,iBAAiB,CAC1B;CAED,IAAI,aACF;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY,KAAK,OAAO;GACtB,SAAS,KAAK,QAAQ;GACtB,YAAY,KAAK,QAAQ;GACzB,aAAa,KAAK,QAAQ;GAC1B,UAAU,KAAK,SAAS,KAAK,MAAM,KAAK,QAAQ,CAAC,CAAC;GAClD,YAAY,KAAK,SAAS,KAAK,SAAS,CAAC;GAC1C,CAAC;EACF,MAAM,QAAQ,KAAa,QAAiC;GAC1D,IAAI,CAAC,GAAG,SAAS,OAAO,YAAY;GACpC,IAAI;IACF,MAAM,IAAI;IAOV,MAAM,OAAO,MAAM,cAAc,UAAU,EAAE,QAAQ;IACrD,IAAI,CAAC,MAAM,OAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAmB,CAAC;KAAE,SAAS,EAAE,OAAO,aAAa;KAAE;IAC3G,IAAI,iBAAiB,KAAK,OAAO,EAC/B,OAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,gBAAgB,KAAK;MAAU,CAAC;KAAE,SAAS,EAAE,OAAO,YAAY;KAAE;IAE7G,IAAI,KAAK,mBAAmB,KAAK,gBAAgB;KAC/C,MAAM,WACJ,UACA,KAAK,IACL;MAAE,QAAQ;MAAW,iBAAiB,CAAC,8BAA8B;MAAE,EACvE;MAAE,4BAAW,IAAI,MAAM,EAAC,aAAa;MAAE,QAAQ;MAAW,QAAQ;MAAe,OAAO;MAAW,CACpG;KACD,OAAO;MAAE,SAAS,CAAC;OAAE,MAAM;OAAQ,MAAM;OAAgC,CAAC;MAAE,SAAS,EAAE,OAAO,UAAU;MAAE;;IAE5G,MAAM,sBAAK,IAAI,MAAM,EAAC,aAAa;IACnC,IAAI,gBAAgB,KAAK;IACzB,IAAI,mBAAmB,KAAK;IAC5B,IAAI,EAAE,YAAY;KAChB,IAAI,oBAAoB,GAAG,aAAa,sBAAsB,SAAS,EACrE,OAAO;MACL,SAAS,CAAC;OAAE,MAAM;OAAQ,MAAM;OAAuC,CAAC;MACxE,SAAS,EAAE,OAAO,gBAAgB;MACnC;KAEH,IAAI,KAAK,iBAAiB,KAAK,eAC7B,OAAO;MACL,SAAS,CAAC;OAAE,MAAM;OAAQ,MAAM;OAA8B,CAAC;MAC/D,SAAS,EAAE,OAAO,mBAAmB;MACtC;KAEH,mBAAmB,SAAS;KAC5B,iBAAiB;KACjB,mBAAmB;;IAErB,MAAM,6BAA6B,EAAE,aAAa,KAAA;IAClD,MAAM,cAAc,6BAA6B,EAAE,WAAY,KAAK;IACpE,MAAM,qBAAqB,KAAK,kBAAkB;IAClD,MAAM,UAAU,6BACZ,sCAAsC,MAAM,aAAa,mBAAmB,GAC5E;KACE,wBAAwB,KAAK;KAC7B,mBAAmB,KAAK;KACxB,2CAA2C,KAAK;KACjD;IACL,MAAM,WAAW,2BAA2B,GAAG,gBAAgB,SAAS,mBAAmB;IAE3F,MAAM,YAAY;KAChB,iBAAiB;KACjB,gBAAgB;KAChB;KACA;KACA,aAAa,GAAG,EAAE,WAAW,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,MAAM,GAAG,IAAI;KACjF,iBAAiB;KACjB,GAAG;KACJ;IAED,MAAM,cAAgC;KACpC,WAAW;KACX,QAAQ;KACR,QAAQ,GAAG,EAAE,WAAW,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,MAAM,GAAG,IAAI;KAC5E,OAAO;KACR;IAED,IAAI,SAAS,MAAM;KAMjB,MAAM,UAAU,kCAAkC;MAJhD,GAAG;MACH,GAAG;MACH,iBAAiB;MAE0C,EAAE,SAAS,QAAQ,GAAG,eAAe;KAClG,MAAM,eAAe;MACnB,GAAG;MACH,QAAQ;MACR,iBAAiB,CAAC,2BAA2B,SAAS,OAAO,CAAC;MAC9D,wBAAwB;MACxB,gBAAgB;MAChB,aAAa,2BAA2B,SAAS,OAAO;MACzD;KACD,MAAM,UAA4B;MAChC,WAAW;MACX,QAAQ;MACR,QAAQ,QAAQ,MAAM,GAAG,IAAK;MAC9B,OAAO;MACR;KACD,MAAM,UAAU,MAAM,WAAW,UAAU,KAAK,IAAI,cAAc,CAAC,aAAa,QAAQ,CAAC;KACzF,IAAI;MACF,UAAU,OAAO;OACf,WAAW;OACX,WAAW;OACX,WAAW;OACX,SAAS;QACP,MAAM;QACN,QAAQ,QAAQ;QAChB,OAAO,QAAQ;QACf,QAAQ,SAAS;QAClB;OACF,CAAC;aACI;KAGR,IAAI,GAAG,eAAe,wBACpB,MAAM,yBAAyB,WAAW,oBAAoB,QAAQ,SAAS;MAC7E;MACA;MACA,GAAG,QAAQ,MAAM,KAAK;MACvB,CAAC;KAEJ,OAAO;MACL,SAAS,CACP;OACE,MAAM;OACN,MAAM,oBAAoB,QAAQ,MAAM;OACzC,CACF;MACD,SAAS;OAAE,MAAM;OAAS,gBAAgB,SAAS;OAAQ;MAC5D;;IAGH,MAAM,UAAU,MAAM,WAAW,UAAU,KAAK,IAAI,WAAW,YAAY;IAC3E,IAAI;KACF,UAAU,OAAO;MACf,WAAW;MACX,WAAW;MACX,WAAW;MACX,SAAS;OAAE,MAAM;OAAiB,QAAQ,QAAQ;OAAI,OAAO,QAAQ;OAAO;MAC7E,CAAC;YACI;IAGR,OAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,YAAY,QAAQ,MAAM,UAAU,EAAE;MAAe,CAAC;KACtF,SAAS,EAAE,MAAM,SAAS;KAC3B;YACM,KAAK;IACZ,mBAAmB,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,EAAE;KACtE,WAAW;KACX,WAAW;KACZ,CAAC;IACF,OAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,OAAO,IAAI;MAAE,CAAC;KAAE,SAAS,EAAE,OAAO,OAAO,IAAI,EAAE;KAAE;;;EAG/F,EACD,EAAE,MAAM,eAAe,CACxB;CAED,IAAI,aACF;EACE,MAAM;EACN,OAAO;EACP,YAAY,KAAK,OAAO;GACtB,SAAS,KAAK,QAAQ;GACtB,aAAa,KAAK,SAAS,KAAK,QAAQ,CAAC;GACzC,qBAAqB,KAAK,SAAS,KAAK,MAAM,KAAK,QAAQ,CAAC,CAAC;GAC7D,UAAU,KAAK,SAAS,WAAW,WAA2C,CAAC;GAC/E,MAAM,KAAK,SAAS,KAAK,QAAQ,CAAC;GACnC,CAAC;EACF,MAAM,QAAQ,KAAa,QAAiC;GAC1D,IAAI,CAAC,GAAG,SAAS,OAAO,YAAY;GACpC,MAAM,IAAI;GAOV,MAAM,OAAO,MAAM,cAAc,UAAU,EAAE,QAAQ;GACrD,IAAI,CAAC,MAAM,OAAO;IAAE,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAmB,CAAC;IAAE,SAAS,EAAE,OAAO,aAAa;IAAE;GAC3G,MAAM,QAA0C,EAAE;GAClD,IAAI,EAAE,gBAAgB,KAAA,GAAW,MAAM,cAAc,EAAE;GACvD,IAAI,EAAE,wBAAwB,KAAA,GAAW,MAAM,qBAAqB,EAAE;GACtE,IAAI,EAAE,aAAa,KAAA,GAAW,MAAM,WAAW,EAAE;GACjD,MAAM,UAAU,MAAM,WAAW,UAAU,KAAK,IAAI,OAAO;IACzD,4BAAW,IAAI,MAAM,EAAC,aAAa;IACnC,QAAQ;IACR,QAAQ,EAAE,QAAQ;IAClB,OAAO;IACR,CAAC;GACF,OAAO;IAAE,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM,WAAW,QAAQ;KAAS,CAAC;IAAE,SAAS,EAAE,MAAM,SAAS;IAAE;;EAEvG,EACD,EAAE,MAAM,eAAe,CACxB;CAED,IAAI,aACF;EACE,MAAM;EACN,OAAO;EACP,YAAY,KAAK,OAAO;GAAE,SAAS,KAAK,QAAQ;GAAE,QAAQ,KAAK,QAAQ;GAAE,CAAC;EAC1E,MAAM,QAAQ,KAAa,QAAiC;GAC1D,IAAI,CAAC,GAAG,SAAS,OAAO,YAAY;GACpC,MAAM,IAAI;GACV,MAAM,OAAO,MAAM,cAAc,UAAU,EAAE,QAAQ;GACrD,IAAI,CAAC,MAAM,OAAO;IAAE,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAmB,CAAC;IAAE,SAAS,EAAE,OAAO,aAAa;IAAE;GAC3G,IAAI,iBAAiB,KAAK,OAAO,EAC/B,OAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM,QAAQ,KAAK,MAAM,cAAc,KAAK,OAAO;KAAI,CAAC;IAClF,SAAS,EAAE,OAAO,YAAY;IAC/B;GAEH,MAAM,YAAY,MAAM,cAAc,UAAU,KAAK,IAAI,aAAa,EAAE,QAAQ,SAAS,SAAS;GAClG,IAAI,IAAI,WAAW,oBAAoB,OACrC,MAAM,yBAAyB,WAAW,mBAAmB,UAAU,SAAS,CAAC,gBAAgB,EAAE,SAAS,CAAC;GAE/G,IAAI;IACF,SAAS,gBAAgB;KACvB,OAAO,mBAAmB,UAAU;KACpC,SAAS;KACT,SAAS,EAAE;KACX,YAAY;KACb,CAAC;WACI;GAGR,OAAO;IAAE,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM,aAAa,UAAU;KAAS,CAAC;IAAE,SAAS,EAAE,MAAM,WAAW;IAAE;;EAE7G,EACD,EAAE,MAAM,iBAAiB,CAC1B;CAED,IAAI,aACF;EACE,MAAM;EACN,OAAO;EACP,YAAY,KAAK,OAAO;GAAE,SAAS,KAAK,QAAQ;GAAE,QAAQ,KAAK,QAAQ;GAAE,CAAC;EAC1E,MAAM,QAAQ,KAAa,QAAiC;GAC1D,IAAI,CAAC,GAAG,SAAS,OAAO,YAAY;GACpC,MAAM,IAAI;GACV,MAAM,OAAO,MAAM,cAAc,UAAU,EAAE,QAAQ;GACrD,IAAI,CAAC,MAAM,OAAO;IAAE,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAmB,CAAC;IAAE,SAAS,EAAE,OAAO,aAAa;IAAE;GAC3G,IAAI,iBAAiB,KAAK,OAAO,EAC/B,OAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM,QAAQ,KAAK,MAAM,cAAc,KAAK,OAAO;KAAI,CAAC;IAClF,SAAS,EAAE,OAAO,YAAY;IAC/B;GAEH,MAAM,YAAY,MAAM,cAAc,UAAU,KAAK,IAAI,aAAa,EAAE,QAAQ,SAAS,SAAS;GAClG,IAAI,IAAI,WAAW,oBAAoB,OACrC,MAAM,yBAAyB,WAAW,mBAAmB,UAAU,SAAS,CAAC,eAAe,EAAE,SAAS,CAAC;GAE9G,IAAI;IACF,SAAS,gBAAgB;KACvB,OAAO,mBAAmB,UAAU;KACpC,SAAS;KACT,SAAS,EAAE;KACX,YAAY;KACb,CAAC;WACI;GAGR,OAAO;IAAE,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM,aAAa,UAAU;KAAS,CAAC;IAAE,SAAS,EAAE,MAAM,WAAW;IAAE;;EAE7G,EACD,EAAE,MAAM,gBAAgB,CACzB"}
|
|
1
|
+
{"version":3,"file":"goal-tools.js","names":[],"sources":["../../tools/goal-tools.ts"],"sourcesContent":["import { appendFile, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n/**\n * Goal stewardship tools — see docs/GOAL-STEWARDSHIP-DESIGN.md\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ClawdbotPluginApi } from \"openclaw/plugin-sdk/core\";\nimport type { EventLog } from \"../backends/event-log.js\";\nimport type { FactsDB } from \"../backends/facts-db.js\";\nimport type { HybridMemoryConfig } from \"../config.js\";\nimport { capturePluginError } from \"../services/error-reporter.js\";\nimport {\n circuitBreakerShortBlocker,\n composeCircuitBreakerHumanSummary,\n computeCircuitBreakerStateAfterAssess,\n evaluateCircuitBreakerTrip,\n} from \"../services/goal-circuit-breaker.js\";\nimport type { GoalHistoryEntry } from \"../services/goal-stewardship-types.js\";\nimport {\n type GoalVerification,\n createGoal,\n goalStewardshipDefaultsFromConfig,\n isGlobalRateLimited,\n isTerminalStatus,\n listActiveGoals,\n recordGoalDispatch,\n resolveGoalId,\n terminateGoal,\n updateGoal,\n} from \"../services/goal-stewardship.js\";\nimport { stringEnum } from \"../utils/typebox.js\";\n\nexport interface GoalToolsContext {\n cfg: HybridMemoryConfig;\n goalsDir: string;\n workspaceRoot: string;\n /** Absolute path to ACTIVE-TASKS.md (for task hygiene tools). */\n resolvedActiveTaskPath: string;\n factsDb: FactsDB | null;\n eventLog: EventLog | null;\n memoryDir: string;\n}\n\nconst PRIORITIES = [\"critical\", \"high\", \"normal\", \"low\"] as const;\n\nasync function flushGoalOutcomeToMemory(memoryDir: string, title: string, lines: string[]): Promise<void> {\n const date = new Date().toISOString().slice(0, 10);\n const filePath = join(memoryDir, `${date}.md`);\n await mkdir(memoryDir, { recursive: true });\n const block = [\"\", `## ${title} — ${date}`, \"\", ...lines, \"\"].join(\"\\n\");\n await appendFile(filePath, block, \"utf-8\").catch((err) => {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"goal-tools\",\n operation: \"flushGoalOutcomeToMemory\",\n });\n });\n}\n\nexport function registerGoalTools(ctx: GoalToolsContext, api: ClawdbotPluginApi): void {\n const { cfg, goalsDir, factsDb, eventLog, memoryDir } = ctx;\n const gs = cfg.goalStewardship;\n const defaults = goalStewardshipDefaultsFromConfig(gs);\n const notEnabled = () => ({\n content: [\n {\n type: \"text\" as const,\n text: \"Goal stewardship is disabled. Set goalStewardship.enabled: true in plugin config.\",\n },\n ],\n details: { error: \"goal_stewardship_disabled\" },\n });\n\n api.registerTool(\n {\n name: \"goal_register\",\n label: \"Register Goal\",\n description: \"Register a long-running goal with acceptance criteria.\",\n parameters: Type.Object({\n label: Type.String(),\n description: Type.String(),\n acceptance_criteria: Type.Array(Type.String(), { minItems: 1 }),\n priority: Type.Optional(stringEnum(PRIORITIES as unknown as readonly string[])),\n verification_type: Type.Optional(\n stringEnum([\"manual\", \"file_exists\", \"command_exit_zero\", \"pr_merged\", \"http_ok\"] as const),\n ),\n verification_target: Type.Optional(Type.String()),\n max_dispatches: Type.Optional(Type.Number()),\n max_assessments: Type.Optional(Type.Number()),\n cooldown_minutes: Type.Optional(Type.Number()),\n confirmed: Type.Optional(Type.Boolean()),\n }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n try {\n const active = await listActiveGoals(goalsDir);\n if (active.length >= gs.globalLimits.maxActiveGoals) {\n return {\n content: [{ type: \"text\", text: `Max active goals (${gs.globalLimits.maxActiveGoals}) reached.` }],\n details: { error: \"max_active_goals\" },\n };\n }\n const p = params as {\n label: string;\n description: string;\n acceptance_criteria: string[];\n priority?: (typeof PRIORITIES)[number];\n verification_type?: GoalVerification[\"type\"];\n verification_target?: string;\n max_dispatches?: number;\n max_assessments?: number;\n cooldown_minutes?: number;\n confirmed?: boolean;\n };\n const effectivePriority = p.priority ?? defaults.priority;\n if (\n gs.confirmationPolicy.requireRegisterAckForPriorities.includes(effectivePriority) &&\n p.confirmed !== true\n ) {\n return {\n content: [\n {\n type: \"text\",\n text: `Priority \"${effectivePriority}\" requires explicit human confirmation. Ask the user to approve these criteria, then call goal_register again with confirmed: true.`,\n },\n ],\n details: { error: \"confirmation_required\", priority: effectivePriority },\n };\n }\n let verification: GoalVerification | undefined;\n if (p.verification_type && p.verification_target) {\n verification = { type: p.verification_type, target: p.verification_target };\n }\n const goal = await createGoal(\n goalsDir,\n {\n label: p.label,\n description: p.description,\n acceptanceCriteria: p.acceptance_criteria,\n priority: p.priority,\n verification,\n maxDispatches: p.max_dispatches,\n maxAssessments: p.max_assessments,\n cooldownMinutes: p.cooldown_minutes,\n },\n defaults,\n eventLog,\n );\n return {\n content: [{ type: \"text\", text: `Goal registered: ${goal.label} (${goal.id})` }],\n details: { goal },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"goal-tools\",\n operation: \"goal_register\",\n });\n return { content: [{ type: \"text\", text: String(err) }], details: { error: String(err) } };\n }\n },\n },\n { name: \"goal_register\" },\n );\n\n api.registerTool(\n {\n name: \"goal_assess\",\n label: \"Assess Goal\",\n description: \"Record a stewardship assessment.\",\n parameters: Type.Object({\n goal_id: Type.String(),\n assessment: Type.String(),\n next_action: Type.String(),\n blockers: Type.Optional(Type.Array(Type.String())),\n dispatched: Type.Optional(Type.Boolean()),\n }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n try {\n const p = params as {\n goal_id: string;\n assessment: string;\n next_action: string;\n blockers?: string[];\n dispatched?: boolean;\n };\n const goal = await resolveGoalId(goalsDir, p.goal_id);\n if (!goal) return { content: [{ type: \"text\", text: \"Goal not found.\" }], details: { error: \"not_found\" } };\n if (isTerminalStatus(goal.status)) {\n return { content: [{ type: \"text\", text: `Goal already ${goal.status}` }], details: { error: \"terminal\" } };\n }\n if (goal.assessmentCount >= goal.maxAssessments) {\n await updateGoal(\n goalsDir,\n goal.id,\n { status: \"blocked\", currentBlockers: [\"Assessment budget exhausted\"] },\n { timestamp: new Date().toISOString(), action: \"blocked\", detail: \"assessments\", actor: \"steward\" },\n );\n return { content: [{ type: \"text\", text: \"Assessment budget exhausted.\" }], details: { error: \"budget\" } };\n }\n const ts = new Date().toISOString();\n let dispatchCount = goal.dispatchCount;\n let lastDispatchedAt = goal.lastDispatchedAt;\n if (p.dispatched) {\n if (isGlobalRateLimited(gs.globalLimits.maxDispatchesPerHour, goalsDir)) {\n return {\n content: [{ type: \"text\", text: \"Global dispatch rate limit reached.\" }],\n details: { error: \"rate_limited\" },\n };\n }\n if (goal.dispatchCount >= goal.maxDispatches) {\n return {\n content: [{ type: \"text\", text: \"Dispatch budget exhausted.\" }],\n details: { error: \"dispatch_budget\" },\n };\n }\n recordGoalDispatch(goalsDir);\n dispatchCount += 1;\n lastDispatchedAt = ts;\n }\n const blockersExplicitlyProvided = p.blockers !== undefined;\n const newBlockers = blockersExplicitlyProvided ? p.blockers! : goal.currentBlockers;\n const newAssessmentCount = goal.assessmentCount + 1;\n const cbState = blockersExplicitlyProvided\n ? computeCircuitBreakerStateAfterAssess(goal, newBlockers, newAssessmentCount)\n : {\n lastBlockerFingerprint: goal.lastBlockerFingerprint,\n sameBlockerStreak: goal.sameBlockerStreak,\n circuitBreakerLastProgressAssessmentCount: goal.circuitBreakerLastProgressAssessmentCount,\n };\n const tripEval = evaluateCircuitBreakerTrip(gs.circuitBreaker, cbState, newAssessmentCount);\n\n const basePatch = {\n assessmentCount: newAssessmentCount,\n lastAssessedAt: ts,\n dispatchCount,\n lastDispatchedAt,\n lastOutcome: `${p.assessment.slice(0, 400)} | next: ${p.next_action.slice(0, 200)}`,\n currentBlockers: newBlockers,\n ...cbState,\n };\n\n const assessEntry: GoalHistoryEntry = {\n timestamp: ts,\n action: \"assessed\",\n detail: `${p.assessment.slice(0, 400)} | next: ${p.next_action.slice(0, 100)}`,\n actor: \"steward\",\n };\n\n if (tripEval.trip) {\n const goalPreview = {\n ...goal,\n ...basePatch,\n currentBlockers: newBlockers,\n };\n const summary = composeCircuitBreakerHumanSummary(goalPreview, tripEval.reason, gs.circuitBreaker);\n const blockedPatch = {\n ...basePatch,\n status: \"blocked\" as const,\n currentBlockers: [circuitBreakerShortBlocker(tripEval.reason)],\n humanEscalationSummary: summary,\n escalationKind: \"circuit_breaker\" as const,\n lastOutcome: circuitBreakerShortBlocker(tripEval.reason),\n };\n const cbEntry: GoalHistoryEntry = {\n timestamp: ts,\n action: \"circuit_breaker\",\n detail: summary.slice(0, 8000),\n actor: \"watchdog\",\n };\n const updated = await updateGoal(goalsDir, goal.id, blockedPatch, [assessEntry, cbEntry]);\n try {\n eventLog?.append({\n sessionId: \"goal-stewardship\",\n timestamp: ts,\n eventType: \"action_taken\",\n content: {\n kind: \"goal.circuit_breaker\",\n goalId: updated.id,\n label: updated.label,\n reason: tripEval.reason,\n },\n });\n } catch {\n /* */\n }\n if (gs.circuitBreaker.appendMemoryEscalation) {\n await flushGoalOutcomeToMemory(memoryDir, `Circuit breaker: ${updated.label}`, [\n \"**Summary:**\",\n \"\",\n ...summary.split(\"\\n\"),\n ]);\n }\n return {\n content: [\n {\n type: \"text\",\n text: `Circuit breaker: ${updated.label} is blocked — human escalation required. See goal JSON (humanEscalationSummary) or workspace memory/.`,\n },\n ],\n details: { goal: updated, circuitBreaker: tripEval.reason },\n };\n }\n\n const updated = await updateGoal(goalsDir, goal.id, basePatch, assessEntry);\n try {\n eventLog?.append({\n sessionId: \"goal-stewardship\",\n timestamp: ts,\n eventType: \"action_taken\",\n content: { kind: \"goal.assessed\", goalId: updated.id, label: updated.label },\n });\n } catch {\n /* */\n }\n return {\n content: [{ type: \"text\", text: `Assessed ${updated.label}. Next: ${p.next_action}` }],\n details: { goal: updated },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"goal-tools\",\n operation: \"goal_assess\",\n });\n return { content: [{ type: \"text\", text: String(err) }], details: { error: String(err) } };\n }\n },\n },\n { name: \"goal_assess\" },\n );\n\n api.registerTool(\n {\n name: \"goal_update\",\n label: \"Update Goal\",\n parameters: Type.Object({\n goal_id: Type.String(),\n description: Type.Optional(Type.String()),\n acceptance_criteria: Type.Optional(Type.Array(Type.String())),\n priority: Type.Optional(stringEnum(PRIORITIES as unknown as readonly string[])),\n note: Type.Optional(Type.String()),\n }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n const p = params as {\n goal_id: string;\n description?: string;\n acceptance_criteria?: string[];\n priority?: (typeof PRIORITIES)[number];\n note?: string;\n };\n const goal = await resolveGoalId(goalsDir, p.goal_id);\n if (!goal) return { content: [{ type: \"text\", text: \"Goal not found.\" }], details: { error: \"not_found\" } };\n const patch: Parameters<typeof updateGoal>[2] = {};\n if (p.description !== undefined) patch.description = p.description;\n if (p.acceptance_criteria !== undefined) patch.acceptanceCriteria = p.acceptance_criteria;\n if (p.priority !== undefined) patch.priority = p.priority;\n const updated = await updateGoal(goalsDir, goal.id, patch, {\n timestamp: new Date().toISOString(),\n action: \"updated\",\n detail: p.note ?? \"update\",\n actor: \"agent\",\n });\n return { content: [{ type: \"text\", text: `Updated ${updated.label}` }], details: { goal: updated } };\n },\n },\n { name: \"goal_update\" },\n );\n\n api.registerTool(\n {\n name: \"goal_complete\",\n label: \"Complete Goal\",\n parameters: Type.Object({ goal_id: Type.String(), reason: Type.String() }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n const p = params as { goal_id: string; reason: string };\n const goal = await resolveGoalId(goalsDir, p.goal_id);\n if (!goal) return { content: [{ type: \"text\", text: \"Goal not found.\" }], details: { error: \"not_found\" } };\n if (isTerminalStatus(goal.status)) {\n return {\n content: [{ type: \"text\", text: `Goal ${goal.label} is already ${goal.status}.` }],\n details: { error: \"terminal\" },\n };\n }\n const completed = await terminateGoal(goalsDir, goal.id, \"completed\", p.reason, \"agent\", eventLog);\n if (cfg.activeTask.flushOnComplete !== false) {\n await flushGoalOutcomeToMemory(memoryDir, `Goal completed: ${completed.label}`, [`**Outcome:** ${p.reason}`]);\n }\n try {\n factsDb?.recordEpisode?.({\n event: `Goal completed: ${completed.label}`,\n outcome: \"success\",\n context: p.reason,\n importance: 0.7,\n });\n } catch {\n /* */\n }\n return { content: [{ type: \"text\", text: `Completed ${completed.label}` }], details: { goal: completed } };\n },\n },\n { name: \"goal_complete\" },\n );\n\n api.registerTool(\n {\n name: \"goal_abandon\",\n label: \"Abandon Goal\",\n parameters: Type.Object({ goal_id: Type.String(), reason: Type.String() }),\n async execute(_id: string, params: Record<string, unknown>) {\n if (!gs.enabled) return notEnabled();\n const p = params as { goal_id: string; reason: string };\n const goal = await resolveGoalId(goalsDir, p.goal_id);\n if (!goal) return { content: [{ type: \"text\", text: \"Goal not found.\" }], details: { error: \"not_found\" } };\n if (isTerminalStatus(goal.status)) {\n return {\n content: [{ type: \"text\", text: `Goal ${goal.label} is already ${goal.status}.` }],\n details: { error: \"terminal\" },\n };\n }\n const abandoned = await terminateGoal(goalsDir, goal.id, \"abandoned\", p.reason, \"agent\", eventLog);\n if (cfg.activeTask.flushOnComplete !== false) {\n await flushGoalOutcomeToMemory(memoryDir, `Goal abandoned: ${abandoned.label}`, [`**Reason:** ${p.reason}`]);\n }\n try {\n factsDb?.recordEpisode?.({\n event: `Goal abandoned: ${abandoned.label}`,\n outcome: \"failure\",\n context: p.reason,\n importance: 0.5,\n });\n } catch {\n /* */\n }\n return { content: [{ type: \"text\", text: `Abandoned ${abandoned.label}` }], details: { goal: abandoned } };\n },\n },\n { name: \"goal_abandon\" },\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-tools.js","names":[],"sources":["../../tools/graph-tools.ts"],"sourcesContent":["/**\n * Graph Tool Registrations\n *\n * Tool definitions for memory link creation and graph exploration.\n * Extracted from index.ts for better modularity.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport type { ClawdbotPluginApi } from \"openclaw/plugin-sdk/core\";\nimport { stringEnum } from \"../utils/typebox.js\";\n\nimport type { FactsDB, MemoryLinkType } from \"../backends/facts-db.js\";\nimport { MEMORY_LINK_TYPES } from \"../backends/facts-db.js\";\nimport type { HybridMemoryConfig } from \"../config.js\";\nimport { findShortestPath, formatPath, resolveInput } from \"../services/shortest-path.js\";\n\nexport interface PluginContext {\n factsDb: FactsDB;\n cfg: HybridMemoryConfig;\n}\n\n/**\n * Register graph-related tools with the plugin API.\n *\n * This includes: memory_link and memory_graph (when graph is enabled).\n */\nexport function registerGraphTools(ctx: PluginContext, api: ClawdbotPluginApi): void {\n const { factsDb, cfg } = ctx;\n\n // Graph tools (when graph enabled)\n if (cfg.graph.enabled) {\n api.registerTool(\n {\n name: \"memory_link\",\n label: \"Memory Link\",\n description:\n \"Create a typed relationship between two memories. Link types: SUPERSEDES, CAUSED_BY, PART_OF, RELATED_TO, DEPENDS_ON, CONTRADICTS (bidirectional), INSTANCE_OF (type taxonomy). DERIVED_FROM provenance is stored on facts.provenance_json, not memory_links.\",\n parameters: Type.Object({\n sourceFact: Type.String({ description: \"ID of the source fact\" }),\n targetFact: Type.String({ description: \"ID of the target fact\" }),\n linkType: stringEnum(MEMORY_LINK_TYPES as unknown as readonly string[]),\n strength: Type.Optional(Type.Number({ description: \"Link strength 0.0-1.0 (default 1.0)\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const {\n sourceFact,\n targetFact,\n linkType,\n strength = 1.0,\n } = params as {\n sourceFact: string;\n targetFact: string;\n linkType: MemoryLinkType;\n strength?: number;\n };\n const src = factsDb.getById(sourceFact);\n const tgt = factsDb.getById(targetFact);\n if (!src) {\n return {\n content: [{ type: \"text\", text: `Source fact not found: ${sourceFact}` }],\n details: { error: \"source_not_found\", id: sourceFact },\n };\n }\n if (!tgt) {\n return {\n content: [{ type: \"text\", text: `Target fact not found: ${targetFact}` }],\n details: { error: \"target_not_found\", id: targetFact },\n };\n }\n if (linkType === \"CONTRADICTS\") {\n const contradictionId = factsDb.recordContradiction(sourceFact, targetFact);\n const msg = `Created bidirectional ${linkType} link from \"${src.text.slice(0, 50)}${src.text.length > 50 ? \"…\" : \"\"}\" to \"${tgt.text.slice(0, 50)}${tgt.text.length > 50 ? \"…\" : \"\"}\" and reduced confidence`;\n return {\n content: [{ type: \"text\", text: msg }],\n details: { contradictionId, sourceFact, targetFact, linkType },\n };\n }\n const linkId = factsDb.createLink(sourceFact, targetFact, linkType, strength);\n const msg = `Created ${linkType} link from \"${src.text.slice(0, 50)}${src.text.length > 50 ? \"…\" : \"\"}\" to \"${tgt.text.slice(0, 50)}${tgt.text.length > 50 ? \"…\" : \"\"}\" (strength: ${strength})`;\n return {\n content: [{ type: \"text\", text: msg }],\n details: { linkId, sourceFact, targetFact, linkType, strength },\n };\n },\n },\n { name: \"memory_link\" },\n );\n\n api.registerTool(\n {\n name: \"memory_graph\",\n label: \"Memory Graph\",\n description: \"Explore connections from a memory: show direct links and optionally traverse up to depth 3.\",\n parameters: Type.Object({\n factId: Type.String({ description: \"ID of the fact to explore\" }),\n depth: Type.Optional(Type.Number({ description: \"Max hops to traverse (default 2, max 3)\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { factId, depth = 2 } = params as { factId: string; depth?: number };\n const fact = factsDb.getById(factId);\n if (!fact) {\n return {\n content: [{ type: \"text\", text: `Fact not found: ${factId}` }],\n details: { error: \"not_found\", id: factId },\n };\n }\n const maxD = Math.min(3, Math.max(1, depth));\n const out = factsDb.getLinksFrom(factId);\n const in_ = factsDb.getLinksTo(factId);\n const lines: string[] = [\n `Fact: \"${fact.text.slice(0, 80)}${fact.text.length > 80 ? \"…\" : \"\"}\"`,\n \"\",\n \"Direct links:\",\n ];\n for (const l of out) {\n const t = factsDb.getById(l.targetFactId);\n lines.push(\n ` → [${l.linkType}] ${t ? t.text.slice(0, 60) + (t.text.length > 60 ? \"…\" : \"\") : l.targetFactId} (strength: ${l.strength.toFixed(2)})`,\n );\n }\n for (const l of in_) {\n const s = factsDb.getById(l.sourceFactId);\n lines.push(\n ` ← [${l.linkType}] ${s ? s.text.slice(0, 60) + (s.text.length > 60 ? \"…\" : \"\") : l.sourceFactId} (strength: ${l.strength.toFixed(2)})`,\n );\n }\n const connectedIds = factsDb.getConnectedFactIds([factId], maxD, { hubDegreeCap: cfg.graph.hubDegreeCap });\n lines.push(\"\");\n lines.push(`Total connected facts (depth ${maxD}): ${connectedIds.length}`);\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n details: {\n factId,\n outbound: out.length,\n inbound: in_.length,\n connectedCount: connectedIds.length,\n },\n };\n },\n },\n { name: \"memory_graph\" },\n );\n }\n\n // Shortest-path tool (when path is enabled)\n if (cfg.path.enabled) {\n api.registerTool(\n {\n name: \"memory_path\",\n label: \"Memory Path\",\n description:\n \"Find the shortest path between two memories via BFS on the memory graph. \" +\n \"Both `from` and `to` accept a fact ID or an entity name (resolved automatically). \" +\n \"Returns the chain of facts and link types, or reports no path within maxDepth.\",\n parameters: Type.Object({\n from: Type.String({ description: \"Start fact ID or entity name\" }),\n to: Type.String({ description: \"End fact ID or entity name\" }),\n maxDepth: Type.Optional(\n Type.Number({ description: `Max hops to traverse (default 5, max ${cfg.path.maxPathDepth})` }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const {\n from,\n to,\n maxDepth = 5,\n } = params as {\n from: string;\n to: string;\n maxDepth?: number;\n };\n\n const depthCap = Math.min(cfg.path.maxPathDepth, Math.max(1, Math.floor(maxDepth)));\n\n const fromId = resolveInput(factsDb, from);\n if (!fromId) {\n return {\n content: [\n { type: \"text\", text: `Could not resolve start: \"${from}\" (not a known fact ID or entity name)` },\n ],\n details: { error: \"from_not_found\", from },\n };\n }\n\n const toId = resolveInput(factsDb, to);\n if (!toId) {\n return {\n content: [{ type: \"text\", text: `Could not resolve end: \"${to}\" (not a known fact ID or entity name)` }],\n details: { error: \"to_not_found\", to },\n };\n }\n\n const result = findShortestPath(factsDb, fromId, toId, { maxDepth: depthCap });\n\n if (!result) {\n return {\n content: [{ type: \"text\", text: `No path found between \"${from}\" and \"${to}\" within ${depthCap} hops.` }],\n details: { found: false, fromId, toId, maxDepth: depthCap },\n };\n }\n\n const lines: string[] = [\n `Path found: ${result.hops} hop${result.hops === 1 ? \"\" : \"s\"}`,\n \"\",\n formatPath(result.steps),\n \"\",\n \"Chain:\",\n ];\n for (let i = 0; i < result.chain.length; i++) {\n const entry = result.chain[i];\n const step = result.steps[i - 1];\n if (step) {\n lines.push(` —[${step.linkType}]→`);\n }\n lines.push(` [${entry.id.slice(0, 8)}…] ${entry.text.slice(0, 80)}${entry.text.length > 80 ? \"…\" : \"\"}`);\n }\n\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n details: {\n found: true,\n fromId,\n toId,\n hops: result.hops,\n steps: result.steps,\n },\n };\n },\n },\n { name: \"memory_path\" },\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"graph-tools.js","names":[],"sources":["../../tools/graph-tools.ts"],"sourcesContent":["/**\n * Graph Tool Registrations\n *\n * Tool definitions for memory link creation and graph exploration.\n * Extracted from index.ts for better modularity.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport type { ClawdbotPluginApi } from \"openclaw/plugin-sdk/core\";\nimport { stringEnum } from \"../utils/typebox.js\";\n\nimport type { FactsDB, MemoryLinkType } from \"../backends/facts-db.js\";\nimport { MEMORY_LINK_TYPES } from \"../backends/facts-db.js\";\nimport type { HybridMemoryConfig } from \"../config.js\";\nimport { findShortestPath, formatPath, resolveInput } from \"../services/shortest-path.js\";\n\nexport interface PluginContext {\n factsDb: FactsDB;\n cfg: HybridMemoryConfig;\n}\n\n/**\n * Register graph-related tools with the plugin API.\n *\n * This includes: memory_link and memory_graph (when graph is enabled).\n */\nexport function registerGraphTools(ctx: PluginContext, api: ClawdbotPluginApi): void {\n const { factsDb, cfg } = ctx;\n\n // Graph tools (when graph enabled)\n if (cfg.graph.enabled) {\n api.registerTool(\n {\n name: \"memory_link\",\n label: \"Memory Link\",\n description:\n \"Create a typed relationship between two memories. Link types: SUPERSEDES, CAUSED_BY, PART_OF, RELATED_TO, DEPENDS_ON, CONTRADICTS (bidirectional), INSTANCE_OF (type taxonomy). DERIVED_FROM provenance is stored on facts.provenance_json, not memory_links.\",\n parameters: Type.Object({\n sourceFact: Type.String({ description: \"ID of the source fact\" }),\n targetFact: Type.String({ description: \"ID of the target fact\" }),\n linkType: stringEnum(MEMORY_LINK_TYPES as unknown as readonly string[]),\n strength: Type.Optional(Type.Number({ description: \"Link strength 0.0-1.0 (default 1.0)\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const {\n sourceFact,\n targetFact,\n linkType,\n strength = 1.0,\n } = params as {\n sourceFact: string;\n targetFact: string;\n linkType: MemoryLinkType;\n strength?: number;\n };\n const src = factsDb.getById(sourceFact);\n const tgt = factsDb.getById(targetFact);\n if (!src) {\n return {\n content: [{ type: \"text\", text: `Source fact not found: ${sourceFact}` }],\n details: { error: \"source_not_found\", id: sourceFact },\n };\n }\n if (!tgt) {\n return {\n content: [{ type: \"text\", text: `Target fact not found: ${targetFact}` }],\n details: { error: \"target_not_found\", id: targetFact },\n };\n }\n if (linkType === \"CONTRADICTS\") {\n const contradictionId = factsDb.recordContradiction(sourceFact, targetFact);\n const msg = `Created bidirectional ${linkType} link from \"${src.text.slice(0, 50)}${src.text.length > 50 ? \"…\" : \"\"}\" to \"${tgt.text.slice(0, 50)}${tgt.text.length > 50 ? \"…\" : \"\"}\" and reduced confidence`;\n return {\n content: [{ type: \"text\", text: msg }],\n details: { contradictionId, sourceFact, targetFact, linkType },\n };\n }\n const linkId = factsDb.createLink(sourceFact, targetFact, linkType, strength);\n const msg = `Created ${linkType} link from \"${src.text.slice(0, 50)}${src.text.length > 50 ? \"…\" : \"\"}\" to \"${tgt.text.slice(0, 50)}${tgt.text.length > 50 ? \"…\" : \"\"}\" (strength: ${strength})`;\n return {\n content: [{ type: \"text\", text: msg }],\n details: { linkId, sourceFact, targetFact, linkType, strength },\n };\n },\n },\n { name: \"memory_link\" },\n );\n\n api.registerTool(\n {\n name: \"memory_graph\",\n label: \"Memory Graph\",\n description: \"Explore connections from a memory: show direct links and optionally traverse up to depth 3.\",\n parameters: Type.Object({\n factId: Type.String({ description: \"ID of the fact to explore\" }),\n depth: Type.Optional(Type.Number({ description: \"Max hops to traverse (default 2, max 3)\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { factId, depth = 2 } = params as { factId: string; depth?: number };\n const fact = factsDb.getById(factId);\n if (!fact) {\n return {\n content: [{ type: \"text\", text: `Fact not found: ${factId}` }],\n details: { error: \"not_found\", id: factId },\n };\n }\n const maxD = Math.min(3, Math.max(1, depth));\n const out = factsDb.getLinksFrom(factId);\n const in_ = factsDb.getLinksTo(factId);\n const lines: string[] = [\n `Fact: \"${fact.text.slice(0, 80)}${fact.text.length > 80 ? \"…\" : \"\"}\"`,\n \"\",\n \"Direct links:\",\n ];\n for (const l of out) {\n const t = factsDb.getById(l.targetFactId);\n lines.push(\n ` → [${l.linkType}] ${t ? t.text.slice(0, 60) + (t.text.length > 60 ? \"…\" : \"\") : l.targetFactId} (strength: ${l.strength.toFixed(2)})`,\n );\n }\n for (const l of in_) {\n const s = factsDb.getById(l.sourceFactId);\n lines.push(\n ` ← [${l.linkType}] ${s ? s.text.slice(0, 60) + (s.text.length > 60 ? \"…\" : \"\") : l.sourceFactId} (strength: ${l.strength.toFixed(2)})`,\n );\n }\n const connectedIds = factsDb.getConnectedFactIds([factId], maxD, { hubDegreeCap: cfg.graph.hubDegreeCap });\n lines.push(\"\");\n lines.push(`Total connected facts (depth ${maxD}): ${connectedIds.length}`);\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n details: {\n factId,\n outbound: out.length,\n inbound: in_.length,\n connectedCount: connectedIds.length,\n },\n };\n },\n },\n { name: \"memory_graph\" },\n );\n }\n\n // Shortest-path tool (when path is enabled)\n if (cfg.path.enabled) {\n api.registerTool(\n {\n name: \"memory_path\",\n label: \"Memory Path\",\n description:\n \"Find the shortest path between two memories via BFS on the memory graph. \" +\n \"Both `from` and `to` accept a fact ID or an entity name (resolved automatically). \" +\n \"Returns the chain of facts and link types, or reports no path within maxDepth.\",\n parameters: Type.Object({\n from: Type.String({ description: \"Start fact ID or entity name\" }),\n to: Type.String({ description: \"End fact ID or entity name\" }),\n maxDepth: Type.Optional(\n Type.Number({ description: `Max hops to traverse (default 5, max ${cfg.path.maxPathDepth})` }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const {\n from,\n to,\n maxDepth = 5,\n } = params as {\n from: string;\n to: string;\n maxDepth?: number;\n };\n\n const depthCap = Math.min(cfg.path.maxPathDepth, Math.max(1, Math.floor(maxDepth)));\n\n const fromId = resolveInput(factsDb, from);\n if (!fromId) {\n return {\n content: [\n { type: \"text\", text: `Could not resolve start: \"${from}\" (not a known fact ID or entity name)` },\n ],\n details: { error: \"from_not_found\", from },\n };\n }\n\n const toId = resolveInput(factsDb, to);\n if (!toId) {\n return {\n content: [{ type: \"text\", text: `Could not resolve end: \"${to}\" (not a known fact ID or entity name)` }],\n details: { error: \"to_not_found\", to },\n };\n }\n\n const result = findShortestPath(factsDb, fromId, toId, { maxDepth: depthCap });\n\n if (!result) {\n return {\n content: [{ type: \"text\", text: `No path found between \"${from}\" and \"${to}\" within ${depthCap} hops.` }],\n details: { found: false, fromId, toId, maxDepth: depthCap },\n };\n }\n\n const lines: string[] = [\n `Path found: ${result.hops} hop${result.hops === 1 ? \"\" : \"s\"}`,\n \"\",\n formatPath(result.steps),\n \"\",\n \"Chain:\",\n ];\n for (let i = 0; i < result.chain.length; i++) {\n const entry = result.chain[i];\n const step = result.steps[i - 1];\n if (step) {\n lines.push(` —[${step.linkType}]→`);\n }\n lines.push(` [${entry.id.slice(0, 8)}…] ${entry.text.slice(0, 80)}${entry.text.length > 80 ? \"…\" : \"\"}`);\n }\n\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n details: {\n found: true,\n fromId,\n toId,\n hops: result.hops,\n steps: result.steps,\n },\n };\n },\n },\n { name: \"memory_path\" },\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-tools.js","names":[],"sources":["../../tools/issue-tools.ts"],"sourcesContent":["/**\n * Issue Tool Registrations — Issue #137\n *\n * Tools for creating, updating, listing, searching, and linking issues\n * through their lifecycle (open → diagnosed → fix-attempted → resolved → verified).\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport type { ClawdbotPluginApi } from \"openclaw/plugin-sdk/core\";\nimport { stringEnum } from \"../utils/typebox.js\";\n\nimport type { IssueStore } from \"../backends/issue-store.js\";\nimport type { HybridMemoryConfig } from \"../config.js\";\nimport { isCompactVerbosity } from \"../config.js\";\nimport type { IssueSeverity, IssueStatus } from \"../types/issue-types.js\";\nimport { withErrorTracking } from \"../utils/error-tracking.js\";\n\nconst ISSUE_STATUSES = [\"open\", \"diagnosed\", \"fix-attempted\", \"resolved\", \"verified\", \"wont-fix\"] as const;\n\nconst ISSUE_SEVERITIES = [\"low\", \"medium\", \"high\", \"critical\"] as const;\n\ninterface IssueToolsContext {\n issueStore: IssueStore;\n /** Optional config for verbosity-aware output (Issue #282). */\n cfg?: Pick<HybridMemoryConfig, \"verbosity\">;\n}\n\nexport function registerIssueTools(ctx: IssueToolsContext, api: ClawdbotPluginApi): void {\n const { issueStore } = ctx;\n const verbosity = ctx.cfg?.verbosity ?? \"normal\";\n\n // -------------------------------------------------------------------------\n // memory_issue_create\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_create\",\n label: \"Create Issue\",\n description:\n \"Create a new tracked issue. Use when a problem is detected that needs structured lifecycle tracking (open → diagnosed → fix-attempted → resolved → verified).\",\n parameters: Type.Object({\n title: Type.String({ description: \"Short descriptive title for the issue\" }),\n symptoms: Type.Array(Type.String(), {\n description: \"Observable symptoms or error messages\",\n }),\n severity: Type.Optional(stringEnum(ISSUE_SEVERITIES as unknown as readonly string[])),\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Optional tags for categorization\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { title, symptoms, severity, tags } = params as {\n title: string;\n symptoms: string[];\n severity?: IssueSeverity;\n tags?: string[];\n };\n\n const issue = withErrorTracking(() => issueStore.create({ title, symptoms, severity, tags }), {\n subsystem: \"issues\",\n operation: \"issue-create\",\n phase: \"runtime\",\n })();\n const createText = isCompactVerbosity(verbosity)\n ? `Issue: ${issue.id}.`\n : `Created issue \"${issue.title}\" [${issue.id}] (status: ${issue.status}, severity: ${issue.severity})`;\n return {\n content: [\n {\n type: \"text\",\n text: createText,\n },\n ],\n details: issue,\n };\n },\n },\n { name: \"memory_issue_create\" },\n );\n\n // -------------------------------------------------------------------------\n // memory_issue_update\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_update\",\n label: \"Update Issue\",\n description:\n \"Update an issue's fields or advance its status through the lifecycle. Status changes validate allowed transitions. Setting status to 'resolved' auto-sets resolvedAt; 'verified' auto-sets verifiedAt.\",\n parameters: Type.Object({\n id: Type.String({ description: \"Issue ID to update\" }),\n status: Type.Optional(stringEnum(ISSUE_STATUSES as unknown as readonly string[])),\n rootCause: Type.Optional(Type.String({ description: \"Root cause diagnosis\" })),\n fix: Type.Optional(Type.String({ description: \"Description of the applied fix\" })),\n rollback: Type.Optional(Type.String({ description: \"Rollback procedure if fix fails\" })),\n symptoms: Type.Optional(Type.Array(Type.String(), { description: \"Updated list of symptoms\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { id, status, rootCause, fix, rollback, symptoms } = params as {\n id: string;\n status?: IssueStatus;\n rootCause?: string;\n fix?: string;\n rollback?: string;\n symptoms?: string[];\n };\n\n const issue = withErrorTracking(\n () => {\n // Use transition() to validate state machine\n if (status) {\n return issueStore.transition(id, status, { rootCause, fix, rollback, symptoms });\n }\n return issueStore.update(id, { rootCause, fix, rollback, symptoms });\n },\n {\n subsystem: \"issues\",\n operation: \"issue-update\",\n phase: \"runtime\",\n },\n )();\n\n const updateText = isCompactVerbosity(verbosity)\n ? `Issue ${issue.id}: ${issue.status}.`\n : `Updated issue \"${issue.title}\" [${issue.id}] (status: ${issue.status})`;\n return {\n content: [\n {\n type: \"text\",\n text: updateText,\n },\n ],\n details: issue,\n };\n },\n },\n { name: \"memory_issue_update\" },\n );\n\n // -------------------------------------------------------------------------\n // memory_issue_list\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_list\",\n label: \"List Issues\",\n description: \"List tracked issues with optional filters by status, severity, and tags.\",\n parameters: Type.Object({\n status: Type.Optional(\n Type.Array(stringEnum(ISSUE_STATUSES as unknown as readonly string[]), {\n description: \"Filter by status values\",\n }),\n ),\n severity: Type.Optional(\n Type.Array(stringEnum(ISSUE_SEVERITIES as unknown as readonly string[]), {\n description: \"Filter by severity values\",\n }),\n ),\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Filter by tags (any match)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 50)\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { status, severity, tags, limit } = params as {\n status?: IssueStatus[];\n severity?: string[];\n tags?: string[];\n limit?: number;\n };\n\n const issues = withErrorTracking(() => issueStore.list({ status, severity, tags, limit }), {\n subsystem: \"issues\",\n operation: \"issue-list\",\n phase: \"runtime\",\n })();\n const summary = issues.map((i) => `[${i.id.slice(0, 8)}] ${i.title} — ${i.status} (${i.severity})`).join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: issues.length === 0 ? \"No issues found.\" : `${issues.length} issue(s):\\n${summary}`,\n },\n ],\n details: issues,\n };\n },\n },\n { name: \"memory_issue_list\" },\n );\n\n // -------------------------------------------------------------------------\n // memory_issue_search\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_search\",\n label: \"Search Issues\",\n description: \"Search issues by title and symptoms using LIKE-based text matching.\",\n parameters: Type.Object({\n query: Type.String({ description: \"Search query to match against issue title and symptoms\" }),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { query } = params as { query: string };\n\n const issues = withErrorTracking(() => issueStore.search(query), {\n subsystem: \"issues\",\n operation: \"issue-search\",\n phase: \"runtime\",\n })();\n const summary = issues.map((i) => `[${i.id.slice(0, 8)}] ${i.title} — ${i.status} (${i.severity})`).join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text:\n issues.length === 0\n ? `No issues found for query: \"${query}\"`\n : `${issues.length} issue(s) matching \"${query}\":\\n${summary}`,\n },\n ],\n details: issues,\n };\n },\n },\n { name: \"memory_issue_search\" },\n );\n\n // -------------------------------------------------------------------------\n // memory_issue_link_fact\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_link_fact\",\n label: \"Link Fact to Issue\",\n description:\n \"Associate a memory fact with an issue for cross-referencing problem context with supporting knowledge.\",\n parameters: Type.Object({\n issueId: Type.String({ description: \"Issue ID\" }),\n factId: Type.String({ description: \"Fact ID to link to the issue\" }),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { issueId, factId } = params as { issueId: string; factId: string };\n\n withErrorTracking(() => issueStore.linkFact(issueId, factId), {\n subsystem: \"issues\",\n operation: \"issue-link-fact\",\n phase: \"runtime\",\n })();\n return {\n content: [\n {\n type: \"text\",\n text: `Linked fact ${factId} to issue ${issueId}.`,\n },\n ],\n details: { issueId, factId },\n };\n },\n },\n { name: \"memory_issue_link_fact\" },\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"issue-tools.js","names":[],"sources":["../../tools/issue-tools.ts"],"sourcesContent":["/**\n * Issue Tool Registrations — Issue #137\n *\n * Tools for creating, updating, listing, searching, and linking issues\n * through their lifecycle (open → diagnosed → fix-attempted → resolved → verified).\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport type { ClawdbotPluginApi } from \"openclaw/plugin-sdk/core\";\nimport { stringEnum } from \"../utils/typebox.js\";\n\nimport type { IssueStore } from \"../backends/issue-store.js\";\nimport type { HybridMemoryConfig } from \"../config.js\";\nimport { isCompactVerbosity } from \"../config.js\";\nimport type { IssueSeverity, IssueStatus } from \"../types/issue-types.js\";\nimport { withErrorTracking } from \"../utils/error-tracking.js\";\n\nconst ISSUE_STATUSES = [\"open\", \"diagnosed\", \"fix-attempted\", \"resolved\", \"verified\", \"wont-fix\"] as const;\n\nconst ISSUE_SEVERITIES = [\"low\", \"medium\", \"high\", \"critical\"] as const;\n\ninterface IssueToolsContext {\n issueStore: IssueStore;\n /** Optional config for verbosity-aware output (Issue #282). */\n cfg?: Pick<HybridMemoryConfig, \"verbosity\">;\n}\n\nexport function registerIssueTools(ctx: IssueToolsContext, api: ClawdbotPluginApi): void {\n const { issueStore } = ctx;\n const verbosity = ctx.cfg?.verbosity ?? \"normal\";\n\n // -------------------------------------------------------------------------\n // memory_issue_create\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_create\",\n label: \"Create Issue\",\n description:\n \"Create a new tracked issue. Use when a problem is detected that needs structured lifecycle tracking (open → diagnosed → fix-attempted → resolved → verified).\",\n parameters: Type.Object({\n title: Type.String({ description: \"Short descriptive title for the issue\" }),\n symptoms: Type.Array(Type.String(), {\n description: \"Observable symptoms or error messages\",\n }),\n severity: Type.Optional(stringEnum(ISSUE_SEVERITIES as unknown as readonly string[])),\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Optional tags for categorization\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { title, symptoms, severity, tags } = params as {\n title: string;\n symptoms: string[];\n severity?: IssueSeverity;\n tags?: string[];\n };\n\n const issue = withErrorTracking(() => issueStore.create({ title, symptoms, severity, tags }), {\n subsystem: \"issues\",\n operation: \"issue-create\",\n phase: \"runtime\",\n })();\n const createText = isCompactVerbosity(verbosity)\n ? `Issue: ${issue.id}.`\n : `Created issue \"${issue.title}\" [${issue.id}] (status: ${issue.status}, severity: ${issue.severity})`;\n return {\n content: [\n {\n type: \"text\",\n text: createText,\n },\n ],\n details: issue,\n };\n },\n },\n { name: \"memory_issue_create\" },\n );\n\n // -------------------------------------------------------------------------\n // memory_issue_update\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_update\",\n label: \"Update Issue\",\n description:\n \"Update an issue's fields or advance its status through the lifecycle. Status changes validate allowed transitions. Setting status to 'resolved' auto-sets resolvedAt; 'verified' auto-sets verifiedAt.\",\n parameters: Type.Object({\n id: Type.String({ description: \"Issue ID to update\" }),\n status: Type.Optional(stringEnum(ISSUE_STATUSES as unknown as readonly string[])),\n rootCause: Type.Optional(Type.String({ description: \"Root cause diagnosis\" })),\n fix: Type.Optional(Type.String({ description: \"Description of the applied fix\" })),\n rollback: Type.Optional(Type.String({ description: \"Rollback procedure if fix fails\" })),\n symptoms: Type.Optional(Type.Array(Type.String(), { description: \"Updated list of symptoms\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { id, status, rootCause, fix, rollback, symptoms } = params as {\n id: string;\n status?: IssueStatus;\n rootCause?: string;\n fix?: string;\n rollback?: string;\n symptoms?: string[];\n };\n\n const issue = withErrorTracking(\n () => {\n // Use transition() to validate state machine\n if (status) {\n return issueStore.transition(id, status, { rootCause, fix, rollback, symptoms });\n }\n return issueStore.update(id, { rootCause, fix, rollback, symptoms });\n },\n {\n subsystem: \"issues\",\n operation: \"issue-update\",\n phase: \"runtime\",\n },\n )();\n\n const updateText = isCompactVerbosity(verbosity)\n ? `Issue ${issue.id}: ${issue.status}.`\n : `Updated issue \"${issue.title}\" [${issue.id}] (status: ${issue.status})`;\n return {\n content: [\n {\n type: \"text\",\n text: updateText,\n },\n ],\n details: issue,\n };\n },\n },\n { name: \"memory_issue_update\" },\n );\n\n // -------------------------------------------------------------------------\n // memory_issue_list\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_list\",\n label: \"List Issues\",\n description: \"List tracked issues with optional filters by status, severity, and tags.\",\n parameters: Type.Object({\n status: Type.Optional(\n Type.Array(stringEnum(ISSUE_STATUSES as unknown as readonly string[]), {\n description: \"Filter by status values\",\n }),\n ),\n severity: Type.Optional(\n Type.Array(stringEnum(ISSUE_SEVERITIES as unknown as readonly string[]), {\n description: \"Filter by severity values\",\n }),\n ),\n tags: Type.Optional(Type.Array(Type.String(), { description: \"Filter by tags (any match)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 50)\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { status, severity, tags, limit } = params as {\n status?: IssueStatus[];\n severity?: string[];\n tags?: string[];\n limit?: number;\n };\n\n const issues = withErrorTracking(() => issueStore.list({ status, severity, tags, limit }), {\n subsystem: \"issues\",\n operation: \"issue-list\",\n phase: \"runtime\",\n })();\n const summary = issues.map((i) => `[${i.id.slice(0, 8)}] ${i.title} — ${i.status} (${i.severity})`).join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: issues.length === 0 ? \"No issues found.\" : `${issues.length} issue(s):\\n${summary}`,\n },\n ],\n details: issues,\n };\n },\n },\n { name: \"memory_issue_list\" },\n );\n\n // -------------------------------------------------------------------------\n // memory_issue_search\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_search\",\n label: \"Search Issues\",\n description: \"Search issues by title and symptoms using LIKE-based text matching.\",\n parameters: Type.Object({\n query: Type.String({ description: \"Search query to match against issue title and symptoms\" }),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { query } = params as { query: string };\n\n const issues = withErrorTracking(() => issueStore.search(query), {\n subsystem: \"issues\",\n operation: \"issue-search\",\n phase: \"runtime\",\n })();\n const summary = issues.map((i) => `[${i.id.slice(0, 8)}] ${i.title} — ${i.status} (${i.severity})`).join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text:\n issues.length === 0\n ? `No issues found for query: \"${query}\"`\n : `${issues.length} issue(s) matching \"${query}\":\\n${summary}`,\n },\n ],\n details: issues,\n };\n },\n },\n { name: \"memory_issue_search\" },\n );\n\n // -------------------------------------------------------------------------\n // memory_issue_link_fact\n // -------------------------------------------------------------------------\n api.registerTool(\n {\n name: \"memory_issue_link_fact\",\n label: \"Link Fact to Issue\",\n description:\n \"Associate a memory fact with an issue for cross-referencing problem context with supporting knowledge.\",\n parameters: Type.Object({\n issueId: Type.String({ description: \"Issue ID\" }),\n factId: Type.String({ description: \"Fact ID to link to the issue\" }),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n const { issueId, factId } = params as { issueId: string; factId: string };\n\n withErrorTracking(() => issueStore.linkFact(issueId, factId), {\n subsystem: \"issues\",\n operation: \"issue-link-fact\",\n phase: \"runtime\",\n })();\n return {\n content: [\n {\n type: \"text\",\n text: `Linked fact ${factId} to issue ${issueId}.`,\n },\n ],\n details: { issueId, factId },\n };\n },\n },\n { name: \"memory_issue_link_fact\" },\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-runtime.js","names":[],"sources":["../../../tools/memory/build-runtime.ts"],"sourcesContent":["import type { ClawdbotPluginApi } from \"openclaw/plugin-sdk/core\";\nimport { TASK_LEDGER_CATEGORY, refreshActiveTaskProjectionBestEffort } from \"../../services/task-ledger-facts.js\";\nimport { storeCanonicalVectorForFact } from \"../../services/vector-maintenance.js\";\nimport { parseDuration } from \"../../utils/duration.js\";\nimport { resolveWorkspacePath } from \"../../utils/path.js\";\nimport type { MemoryToolsContext } from \"./types.js\";\nimport type { MemoryToolRuntime } from \"./runtime.js\";\nimport { isEdictWriteToolEnabled, sanitizeScopeParam, storeRegistryEmbeddings } from \"./helpers.js\";\n\nexport function buildMemoryToolRuntime(resolvedContext: MemoryToolsContext, api: ClawdbotPluginApi): MemoryToolRuntime {\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 } = resolvedContext;\n\n const agentIdForAudit = () => currentAgentIdRef.value || cfg.multiAgent.orchestratorId || \"unknown\";\n\n function auditAppend(input: import(\"../../backends/audit-store.js\").AuditEventInput): void {\n if (!auditStore) return;\n try {\n auditStore.append(input);\n } catch {\n /* non-fatal */\n }\n }\n\n const activeTaskCfg = cfg.activeTask;\n const activeTaskProjectionPath = activeTaskCfg ? resolveWorkspacePath(activeTaskCfg.filePath) : null;\n const activeTaskStaleMinutes = (() => {\n if (!activeTaskCfg) return parseDuration(\"24h\");\n try {\n return parseDuration(activeTaskCfg.staleThreshold);\n } catch {\n return parseDuration(\"24h\");\n }\n })();\n\n const maybeRefreshProjectActiveTaskProjection = async (\n factCategory: string,\n factId: string,\n factScope: string | null | undefined,\n ): Promise<void> => {\n if (!activeTaskCfg?.enabled || activeTaskCfg.ledger !== \"facts\" || !activeTaskProjectionPath) return;\n if (factCategory !== TASK_LEDGER_CATEGORY) return;\n if ((factScope ?? \"global\") !== \"global\") return;\n await refreshActiveTaskProjectionBestEffort({\n factsDb,\n staleMinutes: activeTaskStaleMinutes,\n filePath: activeTaskProjectionPath,\n projection: activeTaskCfg.projection,\n reason: \"memory_store_project_fact_write\",\n source: \"memory_store\",\n factId,\n logger: api.logger,\n });\n };\n\n const storeActiveCanonicalVector = async (options: {\n factId: string;\n text: string;\n why?: string | null;\n vector: number[];\n importance: number;\n category: string;\n }): Promise<void> => {\n await storeCanonicalVectorForFact({\n vectorDb,\n factsDb,\n factId: options.factId,\n text: options.text,\n why: options.why,\n vector: options.vector,\n importance: options.importance,\n category: options.category,\n embeddingModel: embeddings.modelName,\n });\n };\n\n return {\n ...resolvedContext,\n api,\n auditAppend,\n agentIdForAudit,\n maybeRefreshProjectActiveTaskProjection,\n storeActiveCanonicalVector,\n storeRegistryEmbeddings,\n isEdictWriteToolEnabled,\n sanitizeScopeParam,\n };\n}\n"],"mappings":";;;;;;AASA,SAAgB,uBAAuB,iBAAqC,KAA2C;CACrH,MAAM,EACJ,SACA,YACA,UACA,KACA,YACA,QACA,eACA,UACA,cACA,mBACA,SACA,mBACA,mBACA,yBACA,mBACA,oBACA,cACA,sBACA,UACA,WACA,wBACA,eACE;CAEJ,MAAM,wBAAwB,kBAAkB,SAAS,IAAI,WAAW,kBAAkB;CAE1F,SAAS,YAAY,OAAsE;EACzF,IAAI,CAAC,YAAY;EACjB,IAAI;GACF,WAAW,OAAO,
|
|
1
|
+
{"version":3,"file":"build-runtime.js","names":[],"sources":["../../../tools/memory/build-runtime.ts"],"sourcesContent":["import type { ClawdbotPluginApi } from \"openclaw/plugin-sdk/core\";\nimport { TASK_LEDGER_CATEGORY, refreshActiveTaskProjectionBestEffort } from \"../../services/task-ledger-facts.js\";\nimport { storeCanonicalVectorForFact } from \"../../services/vector-maintenance.js\";\nimport { parseDuration } from \"../../utils/duration.js\";\nimport { resolveWorkspacePath } from \"../../utils/path.js\";\nimport type { MemoryToolsContext } from \"./types.js\";\nimport type { MemoryToolRuntime } from \"./runtime.js\";\nimport { isEdictWriteToolEnabled, sanitizeScopeParam, storeRegistryEmbeddings } from \"./helpers.js\";\n\nexport function buildMemoryToolRuntime(resolvedContext: MemoryToolsContext, api: ClawdbotPluginApi): MemoryToolRuntime {\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 } = resolvedContext;\n\n const agentIdForAudit = () => currentAgentIdRef.value || cfg.multiAgent.orchestratorId || \"unknown\";\n\n function auditAppend(input: import(\"../../backends/audit-store.js\").AuditEventInput): void {\n if (!auditStore) return;\n try {\n auditStore.append(input);\n } catch {\n /* non-fatal */\n }\n }\n\n const activeTaskCfg = cfg.activeTask;\n const activeTaskProjectionPath = activeTaskCfg ? resolveWorkspacePath(activeTaskCfg.filePath) : null;\n const activeTaskStaleMinutes = (() => {\n if (!activeTaskCfg) return parseDuration(\"24h\");\n try {\n return parseDuration(activeTaskCfg.staleThreshold);\n } catch {\n return parseDuration(\"24h\");\n }\n })();\n\n const maybeRefreshProjectActiveTaskProjection = async (\n factCategory: string,\n factId: string,\n factScope: string | null | undefined,\n ): Promise<void> => {\n if (!activeTaskCfg?.enabled || activeTaskCfg.ledger !== \"facts\" || !activeTaskProjectionPath) return;\n if (factCategory !== TASK_LEDGER_CATEGORY) return;\n if ((factScope ?? \"global\") !== \"global\") return;\n await refreshActiveTaskProjectionBestEffort({\n factsDb,\n staleMinutes: activeTaskStaleMinutes,\n filePath: activeTaskProjectionPath,\n projection: activeTaskCfg.projection,\n reason: \"memory_store_project_fact_write\",\n source: \"memory_store\",\n factId,\n logger: api.logger,\n });\n };\n\n const storeActiveCanonicalVector = async (options: {\n factId: string;\n text: string;\n why?: string | null;\n vector: number[];\n importance: number;\n category: string;\n }): Promise<void> => {\n await storeCanonicalVectorForFact({\n vectorDb,\n factsDb,\n factId: options.factId,\n text: options.text,\n why: options.why,\n vector: options.vector,\n importance: options.importance,\n category: options.category,\n embeddingModel: embeddings.modelName,\n });\n };\n\n return {\n ...resolvedContext,\n api,\n auditAppend,\n agentIdForAudit,\n maybeRefreshProjectActiveTaskProjection,\n storeActiveCanonicalVector,\n storeRegistryEmbeddings,\n isEdictWriteToolEnabled,\n sanitizeScopeParam,\n };\n}\n"],"mappings":";;;;;;AASA,SAAgB,uBAAuB,iBAAqC,KAA2C;CACrH,MAAM,EACJ,SACA,YACA,UACA,KACA,YACA,QACA,eACA,UACA,cACA,mBACA,SACA,mBACA,mBACA,yBACA,mBACA,oBACA,cACA,sBACA,UACA,WACA,wBACA,eACE;CAEJ,MAAM,wBAAwB,kBAAkB,SAAS,IAAI,WAAW,kBAAkB;CAE1F,SAAS,YAAY,OAAsE;EACzF,IAAI,CAAC,YAAY;EACjB,IAAI;GACF,WAAW,OAAO,KAAK;EACzB,QAAQ,CAER;CACF;CAEA,MAAM,gBAAgB,IAAI;CAC1B,MAAM,2BAA2B,gBAAgB,qBAAqB,cAAc,QAAQ,IAAI;CAChG,MAAM,gCAAgC;EACpC,IAAI,CAAC,eAAe,OAAO,cAAc,KAAK;EAC9C,IAAI;GACF,OAAO,cAAc,cAAc,cAAc;EACnD,QAAQ;GACN,OAAO,cAAc,KAAK;EAC5B;CACF,GAAG;CAEH,MAAM,0CAA0C,OAC9C,cACA,QACA,cACkB;EAClB,IAAI,CAAC,eAAe,WAAW,cAAc,WAAW,WAAW,CAAC,0BAA0B;EAC9F,IAAI,iBAAA,WAAuC;EAC3C,KAAK,aAAa,cAAc,UAAU;EAC1C,MAAM,sCAAsC;GAC1C;GACA,cAAc;GACd,UAAU;GACV,YAAY,cAAc;GAC1B,QAAQ;GACR,QAAQ;GACR;GACA,QAAQ,IAAI;EACd,CAAC;CACH;CAEA,MAAM,6BAA6B,OAAO,YAOrB;EACnB,MAAM,4BAA4B;GAChC;GACA;GACA,QAAQ,QAAQ;GAChB,MAAM,QAAQ;GACd,KAAK,QAAQ;GACb,QAAQ,QAAQ;GAChB,YAAY,QAAQ;GACpB,UAAU,QAAQ;GAClB,gBAAgB,WAAW;EAC7B,CAAC;CACH;CAEA,OAAO;EACL,GAAG;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","names":[],"sources":["../../../tools/memory/helpers.ts"],"sourcesContent":["import { toFloat32Array } from \"../../services/embedding-registry.js\";\nimport type { EmbeddingProvider } from \"../../services/embeddings.js\";\nimport type { FactsDB } from \"../../backends/facts-db.js\";\nimport { capturePluginError } from \"../../services/error-reporter.js\";\nimport { embedCallWithTimeoutAndRetry } from \"../../utils/embed-call.js\";\nimport { getEnv } from \"../../utils/env-manager.js\";\nimport type { BuildToolScopeFilterFn, FindSimilarByEmbeddingFn } from \"../../api/memory-plugin-api.js\";\nimport type { MemoryToolsContext } from \"./types.js\";\n\nexport const SCOPE_PARAM_MAX_LENGTH = 256;\n\nexport function sanitizeScopeParam(\n paramName: \"userId\" | \"agentId\" | \"sessionId\",\n v: string | undefined,\n): string | undefined {\n if (v === undefined) return undefined;\n if (v.length > SCOPE_PARAM_MAX_LENGTH) {\n throw new Error(`${paramName} must be <= ${SCOPE_PARAM_MAX_LENGTH} characters`);\n }\n return v;\n}\n\ntype LegacyMemoryToolsContext = Omit<\n MemoryToolsContext,\n \"buildToolScopeFilter\" | \"walWrite\" | \"walRemove\" | \"findSimilarByEmbedding\"\n> & {\n wal?: unknown;\n};\n\nexport function hasBoundMemoryToolHelpers(\n ctx: MemoryToolsContext | LegacyMemoryToolsContext,\n): ctx is MemoryToolsContext {\n const maybe = ctx as Partial<MemoryToolsContext> & { wal?: unknown };\n const hasAllNewHelpers =\n typeof maybe.buildToolScopeFilter === \"function\" &&\n typeof maybe.walWrite === \"function\" &&\n typeof maybe.walRemove === \"function\" &&\n typeof maybe.findSimilarByEmbedding === \"function\";\n const hasLegacyWal = typeof maybe.wal === \"object\" && maybe.wal !== null;\n return hasAllNewHelpers && !hasLegacyWal;\n}\n\nexport function isEdictWriteToolEnabled(): boolean {\n const raw = getEnv(\"OPENCLAW_ENABLE_EDICT_WRITE_TOOL\");\n return raw === \"1\" || raw?.toLowerCase() === \"true\";\n}\n\nexport async function storeRegistryEmbeddings({\n factsDb,\n embeddingRegistry,\n embeddings,\n factId,\n text,\n vector,\n logger,\n operation,\n}: {\n factsDb: FactsDB;\n embeddingRegistry: import(\"../../services/embedding-registry.js\").EmbeddingRegistry | null | undefined;\n embeddings: EmbeddingProvider;\n factId: string;\n text: string;\n vector?: number[] | Float32Array;\n logger: { warn: (msg: string) => void };\n operation: string;\n}): Promise<void> {\n if (!embeddingRegistry) return;\n const vectors = new Map<string, Float32Array>();\n if (vector && vector.length > 0) {\n vectors.set(embeddings.modelName, toFloat32Array(vector));\n }\n if (embeddingRegistry.isMultiModel()) {\n const models = embeddingRegistry.getModels();\n const tasks = models.map(async (cfg) => ({\n name: cfg.name,\n vec: await embedCallWithTimeoutAndRetry(\n () => embeddingRegistry.embed(text, cfg.name),\n `${operation}:${cfg.name}`,\n ),\n }));\n const settled = await Promise.allSettled(tasks);\n for (const s of settled) {\n if (s.status === \"fulfilled\") {\n vectors.set(s.value.name, s.value.vec);\n } else {\n capturePluginError(s.reason instanceof Error ? s.reason : new Error(String(s.reason)), {\n subsystem: \"embeddings\",\n operation,\n });\n }\n }\n if (!vector) {\n try {\n const vec = await embedCallWithTimeoutAndRetry(() => embeddingRegistry.embed(text), `${operation}:primary`);\n const modelName = embeddings.modelName || embeddingRegistry.getPrimaryModel().name;\n vectors.set(modelName, vec);\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"embeddings\",\n operation,\n });\n }\n }\n } else if (!vector) {\n try {\n const vec = await embedCallWithTimeoutAndRetry(() => embeddingRegistry.embed(text), `${operation}:primary`);\n const modelName = embeddings.modelName || embeddingRegistry.getPrimaryModel().name;\n vectors.set(modelName, vec);\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"embeddings\",\n operation,\n });\n }\n }\n if (vectors.size === 0) {\n logger.warn(\n `memory-hybrid: embeddingRegistry produced no vectors for fact ${factId} (${operation}) — caller should treat as embedding failure`,\n );\n return;\n }\n for (const [model, vec] of vectors) {\n try {\n factsDb.storeEmbedding(factId, model, \"canonical\", vec, vec.length);\n } catch (err) {\n logger.warn(`memory-hybrid: fact_embeddings store failed (${model}): ${err}`);\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"fact-embeddings\",\n operation,\n });\n }\n }\n}\n\nexport function resolveMemoryToolsContext(\n ctx: MemoryToolsContext | LegacyMemoryToolsContext,\n legacyBuildToolScopeFilter?: BuildToolScopeFilterFn,\n legacyWalWrite?: import(\"./types.js\").BoundWalWriteFn,\n legacyWalRemove?: import(\"./types.js\").BoundWalRemoveFn,\n legacyFindSimilarByEmbedding?: FindSimilarByEmbeddingFn,\n): MemoryToolsContext {\n if (hasBoundMemoryToolHelpers(ctx)) {\n return ctx;\n }\n if (\n typeof legacyBuildToolScopeFilter !== \"function\" ||\n typeof legacyWalWrite !== \"function\" ||\n typeof legacyWalRemove !== \"function\" ||\n typeof legacyFindSimilarByEmbedding !== \"function\"\n ) {\n throw new Error(\"registerMemoryTools: Missing required legacy helper functions for memory tools initialization.\");\n }\n return {\n ...ctx,\n buildToolScopeFilter: legacyBuildToolScopeFilter,\n walWrite: legacyWalWrite,\n walRemove: legacyWalRemove,\n findSimilarByEmbedding: legacyFindSimilarByEmbedding,\n };\n}\n"],"mappings":";;;;AAWA,SAAgB,mBACd,WACA,GACoB;CACpB,IAAI,MAAM,KAAA,GAAW,OAAO,KAAA;CAC5B,IAAI,EAAE,SAAA,KACJ,MAAM,IAAI,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"helpers.js","names":[],"sources":["../../../tools/memory/helpers.ts"],"sourcesContent":["import { toFloat32Array } from \"../../services/embedding-registry.js\";\nimport type { EmbeddingProvider } from \"../../services/embeddings.js\";\nimport type { FactsDB } from \"../../backends/facts-db.js\";\nimport { capturePluginError } from \"../../services/error-reporter.js\";\nimport { embedCallWithTimeoutAndRetry } from \"../../utils/embed-call.js\";\nimport { getEnv } from \"../../utils/env-manager.js\";\nimport type { BuildToolScopeFilterFn, FindSimilarByEmbeddingFn } from \"../../api/memory-plugin-api.js\";\nimport type { MemoryToolsContext } from \"./types.js\";\n\nexport const SCOPE_PARAM_MAX_LENGTH = 256;\n\nexport function sanitizeScopeParam(\n paramName: \"userId\" | \"agentId\" | \"sessionId\",\n v: string | undefined,\n): string | undefined {\n if (v === undefined) return undefined;\n if (v.length > SCOPE_PARAM_MAX_LENGTH) {\n throw new Error(`${paramName} must be <= ${SCOPE_PARAM_MAX_LENGTH} characters`);\n }\n return v;\n}\n\ntype LegacyMemoryToolsContext = Omit<\n MemoryToolsContext,\n \"buildToolScopeFilter\" | \"walWrite\" | \"walRemove\" | \"findSimilarByEmbedding\"\n> & {\n wal?: unknown;\n};\n\nexport function hasBoundMemoryToolHelpers(\n ctx: MemoryToolsContext | LegacyMemoryToolsContext,\n): ctx is MemoryToolsContext {\n const maybe = ctx as Partial<MemoryToolsContext> & { wal?: unknown };\n const hasAllNewHelpers =\n typeof maybe.buildToolScopeFilter === \"function\" &&\n typeof maybe.walWrite === \"function\" &&\n typeof maybe.walRemove === \"function\" &&\n typeof maybe.findSimilarByEmbedding === \"function\";\n const hasLegacyWal = typeof maybe.wal === \"object\" && maybe.wal !== null;\n return hasAllNewHelpers && !hasLegacyWal;\n}\n\nexport function isEdictWriteToolEnabled(): boolean {\n const raw = getEnv(\"OPENCLAW_ENABLE_EDICT_WRITE_TOOL\");\n return raw === \"1\" || raw?.toLowerCase() === \"true\";\n}\n\nexport async function storeRegistryEmbeddings({\n factsDb,\n embeddingRegistry,\n embeddings,\n factId,\n text,\n vector,\n logger,\n operation,\n}: {\n factsDb: FactsDB;\n embeddingRegistry: import(\"../../services/embedding-registry.js\").EmbeddingRegistry | null | undefined;\n embeddings: EmbeddingProvider;\n factId: string;\n text: string;\n vector?: number[] | Float32Array;\n logger: { warn: (msg: string) => void };\n operation: string;\n}): Promise<void> {\n if (!embeddingRegistry) return;\n const vectors = new Map<string, Float32Array>();\n if (vector && vector.length > 0) {\n vectors.set(embeddings.modelName, toFloat32Array(vector));\n }\n if (embeddingRegistry.isMultiModel()) {\n const models = embeddingRegistry.getModels();\n const tasks = models.map(async (cfg) => ({\n name: cfg.name,\n vec: await embedCallWithTimeoutAndRetry(\n () => embeddingRegistry.embed(text, cfg.name),\n `${operation}:${cfg.name}`,\n ),\n }));\n const settled = await Promise.allSettled(tasks);\n for (const s of settled) {\n if (s.status === \"fulfilled\") {\n vectors.set(s.value.name, s.value.vec);\n } else {\n capturePluginError(s.reason instanceof Error ? s.reason : new Error(String(s.reason)), {\n subsystem: \"embeddings\",\n operation,\n });\n }\n }\n if (!vector) {\n try {\n const vec = await embedCallWithTimeoutAndRetry(() => embeddingRegistry.embed(text), `${operation}:primary`);\n const modelName = embeddings.modelName || embeddingRegistry.getPrimaryModel().name;\n vectors.set(modelName, vec);\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"embeddings\",\n operation,\n });\n }\n }\n } else if (!vector) {\n try {\n const vec = await embedCallWithTimeoutAndRetry(() => embeddingRegistry.embed(text), `${operation}:primary`);\n const modelName = embeddings.modelName || embeddingRegistry.getPrimaryModel().name;\n vectors.set(modelName, vec);\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"embeddings\",\n operation,\n });\n }\n }\n if (vectors.size === 0) {\n logger.warn(\n `memory-hybrid: embeddingRegistry produced no vectors for fact ${factId} (${operation}) — caller should treat as embedding failure`,\n );\n return;\n }\n for (const [model, vec] of vectors) {\n try {\n factsDb.storeEmbedding(factId, model, \"canonical\", vec, vec.length);\n } catch (err) {\n logger.warn(`memory-hybrid: fact_embeddings store failed (${model}): ${err}`);\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"fact-embeddings\",\n operation,\n });\n }\n }\n}\n\nexport function resolveMemoryToolsContext(\n ctx: MemoryToolsContext | LegacyMemoryToolsContext,\n legacyBuildToolScopeFilter?: BuildToolScopeFilterFn,\n legacyWalWrite?: import(\"./types.js\").BoundWalWriteFn,\n legacyWalRemove?: import(\"./types.js\").BoundWalRemoveFn,\n legacyFindSimilarByEmbedding?: FindSimilarByEmbeddingFn,\n): MemoryToolsContext {\n if (hasBoundMemoryToolHelpers(ctx)) {\n return ctx;\n }\n if (\n typeof legacyBuildToolScopeFilter !== \"function\" ||\n typeof legacyWalWrite !== \"function\" ||\n typeof legacyWalRemove !== \"function\" ||\n typeof legacyFindSimilarByEmbedding !== \"function\"\n ) {\n throw new Error(\"registerMemoryTools: Missing required legacy helper functions for memory tools initialization.\");\n }\n return {\n ...ctx,\n buildToolScopeFilter: legacyBuildToolScopeFilter,\n walWrite: legacyWalWrite,\n walRemove: legacyWalRemove,\n findSimilarByEmbedding: legacyFindSimilarByEmbedding,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-checkpoint-tools.js","names":[],"sources":["../../../tools/memory/register-checkpoint-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 { runActiveTaskCheckpoint } from \"../../services/active-task-checkpoint.js\";\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerCheckpointTools(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 // ---------------------------------------------------------------------------\n // Active-task checkpoint tool (#1270)\n // ---------------------------------------------------------------------------\n\n {\n const _activeTaskCheckpointParams = Type.Object({\n entity: Type.String({ description: \"Stable task entity/label (category:project row key).\" }),\n status: Type.Optional(\n Type.String({\n description:\n \"Task status: open|in_progress|blocked|waiting|done|completed|closed|cancelled|abandoned|failed.\",\n }),\n ),\n owner: Type.Optional(Type.String({ description: \"Task owner (free-form, e.g. subagent/session/role).\" })),\n next: Type.Optional(Type.String({ description: \"Next concrete action for safe resume.\" })),\n relatedSession: Type.Optional(Type.String({ description: \"Related OpenClaw session key/id.\" })),\n title: Type.Optional(\n Type.String({ description: \"Human-readable task title (defaults to existing or Project task).\" }),\n ),\n resumeAt: Type.Optional(\n Type.String({\n description: \"Optional future ISO timestamp for wake/reminder scheduling via cron jobs store.\",\n }),\n ),\n state: Type.Optional(\n Type.Record(Type.String(), Type.Unknown(), {\n description: \"Structured checkpoint state object (serialized into facts + episode context).\",\n }),\n ),\n scheduleWake: Type.Optional(\n Type.Boolean({ description: \"When true (default), schedule wake job when resumeAt is supplied.\" }),\n ),\n refreshProjection: Type.Optional(\n Type.Boolean({\n description: \"When true, best-effort refresh ACTIVE-TASKS.md projection (activeTask.ledger=facts only).\",\n }),\n ),\n recordEpisode: Type.Optional(\n Type.Boolean({ description: \"When true (default), record an episode audit trail for the checkpoint.\" }),\n ),\n });\n const _activeTaskCheckpointDesc =\n \"Best-effort checkpoint active task state for reliable resume. One call updates project facts (status/next/owner/related_session/task_updated/title), records an episode audit trail, optionally schedules wake/reminder from resumeAt, and optionally refreshes ACTIVE-TASKS.md projection. Returns structured partial-failure details when later steps fail.\";\n const _execActiveTaskCheckpoint = async (_toolCallId: string, params: Record<string, unknown>) => {\n const scopeFilter = buildToolScopeFilter({}, currentAgentIdRef.value, cfg);\n try {\n const result = await runActiveTaskCheckpoint(\n {\n factsDb,\n vectorDb,\n embeddings,\n cfg,\n logger: api.logger,\n episodeScopeFilter: scopeFilter,\n },\n params as {\n entity?: string;\n status?: string;\n owner?: string;\n next?: string;\n relatedSession?: string;\n title?: string;\n resumeAt?: string;\n state?: Record<string, unknown>;\n scheduleWake?: boolean;\n refreshProjection?: boolean;\n recordEpisode?: boolean;\n },\n );\n\n return {\n content: [{ type: \"text\", text: result.message }],\n details: result,\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"active_task_checkpoint\",\n phase: \"runtime\",\n });\n return {\n content: [{ type: \"text\", text: `active_task_checkpoint failed: ${String(err)}` }],\n details: {\n ok: false,\n partial: false,\n error: String(err),\n },\n };\n }\n };\n api.registerTool(\n {\n name: \"active_task_checkpoint\",\n description: _activeTaskCheckpointDesc,\n parameters: _activeTaskCheckpointParams,\n execute: _execActiveTaskCheckpoint,\n },\n { name: \"active_task_checkpoint\" },\n );\n }\n}\n"],"mappings":";;;;;;;;;;AAYA,SAAgB,wBAAwB,SAAkC;CACxE,MAAM,EACJ,SACA,YACA,UACA,KACA,YACA,QACA,eACA,UACA,cACA,mBACA,SACA,mBACA,mBACA,yBACA,mBACA,oBACA,cACA,sBACA,UACA,WACA,wBACA,YACA,KACA,aACA,iBACA,yCACA,4BACA,yBACA,yBACA,uBACE;CAMJ;EACE,MAAM,8BAA8B,KAAK,OAAO;GAC9C,QAAQ,KAAK,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"register-checkpoint-tools.js","names":[],"sources":["../../../tools/memory/register-checkpoint-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 { runActiveTaskCheckpoint } from \"../../services/active-task-checkpoint.js\";\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerCheckpointTools(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 // ---------------------------------------------------------------------------\n // Active-task checkpoint tool (#1270)\n // ---------------------------------------------------------------------------\n\n {\n const _activeTaskCheckpointParams = Type.Object({\n entity: Type.String({ description: \"Stable task entity/label (category:project row key).\" }),\n status: Type.Optional(\n Type.String({\n description:\n \"Task status: open|in_progress|blocked|waiting|done|completed|closed|cancelled|abandoned|failed.\",\n }),\n ),\n owner: Type.Optional(Type.String({ description: \"Task owner (free-form, e.g. subagent/session/role).\" })),\n next: Type.Optional(Type.String({ description: \"Next concrete action for safe resume.\" })),\n relatedSession: Type.Optional(Type.String({ description: \"Related OpenClaw session key/id.\" })),\n title: Type.Optional(\n Type.String({ description: \"Human-readable task title (defaults to existing or Project task).\" }),\n ),\n resumeAt: Type.Optional(\n Type.String({\n description: \"Optional future ISO timestamp for wake/reminder scheduling via cron jobs store.\",\n }),\n ),\n state: Type.Optional(\n Type.Record(Type.String(), Type.Unknown(), {\n description: \"Structured checkpoint state object (serialized into facts + episode context).\",\n }),\n ),\n scheduleWake: Type.Optional(\n Type.Boolean({ description: \"When true (default), schedule wake job when resumeAt is supplied.\" }),\n ),\n refreshProjection: Type.Optional(\n Type.Boolean({\n description: \"When true, best-effort refresh ACTIVE-TASKS.md projection (activeTask.ledger=facts only).\",\n }),\n ),\n recordEpisode: Type.Optional(\n Type.Boolean({ description: \"When true (default), record an episode audit trail for the checkpoint.\" }),\n ),\n });\n const _activeTaskCheckpointDesc =\n \"Best-effort checkpoint active task state for reliable resume. One call updates project facts (status/next/owner/related_session/task_updated/title), records an episode audit trail, optionally schedules wake/reminder from resumeAt, and optionally refreshes ACTIVE-TASKS.md projection. Returns structured partial-failure details when later steps fail.\";\n const _execActiveTaskCheckpoint = async (_toolCallId: string, params: Record<string, unknown>) => {\n const scopeFilter = buildToolScopeFilter({}, currentAgentIdRef.value, cfg);\n try {\n const result = await runActiveTaskCheckpoint(\n {\n factsDb,\n vectorDb,\n embeddings,\n cfg,\n logger: api.logger,\n episodeScopeFilter: scopeFilter,\n },\n params as {\n entity?: string;\n status?: string;\n owner?: string;\n next?: string;\n relatedSession?: string;\n title?: string;\n resumeAt?: string;\n state?: Record<string, unknown>;\n scheduleWake?: boolean;\n refreshProjection?: boolean;\n recordEpisode?: boolean;\n },\n );\n\n return {\n content: [{ type: \"text\", text: result.message }],\n details: result,\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"active_task_checkpoint\",\n phase: \"runtime\",\n });\n return {\n content: [{ type: \"text\", text: `active_task_checkpoint failed: ${String(err)}` }],\n details: {\n ok: false,\n partial: false,\n error: String(err),\n },\n };\n }\n };\n api.registerTool(\n {\n name: \"active_task_checkpoint\",\n description: _activeTaskCheckpointDesc,\n parameters: _activeTaskCheckpointParams,\n execute: _execActiveTaskCheckpoint,\n },\n { name: \"active_task_checkpoint\" },\n );\n }\n}\n"],"mappings":";;;;;;;;;;AAYA,SAAgB,wBAAwB,SAAkC;CACxE,MAAM,EACJ,SACA,YACA,UACA,KACA,YACA,QACA,eACA,UACA,cACA,mBACA,SACA,mBACA,mBACA,yBACA,mBACA,oBACA,cACA,sBACA,UACA,WACA,wBACA,YACA,KACA,aACA,iBACA,yCACA,4BACA,yBACA,yBACA,uBACE;CAMJ;EACE,MAAM,8BAA8B,KAAK,OAAO;GAC9C,QAAQ,KAAK,OAAO,EAAE,aAAa,uDAAuD,CAAC;GAC3F,QAAQ,KAAK,SACX,KAAK,OAAO,EACV,aACE,kGACJ,CAAC,CACH;GACA,OAAO,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,sDAAsD,CAAC,CAAC;GACxG,MAAM,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,wCAAwC,CAAC,CAAC;GACzF,gBAAgB,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,mCAAmC,CAAC,CAAC;GAC9F,OAAO,KAAK,SACV,KAAK,OAAO,EAAE,aAAa,oEAAoE,CAAC,CAClG;GACA,UAAU,KAAK,SACb,KAAK,OAAO,EACV,aAAa,kFACf,CAAC,CACH;GACA,OAAO,KAAK,SACV,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,QAAQ,GAAG,EACzC,aAAa,gFACf,CAAC,CACH;GACA,cAAc,KAAK,SACjB,KAAK,QAAQ,EAAE,aAAa,oEAAoE,CAAC,CACnG;GACA,mBAAmB,KAAK,SACtB,KAAK,QAAQ,EACX,aAAa,4FACf,CAAC,CACH;GACA,eAAe,KAAK,SAClB,KAAK,QAAQ,EAAE,aAAa,yEAAyE,CAAC,CACxG;EACF,CAAC;EACD,MAAM,4BACJ;EACF,MAAM,4BAA4B,OAAO,aAAqB,WAAoC;GAChG,MAAM,cAAc,qBAAqB,CAAC,GAAG,kBAAkB,OAAO,GAAG;GACzE,IAAI;IACF,MAAM,SAAS,MAAM,wBACnB;KACE;KACA;KACA;KACA;KACA,QAAQ,IAAI;KACZ,oBAAoB;IACtB,GACA,MAaF;IAEA,OAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,OAAO;KAAQ,CAAC;KAChD,SAAS;IACX;GACF,SAAS,KAAK;IACZ,mBAAmB,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC,GAAG;KACtE,WAAW;KACX,WAAW;KACX,OAAO;IACT,CAAC;IACD,OAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,kCAAkC,OAAO,GAAG;KAAI,CAAC;KACjF,SAAS;MACP,IAAI;MACJ,SAAS;MACT,OAAO,OAAO,GAAG;KACnB;IACF;GACF;EACF;EACA,IAAI,aACF;GACE,MAAM;GACN,aAAa;GACb,YAAY;GACZ,SAAS;EACX,GACA,EAAE,MAAM,yBAAyB,CACnC;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-directory-tools.js","names":[],"sources":["../../../tools/memory/register-directory-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 { AllEmbeddingProvidersFailed } from \"../../services/embeddings.js\";\nimport { capturePluginError } from \"../../services/error-reporter.js\";\nimport { mergeResults } from \"../../services/merge-results.js\";\nimport type { SearchResult } from \"../../types/memory.js\";\nimport { UUID_REGEX } from \"../../utils/constants.js\";\nimport { embedCallWithTimeoutAndRetry } from \"../../utils/embed-call.js\";\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerDirectoryTools(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_directory\",\n label: \"Memory directory\",\n description:\n \"Structured contacts and organizations (from NER + contact layer). Use list_contacts to browse people; org_view returns fact ids and people for an organization — stable views, not a single ranked memory_recall.\",\n parameters: Type.Object({\n operation: stringEnum([\"list_contacts\", \"org_view\"] as const),\n name_prefix: Type.Optional(\n Type.String({ description: \"For list_contacts: filter by display name prefix (optional).\" }),\n ),\n org_name: Type.Optional(\n Type.String({\n description: \"For org_view: organization name or key (resolves canonical org).\",\n }),\n ),\n limit: Type.Optional(\n Type.Number({\n description: \"Max rows (default 40, max 100).\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const operation = params.operation as string;\n const limitRaw = params.limit;\n const cap = Math.min(100, Math.max(1, typeof limitRaw === \"number\" ? Math.floor(limitRaw) : 40));\n if (operation === \"list_contacts\") {\n const prefix = typeof params.name_prefix === \"string\" ? params.name_prefix : \"\";\n const rows = factsDb.listContactsByNamePrefix(prefix, cap);\n const lines = rows.map(\n (c) =>\n `- ${c.displayName} (id=${c.id})${c.primaryOrgId ? ` [org: ${c.primaryOrgId}]` : \"\"}${c.email ? ` email=${c.email}` : \"\"}`,\n );\n return {\n content: [\n {\n type: \"text\",\n text: rows.length === 0 ? \"No contacts found.\" : `Contacts (${rows.length}):\\n${lines.join(\"\\n\")}`,\n },\n ],\n details: { operation: \"list_contacts\", count: rows.length, contacts: rows },\n };\n }\n if (operation === \"org_view\") {\n const orgName = typeof params.org_name === \"string\" ? params.org_name.trim() : \"\";\n if (!orgName) {\n return {\n content: [{ type: \"text\", text: \"org_view requires org_name.\" }],\n details: { error: \"org_name_required\" },\n };\n }\n const org = factsDb.lookupOrganization(orgName);\n if (!org) {\n return {\n content: [\n {\n type: \"text\",\n text: `No organization matched \"${orgName}\". Try the exact name from a fact or a shorter key.`,\n },\n ],\n details: { error: \"org_not_found\", query: orgName },\n };\n }\n const people = factsDb.listContactsForOrganization(org.id, cap);\n const factIds = factsDb.listFactIdsLinkedToOrg(org.id, cap);\n const factSummaries = factIds.map((id) => {\n const f = factsDb.getById(id);\n return f\n ? { id: f.id, text: f.text.slice(0, 240), category: f.category }\n : { id, text: \"(missing)\", category: \"?\" };\n });\n const peopleLines = people.map((p) => `- ${p.displayName} (contact id=${p.id})`);\n const factLines = factSummaries.map((f) => `- [${f.id}] ${f.text}${f.text.length >= 240 ? \"…\" : \"\"}`);\n return {\n content: [\n {\n type: \"text\",\n text: `Organization: ${org.displayName} (id=${org.id}, key=${org.canonicalKey})\\n\\nPeople (${people.length}):\\n${people.length ? peopleLines.join(\"\\n\") : \"(none)\"}\\n\\nFacts linked (${factSummaries.length}):\\n${factSummaries.length ? factLines.join(\"\\n\") : \"(none)\"}`,\n },\n ],\n details: {\n operation: \"org_view\",\n organization: org,\n people,\n facts: factSummaries,\n },\n };\n }\n return {\n content: [{ type: \"text\", text: `Unknown operation: ${operation}` }],\n details: { error: \"bad_operation\" },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-directory\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_directory\" },\n );\n\n api.registerTool(\n {\n name: \"memory_promote\",\n label: \"Memory Promote\",\n description: \"Promote a session-scoped memory to global or agent scope (so it persists after session end).\",\n parameters: Type.Object({\n memoryId: Type.String({ description: \"Fact id to promote\" }),\n scope: Type.Union([Type.Literal(\"global\"), Type.Literal(\"agent\")], {\n description: \"New scope: global (available to all) or agent (this agent only).\",\n }),\n scopeTarget: Type.Optional(\n Type.String({\n description: \"Required when scope is agent: agent identifier.\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const { memoryId, scope, scopeTarget } = params as {\n memoryId: string;\n scope: \"global\" | \"agent\";\n scopeTarget?: string;\n };\n const entry = factsDb.getById(memoryId);\n if (!entry) {\n return {\n content: [{ type: \"text\", text: `No memory found with id: ${memoryId}.` }],\n details: { error: \"not_found\" },\n };\n }\n if (scope === \"agent\" && !scopeTarget?.trim()) {\n return {\n content: [{ type: \"text\", text: \"Scope 'agent' requires scopeTarget (agent identifier).\" }],\n details: { error: \"scope_target_required\" },\n };\n }\n const scopeTargetValue = scope === \"agent\" ? (scopeTarget?.trim() ?? null) : null;\n const ok = factsDb.promoteScope(memoryId, scope, scopeTargetValue);\n if (!ok) {\n return {\n content: [{ type: \"text\", text: `Could not promote memory ${memoryId}.` }],\n details: { error: \"promote_failed\" },\n };\n }\n return {\n content: [\n {\n type: \"text\",\n text: `Promoted memory ${memoryId} to scope \"${scope}\"${scope === \"agent\" ? ` (agent: ${scopeTarget})` : \"\"}. It will persist after session end.`,\n },\n ],\n details: {\n action: \"promoted\",\n id: memoryId,\n scope,\n scopeTarget: scope === \"agent\" ? scopeTarget : undefined,\n },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-promote\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_promote\" },\n );\n\n api.registerTool(\n {\n name: \"memory_forget\",\n label: \"Memory Forget\",\n description: \"Delete specific memories from both backends.\",\n parameters: Type.Object({\n query: Type.Optional(Type.String({ description: \"Search to find memory\" })),\n memoryId: Type.Optional(Type.String({ description: \"Specific memory ID\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const { query, memoryId } = params as {\n query?: string;\n memoryId?: string;\n };\n\n if (memoryId) {\n // Support prefix matching: if the ID looks truncated (not a full UUID),\n // try to resolve the full ID via prefix search\n let resolvedId = memoryId;\n if (memoryId.length < 36 && !memoryId.includes(\"-\")) {\n const prefixResult = factsDb.findByIdPrefix(memoryId);\n if (prefixResult && \"ambiguous\" in prefixResult) {\n const countText = prefixResult.count >= 3 ? `${prefixResult.count}+` : `${prefixResult.count}`;\n return {\n content: [\n {\n type: \"text\",\n text: `Prefix \"${memoryId}\" is ambiguous (matches ${countText} facts). Use the full UUID from memory_recall.`,\n },\n ],\n details: { action: \"ambiguous\", prefix: memoryId, matchCount: prefixResult.count },\n };\n }\n if (prefixResult && \"id\" in prefixResult) {\n resolvedId = prefixResult.id;\n }\n }\n\n // Validate that resolvedId is a proper UUID before attempting deletion.\n // LLMs sometimes pass memory text content as the ID instead of the UUID.\n if (!UUID_REGEX.test(resolvedId)) {\n return {\n content: [\n {\n type: \"text\",\n text: `\"${memoryId}\" is not a valid memory ID. Use memory_recall to find the memory and get its UUID, then pass the UUID to memory_forget.`,\n },\n ],\n details: { action: \"invalid_id\", originalId: memoryId },\n };\n }\n\n const sqlDeleted = factsDb.delete(resolvedId);\n let lanceDeleted = false;\n let lanceError: string | null = null;\n try {\n lanceDeleted = await vectorDb.delete(resolvedId);\n } catch (err) {\n lanceError = err instanceof Error ? err.message : String(err);\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"vector\",\n operation: \"forget-delete\",\n phase: \"runtime\",\n backend: \"lancedb\",\n });\n api.logger.warn(`memory-hybrid: LanceDB delete during tool failed: ${err}`);\n }\n aliasDb?.deleteByFactId(resolvedId);\n\n if (!sqlDeleted && !lanceDeleted) {\n if (lanceError) {\n return {\n content: [\n {\n type: \"text\",\n text: `Deletion failed for \"${memoryId}\": SQLite not found, LanceDB error: ${lanceError}`,\n },\n ],\n details: { action: \"error\", originalId: memoryId, resolvedId, error: lanceError },\n };\n }\n return {\n content: [\n {\n type: \"text\",\n text: `Failed to delete memory \"${memoryId}\" — not found in either backend. Use the full UUID from memory_recall.`,\n },\n ],\n details: { action: \"not_found\", originalId: memoryId, resolvedId },\n };\n }\n\n const resolveNote = resolvedId !== memoryId ? ` (resolved from prefix \"${memoryId}\")` : \"\";\n return {\n content: [\n {\n type: \"text\",\n text: `Memory ${resolvedId} forgotten${resolveNote} (sqlite: ${sqlDeleted}, lance: ${lanceDeleted}).`,\n },\n ],\n details: { action: \"deleted\", originalId: memoryId, resolvedId },\n };\n }\n\n if (query) {\n const sqlResults = factsDb.search(query, 5);\n let lanceResults: SearchResult[] = [];\n try {\n const vector = await embedCallWithTimeoutAndRetry(\n () => embeddings.embed(query),\n \"memory-tools:forget-vector-search\",\n );\n lanceResults = await vectorDb.search(vector, 5, 0.7);\n } catch (err) {\n // AllEmbeddingProvidersFailed is expected when no providers are configured — don't report to Sentry.\n if (!(err instanceof AllEmbeddingProvidersFailed)) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"vector\",\n operation: \"forget-vector-search\",\n phase: \"runtime\",\n backend: \"lancedb\",\n });\n }\n api.logger.warn(`memory-hybrid: vector search failed: ${err}`);\n }\n\n const results = mergeResults(sqlResults, lanceResults, 5, factsDb);\n\n if (results.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No matching memories found.\" }],\n details: { found: 0 },\n };\n }\n\n if (results.length === 1 && results[0].score > 0.9) {\n const id = results[0].entry.id;\n factsDb.delete(id);\n try {\n await vectorDb.delete(id);\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"vector\",\n operation: \"forget-supersede-delete\",\n phase: \"runtime\",\n backend: \"lancedb\",\n });\n api.logger.warn(`memory-hybrid: LanceDB delete during supersede failed: ${err}`);\n }\n aliasDb?.deleteByFactId(id);\n return {\n content: [\n {\n type: \"text\",\n text: `Forgotten: \"${results[0].entry.text}\"`,\n },\n ],\n details: { action: \"deleted\", id },\n };\n }\n\n const list = results\n .map((r) => {\n const normalized = r.entry.text.replace(/\\s+/g, \" \");\n const preview = normalized.slice(0, 80).trim();\n const ellipsis = normalized.length > 80 ? \"…\" : \"\";\n return `- [${r.entry.id}] (${r.backend}) ${preview}${ellipsis}`;\n })\n .join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${results.length} candidates. Specify memoryId:\\n${list}`,\n },\n ],\n details: {\n action: \"candidates\",\n candidates: results.map((r) => ({\n id: r.entry.id,\n text: r.entry.text,\n backend: r.backend,\n score: r.score,\n })),\n },\n };\n }\n\n return {\n content: [{ type: \"text\", text: \"Provide query or memoryId.\" }],\n details: { error: \"missing_param\" },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-forget\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_forget\" },\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"register-directory-tools.js","names":[],"sources":["../../../tools/memory/register-directory-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 { AllEmbeddingProvidersFailed } from \"../../services/embeddings.js\";\nimport { capturePluginError } from \"../../services/error-reporter.js\";\nimport { mergeResults } from \"../../services/merge-results.js\";\nimport type { SearchResult } from \"../../types/memory.js\";\nimport { UUID_REGEX } from \"../../utils/constants.js\";\nimport { embedCallWithTimeoutAndRetry } from \"../../utils/embed-call.js\";\nimport type { MemoryToolRuntime } from \"./runtime.js\";\n\nexport function registerDirectoryTools(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_directory\",\n label: \"Memory directory\",\n description:\n \"Structured contacts and organizations (from NER + contact layer). Use list_contacts to browse people; org_view returns fact ids and people for an organization — stable views, not a single ranked memory_recall.\",\n parameters: Type.Object({\n operation: stringEnum([\"list_contacts\", \"org_view\"] as const),\n name_prefix: Type.Optional(\n Type.String({ description: \"For list_contacts: filter by display name prefix (optional).\" }),\n ),\n org_name: Type.Optional(\n Type.String({\n description: \"For org_view: organization name or key (resolves canonical org).\",\n }),\n ),\n limit: Type.Optional(\n Type.Number({\n description: \"Max rows (default 40, max 100).\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const operation = params.operation as string;\n const limitRaw = params.limit;\n const cap = Math.min(100, Math.max(1, typeof limitRaw === \"number\" ? Math.floor(limitRaw) : 40));\n if (operation === \"list_contacts\") {\n const prefix = typeof params.name_prefix === \"string\" ? params.name_prefix : \"\";\n const rows = factsDb.listContactsByNamePrefix(prefix, cap);\n const lines = rows.map(\n (c) =>\n `- ${c.displayName} (id=${c.id})${c.primaryOrgId ? ` [org: ${c.primaryOrgId}]` : \"\"}${c.email ? ` email=${c.email}` : \"\"}`,\n );\n return {\n content: [\n {\n type: \"text\",\n text: rows.length === 0 ? \"No contacts found.\" : `Contacts (${rows.length}):\\n${lines.join(\"\\n\")}`,\n },\n ],\n details: { operation: \"list_contacts\", count: rows.length, contacts: rows },\n };\n }\n if (operation === \"org_view\") {\n const orgName = typeof params.org_name === \"string\" ? params.org_name.trim() : \"\";\n if (!orgName) {\n return {\n content: [{ type: \"text\", text: \"org_view requires org_name.\" }],\n details: { error: \"org_name_required\" },\n };\n }\n const org = factsDb.lookupOrganization(orgName);\n if (!org) {\n return {\n content: [\n {\n type: \"text\",\n text: `No organization matched \"${orgName}\". Try the exact name from a fact or a shorter key.`,\n },\n ],\n details: { error: \"org_not_found\", query: orgName },\n };\n }\n const people = factsDb.listContactsForOrganization(org.id, cap);\n const factIds = factsDb.listFactIdsLinkedToOrg(org.id, cap);\n const factSummaries = factIds.map((id) => {\n const f = factsDb.getById(id);\n return f\n ? { id: f.id, text: f.text.slice(0, 240), category: f.category }\n : { id, text: \"(missing)\", category: \"?\" };\n });\n const peopleLines = people.map((p) => `- ${p.displayName} (contact id=${p.id})`);\n const factLines = factSummaries.map((f) => `- [${f.id}] ${f.text}${f.text.length >= 240 ? \"…\" : \"\"}`);\n return {\n content: [\n {\n type: \"text\",\n text: `Organization: ${org.displayName} (id=${org.id}, key=${org.canonicalKey})\\n\\nPeople (${people.length}):\\n${people.length ? peopleLines.join(\"\\n\") : \"(none)\"}\\n\\nFacts linked (${factSummaries.length}):\\n${factSummaries.length ? factLines.join(\"\\n\") : \"(none)\"}`,\n },\n ],\n details: {\n operation: \"org_view\",\n organization: org,\n people,\n facts: factSummaries,\n },\n };\n }\n return {\n content: [{ type: \"text\", text: `Unknown operation: ${operation}` }],\n details: { error: \"bad_operation\" },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-directory\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_directory\" },\n );\n\n api.registerTool(\n {\n name: \"memory_promote\",\n label: \"Memory Promote\",\n description: \"Promote a session-scoped memory to global or agent scope (so it persists after session end).\",\n parameters: Type.Object({\n memoryId: Type.String({ description: \"Fact id to promote\" }),\n scope: Type.Union([Type.Literal(\"global\"), Type.Literal(\"agent\")], {\n description: \"New scope: global (available to all) or agent (this agent only).\",\n }),\n scopeTarget: Type.Optional(\n Type.String({\n description: \"Required when scope is agent: agent identifier.\",\n }),\n ),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const { memoryId, scope, scopeTarget } = params as {\n memoryId: string;\n scope: \"global\" | \"agent\";\n scopeTarget?: string;\n };\n const entry = factsDb.getById(memoryId);\n if (!entry) {\n return {\n content: [{ type: \"text\", text: `No memory found with id: ${memoryId}.` }],\n details: { error: \"not_found\" },\n };\n }\n if (scope === \"agent\" && !scopeTarget?.trim()) {\n return {\n content: [{ type: \"text\", text: \"Scope 'agent' requires scopeTarget (agent identifier).\" }],\n details: { error: \"scope_target_required\" },\n };\n }\n const scopeTargetValue = scope === \"agent\" ? (scopeTarget?.trim() ?? null) : null;\n const ok = factsDb.promoteScope(memoryId, scope, scopeTargetValue);\n if (!ok) {\n return {\n content: [{ type: \"text\", text: `Could not promote memory ${memoryId}.` }],\n details: { error: \"promote_failed\" },\n };\n }\n return {\n content: [\n {\n type: \"text\",\n text: `Promoted memory ${memoryId} to scope \"${scope}\"${scope === \"agent\" ? ` (agent: ${scopeTarget})` : \"\"}. It will persist after session end.`,\n },\n ],\n details: {\n action: \"promoted\",\n id: memoryId,\n scope,\n scopeTarget: scope === \"agent\" ? scopeTarget : undefined,\n },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-promote\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_promote\" },\n );\n\n api.registerTool(\n {\n name: \"memory_forget\",\n label: \"Memory Forget\",\n description: \"Delete specific memories from both backends.\",\n parameters: Type.Object({\n query: Type.Optional(Type.String({ description: \"Search to find memory\" })),\n memoryId: Type.Optional(Type.String({ description: \"Specific memory ID\" })),\n }),\n async execute(_toolCallId: string, params: Record<string, unknown>) {\n try {\n const { query, memoryId } = params as {\n query?: string;\n memoryId?: string;\n };\n\n if (memoryId) {\n // Support prefix matching: if the ID looks truncated (not a full UUID),\n // try to resolve the full ID via prefix search\n let resolvedId = memoryId;\n if (memoryId.length < 36 && !memoryId.includes(\"-\")) {\n const prefixResult = factsDb.findByIdPrefix(memoryId);\n if (prefixResult && \"ambiguous\" in prefixResult) {\n const countText = prefixResult.count >= 3 ? `${prefixResult.count}+` : `${prefixResult.count}`;\n return {\n content: [\n {\n type: \"text\",\n text: `Prefix \"${memoryId}\" is ambiguous (matches ${countText} facts). Use the full UUID from memory_recall.`,\n },\n ],\n details: { action: \"ambiguous\", prefix: memoryId, matchCount: prefixResult.count },\n };\n }\n if (prefixResult && \"id\" in prefixResult) {\n resolvedId = prefixResult.id;\n }\n }\n\n // Validate that resolvedId is a proper UUID before attempting deletion.\n // LLMs sometimes pass memory text content as the ID instead of the UUID.\n if (!UUID_REGEX.test(resolvedId)) {\n return {\n content: [\n {\n type: \"text\",\n text: `\"${memoryId}\" is not a valid memory ID. Use memory_recall to find the memory and get its UUID, then pass the UUID to memory_forget.`,\n },\n ],\n details: { action: \"invalid_id\", originalId: memoryId },\n };\n }\n\n const sqlDeleted = factsDb.delete(resolvedId);\n let lanceDeleted = false;\n let lanceError: string | null = null;\n try {\n lanceDeleted = await vectorDb.delete(resolvedId);\n } catch (err) {\n lanceError = err instanceof Error ? err.message : String(err);\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"vector\",\n operation: \"forget-delete\",\n phase: \"runtime\",\n backend: \"lancedb\",\n });\n api.logger.warn(`memory-hybrid: LanceDB delete during tool failed: ${err}`);\n }\n aliasDb?.deleteByFactId(resolvedId);\n\n if (!sqlDeleted && !lanceDeleted) {\n if (lanceError) {\n return {\n content: [\n {\n type: \"text\",\n text: `Deletion failed for \"${memoryId}\": SQLite not found, LanceDB error: ${lanceError}`,\n },\n ],\n details: { action: \"error\", originalId: memoryId, resolvedId, error: lanceError },\n };\n }\n return {\n content: [\n {\n type: \"text\",\n text: `Failed to delete memory \"${memoryId}\" — not found in either backend. Use the full UUID from memory_recall.`,\n },\n ],\n details: { action: \"not_found\", originalId: memoryId, resolvedId },\n };\n }\n\n const resolveNote = resolvedId !== memoryId ? ` (resolved from prefix \"${memoryId}\")` : \"\";\n return {\n content: [\n {\n type: \"text\",\n text: `Memory ${resolvedId} forgotten${resolveNote} (sqlite: ${sqlDeleted}, lance: ${lanceDeleted}).`,\n },\n ],\n details: { action: \"deleted\", originalId: memoryId, resolvedId },\n };\n }\n\n if (query) {\n const sqlResults = factsDb.search(query, 5);\n let lanceResults: SearchResult[] = [];\n try {\n const vector = await embedCallWithTimeoutAndRetry(\n () => embeddings.embed(query),\n \"memory-tools:forget-vector-search\",\n );\n lanceResults = await vectorDb.search(vector, 5, 0.7);\n } catch (err) {\n // AllEmbeddingProvidersFailed is expected when no providers are configured — don't report to Sentry.\n if (!(err instanceof AllEmbeddingProvidersFailed)) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"vector\",\n operation: \"forget-vector-search\",\n phase: \"runtime\",\n backend: \"lancedb\",\n });\n }\n api.logger.warn(`memory-hybrid: vector search failed: ${err}`);\n }\n\n const results = mergeResults(sqlResults, lanceResults, 5, factsDb);\n\n if (results.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No matching memories found.\" }],\n details: { found: 0 },\n };\n }\n\n if (results.length === 1 && results[0].score > 0.9) {\n const id = results[0].entry.id;\n factsDb.delete(id);\n try {\n await vectorDb.delete(id);\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"vector\",\n operation: \"forget-supersede-delete\",\n phase: \"runtime\",\n backend: \"lancedb\",\n });\n api.logger.warn(`memory-hybrid: LanceDB delete during supersede failed: ${err}`);\n }\n aliasDb?.deleteByFactId(id);\n return {\n content: [\n {\n type: \"text\",\n text: `Forgotten: \"${results[0].entry.text}\"`,\n },\n ],\n details: { action: \"deleted\", id },\n };\n }\n\n const list = results\n .map((r) => {\n const normalized = r.entry.text.replace(/\\s+/g, \" \");\n const preview = normalized.slice(0, 80).trim();\n const ellipsis = normalized.length > 80 ? \"…\" : \"\";\n return `- [${r.entry.id}] (${r.backend}) ${preview}${ellipsis}`;\n })\n .join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${results.length} candidates. Specify memoryId:\\n${list}`,\n },\n ],\n details: {\n action: \"candidates\",\n candidates: results.map((r) => ({\n id: r.entry.id,\n text: r.entry.text,\n backend: r.backend,\n score: r.score,\n })),\n },\n };\n }\n\n return {\n content: [{ type: \"text\", text: \"Provide query or memoryId.\" }],\n details: { error: \"missing_param\" },\n };\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"memory\",\n operation: \"memory-forget\",\n phase: \"runtime\",\n });\n throw err;\n }\n },\n },\n { name: \"memory_forget\" },\n );\n}\n"],"mappings":"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"}
|