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":"llm-models.js","names":[],"sources":["../../../../cli/verify/sections/llm-models.ts"],"sourcesContent":["import { getEnv } from \"../../../utils/env-manager.js\";\n/**\n * CLI Verify Command Handler\n *\n * Contains runVerifyForCli and its private helper functions.\n * Checks infrastructure (SQLite, LanceDB, embeddings, LLM credentials,\n * cron jobs) and optionally applies fixes.\n *\n * Extracted from cli/handlers.ts to keep that file manageable.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport OpenAI from \"openai\";\n\nimport {\n getCronModelConfig,\n getLLMModelPreference,\n getLLMModelPreferenceUnfiltered,\n getProvidersWithKeys,\n} from \"../../../config.js\";\nimport { resolveSecretRef } from \"../../../config/parsers/core.js\";\nimport { getEffectiveModelLimits, loadAdaptiveModelLimits } from \"../../../services/adaptive-model-limits.js\";\nimport { chatComplete, distillBatchTokenLimit, distillMaxOutputTokens } from \"../../../services/chat.js\";\nimport { CostFeature } from \"../../../services/cost-feature-labels.js\";\nimport { capturePluginError } from \"../../../services/error-reporter.js\";\nimport { resolveWireApi } from \"../../../services/model-capabilities.js\";\nimport { callResponsesApi } from \"../../../services/responses-adapter.js\";\nimport { hasOAuthProfiles } from \"../../../utils/auth.js\";\nimport { isHeavyModel } from \"../../../utils/model-tier.js\";\nimport {\n buildUnsupportedPerAgentCompactionWarning,\n buildCompactionWatchdogAlert,\n DEFAULT_COMPACTION_MODEL,\n isCompactionModelTooStrong,\n resolveCompactionModelSelection,\n} from \"../../../utils/compaction-model-watchdog.js\";\nimport { applyAzureFoundryVerifyDirectClientAuth } from \"../../verify-llm-azure-auth.js\";\n\nimport type { VerifyRunState } from \"../verify-run-state.js\";\nimport {\n credentialSource,\n ensureRawPluginConfigOnState,\n rawClaudeApiKey,\n rawDistillApiKey,\n rawEmbeddingApiKey,\n rawLlmProviderApiKey,\n} from \"../plugin-config-credentials.js\";\n\nexport async function runVerifyLlmModelsSection(state: VerifyRunState): Promise<void> {\n ensureRawPluginConfigOnState(state);\n const {\n ctx,\n opts,\n cfg,\n factsDb,\n vectorDb,\n embeddings,\n credentialsDb,\n resolvedSqlitePath,\n resolvedLancePath,\n openai,\n log,\n tableLog,\n OK,\n FAIL,\n PAUSE,\n WARN_LINE,\n noEmoji,\n issues,\n fixes,\n warnings,\n loadBlocking,\n extDir,\n defaultConfigPath,\n openclawDir,\n openclawConfigRead,\n recommendedEmbedding,\n dashboardUrl,\n } = state;\n\n // ───── LLM / models table: one row per model from llm.nano / llm.maintenance / llm.default / llm.heavy; auth + source ─────\n tableLog(\"\\n───── LLM / Models (from llm.nano, llm.maintenance, llm.default, llm.heavy) ─────\");\n const cronCfg = getCronModelConfig(cfg);\n const providersWithKeys = getProvidersWithKeys(cronCfg);\n const authOrder = (cfg as Record<string, unknown>).auth as { order?: Record<string, string[]> } | undefined;\n const gatewayPort = getEnv(\"OPENCLAW_GATEWAY_PORT\");\n const gatewayToken = getEnv(\"OPENCLAW_GATEWAY_TOKEN\");\n const gatewayAvailable = Boolean(\n gatewayPort && Number(gatewayPort) >= 1 && Number(gatewayPort) <= 65535 && gatewayToken,\n );\n const tierNano = getLLMModelPreferenceUnfiltered(cronCfg, \"nano\");\n const tierMaintenance = getLLMModelPreferenceUnfiltered(cronCfg, \"maintenance\");\n const tierDefault = getLLMModelPreferenceUnfiltered(cronCfg, \"default\");\n const tierHeavy = getLLMModelPreferenceUnfiltered(cronCfg, \"heavy\");\n const nanoExplicitConfigured =\n Array.isArray(cronCfg.llm?.nano) && cronCfg.llm.nano.some((m) => typeof m === \"string\" && m.trim().length > 0);\n const maintenanceExplicitConfigured =\n Array.isArray(cronCfg.llm?.maintenance) &&\n cronCfg.llm.maintenance.some((m) => typeof m === \"string\" && m.trim().length > 0);\n const allModelsUnfiltered: string[] = [...tierNano, ...tierMaintenance, ...tierDefault, ...tierHeavy];\n function tiersForModel(model: string): string {\n const tags: string[] = [];\n if (tierNano.includes(model)) tags.push(\"nano\");\n if (tierMaintenance.includes(model)) tags.push(\"maintenance\");\n if (tierDefault.includes(model)) tags.push(\"default\");\n if (tierHeavy.includes(model)) tags.push(\"heavy\");\n if (tags.length === 0) return \"—\";\n return tags.join(\", \");\n }\n const fmtTierList = (arr: string[]) => (arr.length > 0 ? arr.join(\", \") : \"(none)\");\n tableLog(\" Effective tier lists (first model in each tier wins when that tier is selected):\");\n tableLog(\n ` nano: ${fmtTierList(tierNano)}${nanoExplicitConfigured ? \"\" : \" — llm.nano unset; nano tier reuses the default list\"}`,\n );\n tableLog(\n ` maintenance: ${fmtTierList(tierMaintenance)}${maintenanceExplicitConfigured ? \"\" : \" — llm.maintenance unset; maintenance tier reuses the default list\"}`,\n );\n tableLog(` default: ${fmtTierList(tierDefault)}`);\n tableLog(` heavy: ${fmtTierList(tierHeavy)}`);\n tableLog(\n ` First choice per tier: nano=${tierNano[0] ?? \"—\"} | maintenance=${tierMaintenance[0] ?? \"—\"} | default=${tierDefault[0] ?? \"—\"} | heavy=${tierHeavy[0] ?? \"—\"}`,\n );\n const distillMainTier = cfg.distill?.modelTier ?? \"maintenance\";\n const distillMainTierRaw = (cfg.distill as { modelTier?: string } | undefined)?.modelTier ?? \"maintenance\";\n const distillMainRequestedHeavy = distillMainTierRaw === \"heavy\";\n // Show the actual effective tier after clamping (cmd-distill.ts clamps \"heavy\" to \"maintenance\")\n const effectiveDistillMainTier = distillMainRequestedHeavy ? \"maintenance\" : distillMainTier;\n const distillMainEffective = getLLMModelPreference(cronCfg, effectiveDistillMainTier)[0] ?? \"—\";\n tableLog(\n ` Distill main pass: distill.modelTier=${distillMainTierRaw}${distillMainRequestedHeavy ? \" (clamped to maintenance)\" : \"\"} -> ${distillMainEffective}; --model overrides one run.`,\n );\n const dreamOverride =\n typeof cfg.nightlyCycle?.model === \"string\" && cfg.nightlyCycle.model.trim().length > 0\n ? cfg.nightlyCycle.model.trim()\n : null;\n const dreamEffective = dreamOverride ?? getLLMModelPreference(cronCfg, \"maintenance\")[0] ?? \"—\";\n const extractionTier = cfg.distill?.extractionModelTier ?? \"nano\";\n let compactionSelection = resolveCompactionModelSelection(undefined, { fallbackPolicy: \"inherit-defaults-primary\" });\n const compactionSelectionUnknownReason = openclawConfigRead.root\n ? null\n : openclawConfigRead.error !== undefined\n ? `active OpenClaw config (${defaultConfigPath}) is unreadable/invalid (${openclawConfigRead.error})`\n : `active OpenClaw config (${defaultConfigPath}) is missing`;\n if (openclawConfigRead.root) {\n // Use defaults-primary inheritance fallback to mirror current OpenClaw core behavior\n // when agents.defaults.compaction.model is unset.\n compactionSelection = resolveCompactionModelSelection(openclawConfigRead.root, {\n fallbackPolicy: \"inherit-defaults-primary\",\n });\n }\n const compactionRoutingUnknownReason =\n compactionSelectionUnknownReason ??\n (compactionSelection.routingUnknownFromConfig\n ? \"neither agents.defaults.compaction.model nor agents.defaults.model.primary is set; compaction may follow the active session chat model\"\n : null);\n tableLog(\n dreamOverride\n ? ` Dream cycle + MEMORY_INDEX.md: nightlyCycle.model=\"${dreamOverride}\" (overrides default tier for that pipeline).`\n : ` Dream cycle + MEMORY_INDEX.md: uses maintenance tier first choice (${tierMaintenance[0] ?? \"—\"}) unless nightlyCycle.model is set.`,\n );\n tableLog(\n \" Embeddings / re-index: embedding.model + embedding.* (not llm tiers). Chat LLM spend is separate from embedding API spend.\",\n );\n tableLog(\n ` Compaction (agents.*.compaction): provider=${compactionSelection.provider}, model=${compactionSelection.model || \"—\"}, reason=${compactionSelection.reason}${\n compactionRoutingUnknownReason ? `; status=unknown (${compactionRoutingUnknownReason})` : \"\"\n }`,\n );\n\n const adaptiveEnabled = (getEnv(\"OPENCLAW_HYBRID_MEM_ADAPTIVE_DISTILL\") ?? \"\").trim() !== \"0\";\n const adaptiveStatePath =\n typeof ctx.resolvedSqlitePath === \"string\" && ctx.resolvedSqlitePath.length > 0\n ? join(dirname(ctx.resolvedSqlitePath), \".adaptive-llm-limits.json\")\n : \"\";\n tableLog(\n ` Adaptive maintenance LLM sizing: ${adaptiveEnabled ? \"enabled\" : \"disabled\"} (state=${adaptiveStatePath}; applies to distill, reflect, extract-reinforcement, self-correction-run)`,\n );\n if (adaptiveEnabled && adaptiveStatePath && existsSync(adaptiveStatePath)) {\n try {\n const adaptiveState = loadAdaptiveModelLimits(adaptiveStatePath);\n const sampleModels = [\n distillMainEffective,\n dreamEffective,\n getLLMModelPreference(cronCfg, extractionTier)[0] ?? \"—\",\n tierHeavy[0] ?? \"—\",\n ].filter((m, i, arr) => m !== \"—\" && arr.indexOf(m) === i);\n for (const sampleModel of sampleModels) {\n const effective = getEffectiveModelLimits({\n state: adaptiveState,\n model: sampleModel,\n catalogBatchTokenLimit: distillBatchTokenLimit(sampleModel),\n catalogMaxOutputTokens: distillMaxOutputTokens(sampleModel),\n });\n tableLog(\n ` ${sampleModel}: batchTokenLimit=${effective.batchTokenLimit}, maxOutputTokens=${effective.maxOutputTokens}, source=${effective.source}`,\n );\n }\n } catch (err) {\n state.warnings.push(\n `adaptive maintenance LLM state could not be read: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n // Maintenance routing warnings: flag when maintenance-adjacent tasks are routed to heavy/expensive models unintentionally.\n // NOTE: cmd-distill.ts now clamps distill.modelTier=heavy to maintenance, so this check uses effectiveDistillMainTier.\n if (distillMainEffective !== \"—\" && isHeavyModel(distillMainEffective)) {\n state.warnings.push(\n `distill.modelTier=${distillMainTier} routes the main distill pass to a heavy/expensive first-choice model (${distillMainEffective}); configure llm.maintenance with a cheap-first list or set distill.modelTier=nano`,\n );\n }\n if (distillMainRequestedHeavy) {\n state.warnings.push(\n \"distill.modelTier=heavy is not supported for the main distill pass (clamped to maintenance in cmd-distill.ts). Use --model to override for a single run if needed.\",\n );\n }\n const extractionFirst =\n getLLMModelPreference(cronCfg, extractionTier)[0] ?? getLLMModelPreference(cronCfg, \"nano\")[0] ?? \"—\";\n if (extractionTier !== \"heavy\" && extractionFirst !== \"—\" && isHeavyModel(extractionFirst)) {\n state.warnings.push(\n `distill.extractionModelTier=${extractionTier} routes session extraction to a heavy/expensive first-choice model (${extractionFirst}); set distill.extractionModelTier=nano or configure llm.maintenance and use distill.extractionModelTier=maintenance`,\n );\n }\n if (dreamEffective !== \"—\" && isHeavyModel(dreamEffective)) {\n state.warnings.push(\n `dream-cycle/MEMORY_INDEX routes to a heavy/expensive model (${dreamEffective}); set nightlyCycle.model to a cheaper model or configure llm.maintenance with a cheap-first list`,\n );\n }\n if (compactionRoutingUnknownReason) {\n state.warnings.push(\n `verify watchdog: compaction routing check is unknown because ${compactionRoutingUnknownReason}; set/repair config and rerun verify.`,\n );\n } else {\n const unsupportedWarning = buildUnsupportedPerAgentCompactionWarning(compactionSelection, { context: \"verify\" });\n if (unsupportedWarning) state.warnings.push(unsupportedWarning);\n }\n if (!compactionRoutingUnknownReason && isCompactionModelTooStrong(compactionSelection.model)) {\n const alert =\n buildCompactionWatchdogAlert({\n stage: \"verify\",\n model: compactionSelection.model,\n provider: compactionSelection.provider,\n source: compactionSelection.reason,\n }) ??\n `compaction routing uses a stronger-than-mini model (provider=${compactionSelection.provider}, model=${compactionSelection.model}, reason=${compactionSelection.reason}). Set agents.defaults.compaction.model to a mini/nano model such as ${DEFAULT_COMPACTION_MODEL}.`;\n state.warnings.push(alert);\n }\n const _allModelsFiltered: string[] = [\n ...getLLMModelPreference(cronCfg, \"nano\"),\n ...getLLMModelPreference(cronCfg, \"maintenance\"),\n ...getLLMModelPreference(cronCfg, \"default\"),\n ...getLLMModelPreference(cronCfg, \"heavy\"),\n ];\n // Reference models always shown in verify so users see Opus, GPT-5.4, Codex, o3, etc. with auth/source\n const VERIFY_REFERENCE_MODELS: string[] = [\n \"anthropic/claude-opus-4-6\",\n \"anthropic/claude-sonnet-4-6\",\n \"anthropic/claude-haiku-4-5-20251001\",\n \"openai/gpt-5.4\",\n \"openai/gpt-4.1-mini\",\n \"openai/gpt-4.1-nano\",\n \"openai/o3\",\n \"openai/o1\",\n \"openai/gpt-5-codex\",\n \"google/gemini-3.1-pro-preview\",\n \"google/gemini-2.5-flash\",\n \"google/gemini-2.5-flash-lite\",\n \"minimax/MiniMax-M2.5\",\n ];\n const providerFromModel = (m: string) => {\n if (m.includes(\"/\")) {\n return m.split(\"/\")[0].toLowerCase();\n }\n const bare = m.trim().toLowerCase();\n if (bare.startsWith(\"gemini-\")) return \"google\";\n if (bare.startsWith(\"claude-\")) return \"anthropic\";\n if (bare.startsWith(\"gpt-\") || bare.match(/^o[0-9]/)) return \"openai\";\n return \"openai\";\n };\n const disabledSet = new Set((cfg.llm?.disabledProviders ?? []).map((p) => String(p).trim().toLowerCase()));\n const _defaultTestModel: Record<string, string> = {\n openai: \"openai/gpt-4.1-nano\",\n google: \"google/gemini-2.5-flash-lite\",\n anthropic: \"anthropic/claude-haiku-4-5-20251001\",\n ollama: \"ollama/llama3.2\",\n minimax: \"minimax/minimax-01\",\n };\n function llmCredentialSource(provider: string): string {\n if (gatewayAvailable && hasOAuthProfiles(authOrder?.order?.[provider], provider)) return \"gateway\";\n if (provider === \"openai\")\n return credentialSource(rawEmbeddingApiKey(state)) || credentialSource(rawLlmProviderApiKey(state, \"openai\"));\n if (provider === \"google\")\n return credentialSource(rawDistillApiKey(state)) || credentialSource(rawLlmProviderApiKey(state, \"google\"));\n if (provider === \"anthropic\")\n return credentialSource(rawClaudeApiKey(state)) || credentialSource(rawLlmProviderApiKey(state, \"anthropic\"));\n return credentialSource(rawLlmProviderApiKey(state, provider)) || \"plugin\";\n }\n const gatewayBaseUrl =\n gatewayPort && Number(gatewayPort) >= 1 && Number(gatewayPort) <= 65535\n ? `http://127.0.0.1:${Number(gatewayPort)}/v1`\n : undefined;\n const VERIFY_LLM_BASE_URLS: Record<string, string> = {\n openai: \"https://api.openai.com/v1\",\n google: \"https://generativelanguage.googleapis.com/v1beta/openai/\",\n anthropic: \"https://api.anthropic.com/v1\",\n ollama: \"http://127.0.0.1:11434/v1\",\n minimax: \"https://api.minimax.chat/v1\",\n };\n function resolveKey(raw: unknown): string | undefined {\n if (typeof raw !== \"string\" || !raw.trim()) return undefined;\n const trimmed = raw.trim();\n const resolved = trimmed.startsWith(\"env:\") || trimmed.startsWith(\"file:\") ? resolveSecretRef(trimmed) : trimmed;\n return typeof resolved === \"string\" && resolved.length >= 10 ? resolved : undefined;\n }\n function getDirectApiKey(provider: string): string | undefined {\n const prov = cronCfg.llm?.providers as Record<string, { apiKey?: string }> | undefined;\n if (provider === \"openai\") {\n // Prefer OPENAI_API_KEY so Azure (embedding) and OpenAI (chat) can use different keys.\n const fromProv = resolveKey(prov?.openai?.apiKey);\n if (fromProv) return fromProv;\n const fromEnv = getEnv(\"OPENAI_API_KEY\")?.trim();\n if (fromEnv && fromEnv.length >= 10) return fromEnv;\n return resolveKey(cronCfg.embedding?.apiKey);\n }\n if (provider === \"google\") {\n const fromProv = resolveKey(prov?.google?.apiKey ?? cronCfg.distill?.apiKey);\n if (fromProv) return fromProv;\n const fromEnv = getEnv(\"GOOGLE_API_KEY\")?.trim();\n if (fromEnv && fromEnv.length >= 10) return fromEnv;\n return undefined;\n }\n if (provider === \"anthropic\") {\n const fromProv = resolveKey(\n prov?.anthropic?.apiKey ?? (cronCfg.claude as { apiKey?: string } | undefined)?.apiKey,\n );\n if (fromProv) return fromProv;\n const fromEnv = getEnv(\"ANTHROPIC_API_KEY\")?.trim();\n if (fromEnv && fromEnv.length >= 10) return fromEnv;\n return undefined;\n }\n if (provider === \"ollama\") return \"ollama\";\n // Azure Foundry: use AZURE_OPENAI_API_KEY when llm.providers key is not set.\n if (\n (provider === \"azure-foundry\" || provider === \"azure-foundry-responses\" || provider === \"azure-foundry-direct\") &&\n !resolveKey(prov?.[provider]?.apiKey)\n ) {\n const fromEnv = getEnv(\"AZURE_OPENAI_API_KEY\")?.trim();\n if (fromEnv && fromEnv.length >= 10) return fromEnv;\n }\n return resolveKey(prov?.[provider]?.apiKey);\n }\n function buildDirectClient(provider: string): OpenAI | undefined {\n const apiKey = getDirectApiKey(provider);\n if (!apiKey) return undefined;\n const provEntry = (cronCfg.llm?.providers as Record<string, { baseURL?: string; baseUrl?: string }> | undefined)?.[\n provider\n ];\n let baseURL =\n (typeof provEntry?.baseURL === \"string\" && provEntry.baseURL.trim() ? provEntry.baseURL.trim() : undefined) ??\n (typeof provEntry?.baseUrl === \"string\" && provEntry.baseUrl.trim() ? provEntry.baseUrl.trim() : undefined) ??\n VERIFY_LLM_BASE_URLS[provider];\n if (!baseURL) return undefined;\n // Anthropic's OpenAI-compatible chat endpoint requires /v1 suffix; normalize host-only baseURL (issue #950).\n if (provider === \"anthropic\") {\n baseURL = baseURL.replace(/\\/+$/, \"\");\n if (!baseURL.endsWith(\"/v1\")) {\n baseURL = `${baseURL}/v1`;\n }\n }\n const opts: {\n apiKey: string;\n baseURL: string;\n defaultHeaders?: Record<string, string>;\n defaultQuery?: Record<string, string>;\n fetch?: typeof globalThis.fetch;\n } = {\n apiKey,\n baseURL,\n };\n if (provider === \"anthropic\") opts.defaultHeaders = { \"anthropic-version\": \"2023-06-01\" };\n applyAzureFoundryVerifyDirectClientAuth(opts, provider, apiKey);\n return new OpenAI(opts);\n }\n // One row per model: configured models + reference models (Opus, GPT-5.4, Codex, o3, etc.)\n const configModelSet = new Set(allModelsUnfiltered);\n const uniqueModels = [...new Set([...allModelsUnfiltered, ...VERIFY_REFERENCE_MODELS])];\n uniqueModels.sort((a, b) => providerFromModel(a).localeCompare(providerFromModel(b)) || a.localeCompare(b));\n const llmRows: {\n model: string;\n provider: string;\n hasOAuth: boolean;\n hasApi: boolean;\n enabled: boolean;\n source: string;\n inConfig: boolean;\n tiersLabel: string;\n oauthResult?: boolean;\n apiResult?: boolean;\n oauthError?: string;\n apiError?: string;\n /** When set, direct API test was skipped (e.g. Responses API); show this in API column, do not treat as failed. */\n apiSkippedReason?: string;\n }[] = [];\n function shortError(e: unknown): string {\n const msg = e instanceof Error ? e.message : String(e);\n return msg.slice(0, 100).replace(/\\s+/g, \" \").trim();\n }\n /** Azure Responses rejects max_output_tokens below 16; chat probes still work with a small cap. */\n const VERIFY_LLM_PROBE_MAX_TOKENS = 64;\n /** Cache direct client per provider so we use the same client for each model of that provider. */\n const directClientCache = new Map<string, OpenAI | null>();\n function getDirectClient(provider: string): OpenAI | null {\n if (!directClientCache.has(provider)) {\n directClientCache.set(provider, buildDirectClient(provider) ?? null);\n }\n return directClientCache.get(provider)!;\n }\n for (const model of uniqueModels) {\n const provider = providerFromModel(model);\n const hasApi = providersWithKeys.includes(provider);\n const hasOAuth = gatewayAvailable && Boolean(hasOAuthProfiles(authOrder?.order?.[provider], provider));\n const enabled = !disabledSet.has(provider);\n let source = llmCredentialSource(provider);\n if (!source && gatewayAvailable && (hasOAuth || hasApi)) source = \"gateway\";\n if (!source) source = \"—\";\n const inConfig = configModelSet.has(model);\n const tiersLabel = tiersForModel(model);\n let oauthResult: boolean | undefined;\n let apiResult: boolean | undefined;\n let oauthError: string | undefined;\n let apiError: string | undefined;\n let apiSkippedReason: string | undefined;\n // Test each model that has credentials (OAuth or API), so we report which work even if not yet in llm.nano/maintenance/default/heavy.\n if (opts.testLlm && enabled && (hasOAuth || hasApi)) {\n const bareModel = model.includes(\"/\") ? model.slice(model.indexOf(\"/\") + 1) : model;\n const wireApi = resolveWireApi(model);\n // Some Azure SKUs only expose Responses; others reject non-default temperature on chat — probe must match.\n const isResponsesOnlyModel =\n wireApi === \"responses\" ||\n (provider === \"azure-foundry\" && bareModel === \"gpt-5.4-pro\") ||\n (provider === \"azure-foundry\" && /^o3-pro$/i.test(bareModel)) ||\n (provider === \"openai\" && (bareModel === \"gpt-5-codex\" || bareModel === \"codex\"));\n\n if (hasOAuth && gatewayBaseUrl && gatewayToken) {\n try {\n const oauthClient = new OpenAI({ apiKey: gatewayToken, baseURL: gatewayBaseUrl });\n await chatComplete({\n model,\n content: \"Reply with exactly: OK\",\n maxTokens: VERIFY_LLM_PROBE_MAX_TOKENS,\n temperature: 1,\n openai: oauthClient,\n feature: CostFeature.verifyCliLlm,\n ...(isResponsesOnlyModel ? { wireApi: \"responses\" as const } : {}),\n });\n oauthResult = true;\n } catch (e) {\n oauthError = shortError(e);\n capturePluginError(e as Error, {\n subsystem: \"cli\",\n operation: \"runVerifyForCli:llm-test-oauth\",\n phase: provider,\n });\n oauthResult = false;\n }\n }\n if (hasApi) {\n if (isResponsesOnlyModel) {\n const directClient = getDirectClient(provider);\n if (!directClient) {\n apiResult = false;\n apiError = \"No direct client (missing apiKey or baseURL)\";\n } else {\n try {\n await callResponsesApi(directClient, {\n model: bareModel,\n content: \"Reply with exactly: OK\",\n maxTokens: VERIFY_LLM_PROBE_MAX_TOKENS,\n temperature: 1,\n });\n apiResult = true;\n apiSkippedReason = undefined;\n } catch (e) {\n const errMsg = shortError(e);\n if (errMsg.includes(\"does not expose responses.create\") || /\\b(404|405)\\b/.test(errMsg)) {\n apiResult = undefined;\n apiError = undefined;\n apiSkippedReason = \"N/A (Responses API not available on endpoint)\";\n } else {\n apiError = errMsg;\n if (\n /\\b400\\b/i.test(errMsg) &&\n (provider === \"azure-foundry\" ||\n provider === \"azure-foundry-responses\" ||\n provider === \"azure-foundry-direct\") &&\n errMsg.length < 160\n ) {\n apiError = `${errMsg} — HTTP 400 with a minimal body often means the gateway rejected the route or request shape (wrong APIM product path vs resource URL, or policy). See docs/TROUBLESHOOTING.md (#949).`;\n }\n capturePluginError(e as Error, {\n subsystem: \"cli\",\n operation: \"runVerifyForCli:llm-test-responses-api\",\n phase: provider,\n });\n apiResult = false;\n }\n }\n }\n } else {\n const directClient = getDirectClient(provider);\n if (!directClient) {\n apiResult = false;\n apiError = \"No direct client (missing apiKey or baseURL)\";\n } else {\n try {\n await chatComplete({\n model: bareModel,\n content: \"Reply with exactly: OK\",\n maxTokens: VERIFY_LLM_PROBE_MAX_TOKENS,\n temperature: 1,\n openai: directClient,\n feature: CostFeature.verifyCliLlm,\n });\n apiResult = true;\n } catch (e) {\n apiError = shortError(e);\n if (\n apiError &&\n /\\b400\\b/i.test(apiError) &&\n (provider === \"azure-foundry\" ||\n provider === \"azure-foundry-responses\" ||\n provider === \"azure-foundry-direct\") &&\n apiError.length < 160\n ) {\n apiError = `${apiError} — HTTP 400 with a minimal body often means the gateway rejected the route or request shape (wrong APIM product path vs resource URL, or policy). See docs/TROUBLESHOOTING.md (#949).`;\n }\n capturePluginError(e as Error, {\n subsystem: \"cli\",\n operation: \"runVerifyForCli:llm-test-api\",\n phase: provider,\n });\n apiResult = false;\n }\n }\n }\n }\n }\n llmRows.push({\n model,\n provider,\n hasOAuth,\n hasApi,\n enabled,\n source,\n inConfig,\n tiersLabel,\n oauthResult,\n apiResult,\n oauthError,\n apiError,\n apiSkippedReason,\n });\n }\n if (llmRows.length === 0) {\n tableLog(\n \" No LLM models configured (add llm.nano / llm.maintenance / llm.default / llm.heavy or API keys / OAuth).\",\n );\n tableLog(\" LLMs: add model tiers or API keys in config. See docs/LLM-AND-PROVIDERS.md.\");\n tableLog(\"\");\n tableLog(\" Summary: Configure LLM tiers or API keys to use memory and cron jobs.\");\n } else {\n const llmCols = [\n \"Model\",\n \"Provider\",\n \"Auth (OAuth / API key)\",\n \"Source\",\n \"Tier(s)\",\n \"Enabled\",\n ...(opts.testLlm ? [\"OAuth Result\", \"API Result\"] : []),\n ];\n const llmW1 = Math.max(8, ...llmRows.map((r) => r.model.length), 28);\n const llmW2 = Math.max(6, ...llmRows.map((r) => r.provider.length), 10);\n const llmW3 = Math.max(22, 24);\n const llmW4 = 8;\n const llmW5 = Math.max(9, ...llmRows.map((r) => r.tiersLabel.length), 22);\n const llmW6 = 8;\n const llmW7 = opts.testLlm ? 14 : 0;\n const llmW8 = opts.testLlm ? 12 : 0;\n tableLog(\n ` ${llmCols[0].padEnd(llmW1)} ${llmCols[1].padEnd(llmW2)} ${llmCols[2].padEnd(llmW3)} ${llmCols[3].padEnd(llmW4)} ${llmCols[4].padEnd(llmW5)} ${llmCols[5].padEnd(llmW6)}${opts.testLlm ? ` ${llmCols[6].padEnd(llmW7)} ${llmCols[7]}` : \"\"}`,\n );\n const llmSepLen = llmW1 + llmW2 + llmW3 + llmW4 + llmW5 + llmW6 + 12 + (opts.testLlm ? llmW7 + llmW8 + 4 : 0);\n tableLog(` ${\"-\".repeat(llmSepLen)}`);\n for (const row of llmRows) {\n const credStr = `OAuth:${row.hasOAuth ? \"True\" : \"False\"} / API:${row.hasApi ? \"True\" : \"False\"}`;\n const tiersStr = row.tiersLabel;\n const enabledStr = row.enabled ? (noEmoji ? \"Enabled\" : \"✅ Enabled\") : noEmoji ? \"Disabled\" : \"❌ Disabled\";\n // When --test-llm: show Success/Failed if we ran the test; \"Skipped\" if enabled+inConfig but no creds to test; \"—\" if not in config\n const oauthStr =\n row.oauthResult === true\n ? noEmoji\n ? \"Success\"\n : \"✅ Success\"\n : row.oauthResult === false\n ? noEmoji\n ? \"Failed\"\n : \"❌ Failed\"\n : opts.testLlm && row.enabled && row.inConfig && !row.hasOAuth\n ? noEmoji\n ? \"Skipped (no OAuth)\"\n : \"⏭️ Skipped\"\n : \"—\";\n const apiStr = row.apiSkippedReason\n ? row.apiSkippedReason\n : row.apiResult === true\n ? noEmoji\n ? \"Success\"\n : \"✅ Success\"\n : row.apiResult === false\n ? noEmoji\n ? \"Failed\"\n : \"❌ Failed\"\n : opts.testLlm && row.enabled && row.inConfig && !row.hasApi\n ? noEmoji\n ? \"Skipped (no key)\"\n : \"⏭️ Skipped\"\n : \"—\";\n tableLog(\n ` ${row.model.padEnd(llmW1)} ${row.provider.padEnd(llmW2)} ${credStr.padEnd(llmW3)} ${row.source.padEnd(llmW4)} ${tiersStr.padEnd(llmW5)} ${enabledStr.padEnd(llmW6)}${opts.testLlm ? ` ${oauthStr.padEnd(llmW7)} ${apiStr}` : \"\"}`,\n );\n }\n const failedRows = opts.testLlm ? llmRows.filter((r) => r.oauthError || r.apiError) : [];\n if (failedRows.length > 0) {\n tableLog(\" Failed test details:\");\n let has401Openai = false;\n for (const row of failedRows) {\n if (row.oauthError) tableLog(` ${row.model} (OAuth): ${row.oauthError}`);\n if (row.apiError) {\n tableLog(` ${row.model} (API): ${row.apiError}`);\n if (row.provider === \"openai\" && /401|incorrect api key/i.test(row.apiError)) has401Openai = true;\n }\n }\n if (has401Openai) {\n tableLog(\n \" Note: OpenAI: llm.providers.openai.apiKey or OPENAI_API_KEY. Google: llm.providers.google.apiKey or distill.apiKey or GOOGLE_API_KEY. Azure: llm.providers['azure-foundry'].apiKey or AZURE_OPENAI_API_KEY. See docs/LLM-AND-PROVIDERS.md.\",\n );\n }\n tableLog(\"\");\n }\n tableLog(\n ' (Tier(s) = which tier lists include this model; \"—\" = reference row only, not in your llm.nano/maintenance/default/heavy. Source = key origin. Enabled = provider not in llm.disabledProviders. Skipped = not tested.)',\n );\n const llmProvidersWithCreds = new Set(llmRows.filter((r) => r.hasApi || r.hasOAuth).map((r) => r.provider)).size;\n const llmOk = llmProvidersWithCreds >= 1;\n if (llmOk) {\n tableLog(\n ` LLMs: OK — credentials available for ${llmProvidersWithCreds} provider(s). Source \"—\" or \"gateway\" = key from OpenClaw/env (fine).`,\n );\n } else {\n tableLog(\n \" LLMs: no credentials for any provider — set llm.providers.<provider>.apiKey in config or use gateway OAuth. See docs/LLM-AND-PROVIDERS.md.\",\n );\n }\n tableLog(\"\");\n if (state.anyEmbOk && llmOk) {\n tableLog(\n \" Summary: Ready. Embeddings and LLM are configured. Use memory and cron jobs as needed. Run 'openclaw hybrid-mem config' to toggle features.\",\n );\n } else {\n tableLog(\" Summary: Fix the issue(s) above (or in --- Fixes --- below) before using memory features.\");\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"llm-models.js","names":[],"sources":["../../../../cli/verify/sections/llm-models.ts"],"sourcesContent":["import { getEnv } from \"../../../utils/env-manager.js\";\n/**\n * CLI Verify Command Handler\n *\n * Contains runVerifyForCli and its private helper functions.\n * Checks infrastructure (SQLite, LanceDB, embeddings, LLM credentials,\n * cron jobs) and optionally applies fixes.\n *\n * Extracted from cli/handlers.ts to keep that file manageable.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport OpenAI from \"openai\";\n\nimport {\n getCronModelConfig,\n getLLMModelPreference,\n getLLMModelPreferenceUnfiltered,\n getProvidersWithKeys,\n} from \"../../../config.js\";\nimport { resolveSecretRef } from \"../../../config/parsers/core.js\";\nimport { getEffectiveModelLimits, loadAdaptiveModelLimits } from \"../../../services/adaptive-model-limits.js\";\nimport { chatComplete, distillBatchTokenLimit, distillMaxOutputTokens } from \"../../../services/chat.js\";\nimport { CostFeature } from \"../../../services/cost-feature-labels.js\";\nimport { capturePluginError } from \"../../../services/error-reporter.js\";\nimport { resolveWireApi } from \"../../../services/model-capabilities.js\";\nimport { callResponsesApi } from \"../../../services/responses-adapter.js\";\nimport { hasOAuthProfiles } from \"../../../utils/auth.js\";\nimport { isHeavyModel } from \"../../../utils/model-tier.js\";\nimport {\n buildUnsupportedPerAgentCompactionWarning,\n buildCompactionWatchdogAlert,\n DEFAULT_COMPACTION_MODEL,\n isCompactionModelTooStrong,\n resolveCompactionModelSelection,\n} from \"../../../utils/compaction-model-watchdog.js\";\nimport { applyAzureFoundryVerifyDirectClientAuth } from \"../../verify-llm-azure-auth.js\";\n\nimport type { VerifyRunState } from \"../verify-run-state.js\";\nimport {\n credentialSource,\n ensureRawPluginConfigOnState,\n rawClaudeApiKey,\n rawDistillApiKey,\n rawEmbeddingApiKey,\n rawLlmProviderApiKey,\n} from \"../plugin-config-credentials.js\";\n\nexport async function runVerifyLlmModelsSection(state: VerifyRunState): Promise<void> {\n ensureRawPluginConfigOnState(state);\n const {\n ctx,\n opts,\n cfg,\n factsDb,\n vectorDb,\n embeddings,\n credentialsDb,\n resolvedSqlitePath,\n resolvedLancePath,\n openai,\n log,\n tableLog,\n OK,\n FAIL,\n PAUSE,\n WARN_LINE,\n noEmoji,\n issues,\n fixes,\n warnings,\n loadBlocking,\n extDir,\n defaultConfigPath,\n openclawDir,\n openclawConfigRead,\n recommendedEmbedding,\n dashboardUrl,\n } = state;\n\n // ───── LLM / models table: one row per model from llm.nano / llm.maintenance / llm.default / llm.heavy; auth + source ─────\n tableLog(\"\\n───── LLM / Models (from llm.nano, llm.maintenance, llm.default, llm.heavy) ─────\");\n const cronCfg = getCronModelConfig(cfg);\n const providersWithKeys = getProvidersWithKeys(cronCfg);\n const authOrder = (cfg as Record<string, unknown>).auth as { order?: Record<string, string[]> } | undefined;\n const gatewayPort = getEnv(\"OPENCLAW_GATEWAY_PORT\");\n const gatewayToken = getEnv(\"OPENCLAW_GATEWAY_TOKEN\");\n const gatewayAvailable = Boolean(\n gatewayPort && Number(gatewayPort) >= 1 && Number(gatewayPort) <= 65535 && gatewayToken,\n );\n const tierNano = getLLMModelPreferenceUnfiltered(cronCfg, \"nano\");\n const tierMaintenance = getLLMModelPreferenceUnfiltered(cronCfg, \"maintenance\");\n const tierDefault = getLLMModelPreferenceUnfiltered(cronCfg, \"default\");\n const tierHeavy = getLLMModelPreferenceUnfiltered(cronCfg, \"heavy\");\n const nanoExplicitConfigured =\n Array.isArray(cronCfg.llm?.nano) && cronCfg.llm.nano.some((m) => typeof m === \"string\" && m.trim().length > 0);\n const maintenanceExplicitConfigured =\n Array.isArray(cronCfg.llm?.maintenance) &&\n cronCfg.llm.maintenance.some((m) => typeof m === \"string\" && m.trim().length > 0);\n const allModelsUnfiltered: string[] = [...tierNano, ...tierMaintenance, ...tierDefault, ...tierHeavy];\n function tiersForModel(model: string): string {\n const tags: string[] = [];\n if (tierNano.includes(model)) tags.push(\"nano\");\n if (tierMaintenance.includes(model)) tags.push(\"maintenance\");\n if (tierDefault.includes(model)) tags.push(\"default\");\n if (tierHeavy.includes(model)) tags.push(\"heavy\");\n if (tags.length === 0) return \"—\";\n return tags.join(\", \");\n }\n const fmtTierList = (arr: string[]) => (arr.length > 0 ? arr.join(\", \") : \"(none)\");\n tableLog(\" Effective tier lists (first model in each tier wins when that tier is selected):\");\n tableLog(\n ` nano: ${fmtTierList(tierNano)}${nanoExplicitConfigured ? \"\" : \" — llm.nano unset; nano tier reuses the default list\"}`,\n );\n tableLog(\n ` maintenance: ${fmtTierList(tierMaintenance)}${maintenanceExplicitConfigured ? \"\" : \" — llm.maintenance unset; maintenance tier reuses the default list\"}`,\n );\n tableLog(` default: ${fmtTierList(tierDefault)}`);\n tableLog(` heavy: ${fmtTierList(tierHeavy)}`);\n tableLog(\n ` First choice per tier: nano=${tierNano[0] ?? \"—\"} | maintenance=${tierMaintenance[0] ?? \"—\"} | default=${tierDefault[0] ?? \"—\"} | heavy=${tierHeavy[0] ?? \"—\"}`,\n );\n const distillMainTier = cfg.distill?.modelTier ?? \"maintenance\";\n const distillMainTierRaw = (cfg.distill as { modelTier?: string } | undefined)?.modelTier ?? \"maintenance\";\n const distillMainRequestedHeavy = distillMainTierRaw === \"heavy\";\n // Show the actual effective tier after clamping (cmd-distill.ts clamps \"heavy\" to \"maintenance\")\n const effectiveDistillMainTier = distillMainRequestedHeavy ? \"maintenance\" : distillMainTier;\n const distillMainEffective = getLLMModelPreference(cronCfg, effectiveDistillMainTier)[0] ?? \"—\";\n tableLog(\n ` Distill main pass: distill.modelTier=${distillMainTierRaw}${distillMainRequestedHeavy ? \" (clamped to maintenance)\" : \"\"} -> ${distillMainEffective}; --model overrides one run.`,\n );\n const dreamOverride =\n typeof cfg.nightlyCycle?.model === \"string\" && cfg.nightlyCycle.model.trim().length > 0\n ? cfg.nightlyCycle.model.trim()\n : null;\n const dreamEffective = dreamOverride ?? getLLMModelPreference(cronCfg, \"maintenance\")[0] ?? \"—\";\n const extractionTier = cfg.distill?.extractionModelTier ?? \"nano\";\n let compactionSelection = resolveCompactionModelSelection(undefined, { fallbackPolicy: \"inherit-defaults-primary\" });\n const compactionSelectionUnknownReason = openclawConfigRead.root\n ? null\n : openclawConfigRead.error !== undefined\n ? `active OpenClaw config (${defaultConfigPath}) is unreadable/invalid (${openclawConfigRead.error})`\n : `active OpenClaw config (${defaultConfigPath}) is missing`;\n if (openclawConfigRead.root) {\n // Use defaults-primary inheritance fallback to mirror current OpenClaw core behavior\n // when agents.defaults.compaction.model is unset.\n compactionSelection = resolveCompactionModelSelection(openclawConfigRead.root, {\n fallbackPolicy: \"inherit-defaults-primary\",\n });\n }\n const compactionRoutingUnknownReason =\n compactionSelectionUnknownReason ??\n (compactionSelection.routingUnknownFromConfig\n ? \"neither agents.defaults.compaction.model nor agents.defaults.model.primary is set; compaction may follow the active session chat model\"\n : null);\n tableLog(\n dreamOverride\n ? ` Dream cycle + MEMORY_INDEX.md: nightlyCycle.model=\"${dreamOverride}\" (overrides default tier for that pipeline).`\n : ` Dream cycle + MEMORY_INDEX.md: uses maintenance tier first choice (${tierMaintenance[0] ?? \"—\"}) unless nightlyCycle.model is set.`,\n );\n tableLog(\n \" Embeddings / re-index: embedding.model + embedding.* (not llm tiers). Chat LLM spend is separate from embedding API spend.\",\n );\n tableLog(\n ` Compaction (agents.*.compaction): provider=${compactionSelection.provider}, model=${compactionSelection.model || \"—\"}, reason=${compactionSelection.reason}${\n compactionRoutingUnknownReason ? `; status=unknown (${compactionRoutingUnknownReason})` : \"\"\n }`,\n );\n\n const adaptiveEnabled = (getEnv(\"OPENCLAW_HYBRID_MEM_ADAPTIVE_DISTILL\") ?? \"\").trim() !== \"0\";\n const adaptiveStatePath =\n typeof ctx.resolvedSqlitePath === \"string\" && ctx.resolvedSqlitePath.length > 0\n ? join(dirname(ctx.resolvedSqlitePath), \".adaptive-llm-limits.json\")\n : \"\";\n tableLog(\n ` Adaptive maintenance LLM sizing: ${adaptiveEnabled ? \"enabled\" : \"disabled\"} (state=${adaptiveStatePath}; applies to distill, reflect, extract-reinforcement, self-correction-run)`,\n );\n if (adaptiveEnabled && adaptiveStatePath && existsSync(adaptiveStatePath)) {\n try {\n const adaptiveState = loadAdaptiveModelLimits(adaptiveStatePath);\n const sampleModels = [\n distillMainEffective,\n dreamEffective,\n getLLMModelPreference(cronCfg, extractionTier)[0] ?? \"—\",\n tierHeavy[0] ?? \"—\",\n ].filter((m, i, arr) => m !== \"—\" && arr.indexOf(m) === i);\n for (const sampleModel of sampleModels) {\n const effective = getEffectiveModelLimits({\n state: adaptiveState,\n model: sampleModel,\n catalogBatchTokenLimit: distillBatchTokenLimit(sampleModel),\n catalogMaxOutputTokens: distillMaxOutputTokens(sampleModel),\n });\n tableLog(\n ` ${sampleModel}: batchTokenLimit=${effective.batchTokenLimit}, maxOutputTokens=${effective.maxOutputTokens}, source=${effective.source}`,\n );\n }\n } catch (err) {\n state.warnings.push(\n `adaptive maintenance LLM state could not be read: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n // Maintenance routing warnings: flag when maintenance-adjacent tasks are routed to heavy/expensive models unintentionally.\n // NOTE: cmd-distill.ts now clamps distill.modelTier=heavy to maintenance, so this check uses effectiveDistillMainTier.\n if (distillMainEffective !== \"—\" && isHeavyModel(distillMainEffective)) {\n state.warnings.push(\n `distill.modelTier=${distillMainTier} routes the main distill pass to a heavy/expensive first-choice model (${distillMainEffective}); configure llm.maintenance with a cheap-first list or set distill.modelTier=nano`,\n );\n }\n if (distillMainRequestedHeavy) {\n state.warnings.push(\n \"distill.modelTier=heavy is not supported for the main distill pass (clamped to maintenance in cmd-distill.ts). Use --model to override for a single run if needed.\",\n );\n }\n const extractionFirst =\n getLLMModelPreference(cronCfg, extractionTier)[0] ?? getLLMModelPreference(cronCfg, \"nano\")[0] ?? \"—\";\n if (extractionTier !== \"heavy\" && extractionFirst !== \"—\" && isHeavyModel(extractionFirst)) {\n state.warnings.push(\n `distill.extractionModelTier=${extractionTier} routes session extraction to a heavy/expensive first-choice model (${extractionFirst}); set distill.extractionModelTier=nano or configure llm.maintenance and use distill.extractionModelTier=maintenance`,\n );\n }\n if (dreamEffective !== \"—\" && isHeavyModel(dreamEffective)) {\n state.warnings.push(\n `dream-cycle/MEMORY_INDEX routes to a heavy/expensive model (${dreamEffective}); set nightlyCycle.model to a cheaper model or configure llm.maintenance with a cheap-first list`,\n );\n }\n if (compactionRoutingUnknownReason) {\n state.warnings.push(\n `verify watchdog: compaction routing check is unknown because ${compactionRoutingUnknownReason}; set/repair config and rerun verify.`,\n );\n } else {\n const unsupportedWarning = buildUnsupportedPerAgentCompactionWarning(compactionSelection, { context: \"verify\" });\n if (unsupportedWarning) state.warnings.push(unsupportedWarning);\n }\n if (!compactionRoutingUnknownReason && isCompactionModelTooStrong(compactionSelection.model)) {\n const alert =\n buildCompactionWatchdogAlert({\n stage: \"verify\",\n model: compactionSelection.model,\n provider: compactionSelection.provider,\n source: compactionSelection.reason,\n }) ??\n `compaction routing uses a stronger-than-mini model (provider=${compactionSelection.provider}, model=${compactionSelection.model}, reason=${compactionSelection.reason}). Set agents.defaults.compaction.model to a mini/nano model such as ${DEFAULT_COMPACTION_MODEL}.`;\n state.warnings.push(alert);\n }\n const _allModelsFiltered: string[] = [\n ...getLLMModelPreference(cronCfg, \"nano\"),\n ...getLLMModelPreference(cronCfg, \"maintenance\"),\n ...getLLMModelPreference(cronCfg, \"default\"),\n ...getLLMModelPreference(cronCfg, \"heavy\"),\n ];\n // Reference models always shown in verify so users see Opus, GPT-5.4, Codex, o3, etc. with auth/source\n const VERIFY_REFERENCE_MODELS: string[] = [\n \"anthropic/claude-opus-4-6\",\n \"anthropic/claude-sonnet-4-6\",\n \"anthropic/claude-haiku-4-5-20251001\",\n \"openai/gpt-5.4\",\n \"openai/gpt-4.1-mini\",\n \"openai/gpt-4.1-nano\",\n \"openai/o3\",\n \"openai/o1\",\n \"openai/gpt-5-codex\",\n \"google/gemini-3.1-pro-preview\",\n \"google/gemini-2.5-flash\",\n \"google/gemini-2.5-flash-lite\",\n \"minimax/MiniMax-M2.5\",\n ];\n const providerFromModel = (m: string) => {\n if (m.includes(\"/\")) {\n return m.split(\"/\")[0].toLowerCase();\n }\n const bare = m.trim().toLowerCase();\n if (bare.startsWith(\"gemini-\")) return \"google\";\n if (bare.startsWith(\"claude-\")) return \"anthropic\";\n if (bare.startsWith(\"gpt-\") || bare.match(/^o[0-9]/)) return \"openai\";\n return \"openai\";\n };\n const disabledSet = new Set((cfg.llm?.disabledProviders ?? []).map((p) => String(p).trim().toLowerCase()));\n const _defaultTestModel: Record<string, string> = {\n openai: \"openai/gpt-4.1-nano\",\n google: \"google/gemini-2.5-flash-lite\",\n anthropic: \"anthropic/claude-haiku-4-5-20251001\",\n ollama: \"ollama/llama3.2\",\n minimax: \"minimax/minimax-01\",\n };\n function llmCredentialSource(provider: string): string {\n if (gatewayAvailable && hasOAuthProfiles(authOrder?.order?.[provider], provider)) return \"gateway\";\n if (provider === \"openai\")\n return credentialSource(rawEmbeddingApiKey(state)) || credentialSource(rawLlmProviderApiKey(state, \"openai\"));\n if (provider === \"google\")\n return credentialSource(rawDistillApiKey(state)) || credentialSource(rawLlmProviderApiKey(state, \"google\"));\n if (provider === \"anthropic\")\n return credentialSource(rawClaudeApiKey(state)) || credentialSource(rawLlmProviderApiKey(state, \"anthropic\"));\n return credentialSource(rawLlmProviderApiKey(state, provider)) || \"plugin\";\n }\n const gatewayBaseUrl =\n gatewayPort && Number(gatewayPort) >= 1 && Number(gatewayPort) <= 65535\n ? `http://127.0.0.1:${Number(gatewayPort)}/v1`\n : undefined;\n const VERIFY_LLM_BASE_URLS: Record<string, string> = {\n openai: \"https://api.openai.com/v1\",\n google: \"https://generativelanguage.googleapis.com/v1beta/openai/\",\n anthropic: \"https://api.anthropic.com/v1\",\n ollama: \"http://127.0.0.1:11434/v1\",\n minimax: \"https://api.minimax.chat/v1\",\n };\n function resolveKey(raw: unknown): string | undefined {\n if (typeof raw !== \"string\" || !raw.trim()) return undefined;\n const trimmed = raw.trim();\n const resolved = trimmed.startsWith(\"env:\") || trimmed.startsWith(\"file:\") ? resolveSecretRef(trimmed) : trimmed;\n return typeof resolved === \"string\" && resolved.length >= 10 ? resolved : undefined;\n }\n function getDirectApiKey(provider: string): string | undefined {\n const prov = cronCfg.llm?.providers as Record<string, { apiKey?: string }> | undefined;\n if (provider === \"openai\") {\n // Prefer OPENAI_API_KEY so Azure (embedding) and OpenAI (chat) can use different keys.\n const fromProv = resolveKey(prov?.openai?.apiKey);\n if (fromProv) return fromProv;\n const fromEnv = getEnv(\"OPENAI_API_KEY\")?.trim();\n if (fromEnv && fromEnv.length >= 10) return fromEnv;\n return resolveKey(cronCfg.embedding?.apiKey);\n }\n if (provider === \"google\") {\n const fromProv = resolveKey(prov?.google?.apiKey ?? cronCfg.distill?.apiKey);\n if (fromProv) return fromProv;\n const fromEnv = getEnv(\"GOOGLE_API_KEY\")?.trim();\n if (fromEnv && fromEnv.length >= 10) return fromEnv;\n return undefined;\n }\n if (provider === \"anthropic\") {\n const fromProv = resolveKey(\n prov?.anthropic?.apiKey ?? (cronCfg.claude as { apiKey?: string } | undefined)?.apiKey,\n );\n if (fromProv) return fromProv;\n const fromEnv = getEnv(\"ANTHROPIC_API_KEY\")?.trim();\n if (fromEnv && fromEnv.length >= 10) return fromEnv;\n return undefined;\n }\n if (provider === \"ollama\") return \"ollama\";\n // Azure Foundry: use AZURE_OPENAI_API_KEY when llm.providers key is not set.\n if (\n (provider === \"azure-foundry\" || provider === \"azure-foundry-responses\" || provider === \"azure-foundry-direct\") &&\n !resolveKey(prov?.[provider]?.apiKey)\n ) {\n const fromEnv = getEnv(\"AZURE_OPENAI_API_KEY\")?.trim();\n if (fromEnv && fromEnv.length >= 10) return fromEnv;\n }\n return resolveKey(prov?.[provider]?.apiKey);\n }\n function buildDirectClient(provider: string): OpenAI | undefined {\n const apiKey = getDirectApiKey(provider);\n if (!apiKey) return undefined;\n const provEntry = (cronCfg.llm?.providers as Record<string, { baseURL?: string; baseUrl?: string }> | undefined)?.[\n provider\n ];\n let baseURL =\n (typeof provEntry?.baseURL === \"string\" && provEntry.baseURL.trim() ? provEntry.baseURL.trim() : undefined) ??\n (typeof provEntry?.baseUrl === \"string\" && provEntry.baseUrl.trim() ? provEntry.baseUrl.trim() : undefined) ??\n VERIFY_LLM_BASE_URLS[provider];\n if (!baseURL) return undefined;\n // Anthropic's OpenAI-compatible chat endpoint requires /v1 suffix; normalize host-only baseURL (issue #950).\n if (provider === \"anthropic\") {\n baseURL = baseURL.replace(/\\/+$/, \"\");\n if (!baseURL.endsWith(\"/v1\")) {\n baseURL = `${baseURL}/v1`;\n }\n }\n const opts: {\n apiKey: string;\n baseURL: string;\n defaultHeaders?: Record<string, string>;\n defaultQuery?: Record<string, string>;\n fetch?: typeof globalThis.fetch;\n } = {\n apiKey,\n baseURL,\n };\n if (provider === \"anthropic\") opts.defaultHeaders = { \"anthropic-version\": \"2023-06-01\" };\n applyAzureFoundryVerifyDirectClientAuth(opts, provider, apiKey);\n return new OpenAI(opts);\n }\n // One row per model: configured models + reference models (Opus, GPT-5.4, Codex, o3, etc.)\n const configModelSet = new Set(allModelsUnfiltered);\n const uniqueModels = [...new Set([...allModelsUnfiltered, ...VERIFY_REFERENCE_MODELS])];\n uniqueModels.sort((a, b) => providerFromModel(a).localeCompare(providerFromModel(b)) || a.localeCompare(b));\n const llmRows: {\n model: string;\n provider: string;\n hasOAuth: boolean;\n hasApi: boolean;\n enabled: boolean;\n source: string;\n inConfig: boolean;\n tiersLabel: string;\n oauthResult?: boolean;\n apiResult?: boolean;\n oauthError?: string;\n apiError?: string;\n /** When set, direct API test was skipped (e.g. Responses API); show this in API column, do not treat as failed. */\n apiSkippedReason?: string;\n }[] = [];\n function shortError(e: unknown): string {\n const msg = e instanceof Error ? e.message : String(e);\n return msg.slice(0, 100).replace(/\\s+/g, \" \").trim();\n }\n /** Azure Responses rejects max_output_tokens below 16; chat probes still work with a small cap. */\n const VERIFY_LLM_PROBE_MAX_TOKENS = 64;\n /** Cache direct client per provider so we use the same client for each model of that provider. */\n const directClientCache = new Map<string, OpenAI | null>();\n function getDirectClient(provider: string): OpenAI | null {\n if (!directClientCache.has(provider)) {\n directClientCache.set(provider, buildDirectClient(provider) ?? null);\n }\n return directClientCache.get(provider)!;\n }\n for (const model of uniqueModels) {\n const provider = providerFromModel(model);\n const hasApi = providersWithKeys.includes(provider);\n const hasOAuth = gatewayAvailable && Boolean(hasOAuthProfiles(authOrder?.order?.[provider], provider));\n const enabled = !disabledSet.has(provider);\n let source = llmCredentialSource(provider);\n if (!source && gatewayAvailable && (hasOAuth || hasApi)) source = \"gateway\";\n if (!source) source = \"—\";\n const inConfig = configModelSet.has(model);\n const tiersLabel = tiersForModel(model);\n let oauthResult: boolean | undefined;\n let apiResult: boolean | undefined;\n let oauthError: string | undefined;\n let apiError: string | undefined;\n let apiSkippedReason: string | undefined;\n // Test each model that has credentials (OAuth or API), so we report which work even if not yet in llm.nano/maintenance/default/heavy.\n if (opts.testLlm && enabled && (hasOAuth || hasApi)) {\n const bareModel = model.includes(\"/\") ? model.slice(model.indexOf(\"/\") + 1) : model;\n const wireApi = resolveWireApi(model);\n // Some Azure SKUs only expose Responses; others reject non-default temperature on chat — probe must match.\n const isResponsesOnlyModel =\n wireApi === \"responses\" ||\n (provider === \"azure-foundry\" && bareModel === \"gpt-5.4-pro\") ||\n (provider === \"azure-foundry\" && /^o3-pro$/i.test(bareModel)) ||\n (provider === \"openai\" && (bareModel === \"gpt-5-codex\" || bareModel === \"codex\"));\n\n if (hasOAuth && gatewayBaseUrl && gatewayToken) {\n try {\n const oauthClient = new OpenAI({ apiKey: gatewayToken, baseURL: gatewayBaseUrl });\n await chatComplete({\n model,\n content: \"Reply with exactly: OK\",\n maxTokens: VERIFY_LLM_PROBE_MAX_TOKENS,\n temperature: 1,\n openai: oauthClient,\n feature: CostFeature.verifyCliLlm,\n ...(isResponsesOnlyModel ? { wireApi: \"responses\" as const } : {}),\n });\n oauthResult = true;\n } catch (e) {\n oauthError = shortError(e);\n capturePluginError(e as Error, {\n subsystem: \"cli\",\n operation: \"runVerifyForCli:llm-test-oauth\",\n phase: provider,\n });\n oauthResult = false;\n }\n }\n if (hasApi) {\n if (isResponsesOnlyModel) {\n const directClient = getDirectClient(provider);\n if (!directClient) {\n apiResult = false;\n apiError = \"No direct client (missing apiKey or baseURL)\";\n } else {\n try {\n await callResponsesApi(directClient, {\n model: bareModel,\n content: \"Reply with exactly: OK\",\n maxTokens: VERIFY_LLM_PROBE_MAX_TOKENS,\n temperature: 1,\n });\n apiResult = true;\n apiSkippedReason = undefined;\n } catch (e) {\n const errMsg = shortError(e);\n if (errMsg.includes(\"does not expose responses.create\") || /\\b(404|405)\\b/.test(errMsg)) {\n apiResult = undefined;\n apiError = undefined;\n apiSkippedReason = \"N/A (Responses API not available on endpoint)\";\n } else {\n apiError = errMsg;\n if (\n /\\b400\\b/i.test(errMsg) &&\n (provider === \"azure-foundry\" ||\n provider === \"azure-foundry-responses\" ||\n provider === \"azure-foundry-direct\") &&\n errMsg.length < 160\n ) {\n apiError = `${errMsg} — HTTP 400 with a minimal body often means the gateway rejected the route or request shape (wrong APIM product path vs resource URL, or policy). See docs/TROUBLESHOOTING.md (#949).`;\n }\n capturePluginError(e as Error, {\n subsystem: \"cli\",\n operation: \"runVerifyForCli:llm-test-responses-api\",\n phase: provider,\n });\n apiResult = false;\n }\n }\n }\n } else {\n const directClient = getDirectClient(provider);\n if (!directClient) {\n apiResult = false;\n apiError = \"No direct client (missing apiKey or baseURL)\";\n } else {\n try {\n await chatComplete({\n model: bareModel,\n content: \"Reply with exactly: OK\",\n maxTokens: VERIFY_LLM_PROBE_MAX_TOKENS,\n temperature: 1,\n openai: directClient,\n feature: CostFeature.verifyCliLlm,\n });\n apiResult = true;\n } catch (e) {\n apiError = shortError(e);\n if (\n apiError &&\n /\\b400\\b/i.test(apiError) &&\n (provider === \"azure-foundry\" ||\n provider === \"azure-foundry-responses\" ||\n provider === \"azure-foundry-direct\") &&\n apiError.length < 160\n ) {\n apiError = `${apiError} — HTTP 400 with a minimal body often means the gateway rejected the route or request shape (wrong APIM product path vs resource URL, or policy). See docs/TROUBLESHOOTING.md (#949).`;\n }\n capturePluginError(e as Error, {\n subsystem: \"cli\",\n operation: \"runVerifyForCli:llm-test-api\",\n phase: provider,\n });\n apiResult = false;\n }\n }\n }\n }\n }\n llmRows.push({\n model,\n provider,\n hasOAuth,\n hasApi,\n enabled,\n source,\n inConfig,\n tiersLabel,\n oauthResult,\n apiResult,\n oauthError,\n apiError,\n apiSkippedReason,\n });\n }\n if (llmRows.length === 0) {\n tableLog(\n \" No LLM models configured (add llm.nano / llm.maintenance / llm.default / llm.heavy or API keys / OAuth).\",\n );\n tableLog(\" LLMs: add model tiers or API keys in config. See docs/LLM-AND-PROVIDERS.md.\");\n tableLog(\"\");\n tableLog(\" Summary: Configure LLM tiers or API keys to use memory and cron jobs.\");\n } else {\n const llmCols = [\n \"Model\",\n \"Provider\",\n \"Auth (OAuth / API key)\",\n \"Source\",\n \"Tier(s)\",\n \"Enabled\",\n ...(opts.testLlm ? [\"OAuth Result\", \"API Result\"] : []),\n ];\n const llmW1 = Math.max(8, ...llmRows.map((r) => r.model.length), 28);\n const llmW2 = Math.max(6, ...llmRows.map((r) => r.provider.length), 10);\n const llmW3 = Math.max(22, 24);\n const llmW4 = 8;\n const llmW5 = Math.max(9, ...llmRows.map((r) => r.tiersLabel.length), 22);\n const llmW6 = 8;\n const llmW7 = opts.testLlm ? 14 : 0;\n const llmW8 = opts.testLlm ? 12 : 0;\n tableLog(\n ` ${llmCols[0].padEnd(llmW1)} ${llmCols[1].padEnd(llmW2)} ${llmCols[2].padEnd(llmW3)} ${llmCols[3].padEnd(llmW4)} ${llmCols[4].padEnd(llmW5)} ${llmCols[5].padEnd(llmW6)}${opts.testLlm ? ` ${llmCols[6].padEnd(llmW7)} ${llmCols[7]}` : \"\"}`,\n );\n const llmSepLen = llmW1 + llmW2 + llmW3 + llmW4 + llmW5 + llmW6 + 12 + (opts.testLlm ? llmW7 + llmW8 + 4 : 0);\n tableLog(` ${\"-\".repeat(llmSepLen)}`);\n for (const row of llmRows) {\n const credStr = `OAuth:${row.hasOAuth ? \"True\" : \"False\"} / API:${row.hasApi ? \"True\" : \"False\"}`;\n const tiersStr = row.tiersLabel;\n const enabledStr = row.enabled ? (noEmoji ? \"Enabled\" : \"✅ Enabled\") : noEmoji ? \"Disabled\" : \"❌ Disabled\";\n // When --test-llm: show Success/Failed if we ran the test; \"Skipped\" if enabled+inConfig but no creds to test; \"—\" if not in config\n const oauthStr =\n row.oauthResult === true\n ? noEmoji\n ? \"Success\"\n : \"✅ Success\"\n : row.oauthResult === false\n ? noEmoji\n ? \"Failed\"\n : \"❌ Failed\"\n : opts.testLlm && row.enabled && row.inConfig && !row.hasOAuth\n ? noEmoji\n ? \"Skipped (no OAuth)\"\n : \"⏭️ Skipped\"\n : \"—\";\n const apiStr = row.apiSkippedReason\n ? row.apiSkippedReason\n : row.apiResult === true\n ? noEmoji\n ? \"Success\"\n : \"✅ Success\"\n : row.apiResult === false\n ? noEmoji\n ? \"Failed\"\n : \"❌ Failed\"\n : opts.testLlm && row.enabled && row.inConfig && !row.hasApi\n ? noEmoji\n ? \"Skipped (no key)\"\n : \"⏭️ Skipped\"\n : \"—\";\n tableLog(\n ` ${row.model.padEnd(llmW1)} ${row.provider.padEnd(llmW2)} ${credStr.padEnd(llmW3)} ${row.source.padEnd(llmW4)} ${tiersStr.padEnd(llmW5)} ${enabledStr.padEnd(llmW6)}${opts.testLlm ? ` ${oauthStr.padEnd(llmW7)} ${apiStr}` : \"\"}`,\n );\n }\n const failedRows = opts.testLlm ? llmRows.filter((r) => r.oauthError || r.apiError) : [];\n if (failedRows.length > 0) {\n tableLog(\" Failed test details:\");\n let has401Openai = false;\n for (const row of failedRows) {\n if (row.oauthError) tableLog(` ${row.model} (OAuth): ${row.oauthError}`);\n if (row.apiError) {\n tableLog(` ${row.model} (API): ${row.apiError}`);\n if (row.provider === \"openai\" && /401|incorrect api key/i.test(row.apiError)) has401Openai = true;\n }\n }\n if (has401Openai) {\n tableLog(\n \" Note: OpenAI: llm.providers.openai.apiKey or OPENAI_API_KEY. Google: llm.providers.google.apiKey or distill.apiKey or GOOGLE_API_KEY. Azure: llm.providers['azure-foundry'].apiKey or AZURE_OPENAI_API_KEY. See docs/LLM-AND-PROVIDERS.md.\",\n );\n }\n tableLog(\"\");\n }\n tableLog(\n ' (Tier(s) = which tier lists include this model; \"—\" = reference row only, not in your llm.nano/maintenance/default/heavy. Source = key origin. Enabled = provider not in llm.disabledProviders. Skipped = not tested.)',\n );\n const llmProvidersWithCreds = new Set(llmRows.filter((r) => r.hasApi || r.hasOAuth).map((r) => r.provider)).size;\n const llmOk = llmProvidersWithCreds >= 1;\n if (llmOk) {\n tableLog(\n ` LLMs: OK — credentials available for ${llmProvidersWithCreds} provider(s). Source \"—\" or \"gateway\" = key from OpenClaw/env (fine).`,\n );\n } else {\n tableLog(\n \" LLMs: no credentials for any provider — set llm.providers.<provider>.apiKey in config or use gateway OAuth. See docs/LLM-AND-PROVIDERS.md.\",\n );\n }\n tableLog(\"\");\n if (state.anyEmbOk && llmOk) {\n tableLog(\n \" Summary: Ready. Embeddings and LLM are configured. Use memory and cron jobs as needed. Run 'openclaw hybrid-mem config' to toggle features.\",\n );\n } else {\n tableLog(\" Summary: Fix the issue(s) above (or in --- Fixes --- below) before using memory features.\");\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.js","names":[],"sources":["../../../../cli/verify/sections/reconcile.ts"],"sourcesContent":["/**\n * CLI Verify Command Handler\n *\n * Contains runVerifyForCli and its private helper functions.\n * Checks infrastructure (SQLite, LanceDB, embeddings, LLM credentials,\n * cron jobs) and optionally applies fixes.\n *\n * Extracted from cli/handlers.ts to keep that file manageable.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport { getCronModelConfig } from \"../../../config.js\";\nimport { reconcileAllCronRunLedgers } from \"../../../services/cron-maintenance-reconciler.js\";\nimport { capturePluginError } from \"../../../services/error-reporter.js\";\nimport { HYBRID_MEM_CRON_DEFAULT_JOB_STEPS } from \"../../../services/hybrid-mem-cron-default-job-steps.js\";\nimport { appendVectorLifecycleAuditEvent } from \"../../../services/vector-lifecycle-audit.js\";\nimport { PLUGIN_ID } from \"../../../utils/constants.js\";\nimport { ensureGoalStewardshipHeartbeatCronJob, ensureMaintenanceCronJobs } from \"../../cmd-install.js\";\n\nimport type { VerifyRunState } from \"../verify-run-state.js\";\n\nexport async function runVerifyReconcileSection(state: VerifyRunState): Promise<void> {\n const {\n ctx,\n opts,\n cfg,\n factsDb,\n vectorDb,\n embeddings,\n credentialsDb,\n resolvedSqlitePath,\n resolvedLancePath,\n openai,\n log,\n tableLog,\n OK,\n FAIL,\n PAUSE,\n WARN_LINE,\n noEmoji,\n issues,\n fixes,\n warnings,\n loadBlocking,\n extDir,\n defaultConfigPath,\n openclawDir,\n openclawConfigRead,\n recommendedEmbedding,\n dashboardUrl,\n } = state;\n\n // ───── Reconciliation Check ─────\n if (opts.reconcile) {\n log(\"\\n───── Vector DB Reconciliation ─────\");\n if (!state.sqliteOk || !state.lanceOk || !vectorDb.isLanceDbAvailable()) {\n log(`${FAIL} Reconciliation skipped — both SQLite and LanceDB must be healthy to reconcile.`);\n state.allOk = false;\n } else {\n try {\n const reconcilePolicy = opts.reconcilePolicy ?? \"balanced\";\n const reconcileMaxFixes = Math.max(0, Math.min(5000, opts.reconcileMaxFixes ?? 200));\n const sqliteOrphanRebuildBudget =\n reconcilePolicy === \"conservative\"\n ? 0\n : reconcilePolicy === \"balanced\"\n ? reconcileMaxFixes\n : Math.max(reconcileMaxFixes, 2000);\n const sqliteIds = new Set(factsDb.getAllIds());\n const vectorIds = await vectorDb.getAllIds();\n\n // Vector orphans: IDs in LanceDB that have no corresponding SQLite fact.\n const vectorOrphans = vectorIds.filter((id) => !sqliteIds.has(id));\n // SQLite orphans: active facts in SQLite with no vector in LanceDB.\n const vectorIdSet = new Set(vectorIds);\n const sqliteOrphans = Array.from(sqliteIds).filter((id) => !vectorIdSet.has(id));\n\n if (vectorOrphans.length === 0 && sqliteOrphans.length === 0) {\n log(\n `${OK} Reconciliation: SQLite and LanceDB are in sync (${sqliteIds.size} facts, ${vectorIds.length} vectors)`,\n );\n } else {\n state.allOk = false;\n if (vectorOrphans.length > 0) {\n log(`${FAIL} Vector orphans (in LanceDB but not SQLite): ${vectorOrphans.length}`);\n vectorOrphans.slice(0, 10).forEach((id) => {\n log(` - ${id}`);\n });\n if (vectorOrphans.length > 10) log(` … and ${vectorOrphans.length - 10} more`);\n if (opts.fix) {\n let attempted = 0;\n let apiDeleted = 0;\n let apiNoOp = 0;\n let deleteErrors = 0;\n for (const id of vectorOrphans) {\n try {\n attempted++;\n const removed = await vectorDb.delete(id);\n if (removed) {\n apiDeleted++;\n } else {\n apiNoOp++;\n }\n } catch {\n deleteErrors++;\n }\n }\n log(\n ` → Delete attempted for ${attempted} orphan vector(s): ` +\n `apiDeleted=${apiDeleted}, apiNoOp=${apiNoOp}, errors=${deleteErrors}.`,\n );\n\n let unresolvedAfterDelete = [...vectorOrphans];\n let recheckFailed = false;\n try {\n const postDeleteVectorIds = new Set(await vectorDb.getAllIds());\n unresolvedAfterDelete = vectorOrphans.filter((id) => postDeleteVectorIds.has(id));\n } catch (recheckErr) {\n log(`${FAIL} Could not re-query LanceDB after delete attempt: ${String(recheckErr)}`);\n recheckFailed = true;\n }\n\n if (recheckFailed) {\n log(\n `${FAIL} Reconciliation verification failed — cannot confirm whether ${vectorOrphans.length} orphan vector(s) were removed.`,\n );\n state.issues.push(\n `${vectorOrphans.length} orphan vector(s) deletion could not be verified due to LanceDB re-query failure`,\n );\n state.allOk = false;\n } else {\n const verifiedRemoved = vectorOrphans.length - unresolvedAfterDelete.length;\n if (unresolvedAfterDelete.length === 0) {\n log(` → Verified removal: ${verifiedRemoved}/${vectorOrphans.length} orphan vector(s) are gone.`);\n fixes.push(`Verified removal of ${verifiedRemoved} LanceDB orphan vector(s)`);\n } else {\n log(\n `${FAIL} Reconciliation incomplete — ${unresolvedAfterDelete.length}/${vectorOrphans.length} orphan vector(s) remain after delete attempt.`,\n );\n for (const id of unresolvedAfterDelete.slice(0, 10)) {\n log(` - unresolved: ${id}`);\n }\n if (unresolvedAfterDelete.length > 10) {\n log(` … and ${unresolvedAfterDelete.length - 10} more unresolved orphan vectors`);\n }\n const failReason =\n typeof vectorDb.getLastSearchFailReason === \"function\" ? vectorDb.getLastSearchFailReason() : null;\n if (failReason) {\n log(` → LanceDB degraded hint: lastSearchFailReason=${failReason}`);\n }\n state.issues.push(\n `${unresolvedAfterDelete.length} orphan vector(s) still present after --reconcile --fix delete attempts`,\n );\n state.allOk = false;\n }\n }\n } else {\n log(\" → Run with --fix to delete these orphan vectors from LanceDB.\");\n state.issues.push(`${vectorOrphans.length} orphan vector(s) in LanceDB with no matching SQLite fact`);\n }\n }\n if (sqliteOrphans.length > 0) {\n const WARN = noEmoji ? \"[WARN]\" : \"⚠️\";\n log(`${WARN} SQLite orphans (facts in SQLite with no vector): ${sqliteOrphans.length}`);\n sqliteOrphans.slice(0, 10).forEach((id) => {\n log(` - ${id}`);\n });\n if (sqliteOrphans.length > 10) log(` … and ${sqliteOrphans.length - 10} more`);\n if (opts.fix && sqliteOrphanRebuildBudget > 0) {\n let rebuilt = 0;\n let failed = 0;\n for (const id of sqliteOrphans.slice(0, sqliteOrphanRebuildBudget)) {\n try {\n const fact = factsDb.getById(id);\n if (!fact) {\n failed++;\n continue;\n }\n const vec = await embeddings.embed(fact.text);\n await vectorDb.store({\n id: fact.id,\n text: fact.text,\n vector: vec,\n importance: fact.importance ?? 0.5,\n category: fact.category,\n });\n rebuilt++;\n } catch {\n failed++;\n }\n }\n log(\n ` → Rebuild policy=${reconcilePolicy}: rebuilt ${rebuilt}/${Math.min(sqliteOrphans.length, sqliteOrphanRebuildBudget)} SQLite orphan vector(s)${failed > 0 ? ` (${failed} failed)` : \"\"}.`,\n );\n if (sqliteOrphans.length > sqliteOrphanRebuildBudget) {\n log(\n ` → Skipped ${sqliteOrphans.length - sqliteOrphanRebuildBudget} SQLite orphan(s) due to --reconcile-max-fixes budget.`,\n );\n }\n } else if (opts.fix && sqliteOrphanRebuildBudget === 0) {\n log(\n ` → Policy=${reconcilePolicy}: SQLite-orphan auto-rebuild disabled; use re-index for full recovery.`,\n );\n } else {\n log(\" → Re-run the plugin or use the re-index command to rebuild missing vectors.\");\n }\n state.issues.push(`${sqliteOrphans.length} SQLite fact(s) without corresponding vectors in LanceDB`);\n }\n }\n if (resolvedSqlitePath) {\n appendVectorLifecycleAuditEvent(resolvedSqlitePath, {\n event: \"reconcile_completed\",\n ts: new Date().toISOString(),\n details: {\n fix: opts.fix,\n reconcilePolicy,\n reconcileMaxFixes,\n vectorOrphans: vectorOrphans.length,\n sqliteOrphans: sqliteOrphans.length,\n },\n });\n }\n } catch (e) {\n log(`${FAIL} Reconciliation: FAIL — ${String(e)}`);\n state.allOk = false;\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:reconcile\" });\n }\n }\n }\n\n // ───── Cron Ledger Reconciliation (explicit --reconcile only; optional --fix to write) ─────\n if (opts.reconcile) {\n log(\"\\n───── Cron Maintenance Ledger Reconciliation ─────\");\n try {\n const cronRunsDir = join(openclawDir, \"cron\", \"runs\");\n const logDir = join(openclawDir, \"logs\", \"cron-hybrid-mem\");\n\n if (!existsSync(cronRunsDir)) {\n log(`${PAUSE} Cron runs directory not found: ${cronRunsDir}`);\n } else if (!existsSync(logDir)) {\n log(`${PAUSE} Log directory not found: ${logDir}`);\n } else {\n const result = reconcileAllCronRunLedgers(cronRunsDir, logDir, HYBRID_MEM_CRON_DEFAULT_JOB_STEPS, !opts.fix);\n\n if (result.examined === 0) {\n log(`${PAUSE} No cron runs found to examine`);\n } else if (result.falseOk === 0) {\n log(`${OK} All ${result.examined} examined run(s) correctly recorded`);\n } else {\n log(`${FAIL} Found ${result.falseOk} false-OK run(s) out of ${result.examined} examined`);\n if (opts.fix) {\n log(` → Corrected ${result.corrected} ledger entr${result.corrected === 1 ? \"y\" : \"ies\"}`);\n state.fixes.push(\n `Corrected ${result.corrected} false-OK cron run ledger entr${result.corrected === 1 ? \"y\" : \"ies\"}`,\n );\n } else {\n log(\" → Run with --fix to correct ledger entries\");\n state.issues.push(`${result.falseOk} cron run(s) incorrectly recorded as OK despite validation failures`);\n state.allOk = false;\n }\n\n if (result.corrections.length > 0 && result.corrections.length <= 5) {\n for (const correction of result.corrections) {\n log(\n ` • ${correction.jobId} @ ${new Date(correction.timestamp).toISOString()}: ${correction.validationResult.error || \"validation failed\"}`,\n );\n }\n } else if (result.corrections.length > 5) {\n log(\n ` • ${result.corrections.length} corrections (run 'openclaw hybrid-mem reconcile-cron-ledgers' for details)`,\n );\n }\n }\n }\n } catch (e) {\n log(`${FAIL} Cron ledger reconciliation check failed: ${e}`);\n state.allOk = false;\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:reconcile-cron-ledgers\" });\n }\n }\n\n if (opts.fix) {\n const applied: string[] = [];\n if (state.lanceBindingsFailed) {\n try {\n const { spawnSync } = await import(\"node:child_process\");\n function npmExecutable(): string {\n if (process.platform !== \"win32\") return \"npm\";\n const candidate = join(dirname(process.execPath), \"npm.cmd\");\n return existsSync(candidate) ? candidate : \"npm.cmd\";\n }\n const pkgs = state.lanceBindingsFailed ? [\"@lancedb/lancedb\"] : [];\n for (const pkg of pkgs) {\n const r = spawnSync(npmExecutable(), [\"rebuild\", pkg], { cwd: extDir, shell: false, stdio: \"inherit\" });\n if (r.status === 0) {\n applied.push(`Rebuilt native module: ${pkg}`);\n } else {\n log(`Rebuild ${pkg} failed (exit ${r.status}). Run manually: cd ${extDir} && npm rebuild ${pkg}`);\n }\n }\n } catch (e) {\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:rebuild-modules\" });\n }\n }\n\n if (existsSync(defaultConfigPath)) {\n try {\n const raw = readFileSync(defaultConfigPath, \"utf-8\");\n const fixConfig = JSON.parse(raw) as Record<string, unknown>;\n let changed = false;\n if (!fixConfig.plugins || typeof fixConfig.plugins !== \"object\") fixConfig.plugins = {};\n const plugins = fixConfig.plugins as Record<string, unknown>;\n if (!plugins.entries || typeof plugins.entries !== \"object\") plugins.entries = {};\n const entries = plugins.entries as Record<string, unknown>;\n if (!entries[PLUGIN_ID] || typeof entries[PLUGIN_ID] !== \"object\")\n entries[PLUGIN_ID] = { enabled: true, config: {} };\n const mh = entries[PLUGIN_ID] as Record<string, unknown>;\n if (!mh.config || typeof mh.config !== \"object\") mh.config = {};\n const cfgFix = mh.config as Record<string, unknown>;\n if (!cfgFix.embedding || typeof cfgFix.embedding !== \"object\") cfgFix.embedding = {};\n const emb = cfgFix.embedding as Record<string, unknown>;\n const curKey = emb.apiKey;\n const placeholder =\n typeof curKey !== \"string\" ||\n curKey.length < 10 ||\n curKey === \"YOUR_OPENAI_API_KEY\" ||\n curKey === \"<OPENAI_API_KEY>\";\n if (placeholder) {\n emb.apiKey = \"YOUR_OPENAI_API_KEY\";\n emb.model = emb.model || \"text-embedding-3-small\";\n changed = true;\n applied.push(\"Set embedding.apiKey and model (use your key or ${OPENAI_API_KEY} in config)\");\n }\n const memoryDirPath = dirname(resolvedSqlitePath);\n if (!existsSync(memoryDirPath)) {\n mkdirSync(memoryDirPath, { recursive: true });\n applied.push(`Created memory directory: ${memoryDirPath}`);\n }\n\n // Add cron jobs (same logic as install)\n const cronDir = join(openclawDir, \"cron\");\n const cronStorePath = join(cronDir, \"jobs.json\");\n\n try {\n const scheduleOverrides: Record<string, string> = {};\n if (typeof cfg.nightlyCycle?.schedule === \"string\" && cfg.nightlyCycle.schedule.trim().length > 0) {\n scheduleOverrides[\"hybrid-mem:nightly-dream-cycle\"] = cfg.nightlyCycle.schedule;\n }\n if (typeof cfg.sensorSweep?.schedule === \"string\" && cfg.sensorSweep.schedule.trim().length > 0) {\n scheduleOverrides[\"hybrid-mem:sensor-sweep\"] = cfg.sensorSweep.schedule;\n }\n const { added, normalized } = ensureMaintenanceCronJobs(openclawDir, getCronModelConfig(cfg), {\n normalizeExisting: true,\n reEnableDisabled: false,\n scheduleOverrides: Object.keys(scheduleOverrides).length > 0 ? scheduleOverrides : undefined,\n featureGates: {\n \"sensorSweep.enabled\": cfg.sensorSweep?.enabled === true,\n \"nightlyCycle.enabled\": cfg.nightlyCycle?.enabled === true,\n },\n digestWeeklyDelivery: cfg.digest.weekly.delivery,\n });\n added.forEach((name) => {\n applied.push(`Added ${name} job to ${cronStorePath}`);\n });\n normalized.forEach((name) => {\n applied.push(`Normalized ${name} job (schedule/pluginJobId)`);\n });\n if (cfg.goalStewardship.enabled && cfg.goalStewardship.heartbeatStewardship) {\n const heartbeat = ensureGoalStewardshipHeartbeatCronJob(openclawDir, {\n heartbeatPatterns: cfg.goalStewardship.heartbeatPatterns,\n });\n if (heartbeat.added) {\n applied.push(`Added goal-stewardship-heartbeat job to ${cronStorePath}`);\n }\n if (heartbeat.normalized) {\n applied.push(\"Normalized goal-stewardship-heartbeat job (schedule/sessionTarget/delivery/payload)\");\n }\n if (heartbeat.skippedReason) {\n const WARN = noEmoji ? \"[WARN]\" : \"⚠️\";\n log(`${WARN} Goal stewardship heartbeat installer skipped: ${heartbeat.skippedReason}`);\n }\n }\n } catch (e) {\n log(`Could not add optional jobs to cron store: ${String(e)}`);\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:add-cron-jobs\" });\n }\n\n if (changed) {\n writeFileSync(defaultConfigPath, JSON.stringify(fixConfig, null, 2), \"utf-8\");\n }\n if (applied.length > 0) {\n log(\"\\n--- Applied fixes ---\");\n applied.forEach((a) => {\n log(` • ${a}`);\n });\n if (changed) log(`Config written: ${defaultConfigPath}. Restart the gateway and run verify again.`);\n }\n } catch (e) {\n const _err = state.sink.error ?? ((s: string) => console.error(s));\n _err(`\\nCould not apply fixes to config: ${String(e)}`);\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:apply-fixes\" });\n const snippet = {\n embedding: { apiKey: \"<set your key or use ${OPENAI_API_KEY}>\", model: \"text-embedding-3-small\" },\n autoCapture: true,\n autoRecall: true,\n captureMaxChars: 5000,\n store: { fuzzyDedupe: false },\n };\n _err(`Minimal config snippet to merge into plugins.entries[\"${PLUGIN_ID}\"].config:`);\n _err(JSON.stringify(snippet, null, 2));\n }\n } else {\n log(\"\\n--- Fix (--fix) ---\");\n log(\n \"Config file not found. Run 'openclaw hybrid-mem install' to create it with full defaults, then set your API key and restart.\",\n );\n }\n }\n\n if (opts.reconcile) {\n log(\"\\n───── Vector / SQLite consistency (reconcile) ─────\");\n try {\n await vectorDb.ensureInitialized();\n const vCount = await vectorDb.count();\n const embCount = factsDb.countCanonicalEmbeddings();\n log(`${OK} SQLite canonical embeddings (fact_embeddings): ${embCount}`);\n const lanceRowsOk = vectorDb.isLanceAvailable();\n log(`${lanceRowsOk ? OK : PAUSE} LanceDB row count: ${vCount} (lanceAvailable=${lanceRowsOk})`);\n if (lanceRowsOk && vCount !== embCount) {\n log(\n `${FAIL} Drift: fact_embeddings rows (${embCount}) != Lance rows (${vCount}). Consider re-embed or diagnostics.`,\n );\n }\n } catch (e) {\n log(`${FAIL} Reconcile check failed: ${e}`);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,eAAsB,0BAA0B,OAAsC;CACpF,MAAM,EACJ,KACA,MACA,KACA,SACA,UACA,YACA,eACA,oBACA,mBACA,QACA,KACA,UACA,IACA,MACA,OACA,WACA,SACA,QACA,OACA,UACA,cACA,QACA,mBACA,aACA,oBACA,sBACA,iBACE;CAGJ,IAAI,KAAK,WAAW;EAClB,IAAI,yCAAyC;EAC7C,IAAI,CAAC,MAAM,YAAY,CAAC,MAAM,WAAW,CAAC,SAAS,oBAAoB,EAAE;GACvE,IAAI,GAAG,KAAK,iFAAiF;GAC7F,MAAM,QAAQ;SAEd,IAAI;GACF,MAAM,kBAAkB,KAAK,mBAAmB;GAChD,MAAM,oBAAoB,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,KAAK,qBAAqB,IAAI,CAAC;GACpF,MAAM,4BACJ,oBAAoB,iBAChB,IACA,oBAAoB,aAClB,oBACA,KAAK,IAAI,mBAAmB,IAAK;GACzC,MAAM,YAAY,IAAI,IAAI,QAAQ,WAAW,CAAC;GAC9C,MAAM,YAAY,MAAM,SAAS,WAAW;GAG5C,MAAM,gBAAgB,UAAU,QAAQ,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC;GAElE,MAAM,cAAc,IAAI,IAAI,UAAU;GACtC,MAAM,gBAAgB,MAAM,KAAK,UAAU,CAAC,QAAQ,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC;GAEhF,IAAI,cAAc,WAAW,KAAK,cAAc,WAAW,GACzD,IACE,GAAG,GAAG,mDAAmD,UAAU,KAAK,UAAU,UAAU,OAAO,WACpG;QACI;IACL,MAAM,QAAQ;IACd,IAAI,cAAc,SAAS,GAAG;KAC5B,IAAI,GAAG,KAAK,+CAA+C,cAAc,SAAS;KAClF,cAAc,MAAM,GAAG,GAAG,CAAC,SAAS,OAAO;MACzC,IAAI,OAAO,KAAK;OAChB;KACF,IAAI,cAAc,SAAS,IAAI,IAAI,WAAW,cAAc,SAAS,GAAG,OAAO;KAC/E,IAAI,KAAK,KAAK;MACZ,IAAI,YAAY;MAChB,IAAI,aAAa;MACjB,IAAI,UAAU;MACd,IAAI,eAAe;MACnB,KAAK,MAAM,MAAM,eACf,IAAI;OACF;OAEA,IAAI,MADkB,SAAS,OAAO,GAAG,EAEvC;YAEA;cAEI;OACN;;MAGJ,IACE,4BAA4B,UAAU,gCACtB,WAAW,YAAY,QAAQ,WAAW,aAAa,GACxE;MAED,IAAI,wBAAwB,CAAC,GAAG,cAAc;MAC9C,IAAI,gBAAgB;MACpB,IAAI;OACF,MAAM,sBAAsB,IAAI,IAAI,MAAM,SAAS,WAAW,CAAC;OAC/D,wBAAwB,cAAc,QAAQ,OAAO,oBAAoB,IAAI,GAAG,CAAC;eAC1E,YAAY;OACnB,IAAI,GAAG,KAAK,oDAAoD,OAAO,WAAW,GAAG;OACrF,gBAAgB;;MAGlB,IAAI,eAAe;OACjB,IACE,GAAG,KAAK,+DAA+D,cAAc,OAAO,iCAC7F;OACD,MAAM,OAAO,KACX,GAAG,cAAc,OAAO,kFACzB;OACD,MAAM,QAAQ;aACT;OACL,MAAM,kBAAkB,cAAc,SAAS,sBAAsB;OACrE,IAAI,sBAAsB,WAAW,GAAG;QACtC,IAAI,yBAAyB,gBAAgB,GAAG,cAAc,OAAO,6BAA6B;QAClG,MAAM,KAAK,uBAAuB,gBAAgB,2BAA2B;cACxE;QACL,IACE,GAAG,KAAK,+BAA+B,sBAAsB,OAAO,GAAG,cAAc,OAAO,gDAC7F;QACD,KAAK,MAAM,MAAM,sBAAsB,MAAM,GAAG,GAAG,EACjD,IAAI,mBAAmB,KAAK;QAE9B,IAAI,sBAAsB,SAAS,IACjC,IAAI,WAAW,sBAAsB,SAAS,GAAG,iCAAiC;QAEpF,MAAM,aACJ,OAAO,SAAS,4BAA4B,aAAa,SAAS,yBAAyB,GAAG;QAChG,IAAI,YACF,IAAI,mDAAmD,aAAa;QAEtE,MAAM,OAAO,KACX,GAAG,sBAAsB,OAAO,yEACjC;QACD,MAAM,QAAQ;;;YAGb;MACL,IAAI,kEAAkE;MACtE,MAAM,OAAO,KAAK,GAAG,cAAc,OAAO,2DAA2D;;;IAGzG,IAAI,cAAc,SAAS,GAAG;KAE5B,IAAI,GADS,UAAU,WAAW,KACtB,oDAAoD,cAAc,SAAS;KACvF,cAAc,MAAM,GAAG,GAAG,CAAC,SAAS,OAAO;MACzC,IAAI,OAAO,KAAK;OAChB;KACF,IAAI,cAAc,SAAS,IAAI,IAAI,WAAW,cAAc,SAAS,GAAG,OAAO;KAC/E,IAAI,KAAK,OAAO,4BAA4B,GAAG;MAC7C,IAAI,UAAU;MACd,IAAI,SAAS;MACb,KAAK,MAAM,MAAM,cAAc,MAAM,GAAG,0BAA0B,EAChE,IAAI;OACF,MAAM,OAAO,QAAQ,QAAQ,GAAG;OAChC,IAAI,CAAC,MAAM;QACT;QACA;;OAEF,MAAM,MAAM,MAAM,WAAW,MAAM,KAAK,KAAK;OAC7C,MAAM,SAAS,MAAM;QACnB,IAAI,KAAK;QACT,MAAM,KAAK;QACX,QAAQ;QACR,YAAY,KAAK,cAAc;QAC/B,UAAU,KAAK;QAChB,CAAC;OACF;cACM;OACN;;MAGJ,IACE,sBAAsB,gBAAgB,YAAY,QAAQ,GAAG,KAAK,IAAI,cAAc,QAAQ,0BAA0B,CAAC,0BAA0B,SAAS,IAAI,KAAK,OAAO,YAAY,GAAG,GAC1L;MACD,IAAI,cAAc,SAAS,2BACzB,IACE,eAAe,cAAc,SAAS,0BAA0B,wDACjE;YAEE,IAAI,KAAK,OAAO,8BAA8B,GACnD,IACE,cAAc,gBAAgB,wEAC/B;UAED,IAAI,gFAAgF;KAEtF,MAAM,OAAO,KAAK,GAAG,cAAc,OAAO,0DAA0D;;;GAGxG,IAAI,oBACF,gCAAgC,oBAAoB;IAClD,OAAO;IACP,qBAAI,IAAI,MAAM,EAAC,aAAa;IAC5B,SAAS;KACP,KAAK,KAAK;KACV;KACA;KACA,eAAe,cAAc;KAC7B,eAAe,cAAc;KAC9B;IACF,CAAC;WAEG,GAAG;GACV,IAAI,GAAG,KAAK,0BAA0B,OAAO,EAAE,GAAG;GAClD,MAAM,QAAQ;GACd,mBAAmB,GAAY;IAAE,WAAW;IAAO,WAAW;IAA6B,CAAC;;;CAMlG,IAAI,KAAK,WAAW;EAClB,IAAI,uDAAuD;EAC3D,IAAI;GACF,MAAM,cAAc,KAAK,aAAa,QAAQ,OAAO;GACrD,MAAM,SAAS,KAAK,aAAa,QAAQ,kBAAkB;GAE3D,IAAI,CAAC,WAAW,YAAY,EAC1B,IAAI,GAAG,MAAM,kCAAkC,cAAc;QACxD,IAAI,CAAC,WAAW,OAAO,EAC5B,IAAI,GAAG,MAAM,4BAA4B,SAAS;QAC7C;IACL,MAAM,SAAS,2BAA2B,aAAa,QAAQ,mCAAmC,CAAC,KAAK,IAAI;IAE5G,IAAI,OAAO,aAAa,GACtB,IAAI,GAAG,MAAM,gCAAgC;SACxC,IAAI,OAAO,YAAY,GAC5B,IAAI,GAAG,GAAG,OAAO,OAAO,SAAS,qCAAqC;SACjE;KACL,IAAI,GAAG,KAAK,SAAS,OAAO,QAAQ,0BAA0B,OAAO,SAAS,WAAW;KACzF,IAAI,KAAK,KAAK;MACZ,IAAI,iBAAiB,OAAO,UAAU,cAAc,OAAO,cAAc,IAAI,MAAM,QAAQ;MAC3F,MAAM,MAAM,KACV,aAAa,OAAO,UAAU,gCAAgC,OAAO,cAAc,IAAI,MAAM,QAC9F;YACI;MACL,IAAI,+CAA+C;MACnD,MAAM,OAAO,KAAK,GAAG,OAAO,QAAQ,qEAAqE;MACzG,MAAM,QAAQ;;KAGhB,IAAI,OAAO,YAAY,SAAS,KAAK,OAAO,YAAY,UAAU,GAChE,KAAK,MAAM,cAAc,OAAO,aAC9B,IACE,OAAO,WAAW,MAAM,KAAK,IAAI,KAAK,WAAW,UAAU,CAAC,aAAa,CAAC,IAAI,WAAW,iBAAiB,SAAS,sBACpH;UAEE,IAAI,OAAO,YAAY,SAAS,GACrC,IACE,OAAO,OAAO,YAAY,OAAO,6EAClC;;;WAIA,GAAG;GACV,IAAI,GAAG,KAAK,4CAA4C,IAAI;GAC5D,MAAM,QAAQ;GACd,mBAAmB,GAAY;IAAE,WAAW;IAAO,WAAW;IAA0C,CAAC;;;CAI7G,IAAI,KAAK,KAAK;EACZ,MAAM,UAAoB,EAAE;EAC5B,IAAI,MAAM,qBACR,IAAI;GACF,MAAM,EAAE,cAAc,MAAM,OAAO;GACnC,SAAS,gBAAwB;IAC/B,IAAI,QAAQ,aAAa,SAAS,OAAO;IACzC,MAAM,YAAY,KAAK,QAAQ,QAAQ,SAAS,EAAE,UAAU;IAC5D,OAAO,WAAW,UAAU,GAAG,YAAY;;GAE7C,MAAM,OAAO,MAAM,sBAAsB,CAAC,mBAAmB,GAAG,EAAE;GAClE,KAAK,MAAM,OAAO,MAAM;IACtB,MAAM,IAAI,UAAU,eAAe,EAAE,CAAC,WAAW,IAAI,EAAE;KAAE,KAAK;KAAQ,OAAO;KAAO,OAAO;KAAW,CAAC;IACvG,IAAI,EAAE,WAAW,GACf,QAAQ,KAAK,0BAA0B,MAAM;SAE7C,IAAI,WAAW,IAAI,gBAAgB,EAAE,OAAO,sBAAsB,OAAO,kBAAkB,MAAM;;WAG9F,GAAG;GACV,mBAAmB,GAAY;IAAE,WAAW;IAAO,WAAW;IAAmC,CAAC;;EAItG,IAAI,WAAW,kBAAkB,EAC/B,IAAI;GACF,MAAM,MAAM,aAAa,mBAAmB,QAAQ;GACpD,MAAM,YAAY,KAAK,MAAM,IAAI;GACjC,IAAI,UAAU;GACd,IAAI,CAAC,UAAU,WAAW,OAAO,UAAU,YAAY,UAAU,UAAU,UAAU,EAAE;GACvF,MAAM,UAAU,UAAU;GAC1B,IAAI,CAAC,QAAQ,WAAW,OAAO,QAAQ,YAAY,UAAU,QAAQ,UAAU,EAAE;GACjF,MAAM,UAAU,QAAQ;GACxB,IAAI,CAAC,QAAA,6BAAsB,OAAO,QAAA,8BAAuB,UACvD,QAAQ,aAAa;IAAE,SAAS;IAAM,QAAQ,EAAE;IAAE;GACpD,MAAM,KAAK,QAAQ;GACnB,IAAI,CAAC,GAAG,UAAU,OAAO,GAAG,WAAW,UAAU,GAAG,SAAS,EAAE;GAC/D,MAAM,SAAS,GAAG;GAClB,IAAI,CAAC,OAAO,aAAa,OAAO,OAAO,cAAc,UAAU,OAAO,YAAY,EAAE;GACpF,MAAM,MAAM,OAAO;GACnB,MAAM,SAAS,IAAI;GAMnB,IAJE,OAAO,WAAW,YAClB,OAAO,SAAS,MAChB,WAAW,yBACX,WAAW,oBACI;IACf,IAAI,SAAS;IACb,IAAI,QAAQ,IAAI,SAAS;IACzB,UAAU;IACV,QAAQ,KAAK,+EAA+E;;GAE9F,MAAM,gBAAgB,QAAQ,mBAAmB;GACjD,IAAI,CAAC,WAAW,cAAc,EAAE;IAC9B,UAAU,eAAe,EAAE,WAAW,MAAM,CAAC;IAC7C,QAAQ,KAAK,6BAA6B,gBAAgB;;GAK5D,MAAM,gBAAgB,KADN,KAAK,aAAa,OACA,EAAE,YAAY;GAEhD,IAAI;IACF,MAAM,oBAA4C,EAAE;IACpD,IAAI,OAAO,IAAI,cAAc,aAAa,YAAY,IAAI,aAAa,SAAS,MAAM,CAAC,SAAS,GAC9F,kBAAkB,oCAAoC,IAAI,aAAa;IAEzE,IAAI,OAAO,IAAI,aAAa,aAAa,YAAY,IAAI,YAAY,SAAS,MAAM,CAAC,SAAS,GAC5F,kBAAkB,6BAA6B,IAAI,YAAY;IAEjE,MAAM,EAAE,OAAO,eAAe,0BAA0B,aAAa,mBAAmB,IAAI,EAAE;KAC5F,mBAAmB;KACnB,kBAAkB;KAClB,mBAAmB,OAAO,KAAK,kBAAkB,CAAC,SAAS,IAAI,oBAAoB,KAAA;KACnF,cAAc;MACZ,uBAAuB,IAAI,aAAa,YAAY;MACpD,wBAAwB,IAAI,cAAc,YAAY;MACvD;KACD,sBAAsB,IAAI,OAAO,OAAO;KACzC,CAAC;IACF,MAAM,SAAS,SAAS;KACtB,QAAQ,KAAK,SAAS,KAAK,UAAU,gBAAgB;MACrD;IACF,WAAW,SAAS,SAAS;KAC3B,QAAQ,KAAK,cAAc,KAAK,6BAA6B;MAC7D;IACF,IAAI,IAAI,gBAAgB,WAAW,IAAI,gBAAgB,sBAAsB;KAC3E,MAAM,YAAY,sCAAsC,aAAa,EACnE,mBAAmB,IAAI,gBAAgB,mBACxC,CAAC;KACF,IAAI,UAAU,OACZ,QAAQ,KAAK,2CAA2C,gBAAgB;KAE1E,IAAI,UAAU,YACZ,QAAQ,KAAK,sFAAsF;KAErG,IAAI,UAAU,eAEZ,IAAI,GADS,UAAU,WAAW,KACtB,iDAAiD,UAAU,gBAAgB;;YAGpF,GAAG;IACV,IAAI,8CAA8C,OAAO,EAAE,GAAG;IAC9D,mBAAmB,GAAY;KAAE,WAAW;KAAO,WAAW;KAAiC,CAAC;;GAGlG,IAAI,SACF,cAAc,mBAAmB,KAAK,UAAU,WAAW,MAAM,EAAE,EAAE,QAAQ;GAE/E,IAAI,QAAQ,SAAS,GAAG;IACtB,IAAI,0BAA0B;IAC9B,QAAQ,SAAS,MAAM;KACrB,IAAI,OAAO,IAAI;MACf;IACF,IAAI,SAAS,IAAI,mBAAmB,kBAAkB,6CAA6C;;WAE9F,GAAG;GACV,MAAM,OAAO,MAAM,KAAK,WAAW,MAAc,QAAQ,MAAM,EAAE;GACjE,KAAK,sCAAsC,OAAO,EAAE,GAAG;GACvD,mBAAmB,GAAY;IAAE,WAAW;IAAO,WAAW;IAA+B,CAAC;GAC9F,MAAM,UAAU;IACd,WAAW;KAAE,QAAQ;KAA2C,OAAO;KAA0B;IACjG,aAAa;IACb,YAAY;IACZ,iBAAiB;IACjB,OAAO,EAAE,aAAa,OAAO;IAC9B;GACD,KAAK,yDAAyD,UAAU,YAAY;GACpF,KAAK,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;;OAEnC;GACL,IAAI,wBAAwB;GAC5B,IACE,+HACD;;;CAIL,IAAI,KAAK,WAAW;EAClB,IAAI,wDAAwD;EAC5D,IAAI;GACF,MAAM,SAAS,mBAAmB;GAClC,MAAM,SAAS,MAAM,SAAS,OAAO;GACrC,MAAM,WAAW,QAAQ,0BAA0B;GACnD,IAAI,GAAG,GAAG,kDAAkD,WAAW;GACvE,MAAM,cAAc,SAAS,kBAAkB;GAC/C,IAAI,GAAG,cAAc,KAAK,MAAM,sBAAsB,OAAO,mBAAmB,YAAY,GAAG;GAC/F,IAAI,eAAe,WAAW,UAC5B,IACE,GAAG,KAAK,gCAAgC,SAAS,mBAAmB,OAAO,sCAC5E;WAEI,GAAG;GACV,IAAI,GAAG,KAAK,2BAA2B,IAAI"}
|
|
1
|
+
{"version":3,"file":"reconcile.js","names":[],"sources":["../../../../cli/verify/sections/reconcile.ts"],"sourcesContent":["/**\n * CLI Verify Command Handler\n *\n * Contains runVerifyForCli and its private helper functions.\n * Checks infrastructure (SQLite, LanceDB, embeddings, LLM credentials,\n * cron jobs) and optionally applies fixes.\n *\n * Extracted from cli/handlers.ts to keep that file manageable.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport { getCronModelConfig } from \"../../../config.js\";\nimport { reconcileAllCronRunLedgers } from \"../../../services/cron-maintenance-reconciler.js\";\nimport { capturePluginError } from \"../../../services/error-reporter.js\";\nimport { HYBRID_MEM_CRON_DEFAULT_JOB_STEPS } from \"../../../services/hybrid-mem-cron-default-job-steps.js\";\nimport { appendVectorLifecycleAuditEvent } from \"../../../services/vector-lifecycle-audit.js\";\nimport { PLUGIN_ID } from \"../../../utils/constants.js\";\nimport { ensureGoalStewardshipHeartbeatCronJob, ensureMaintenanceCronJobs } from \"../../cmd-install.js\";\n\nimport type { VerifyRunState } from \"../verify-run-state.js\";\n\nexport async function runVerifyReconcileSection(state: VerifyRunState): Promise<void> {\n const {\n ctx,\n opts,\n cfg,\n factsDb,\n vectorDb,\n embeddings,\n credentialsDb,\n resolvedSqlitePath,\n resolvedLancePath,\n openai,\n log,\n tableLog,\n OK,\n FAIL,\n PAUSE,\n WARN_LINE,\n noEmoji,\n issues,\n fixes,\n warnings,\n loadBlocking,\n extDir,\n defaultConfigPath,\n openclawDir,\n openclawConfigRead,\n recommendedEmbedding,\n dashboardUrl,\n } = state;\n\n // ───── Reconciliation Check ─────\n if (opts.reconcile) {\n log(\"\\n───── Vector DB Reconciliation ─────\");\n if (!state.sqliteOk || !state.lanceOk || !vectorDb.isLanceDbAvailable()) {\n log(`${FAIL} Reconciliation skipped — both SQLite and LanceDB must be healthy to reconcile.`);\n state.allOk = false;\n } else {\n try {\n const reconcilePolicy = opts.reconcilePolicy ?? \"balanced\";\n const reconcileMaxFixes = Math.max(0, Math.min(5000, opts.reconcileMaxFixes ?? 200));\n const sqliteOrphanRebuildBudget =\n reconcilePolicy === \"conservative\"\n ? 0\n : reconcilePolicy === \"balanced\"\n ? reconcileMaxFixes\n : Math.max(reconcileMaxFixes, 2000);\n const sqliteIds = new Set(factsDb.getAllIds());\n const vectorIds = await vectorDb.getAllIds();\n\n // Vector orphans: IDs in LanceDB that have no corresponding SQLite fact.\n const vectorOrphans = vectorIds.filter((id) => !sqliteIds.has(id));\n // SQLite orphans: active facts in SQLite with no vector in LanceDB.\n const vectorIdSet = new Set(vectorIds);\n const sqliteOrphans = Array.from(sqliteIds).filter((id) => !vectorIdSet.has(id));\n\n if (vectorOrphans.length === 0 && sqliteOrphans.length === 0) {\n log(\n `${OK} Reconciliation: SQLite and LanceDB are in sync (${sqliteIds.size} facts, ${vectorIds.length} vectors)`,\n );\n } else {\n state.allOk = false;\n if (vectorOrphans.length > 0) {\n log(`${FAIL} Vector orphans (in LanceDB but not SQLite): ${vectorOrphans.length}`);\n vectorOrphans.slice(0, 10).forEach((id) => {\n log(` - ${id}`);\n });\n if (vectorOrphans.length > 10) log(` … and ${vectorOrphans.length - 10} more`);\n if (opts.fix) {\n let attempted = 0;\n let apiDeleted = 0;\n let apiNoOp = 0;\n let deleteErrors = 0;\n for (const id of vectorOrphans) {\n try {\n attempted++;\n const removed = await vectorDb.delete(id);\n if (removed) {\n apiDeleted++;\n } else {\n apiNoOp++;\n }\n } catch {\n deleteErrors++;\n }\n }\n log(\n ` → Delete attempted for ${attempted} orphan vector(s): ` +\n `apiDeleted=${apiDeleted}, apiNoOp=${apiNoOp}, errors=${deleteErrors}.`,\n );\n\n let unresolvedAfterDelete = [...vectorOrphans];\n let recheckFailed = false;\n try {\n const postDeleteVectorIds = new Set(await vectorDb.getAllIds());\n unresolvedAfterDelete = vectorOrphans.filter((id) => postDeleteVectorIds.has(id));\n } catch (recheckErr) {\n log(`${FAIL} Could not re-query LanceDB after delete attempt: ${String(recheckErr)}`);\n recheckFailed = true;\n }\n\n if (recheckFailed) {\n log(\n `${FAIL} Reconciliation verification failed — cannot confirm whether ${vectorOrphans.length} orphan vector(s) were removed.`,\n );\n state.issues.push(\n `${vectorOrphans.length} orphan vector(s) deletion could not be verified due to LanceDB re-query failure`,\n );\n state.allOk = false;\n } else {\n const verifiedRemoved = vectorOrphans.length - unresolvedAfterDelete.length;\n if (unresolvedAfterDelete.length === 0) {\n log(` → Verified removal: ${verifiedRemoved}/${vectorOrphans.length} orphan vector(s) are gone.`);\n fixes.push(`Verified removal of ${verifiedRemoved} LanceDB orphan vector(s)`);\n } else {\n log(\n `${FAIL} Reconciliation incomplete — ${unresolvedAfterDelete.length}/${vectorOrphans.length} orphan vector(s) remain after delete attempt.`,\n );\n for (const id of unresolvedAfterDelete.slice(0, 10)) {\n log(` - unresolved: ${id}`);\n }\n if (unresolvedAfterDelete.length > 10) {\n log(` … and ${unresolvedAfterDelete.length - 10} more unresolved orphan vectors`);\n }\n const failReason =\n typeof vectorDb.getLastSearchFailReason === \"function\" ? vectorDb.getLastSearchFailReason() : null;\n if (failReason) {\n log(` → LanceDB degraded hint: lastSearchFailReason=${failReason}`);\n }\n state.issues.push(\n `${unresolvedAfterDelete.length} orphan vector(s) still present after --reconcile --fix delete attempts`,\n );\n state.allOk = false;\n }\n }\n } else {\n log(\" → Run with --fix to delete these orphan vectors from LanceDB.\");\n state.issues.push(`${vectorOrphans.length} orphan vector(s) in LanceDB with no matching SQLite fact`);\n }\n }\n if (sqliteOrphans.length > 0) {\n const WARN = noEmoji ? \"[WARN]\" : \"⚠️\";\n log(`${WARN} SQLite orphans (facts in SQLite with no vector): ${sqliteOrphans.length}`);\n sqliteOrphans.slice(0, 10).forEach((id) => {\n log(` - ${id}`);\n });\n if (sqliteOrphans.length > 10) log(` … and ${sqliteOrphans.length - 10} more`);\n if (opts.fix && sqliteOrphanRebuildBudget > 0) {\n let rebuilt = 0;\n let failed = 0;\n for (const id of sqliteOrphans.slice(0, sqliteOrphanRebuildBudget)) {\n try {\n const fact = factsDb.getById(id);\n if (!fact) {\n failed++;\n continue;\n }\n const vec = await embeddings.embed(fact.text);\n await vectorDb.store({\n id: fact.id,\n text: fact.text,\n vector: vec,\n importance: fact.importance ?? 0.5,\n category: fact.category,\n });\n rebuilt++;\n } catch {\n failed++;\n }\n }\n log(\n ` → Rebuild policy=${reconcilePolicy}: rebuilt ${rebuilt}/${Math.min(sqliteOrphans.length, sqliteOrphanRebuildBudget)} SQLite orphan vector(s)${failed > 0 ? ` (${failed} failed)` : \"\"}.`,\n );\n if (sqliteOrphans.length > sqliteOrphanRebuildBudget) {\n log(\n ` → Skipped ${sqliteOrphans.length - sqliteOrphanRebuildBudget} SQLite orphan(s) due to --reconcile-max-fixes budget.`,\n );\n }\n } else if (opts.fix && sqliteOrphanRebuildBudget === 0) {\n log(\n ` → Policy=${reconcilePolicy}: SQLite-orphan auto-rebuild disabled; use re-index for full recovery.`,\n );\n } else {\n log(\" → Re-run the plugin or use the re-index command to rebuild missing vectors.\");\n }\n state.issues.push(`${sqliteOrphans.length} SQLite fact(s) without corresponding vectors in LanceDB`);\n }\n }\n if (resolvedSqlitePath) {\n appendVectorLifecycleAuditEvent(resolvedSqlitePath, {\n event: \"reconcile_completed\",\n ts: new Date().toISOString(),\n details: {\n fix: opts.fix,\n reconcilePolicy,\n reconcileMaxFixes,\n vectorOrphans: vectorOrphans.length,\n sqliteOrphans: sqliteOrphans.length,\n },\n });\n }\n } catch (e) {\n log(`${FAIL} Reconciliation: FAIL — ${String(e)}`);\n state.allOk = false;\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:reconcile\" });\n }\n }\n }\n\n // ───── Cron Ledger Reconciliation (explicit --reconcile only; optional --fix to write) ─────\n if (opts.reconcile) {\n log(\"\\n───── Cron Maintenance Ledger Reconciliation ─────\");\n try {\n const cronRunsDir = join(openclawDir, \"cron\", \"runs\");\n const logDir = join(openclawDir, \"logs\", \"cron-hybrid-mem\");\n\n if (!existsSync(cronRunsDir)) {\n log(`${PAUSE} Cron runs directory not found: ${cronRunsDir}`);\n } else if (!existsSync(logDir)) {\n log(`${PAUSE} Log directory not found: ${logDir}`);\n } else {\n const result = reconcileAllCronRunLedgers(cronRunsDir, logDir, HYBRID_MEM_CRON_DEFAULT_JOB_STEPS, !opts.fix);\n\n if (result.examined === 0) {\n log(`${PAUSE} No cron runs found to examine`);\n } else if (result.falseOk === 0) {\n log(`${OK} All ${result.examined} examined run(s) correctly recorded`);\n } else {\n log(`${FAIL} Found ${result.falseOk} false-OK run(s) out of ${result.examined} examined`);\n if (opts.fix) {\n log(` → Corrected ${result.corrected} ledger entr${result.corrected === 1 ? \"y\" : \"ies\"}`);\n state.fixes.push(\n `Corrected ${result.corrected} false-OK cron run ledger entr${result.corrected === 1 ? \"y\" : \"ies\"}`,\n );\n } else {\n log(\" → Run with --fix to correct ledger entries\");\n state.issues.push(`${result.falseOk} cron run(s) incorrectly recorded as OK despite validation failures`);\n state.allOk = false;\n }\n\n if (result.corrections.length > 0 && result.corrections.length <= 5) {\n for (const correction of result.corrections) {\n log(\n ` • ${correction.jobId} @ ${new Date(correction.timestamp).toISOString()}: ${correction.validationResult.error || \"validation failed\"}`,\n );\n }\n } else if (result.corrections.length > 5) {\n log(\n ` • ${result.corrections.length} corrections (run 'openclaw hybrid-mem reconcile-cron-ledgers' for details)`,\n );\n }\n }\n }\n } catch (e) {\n log(`${FAIL} Cron ledger reconciliation check failed: ${e}`);\n state.allOk = false;\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:reconcile-cron-ledgers\" });\n }\n }\n\n if (opts.fix) {\n const applied: string[] = [];\n if (state.lanceBindingsFailed) {\n try {\n const { spawnSync } = await import(\"node:child_process\");\n function npmExecutable(): string {\n if (process.platform !== \"win32\") return \"npm\";\n const candidate = join(dirname(process.execPath), \"npm.cmd\");\n return existsSync(candidate) ? candidate : \"npm.cmd\";\n }\n const pkgs = state.lanceBindingsFailed ? [\"@lancedb/lancedb\"] : [];\n for (const pkg of pkgs) {\n const r = spawnSync(npmExecutable(), [\"rebuild\", pkg], { cwd: extDir, shell: false, stdio: \"inherit\" });\n if (r.status === 0) {\n applied.push(`Rebuilt native module: ${pkg}`);\n } else {\n log(`Rebuild ${pkg} failed (exit ${r.status}). Run manually: cd ${extDir} && npm rebuild ${pkg}`);\n }\n }\n } catch (e) {\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:rebuild-modules\" });\n }\n }\n\n if (existsSync(defaultConfigPath)) {\n try {\n const raw = readFileSync(defaultConfigPath, \"utf-8\");\n const fixConfig = JSON.parse(raw) as Record<string, unknown>;\n let changed = false;\n if (!fixConfig.plugins || typeof fixConfig.plugins !== \"object\") fixConfig.plugins = {};\n const plugins = fixConfig.plugins as Record<string, unknown>;\n if (!plugins.entries || typeof plugins.entries !== \"object\") plugins.entries = {};\n const entries = plugins.entries as Record<string, unknown>;\n if (!entries[PLUGIN_ID] || typeof entries[PLUGIN_ID] !== \"object\")\n entries[PLUGIN_ID] = { enabled: true, config: {} };\n const mh = entries[PLUGIN_ID] as Record<string, unknown>;\n if (!mh.config || typeof mh.config !== \"object\") mh.config = {};\n const cfgFix = mh.config as Record<string, unknown>;\n if (!cfgFix.embedding || typeof cfgFix.embedding !== \"object\") cfgFix.embedding = {};\n const emb = cfgFix.embedding as Record<string, unknown>;\n const curKey = emb.apiKey;\n const placeholder =\n typeof curKey !== \"string\" ||\n curKey.length < 10 ||\n curKey === \"YOUR_OPENAI_API_KEY\" ||\n curKey === \"<OPENAI_API_KEY>\";\n if (placeholder) {\n emb.apiKey = \"YOUR_OPENAI_API_KEY\";\n emb.model = emb.model || \"text-embedding-3-small\";\n changed = true;\n applied.push(\"Set embedding.apiKey and model (use your key or ${OPENAI_API_KEY} in config)\");\n }\n const memoryDirPath = dirname(resolvedSqlitePath);\n if (!existsSync(memoryDirPath)) {\n mkdirSync(memoryDirPath, { recursive: true });\n applied.push(`Created memory directory: ${memoryDirPath}`);\n }\n\n // Add cron jobs (same logic as install)\n const cronDir = join(openclawDir, \"cron\");\n const cronStorePath = join(cronDir, \"jobs.json\");\n\n try {\n const scheduleOverrides: Record<string, string> = {};\n if (typeof cfg.nightlyCycle?.schedule === \"string\" && cfg.nightlyCycle.schedule.trim().length > 0) {\n scheduleOverrides[\"hybrid-mem:nightly-dream-cycle\"] = cfg.nightlyCycle.schedule;\n }\n if (typeof cfg.sensorSweep?.schedule === \"string\" && cfg.sensorSweep.schedule.trim().length > 0) {\n scheduleOverrides[\"hybrid-mem:sensor-sweep\"] = cfg.sensorSweep.schedule;\n }\n const { added, normalized } = ensureMaintenanceCronJobs(openclawDir, getCronModelConfig(cfg), {\n normalizeExisting: true,\n reEnableDisabled: false,\n scheduleOverrides: Object.keys(scheduleOverrides).length > 0 ? scheduleOverrides : undefined,\n featureGates: {\n \"sensorSweep.enabled\": cfg.sensorSweep?.enabled === true,\n \"nightlyCycle.enabled\": cfg.nightlyCycle?.enabled === true,\n },\n digestWeeklyDelivery: cfg.digest.weekly.delivery,\n });\n added.forEach((name) => {\n applied.push(`Added ${name} job to ${cronStorePath}`);\n });\n normalized.forEach((name) => {\n applied.push(`Normalized ${name} job (schedule/pluginJobId)`);\n });\n if (cfg.goalStewardship.enabled && cfg.goalStewardship.heartbeatStewardship) {\n const heartbeat = ensureGoalStewardshipHeartbeatCronJob(openclawDir, {\n heartbeatPatterns: cfg.goalStewardship.heartbeatPatterns,\n });\n if (heartbeat.added) {\n applied.push(`Added goal-stewardship-heartbeat job to ${cronStorePath}`);\n }\n if (heartbeat.normalized) {\n applied.push(\"Normalized goal-stewardship-heartbeat job (schedule/sessionTarget/delivery/payload)\");\n }\n if (heartbeat.skippedReason) {\n const WARN = noEmoji ? \"[WARN]\" : \"⚠️\";\n log(`${WARN} Goal stewardship heartbeat installer skipped: ${heartbeat.skippedReason}`);\n }\n }\n } catch (e) {\n log(`Could not add optional jobs to cron store: ${String(e)}`);\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:add-cron-jobs\" });\n }\n\n if (changed) {\n writeFileSync(defaultConfigPath, JSON.stringify(fixConfig, null, 2), \"utf-8\");\n }\n if (applied.length > 0) {\n log(\"\\n--- Applied fixes ---\");\n applied.forEach((a) => {\n log(` • ${a}`);\n });\n if (changed) log(`Config written: ${defaultConfigPath}. Restart the gateway and run verify again.`);\n }\n } catch (e) {\n const _err = state.sink.error ?? ((s: string) => console.error(s));\n _err(`\\nCould not apply fixes to config: ${String(e)}`);\n capturePluginError(e as Error, { subsystem: \"cli\", operation: \"runVerifyForCli:apply-fixes\" });\n const snippet = {\n embedding: { apiKey: \"<set your key or use ${OPENAI_API_KEY}>\", model: \"text-embedding-3-small\" },\n autoCapture: true,\n autoRecall: true,\n captureMaxChars: 5000,\n store: { fuzzyDedupe: false },\n };\n _err(`Minimal config snippet to merge into plugins.entries[\"${PLUGIN_ID}\"].config:`);\n _err(JSON.stringify(snippet, null, 2));\n }\n } else {\n log(\"\\n--- Fix (--fix) ---\");\n log(\n \"Config file not found. Run 'openclaw hybrid-mem install' to create it with full defaults, then set your API key and restart.\",\n );\n }\n }\n\n if (opts.reconcile) {\n log(\"\\n───── Vector / SQLite consistency (reconcile) ─────\");\n try {\n await vectorDb.ensureInitialized();\n const vCount = await vectorDb.count();\n const embCount = factsDb.countCanonicalEmbeddings();\n log(`${OK} SQLite canonical embeddings (fact_embeddings): ${embCount}`);\n const lanceRowsOk = vectorDb.isLanceAvailable();\n log(`${lanceRowsOk ? OK : PAUSE} LanceDB row count: ${vCount} (lanceAvailable=${lanceRowsOk})`);\n if (lanceRowsOk && vCount !== embCount) {\n log(\n `${FAIL} Drift: fact_embeddings rows (${embCount}) != Lance rows (${vCount}). Consider re-embed or diagnostics.`,\n );\n }\n } catch (e) {\n log(`${FAIL} Reconcile check failed: ${e}`);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-run-state.js","names":[],"sources":["../../../cli/verify/verify-run-state.ts"],"sourcesContent":["import { getEnv } from \"../../utils/env-manager.js\";\nimport { isCompactVerbosity, type HybridMemoryConfig } from \"../../config.js\";\nimport type { HandlerContext } from \"../handlers.js\";\nimport type { VerifyCliSink } from \"../types.js\";\nimport { readOpenclawConfigRoot, type OpenclawConfigReadResult } from \"./openclaw-config.js\";\nimport {\n detectRecommendedEmbeddingSetup,\n getDashboardUrl,\n resolveOpenclawJsonPathForWorkspace,\n} from \"../cmd-install.js\";\nimport { findPluginRoot } from \"../../utils/plugin-root.js\";\nimport { PLUGIN_ID } from \"../../utils/constants.js\";\nimport { dirname } from \"node:path\";\nimport type { FactsDB } from \"../../backends/facts-db.js\";\nimport type { VectorDB } from \"../../backends/vector-db.js\";\nimport type { EmbeddingProvider } from \"../../services/embeddings.js\";\nimport type { CredentialsDB } from \"../../backends/credentials-db.js\";\nimport type OpenAI from \"openai\";\n\nexport type VerifyRunOpts = {\n fix: boolean;\n logFile?: string;\n testLlm?: boolean;\n reconcile?: boolean;\n reconcilePolicy?: \"conservative\" | \"balanced\" | \"aggressive\";\n reconcileMaxFixes?: number;\n};\n\nexport type VerifyRunState = {\n ctx: HandlerContext;\n opts: VerifyRunOpts;\n sink: VerifyCliSink;\n cfg: HybridMemoryConfig;\n factsDb: FactsDB;\n vectorDb: VectorDB;\n embeddings: EmbeddingProvider;\n credentialsDb: CredentialsDB | null;\n resolvedSqlitePath: string;\n resolvedLancePath: string;\n openai: OpenAI;\n log: (msg: string) => void;\n tableLog: (msg: string) => void;\n rawLog: (msg: string) => void;\n OK: string;\n FAIL: string;\n PAUSE: string;\n WARN_LINE: string;\n noEmoji: boolean;\n rawPluginConfig?: Record<string, unknown>;\n lanceBindingsFailed: boolean;\n anyEmbOk: boolean;\n issues: string[];\n fixes: string[];\n warnings: string[];\n configOk: boolean;\n sqliteOk: boolean;\n lanceOk: boolean;\n embeddingOk: boolean;\n embeddingAlignmentOk: boolean;\n loadBlocking: string[];\n extDir: string;\n defaultConfigPath: string;\n openclawDir: string;\n openclawConfigRead: OpenclawConfigReadResult;\n recommendedEmbedding: ReturnType<typeof detectRecommendedEmbeddingSetup>;\n dashboardUrl: string;\n credentialsOk: boolean;\n allOk: boolean;\n};\n\nexport function createVerifyRunState(ctx: HandlerContext, opts: VerifyRunOpts, sink: VerifyCliSink): VerifyRunState {\n const { factsDb, vectorDb, embeddings, cfg, credentialsDb, resolvedSqlitePath, resolvedLancePath, openai } = ctx;\n const verbosity = cfg.verbosity ?? \"normal\";\n const rawLog = sink.log;\n const log: typeof rawLog = isCompactVerbosity(verbosity)\n ? (msg: string) => {\n const trimmed = msg.trimStart();\n const isOkLine = /^✅|^\\[OK\\]/.test(trimmed);\n const isHeader = /^─{3,}/.test(trimmed);\n const isIndentedStatus = /^\\s{2,}/.test(msg) && !/❌|\\[FAIL\\]|FAIL —|Error|error/.test(msg);\n if (!isOkLine && !isHeader && !isIndentedStatus) rawLog(msg);\n }\n : rawLog;\n const tableLog = rawLog;\n const noEmoji = getEnv(\"HYBRID_MEM_NO_EMOJI\") === \"1\";\n const extDir = findPluginRoot(import.meta.url);\n const defaultConfigPath = resolveOpenclawJsonPathForWorkspace();\n const openclawDir = dirname(defaultConfigPath);\n const openclawConfigRead = readOpenclawConfigRoot(defaultConfigPath);\n const recommendedEmbedding = detectRecommendedEmbeddingSetup(\n openclawConfigRead.root ?? { plugins: { entries: { [PLUGIN_ID]: { config: cfg } } } },\n extDir,\n );\n const dashboardUrl = getDashboardUrl(\n openclawConfigRead.root ?? { plugins: { entries: { [PLUGIN_ID]: { config: cfg } } } },\n );\n const warnings: string[] = [];\n if (openclawConfigRead.error) {\n warnings.push(\n `OpenClaw config at ${defaultConfigPath} could not be read/parsed (${openclawConfigRead.error}); compaction watchdog status is unknown and verify used fallback defaults.`,\n );\n }\n return {\n ctx,\n opts,\n sink,\n cfg,\n factsDb,\n vectorDb,\n embeddings,\n credentialsDb,\n resolvedSqlitePath,\n resolvedLancePath,\n openai,\n log,\n tableLog,\n rawLog,\n OK: noEmoji ? \"[OK]\" : \"✅\",\n FAIL: noEmoji ? \"[FAIL]\" : \"❌\",\n PAUSE: noEmoji ? \"[paused]\" : \"⏸️ \",\n WARN_LINE: noEmoji ? \"[WARN]\" : \"⚠️\",\n noEmoji,\n lanceBindingsFailed: false,\n anyEmbOk: false,\n issues: [],\n fixes: [],\n warnings,\n configOk: true,\n sqliteOk: false,\n lanceOk: false,\n embeddingOk: false,\n embeddingAlignmentOk: true,\n loadBlocking: [],\n extDir,\n defaultConfigPath,\n openclawDir,\n openclawConfigRead,\n recommendedEmbedding,\n dashboardUrl,\n credentialsOk: true,\n allOk: true,\n };\n}\n"],"mappings":";;;;;;;;;;;AAsEA,SAAgB,qBAAqB,KAAqB,MAAqB,MAAqC;CAClH,MAAM,EAAE,SAAS,UAAU,YAAY,KAAK,eAAe,oBAAoB,mBAAmB,WAAW;CAC7G,MAAM,YAAY,IAAI,aAAa;CACnC,MAAM,SAAS,KAAK;CACpB,MAAM,MAAqB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"verify-run-state.js","names":[],"sources":["../../../cli/verify/verify-run-state.ts"],"sourcesContent":["import { getEnv } from \"../../utils/env-manager.js\";\nimport { isCompactVerbosity, type HybridMemoryConfig } from \"../../config.js\";\nimport type { HandlerContext } from \"../handlers.js\";\nimport type { VerifyCliSink } from \"../types.js\";\nimport { readOpenclawConfigRoot, type OpenclawConfigReadResult } from \"./openclaw-config.js\";\nimport {\n detectRecommendedEmbeddingSetup,\n getDashboardUrl,\n resolveOpenclawJsonPathForWorkspace,\n} from \"../cmd-install.js\";\nimport { findPluginRoot } from \"../../utils/plugin-root.js\";\nimport { PLUGIN_ID } from \"../../utils/constants.js\";\nimport { dirname } from \"node:path\";\nimport type { FactsDB } from \"../../backends/facts-db.js\";\nimport type { VectorDB } from \"../../backends/vector-db.js\";\nimport type { EmbeddingProvider } from \"../../services/embeddings.js\";\nimport type { CredentialsDB } from \"../../backends/credentials-db.js\";\nimport type OpenAI from \"openai\";\n\nexport type VerifyRunOpts = {\n fix: boolean;\n logFile?: string;\n testLlm?: boolean;\n reconcile?: boolean;\n reconcilePolicy?: \"conservative\" | \"balanced\" | \"aggressive\";\n reconcileMaxFixes?: number;\n};\n\nexport type VerifyRunState = {\n ctx: HandlerContext;\n opts: VerifyRunOpts;\n sink: VerifyCliSink;\n cfg: HybridMemoryConfig;\n factsDb: FactsDB;\n vectorDb: VectorDB;\n embeddings: EmbeddingProvider;\n credentialsDb: CredentialsDB | null;\n resolvedSqlitePath: string;\n resolvedLancePath: string;\n openai: OpenAI;\n log: (msg: string) => void;\n tableLog: (msg: string) => void;\n rawLog: (msg: string) => void;\n OK: string;\n FAIL: string;\n PAUSE: string;\n WARN_LINE: string;\n noEmoji: boolean;\n rawPluginConfig?: Record<string, unknown>;\n lanceBindingsFailed: boolean;\n anyEmbOk: boolean;\n issues: string[];\n fixes: string[];\n warnings: string[];\n configOk: boolean;\n sqliteOk: boolean;\n lanceOk: boolean;\n embeddingOk: boolean;\n embeddingAlignmentOk: boolean;\n loadBlocking: string[];\n extDir: string;\n defaultConfigPath: string;\n openclawDir: string;\n openclawConfigRead: OpenclawConfigReadResult;\n recommendedEmbedding: ReturnType<typeof detectRecommendedEmbeddingSetup>;\n dashboardUrl: string;\n credentialsOk: boolean;\n allOk: boolean;\n};\n\nexport function createVerifyRunState(ctx: HandlerContext, opts: VerifyRunOpts, sink: VerifyCliSink): VerifyRunState {\n const { factsDb, vectorDb, embeddings, cfg, credentialsDb, resolvedSqlitePath, resolvedLancePath, openai } = ctx;\n const verbosity = cfg.verbosity ?? \"normal\";\n const rawLog = sink.log;\n const log: typeof rawLog = isCompactVerbosity(verbosity)\n ? (msg: string) => {\n const trimmed = msg.trimStart();\n const isOkLine = /^✅|^\\[OK\\]/.test(trimmed);\n const isHeader = /^─{3,}/.test(trimmed);\n const isIndentedStatus = /^\\s{2,}/.test(msg) && !/❌|\\[FAIL\\]|FAIL —|Error|error/.test(msg);\n if (!isOkLine && !isHeader && !isIndentedStatus) rawLog(msg);\n }\n : rawLog;\n const tableLog = rawLog;\n const noEmoji = getEnv(\"HYBRID_MEM_NO_EMOJI\") === \"1\";\n const extDir = findPluginRoot(import.meta.url);\n const defaultConfigPath = resolveOpenclawJsonPathForWorkspace();\n const openclawDir = dirname(defaultConfigPath);\n const openclawConfigRead = readOpenclawConfigRoot(defaultConfigPath);\n const recommendedEmbedding = detectRecommendedEmbeddingSetup(\n openclawConfigRead.root ?? { plugins: { entries: { [PLUGIN_ID]: { config: cfg } } } },\n extDir,\n );\n const dashboardUrl = getDashboardUrl(\n openclawConfigRead.root ?? { plugins: { entries: { [PLUGIN_ID]: { config: cfg } } } },\n );\n const warnings: string[] = [];\n if (openclawConfigRead.error) {\n warnings.push(\n `OpenClaw config at ${defaultConfigPath} could not be read/parsed (${openclawConfigRead.error}); compaction watchdog status is unknown and verify used fallback defaults.`,\n );\n }\n return {\n ctx,\n opts,\n sink,\n cfg,\n factsDb,\n vectorDb,\n embeddings,\n credentialsDb,\n resolvedSqlitePath,\n resolvedLancePath,\n openai,\n log,\n tableLog,\n rawLog,\n OK: noEmoji ? \"[OK]\" : \"✅\",\n FAIL: noEmoji ? \"[FAIL]\" : \"❌\",\n PAUSE: noEmoji ? \"[paused]\" : \"⏸️ \",\n WARN_LINE: noEmoji ? \"[WARN]\" : \"⚠️\",\n noEmoji,\n lanceBindingsFailed: false,\n anyEmbOk: false,\n issues: [],\n fixes: [],\n warnings,\n configOk: true,\n sqliteOk: false,\n lanceOk: false,\n embeddingOk: false,\n embeddingAlignmentOk: true,\n loadBlocking: [],\n extDir,\n defaultConfigPath,\n openclawDir,\n openclawConfigRead,\n recommendedEmbedding,\n dashboardUrl,\n credentialsOk: true,\n allOk: true,\n };\n}\n"],"mappings":";;;;;;;;;;;AAsEA,SAAgB,qBAAqB,KAAqB,MAAqB,MAAqC;CAClH,MAAM,EAAE,SAAS,UAAU,YAAY,KAAK,eAAe,oBAAoB,mBAAmB,WAAW;CAC7G,MAAM,YAAY,IAAI,aAAa;CACnC,MAAM,SAAS,KAAK;CACpB,MAAM,MAAqB,mBAAmB,SAAS,KAClD,QAAgB;EACf,MAAM,UAAU,IAAI,UAAU;EAC9B,MAAM,WAAW,aAAa,KAAK,OAAO;EAC1C,MAAM,WAAW,SAAS,KAAK,OAAO;EACtC,MAAM,mBAAmB,UAAU,KAAK,GAAG,KAAK,CAAC,gCAAgC,KAAK,GAAG;EACzF,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,kBAAkB,OAAO,GAAG;CAC7D,IACA;CACJ,MAAM,WAAW;CACjB,MAAM,UAAU,OAAO,qBAAqB,MAAM;CAClD,MAAM,SAAS,eAAe,OAAO,KAAK,GAAG;CAC7C,MAAM,oBAAoB,oCAAoC;CAC9D,MAAM,cAAc,QAAQ,iBAAiB;CAC7C,MAAM,qBAAqB,uBAAuB,iBAAiB;CACnE,MAAM,uBAAuB,gCAC3B,mBAAmB,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAA,2BAAe,EAAE,QAAQ,IAAI,EAAE,EAAE,EAAE,GACpF,MACF;CACA,MAAM,eAAe,gBACnB,mBAAmB,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAA,2BAAe,EAAE,QAAQ,IAAI,EAAE,EAAE,EAAE,CACtF;CACA,MAAM,WAAqB,CAAC;CAC5B,IAAI,mBAAmB,OACrB,SAAS,KACP,sBAAsB,kBAAkB,6BAA6B,mBAAmB,MAAM,4EAChG;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,UAAU,SAAS;EACvB,MAAM,UAAU,WAAW;EAC3B,OAAO,UAAU,aAAa;EAC9B,WAAW,UAAU,WAAW;EAChC;EACA,qBAAqB;EACrB,UAAU;EACV,QAAQ,CAAC;EACT,OAAO,CAAC;EACR;EACA,UAAU;EACV,UAAU;EACV,SAAS;EACT,aAAa;EACb,sBAAsB;EACtB,cAAc,CAAC;EACf;EACA;EACA;EACA;EACA;EACA;EACA,eAAe;EACf,OAAO;CACT;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-llm-azure-auth.js","names":[],"sources":["../../cli/verify-llm-azure-auth.ts"],"sourcesContent":["/**\n * Azure Foundry / APIM / direct resource auth for `verify --test-llm` OpenAI SDK clients (#994).\n * The SDK defaults to Bearer; Azure OpenAI resource and APIM expect `api-key` (same as embeddings factory).\n */\n\nimport { AZURE_OPENAI_API_VERSION } from \"../services/embeddings.js\";\nimport { isAzureOpenAiResourceEndpoint } from \"../services/embeddings/shared.js\";\n\n/** True when baseURL is an Azure AI Foundry Services endpoint (e.g. https://services.ai.azure.com). */\nfunction isAzureAiFoundryServicesUrl(baseURL: string): boolean {\n try {\n const u = new URL(baseURL);\n return u.hostname === \"services.ai.azure.com\" || u.hostname.endsWith(\".services.ai.azure.com\");\n } catch {\n return false;\n }\n}\nimport { createApimGatewayFetch, isAzureApiManagementGatewayUrl } from \"../utils/apim-gateway-fetch.js\";\n\nexport function isAzureFoundryFamilyProvider(provider: string): boolean {\n return provider === \"azure-foundry\" || provider === \"azure-foundry-responses\" || provider === \"azure-foundry-direct\";\n}\n\nexport type VerifyDirectOpenAIOpts = {\n apiKey: string;\n baseURL: string;\n defaultHeaders?: Record<string, string>;\n defaultQuery?: Record<string, string>;\n fetch?: typeof globalThis.fetch;\n};\n\n/**\n * Mutates `opts` when `provider` is an Azure Foundry family and `baseURL` is APIM or a direct Azure resource host.\n */\nexport function applyAzureFoundryVerifyDirectClientAuth(\n opts: VerifyDirectOpenAIOpts,\n provider: string,\n apiKey: string,\n): void {\n if (!isAzureFoundryFamilyProvider(provider)) return;\n const { baseURL } = opts;\n if (isAzureApiManagementGatewayUrl(baseURL)) {\n opts.defaultHeaders = { ...(opts.defaultHeaders ?? {}), \"api-key\": apiKey };\n opts.fetch = createApimGatewayFetch(apiKey);\n const openAiV1Compat = /\\/openai\\/v1(?:\\/|$)/i.test(baseURL);\n if (!openAiV1Compat) {\n opts.defaultQuery = { \"api-version\": AZURE_OPENAI_API_VERSION };\n }\n } else if (isAzureOpenAiResourceEndpoint(baseURL)) {\n // Legacy Azure OpenAI resource (e.g. *.openai.azure.com without /openai/v1)\n opts.defaultHeaders = { ...(opts.defaultHeaders ?? {}), \"api-key\": apiKey };\n const openAiV1Compat = /\\/openai\\/v1(?:\\/|$)/i.test(baseURL);\n if (!openAiV1Compat) {\n opts.defaultQuery = { \"api-version\": AZURE_OPENAI_API_VERSION };\n }\n } else if (isAzureAiFoundryServicesUrl(baseURL)) {\n // Azure AI Foundry Services endpoint — requires Bearer token auth (#1125)\n opts.defaultHeaders = { ...(opts.defaultHeaders ?? {}), Authorization: `Bearer ${apiKey}` };\n }\n}\n"],"mappings":";;;;;;;;;;AASA,SAAS,4BAA4B,SAA0B;CAC7D,IAAI;EACF,MAAM,IAAI,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"verify-llm-azure-auth.js","names":[],"sources":["../../cli/verify-llm-azure-auth.ts"],"sourcesContent":["/**\n * Azure Foundry / APIM / direct resource auth for `verify --test-llm` OpenAI SDK clients (#994).\n * The SDK defaults to Bearer; Azure OpenAI resource and APIM expect `api-key` (same as embeddings factory).\n */\n\nimport { AZURE_OPENAI_API_VERSION } from \"../services/embeddings.js\";\nimport { isAzureOpenAiResourceEndpoint } from \"../services/embeddings/shared.js\";\n\n/** True when baseURL is an Azure AI Foundry Services endpoint (e.g. https://services.ai.azure.com). */\nfunction isAzureAiFoundryServicesUrl(baseURL: string): boolean {\n try {\n const u = new URL(baseURL);\n return u.hostname === \"services.ai.azure.com\" || u.hostname.endsWith(\".services.ai.azure.com\");\n } catch {\n return false;\n }\n}\nimport { createApimGatewayFetch, isAzureApiManagementGatewayUrl } from \"../utils/apim-gateway-fetch.js\";\n\nexport function isAzureFoundryFamilyProvider(provider: string): boolean {\n return provider === \"azure-foundry\" || provider === \"azure-foundry-responses\" || provider === \"azure-foundry-direct\";\n}\n\nexport type VerifyDirectOpenAIOpts = {\n apiKey: string;\n baseURL: string;\n defaultHeaders?: Record<string, string>;\n defaultQuery?: Record<string, string>;\n fetch?: typeof globalThis.fetch;\n};\n\n/**\n * Mutates `opts` when `provider` is an Azure Foundry family and `baseURL` is APIM or a direct Azure resource host.\n */\nexport function applyAzureFoundryVerifyDirectClientAuth(\n opts: VerifyDirectOpenAIOpts,\n provider: string,\n apiKey: string,\n): void {\n if (!isAzureFoundryFamilyProvider(provider)) return;\n const { baseURL } = opts;\n if (isAzureApiManagementGatewayUrl(baseURL)) {\n opts.defaultHeaders = { ...(opts.defaultHeaders ?? {}), \"api-key\": apiKey };\n opts.fetch = createApimGatewayFetch(apiKey);\n const openAiV1Compat = /\\/openai\\/v1(?:\\/|$)/i.test(baseURL);\n if (!openAiV1Compat) {\n opts.defaultQuery = { \"api-version\": AZURE_OPENAI_API_VERSION };\n }\n } else if (isAzureOpenAiResourceEndpoint(baseURL)) {\n // Legacy Azure OpenAI resource (e.g. *.openai.azure.com without /openai/v1)\n opts.defaultHeaders = { ...(opts.defaultHeaders ?? {}), \"api-key\": apiKey };\n const openAiV1Compat = /\\/openai\\/v1(?:\\/|$)/i.test(baseURL);\n if (!openAiV1Compat) {\n opts.defaultQuery = { \"api-version\": AZURE_OPENAI_API_VERSION };\n }\n } else if (isAzureAiFoundryServicesUrl(baseURL)) {\n // Azure AI Foundry Services endpoint — requires Bearer token auth (#1125)\n opts.defaultHeaders = { ...(opts.defaultHeaders ?? {}), Authorization: `Bearer ${apiKey}` };\n }\n}\n"],"mappings":";;;;;;;;;;AASA,SAAS,4BAA4B,SAA0B;CAC7D,IAAI;EACF,MAAM,IAAI,IAAI,IAAI,OAAO;EACzB,OAAO,EAAE,aAAa,2BAA2B,EAAE,SAAS,SAAS,wBAAwB;CAC/F,QAAQ;EACN,OAAO;CACT;AACF;AAGA,SAAgB,6BAA6B,UAA2B;CACtE,OAAO,aAAa,mBAAmB,aAAa,6BAA6B,aAAa;AAChG;;;;AAaA,SAAgB,wCACd,MACA,UACA,QACM;CACN,IAAI,CAAC,6BAA6B,QAAQ,GAAG;CAC7C,MAAM,EAAE,YAAY;CACpB,IAAI,+BAA+B,OAAO,GAAG;EAC3C,KAAK,iBAAiB;GAAE,GAAI,KAAK,kBAAkB,CAAC;GAAI,WAAW;EAAO;EAC1E,KAAK,QAAQ,uBAAuB,MAAM;EAE1C,IAAI,CADmB,wBAAwB,KAAK,OAClC,GAChB,KAAK,eAAe,EAAE,eAAe,yBAAyB;CAElE,OAAO,IAAI,8BAA8B,OAAO,GAAG;EAEjD,KAAK,iBAAiB;GAAE,GAAI,KAAK,kBAAkB,CAAC;GAAI,WAAW;EAAO;EAE1E,IAAI,CADmB,wBAAwB,KAAK,OAClC,GAChB,KAAK,eAAe,EAAE,eAAe,yBAAyB;CAElE,OAAO,IAAI,4BAA4B,OAAO,GAE5C,KAAK,iBAAiB;EAAE,GAAI,KAAK,kBAAkB,CAAC;EAAI,eAAe,UAAU;CAAS;AAE9F"}
|
package/dist/cli/verify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","names":[],"sources":["../../cli/verify.ts"],"sourcesContent":["import { setEnv } from \"../utils/env-manager.js\";\n/**\n * CLI commands for verification and installation (verify, install).\n */\n\nimport { capturePluginError } from \"../services/error-reporter.js\";\nimport { type Chainable, withExit } from \"./shared.js\";\nimport type { InstallCliResult, VerifyCliSink } from \"./types.js\";\n\nexport type VerifyContext = {\n runVerify: (\n opts: {\n fix: boolean;\n logFile?: string;\n testLlm?: boolean;\n reconcile?: boolean;\n reconcilePolicy?: \"conservative\" | \"balanced\" | \"aggressive\";\n reconcileMaxFixes?: number;\n },\n sink: VerifyCliSink,\n ) => Promise<void>;\n runInstall: (opts: { dryRun: boolean }) => Promise<InstallCliResult>;\n runResetAuthBackoff: () => Promise<void>;\n};\n\nexport function registerVerifyCommands(mem: Chainable, ctx: VerifyContext): void {\n const { runVerify, runInstall, runResetAuthBackoff } = ctx;\n\n const verifyCommand = mem\n .command(\"verify\")\n .description(\"Verify plugin config, databases, and suggest fixes (run after gateway start for full checks)\");\n if (verifyCommand.alias) verifyCommand.alias(\"preflight\");\n verifyCommand\n .option(\"--fix\", \"Print or apply default config for missing items\")\n .option(\"--log-file <path>\", \"Check this log file for memory-hybrid / cron errors\")\n .option(\"--test-llm\", \"Test each configured LLM model with a minimal completion (requires gateway)\")\n .option(\n \"--reconcile\",\n \"Check SQLite ↔ LanceDB consistency (orphans; issue #904). Use --fix to remove vector-side orphans.\",\n )\n .option(\n \"--reconcile-policy <policy>\",\n \"Self-heal policy with --reconcile --fix: conservative|balanced|aggressive (default: balanced)\",\n \"balanced\",\n )\n .option(\n \"--reconcile-max-fixes <n>\",\n \"Max vectors to rebuild for SQLite orphan gaps (records missing vectors) when --fix is set (default: 200)\",\n \"200\",\n )\n .option(\"--no-emoji\", \"Use plain text indicators instead of emoji (for terminals with poor Unicode support)\")\n .action(\n withExit(\n async (opts: {\n fix?: boolean;\n logFile?: string;\n testLlm?: boolean;\n noEmoji?: boolean;\n reconcile?: boolean;\n reconcilePolicy?: string;\n reconcileMaxFixes?: string;\n }) => {\n if (opts.noEmoji) setEnv(\"HYBRID_MEM_NO_EMOJI\", \"1\");\n const reconcilePolicyRaw = String(opts.reconcilePolicy ?? \"balanced\")\n .trim()\n .toLowerCase();\n const reconcilePolicy =\n reconcilePolicyRaw === \"conservative\" || reconcilePolicyRaw === \"aggressive\"\n ? reconcilePolicyRaw\n : \"balanced\";\n const parsedReconcileMaxFixes = Number.parseInt(String(opts.reconcileMaxFixes ?? \"200\"), 10);\n const reconcileMaxFixes = Math.max(\n 0,\n Math.min(5000, Number.isFinite(parsedReconcileMaxFixes) ? parsedReconcileMaxFixes : 200),\n );\n try {\n await runVerify(\n {\n fix: !!opts.fix,\n logFile: opts.logFile,\n testLlm: !!opts.testLlm,\n reconcile: !!opts.reconcile,\n reconcilePolicy,\n reconcileMaxFixes,\n },\n { log: (s) => console.log(s), error: (s) => console.error(s) },\n );\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"cli\",\n operation: \"verify\",\n });\n throw err;\n }\n },\n ),\n );\n\n mem\n .command(\"reset-auth-backoff\")\n .description(\n \"Clear OAuth failover backoff so the next LLM call will try OAuth again for providers that have both OAuth and API key.\",\n )\n .action(\n withExit(async () => {\n await runResetAuthBackoff();\n }),\n );\n\n const installCommand = mem\n .command(\"install\")\n .description(\n \"Apply full recommended config, prompts, and optional jobs (idempotent). Run after first plugin setup for best defaults.\",\n );\n if (installCommand.alias) installCommand.alias(\"setup\");\n installCommand.option(\"--dry-run\", \"Print what would be merged without writing\").action(\n withExit(async (opts: { dryRun?: boolean }) => {\n let result: InstallCliResult;\n try {\n result = await runInstall({ dryRun: !!opts.dryRun });\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"cli\",\n operation: \"install\",\n });\n throw err;\n }\n if (!result.ok) {\n console.error(result.error);\n process.exitCode = 1;\n return;\n }\n if (result.dryRun) {\n console.log(`Dry run for ${result.configPath}`);\n console.log(`Recommended embedding: ${result.detectedEmbedding.provider}/${result.detectedEmbedding.model}`);\n console.log(`Reason: ${result.detectedEmbedding.reason}`);\n console.log(\"\");\n console.log(\"Planned\");\n for (const item of result.completed) console.log(` - ${item}`);\n if (result.workspaceSkillPath) {\n console.log(\n ` - Workspace skill: ${result.workspaceSkillPath}${result.workspaceSkillError ? ` (${result.workspaceSkillError})` : \"\"}`,\n );\n }\n if (result.workspaceToolsMdPath) {\n console.log(\n ` - TOOLS.md managed block: ${result.workspaceToolsMdPath}${result.workspaceToolsMdError ? ` (${result.workspaceToolsMdError})` : \"\"}`,\n );\n }\n console.log(\"\");\n console.log(\"Still manual\");\n for (const item of result.remaining) console.log(` - ${item}`);\n console.log(\"\");\n console.log(result.configJson ?? \"\");\n return;\n }\n console.log(`Setup complete for ${result.pluginId}`);\n console.log(`Config: ${result.configPath}`);\n console.log(`Workspace: ${result.workspaceRoot}`);\n console.log(`Mission Control: ${result.dashboardUrl}`);\n console.log(\n `Embedding: ${result.detectedEmbedding.provider}/${result.detectedEmbedding.model} (${result.detectedEmbedding.source})`,\n );\n console.log(\"\");\n console.log(\"Done\");\n for (const item of result.completed) console.log(` - ${item}`);\n if (result.workspaceSkillPath) {\n console.log(\n ` - Workspace skill: ${result.workspaceSkillPath}${result.workspaceSkillError ? ` (warning: ${result.workspaceSkillError})` : \"\"}`,\n );\n }\n if (result.workspaceToolsMdPath) {\n const toolsSuffix = result.workspaceToolsMdError\n ? ` (warning: ${result.workspaceToolsMdError})`\n : result.workspaceToolsMdUpdated === true\n ? \" (updated)\"\n : result.workspaceToolsMdUpdated === false\n ? \" (unchanged)\"\n : \"\";\n console.log(` - TOOLS.md: ${result.workspaceToolsMdPath}${toolsSuffix}`);\n }\n console.log(\"\");\n console.log(\"Left\");\n for (const item of result.remaining) console.log(` - ${item}`);\n }),\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"verify.js","names":[],"sources":["../../cli/verify.ts"],"sourcesContent":["import { setEnv } from \"../utils/env-manager.js\";\n/**\n * CLI commands for verification and installation (verify, install).\n */\n\nimport { capturePluginError } from \"../services/error-reporter.js\";\nimport { type Chainable, withExit } from \"./shared.js\";\nimport type { InstallCliResult, VerifyCliSink } from \"./types.js\";\n\nexport type VerifyContext = {\n runVerify: (\n opts: {\n fix: boolean;\n logFile?: string;\n testLlm?: boolean;\n reconcile?: boolean;\n reconcilePolicy?: \"conservative\" | \"balanced\" | \"aggressive\";\n reconcileMaxFixes?: number;\n },\n sink: VerifyCliSink,\n ) => Promise<void>;\n runInstall: (opts: { dryRun: boolean }) => Promise<InstallCliResult>;\n runResetAuthBackoff: () => Promise<void>;\n};\n\nexport function registerVerifyCommands(mem: Chainable, ctx: VerifyContext): void {\n const { runVerify, runInstall, runResetAuthBackoff } = ctx;\n\n const verifyCommand = mem\n .command(\"verify\")\n .description(\"Verify plugin config, databases, and suggest fixes (run after gateway start for full checks)\");\n if (verifyCommand.alias) verifyCommand.alias(\"preflight\");\n verifyCommand\n .option(\"--fix\", \"Print or apply default config for missing items\")\n .option(\"--log-file <path>\", \"Check this log file for memory-hybrid / cron errors\")\n .option(\"--test-llm\", \"Test each configured LLM model with a minimal completion (requires gateway)\")\n .option(\n \"--reconcile\",\n \"Check SQLite ↔ LanceDB consistency (orphans; issue #904). Use --fix to remove vector-side orphans.\",\n )\n .option(\n \"--reconcile-policy <policy>\",\n \"Self-heal policy with --reconcile --fix: conservative|balanced|aggressive (default: balanced)\",\n \"balanced\",\n )\n .option(\n \"--reconcile-max-fixes <n>\",\n \"Max vectors to rebuild for SQLite orphan gaps (records missing vectors) when --fix is set (default: 200)\",\n \"200\",\n )\n .option(\"--no-emoji\", \"Use plain text indicators instead of emoji (for terminals with poor Unicode support)\")\n .action(\n withExit(\n async (opts: {\n fix?: boolean;\n logFile?: string;\n testLlm?: boolean;\n noEmoji?: boolean;\n reconcile?: boolean;\n reconcilePolicy?: string;\n reconcileMaxFixes?: string;\n }) => {\n if (opts.noEmoji) setEnv(\"HYBRID_MEM_NO_EMOJI\", \"1\");\n const reconcilePolicyRaw = String(opts.reconcilePolicy ?? \"balanced\")\n .trim()\n .toLowerCase();\n const reconcilePolicy =\n reconcilePolicyRaw === \"conservative\" || reconcilePolicyRaw === \"aggressive\"\n ? reconcilePolicyRaw\n : \"balanced\";\n const parsedReconcileMaxFixes = Number.parseInt(String(opts.reconcileMaxFixes ?? \"200\"), 10);\n const reconcileMaxFixes = Math.max(\n 0,\n Math.min(5000, Number.isFinite(parsedReconcileMaxFixes) ? parsedReconcileMaxFixes : 200),\n );\n try {\n await runVerify(\n {\n fix: !!opts.fix,\n logFile: opts.logFile,\n testLlm: !!opts.testLlm,\n reconcile: !!opts.reconcile,\n reconcilePolicy,\n reconcileMaxFixes,\n },\n { log: (s) => console.log(s), error: (s) => console.error(s) },\n );\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"cli\",\n operation: \"verify\",\n });\n throw err;\n }\n },\n ),\n );\n\n mem\n .command(\"reset-auth-backoff\")\n .description(\n \"Clear OAuth failover backoff so the next LLM call will try OAuth again for providers that have both OAuth and API key.\",\n )\n .action(\n withExit(async () => {\n await runResetAuthBackoff();\n }),\n );\n\n const installCommand = mem\n .command(\"install\")\n .description(\n \"Apply full recommended config, prompts, and optional jobs (idempotent). Run after first plugin setup for best defaults.\",\n );\n if (installCommand.alias) installCommand.alias(\"setup\");\n installCommand.option(\"--dry-run\", \"Print what would be merged without writing\").action(\n withExit(async (opts: { dryRun?: boolean }) => {\n let result: InstallCliResult;\n try {\n result = await runInstall({ dryRun: !!opts.dryRun });\n } catch (err) {\n capturePluginError(err instanceof Error ? err : new Error(String(err)), {\n subsystem: \"cli\",\n operation: \"install\",\n });\n throw err;\n }\n if (!result.ok) {\n console.error(result.error);\n process.exitCode = 1;\n return;\n }\n if (result.dryRun) {\n console.log(`Dry run for ${result.configPath}`);\n console.log(`Recommended embedding: ${result.detectedEmbedding.provider}/${result.detectedEmbedding.model}`);\n console.log(`Reason: ${result.detectedEmbedding.reason}`);\n console.log(\"\");\n console.log(\"Planned\");\n for (const item of result.completed) console.log(` - ${item}`);\n if (result.workspaceSkillPath) {\n console.log(\n ` - Workspace skill: ${result.workspaceSkillPath}${result.workspaceSkillError ? ` (${result.workspaceSkillError})` : \"\"}`,\n );\n }\n if (result.workspaceToolsMdPath) {\n console.log(\n ` - TOOLS.md managed block: ${result.workspaceToolsMdPath}${result.workspaceToolsMdError ? ` (${result.workspaceToolsMdError})` : \"\"}`,\n );\n }\n console.log(\"\");\n console.log(\"Still manual\");\n for (const item of result.remaining) console.log(` - ${item}`);\n console.log(\"\");\n console.log(result.configJson ?? \"\");\n return;\n }\n console.log(`Setup complete for ${result.pluginId}`);\n console.log(`Config: ${result.configPath}`);\n console.log(`Workspace: ${result.workspaceRoot}`);\n console.log(`Mission Control: ${result.dashboardUrl}`);\n console.log(\n `Embedding: ${result.detectedEmbedding.provider}/${result.detectedEmbedding.model} (${result.detectedEmbedding.source})`,\n );\n console.log(\"\");\n console.log(\"Done\");\n for (const item of result.completed) console.log(` - ${item}`);\n if (result.workspaceSkillPath) {\n console.log(\n ` - Workspace skill: ${result.workspaceSkillPath}${result.workspaceSkillError ? ` (warning: ${result.workspaceSkillError})` : \"\"}`,\n );\n }\n if (result.workspaceToolsMdPath) {\n const toolsSuffix = result.workspaceToolsMdError\n ? ` (warning: ${result.workspaceToolsMdError})`\n : result.workspaceToolsMdUpdated === true\n ? \" (updated)\"\n : result.workspaceToolsMdUpdated === false\n ? \" (unchanged)\"\n : \"\";\n console.log(` - TOOLS.md: ${result.workspaceToolsMdPath}${toolsSuffix}`);\n }\n console.log(\"\");\n console.log(\"Left\");\n for (const item of result.remaining) console.log(` - ${item}`);\n }),\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hybrid-schema.js","names":[],"sources":["../../config/hybrid-schema.ts"],"sourcesContent":["import { parseConfig } from \"./parsers/index.js\";\n\n/**\n * Runtime config validation entry point (issue #866).\n * Uses the same parser pipeline as plugin registration; throws on invalid hybrid config.\n */\nexport const hybridConfigSchema = {\n parse: parseConfig,\n};\n"],"mappings":";;;;;;AAMA,MAAa,qBAAqB,EAChC,OAAO,
|
|
1
|
+
{"version":3,"file":"hybrid-schema.js","names":[],"sources":["../../config/hybrid-schema.ts"],"sourcesContent":["import { parseConfig } from \"./parsers/index.js\";\n\n/**\n * Runtime config validation entry point (issue #866).\n * Uses the same parser pipeline as plugin registration; throws on invalid hybrid config.\n */\nexport const hybridConfigSchema = {\n parse: parseConfig,\n};\n"],"mappings":";;;;;;AAMA,MAAa,qBAAqB,EAChC,OAAO,YACT"}
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../config/index.ts"],"sourcesContent":["import { getEnv } from \"../utils/env-manager.js\";\n// Re-export all types\nexport * from \"./types/index.js\";\n\n// Config schema — isolated module so `hybridConfigSchema` is never undefined when the config\n// barrel re-exports parsers (avoids circular init: parsers → … → config/index before `hybridConfigSchema` is set).\nexport { hybridConfigSchema } from \"./hybrid-schema.js\";\n\n// Re-export utilities\nexport {\n DEFAULT_MEMORY_CATEGORIES,\n getMemoryCategories,\n setMemoryCategories,\n isValidCategory,\n PRESET_OVERRIDES,\n isCompactVerbosity,\n} from \"./utils.js\";\n\n// Re-export embedding dimension utilities\nexport { EMBEDDING_DIMENSIONS, OPENAI_MODELS } from \"./parsers/core.js\";\n\n// Re-export vectorDimsForModel and parseVerbosityLevel from parsers/index\nexport { vectorDimsForModel, parseVerbosityLevel } from \"./parsers/index.js\";\n\nimport { resolveSecretRef } from \"./parsers/core.js\";\nimport {\n effectiveMaintenanceFallbackPolicy,\n filterMaintenanceTierFallbackModels,\n} from \"./maintenance-fallback-policy.js\";\n// LLM model utilities\nimport type { CronModelConfig, CronModelTier, HybridMemoryConfig } from \"./types/index.js\";\n\nexport {\n describeMaintenanceFallbackPolicy,\n effectiveMaintenanceFallbackPolicy,\n isExpensiveMaintenanceFallbackModel,\n} from \"./maintenance-fallback-policy.js\";\n\nconst OPENAI_NANO_CRON_MODEL = \"openai/gpt-4.1-nano\";\nconst OPENAI_DEFAULT_CRON_MODEL = \"openai/gpt-4.1-mini\";\nconst OPENAI_HEAVY_CRON_MODEL = \"openai/gpt-5.4\";\nconst GEMINI_NANO_MODEL = \"google/gemini-2.5-flash-lite\";\nconst GEMINI_DEFAULT_MODEL = \"google/gemini-2.5-flash\";\nconst GEMINI_HEAVY_MODEL = \"google/gemini-3.1-pro-preview\";\nconst CLAUDE_NANO_MODEL = \"anthropic/claude-haiku-4-5-20251001\";\nconst CLAUDE_DEFAULT_MODEL = \"anthropic/claude-sonnet-4-6\";\nconst CLAUDE_HEAVY_MODEL = \"anthropic/claude-opus-4-6\";\n\nfunction hasKey(apiKey: string | undefined): boolean {\n return typeof apiKey === \"string\" && apiKey.length >= 10;\n}\n\n/** True if apiKey is present and, for env:/file: SecretRefs, resolvable at runtime (verify / getProvidersWithKeys). */\nfunction hasEffectiveKey(apiKey: string | undefined): boolean {\n if (typeof apiKey !== \"string\" || !hasKey(apiKey)) return false;\n const k = apiKey.trim();\n if (k.startsWith(\"env:\") || k.startsWith(\"file:\")) return resolveSecretRef(k) !== undefined;\n return true;\n}\n\n/** Legacy single-model resolution (for backward compat when no llm config). Used only when no list is built. */\nfunction getDefaultCronModelLegacy(pluginConfig: CronModelConfig | undefined, tier: CronModelTier): string {\n if (!pluginConfig) {\n if (tier === \"heavy\") return OPENAI_HEAVY_CRON_MODEL;\n if (tier === \"nano\") return OPENAI_NANO_CRON_MODEL;\n return OPENAI_DEFAULT_CRON_MODEL;\n }\n if (hasKey(pluginConfig.distill?.apiKey)) {\n const defaultModel = pluginConfig.distill?.defaultModel?.trim();\n // If the user explicitly configured a defaultModel, respect it for all tiers.\n // Only fall back to provider-specific nano/heavy variants when no explicit model is set.\n // Users who want a specific cheap model for nano operations should configure llm.nano instead.\n if (defaultModel) return defaultModel;\n if (tier === \"heavy\") return GEMINI_HEAVY_MODEL;\n if (tier === \"nano\") return GEMINI_NANO_MODEL;\n return GEMINI_DEFAULT_MODEL;\n }\n if (hasKey(pluginConfig.claude?.apiKey)) {\n const defaultModel = pluginConfig.claude?.defaultModel?.trim();\n // Same: respect explicit defaultModel for all tiers; use nano variant only when unset.\n if (defaultModel) return defaultModel;\n if (tier === \"heavy\") return CLAUDE_HEAVY_MODEL;\n if (tier === \"nano\") return CLAUDE_NANO_MODEL;\n return CLAUDE_DEFAULT_MODEL;\n }\n if (hasKey(pluginConfig.embedding?.apiKey)) {\n if (tier === \"heavy\") return OPENAI_HEAVY_CRON_MODEL;\n if (tier === \"nano\") return OPENAI_NANO_CRON_MODEL;\n return OPENAI_DEFAULT_CRON_MODEL;\n }\n if (tier === \"heavy\") return OPENAI_HEAVY_CRON_MODEL;\n if (tier === \"nano\") return OPENAI_NANO_CRON_MODEL;\n return OPENAI_DEFAULT_CRON_MODEL;\n}\n\n/**\n * Preferred provider order for out-of-the-box failover: Research/Heavy favours Gemini (context), then OpenAI, then Claude.\n * Uses OpenClaw-style provider/model IDs so the gateway accepts them. First working model wins at runtime.\n */\nfunction getDefaultPreferredModelList(pluginConfig: CronModelConfig | undefined, tier: CronModelTier): string[] {\n if (!pluginConfig) {\n if (tier === \"heavy\") return [OPENAI_HEAVY_CRON_MODEL];\n if (tier === \"nano\") return [OPENAI_NANO_CRON_MODEL];\n return [OPENAI_DEFAULT_CRON_MODEL];\n }\n const list: string[] = [];\n if (hasKey(pluginConfig.distill?.apiKey)) {\n const m = pluginConfig.distill?.defaultModel?.trim();\n // Respect explicit defaultModel for all tiers; fall back to tier-specific defaults only when unset.\n list.push(\n m || (tier === \"nano\" ? GEMINI_NANO_MODEL : tier === \"heavy\" ? GEMINI_HEAVY_MODEL : GEMINI_DEFAULT_MODEL),\n );\n }\n if (hasKey(pluginConfig.embedding?.apiKey)) {\n if (tier === \"nano\") list.push(OPENAI_NANO_CRON_MODEL);\n else list.push(tier === \"heavy\" ? OPENAI_HEAVY_CRON_MODEL : OPENAI_DEFAULT_CRON_MODEL);\n }\n if (hasKey(pluginConfig.claude?.apiKey)) {\n const m = pluginConfig.claude?.defaultModel?.trim();\n // Respect explicit defaultModel for all tiers; fall back to tier-specific defaults only when unset.\n list.push(\n m || (tier === \"nano\" ? CLAUDE_NANO_MODEL : tier === \"heavy\" ? CLAUDE_HEAVY_MODEL : CLAUDE_DEFAULT_MODEL),\n );\n }\n if (list.length === 0) {\n list.push(getDefaultCronModelLegacy(pluginConfig, tier));\n }\n const distillFallbacks = pluginConfig.distill?.fallbackModels;\n if (Array.isArray(distillFallbacks)) {\n for (const m of distillFallbacks) {\n const t = typeof m === \"string\" ? m.trim() : \"\";\n if (t && !list.includes(t)) list.push(t);\n }\n }\n const fallback = pluginConfig.llm?.fallbackModel?.trim();\n if (fallback && !list.includes(fallback)) {\n list.push(fallback);\n }\n return list;\n}\n\n/**\n * Return ordered list of models to try for an LLM call.\n * - \"nano\": ultra-cheap for autoClassify, HyDE, classifyBeforeWrite, summarize. Falls back to \"default\" if llm.nano is unset.\n * - \"default\": HyDE, classify, reflection, general.\n * - \"heavy\": distill, self-correction, spawn.\n * First working model wins.\n */\nfunction getDisabledProviderSet(pluginConfig: CronModelConfig | undefined): Set<string> {\n const disabled = pluginConfig?.llm?.disabledProviders;\n if (!Array.isArray(disabled) || disabled.length === 0) return new Set();\n return new Set(disabled.map((p) => String(p).trim().toLowerCase()));\n}\n\n/**\n * Infer provider from model name.\n * Supports bare model names (e.g., gemini-2.5-flash -> google, claude-sonnet-4-6 -> anthropic, gpt-4 -> openai).\n */\nfunction inferProviderFromModel(model: string): string {\n if (model.includes(\"/\")) {\n return model.split(\"/\")[0].trim().toLowerCase();\n }\n const bare = model.trim().toLowerCase();\n if (bare.startsWith(\"gemini-\")) return \"google\";\n if (bare.startsWith(\"claude-\")) return \"anthropic\";\n if (bare.startsWith(\"gpt-\") || bare.match(/^o[0-9]/)) return \"openai\";\n return \"openai\";\n}\n\nfunction filterModelsByDisabled(models: string[], disabledSet: Set<string>): string[] {\n if (disabledSet.size === 0) return models;\n return models.filter((m) => {\n const prefix = inferProviderFromModel(m);\n return !disabledSet.has(prefix);\n });\n}\n\n/** Same as getLLMModelPreference but does not exclude disabledProviders. Use for verify table so disabled providers are still listed. */\nexport function getLLMModelPreferenceUnfiltered(\n pluginConfig: CronModelConfig | undefined,\n tier: CronModelTier,\n): string[] {\n if (tier === \"nano\") {\n const nanoList = pluginConfig?.llm?.nano;\n if (Array.isArray(nanoList) && nanoList.length > 0) {\n const trimmed = nanoList.map((m) => (typeof m === \"string\" ? m.trim() : \"\")).filter(Boolean);\n if (trimmed.length > 0) return trimmed;\n }\n return getLLMModelPreferenceUnfiltered(pluginConfig, \"default\");\n }\n if (tier === \"maintenance\") {\n const maintenanceList = pluginConfig?.llm?.maintenance;\n if (Array.isArray(maintenanceList) && maintenanceList.length > 0) {\n const trimmed = maintenanceList.map((m) => (typeof m === \"string\" ? m.trim() : \"\")).filter(Boolean);\n if (trimmed.length > 0) return trimmed;\n }\n return getLLMModelPreferenceUnfiltered(pluginConfig, \"default\");\n }\n const list = tier === \"heavy\" ? pluginConfig?.llm?.heavy : pluginConfig?.llm?.default;\n if (Array.isArray(list) && list.length > 0) {\n const trimmed = list.map((m) => (typeof m === \"string\" ? m.trim() : \"\")).filter(Boolean);\n if (trimmed.length > 0) {\n if (pluginConfig?.llm?.fallbackToDefault) {\n const fallback = pluginConfig.llm.fallbackModel?.trim();\n if (fallback && !trimmed.includes(fallback)) return [...trimmed, fallback];\n }\n return trimmed;\n }\n }\n return getDefaultPreferredModelList(pluginConfig, tier);\n}\n\nexport function getLLMModelPreference(pluginConfig: CronModelConfig | undefined, tier: CronModelTier): string[] {\n const disabledSet = getDisabledProviderSet(pluginConfig);\n const unfiltered = getLLMModelPreferenceUnfiltered(pluginConfig, tier);\n return filterModelsByDisabled(unfiltered, disabledSet);\n}\n\n/**\n * Report which providers have API keys (for verify/transparency).\n * Checks both legacy key fields (distill.apiKey → gemini, embedding.apiKey → openai)\n * and the new llm.providers map so all configured providers are shown.\n */\nexport function getProvidersWithKeys(pluginConfig: CronModelConfig | undefined): string[] {\n if (!pluginConfig) return [];\n const disabledSet = getDisabledProviderSet(pluginConfig);\n const seen = new Set<string>();\n const out: string[] = [];\n\n function add(name: string) {\n const lower = name.toLowerCase();\n if (disabledSet.has(lower)) return;\n if (!seen.has(lower)) {\n seen.add(lower);\n out.push(name);\n }\n }\n\n // Legacy / built-in key fields (resolve env:/file: so GOOGLE_API_KEY etc. count when set)\n if (hasEffectiveKey(pluginConfig.distill?.apiKey)) add(\"google\");\n if (hasEffectiveKey(pluginConfig.embedding?.apiKey)) add(\"openai\");\n if (hasEffectiveKey(pluginConfig.claude?.apiKey)) add(\"anthropic\");\n\n // llm.providers map — any provider with an explicit apiKey\n const providers = pluginConfig.llm?.providers;\n if (providers && typeof providers === \"object\") {\n for (const [prefix, pCfg] of Object.entries(providers)) {\n if (pCfg && hasEffectiveKey(pCfg.apiKey)) add(prefix);\n }\n }\n\n // Env fallbacks so providers show as configured when only env is set (e.g. GOOGLE_API_KEY)\n const googleKey = getEnv(\"GOOGLE_API_KEY\");\n if (!seen.has(\"google\") && typeof googleKey === \"string\" && googleKey.trim().length >= 10) {\n add(\"google\");\n }\n\n const anthropicKey = getEnv(\"ANTHROPIC_API_KEY\");\n if (!seen.has(\"anthropic\") && typeof anthropicKey === \"string\" && anthropicKey.trim().length >= 10) {\n add(\"anthropic\");\n }\n\n return out;\n}\n\n/**\n * Resolve which LLM model to use for a maintenance cron job based on user config.\n * When llm.default/heavy are set, returns the first model in the preference list (gateway-routed).\n * Otherwise legacy: prefer provider the user has configured (Gemini > Claude > OpenAI) > fallback.\n */\nexport function getDefaultCronModel(pluginConfig: CronModelConfig | undefined, tier: CronModelTier): string {\n const preferred = getLLMModelPreference(pluginConfig, tier);\n return preferred[0] ?? (tier === \"heavy\" ? OPENAI_HEAVY_CRON_MODEL : OPENAI_DEFAULT_CRON_MODEL);\n}\n\n/** Build minimal config for getDefaultCronModel from full HybridMemoryConfig (used by cron jobs and self-correction spawn). */\nexport function getCronModelConfig(cfg: HybridMemoryConfig): CronModelConfig {\n return {\n embedding: cfg.embedding,\n distill: cfg.distill,\n reflection: cfg.reflection,\n claude: (cfg as Record<string, unknown>).claude as CronModelConfig[\"claude\"],\n llm: cfg.llm,\n };\n}\n\nfunction appendUniqueFallback(chain: string[], candidate: string | undefined, primary: string): void {\n const t = candidate?.trim();\n if (!t || t === primary || chain.includes(t)) return;\n chain.push(t);\n}\n\nfunction appendUniqueFallbackList(chain: string[], candidates: string[] | undefined, primary: string): void {\n if (!Array.isArray(candidates)) return;\n for (const c of candidates) appendUniqueFallback(chain, c, primary);\n}\n\n/**\n * Resolve default model and fallback list for reflection/cron (default or heavy tier).\n * Single place for getCronModelConfig + getLLMModelPreference + cfg.llm fallback logic.\n *\n * When `llm.*` lists only one model for the tier, fallbacks are also taken from `llm.fallbackModel`\n * and `distill.fallbackModels` (de-duplicated). That way heavy crons using a single Responses API\n * model (e.g. azure-foundry/o3-pro) can still fail over without duplicating the whole preference list\n * (#1034).\n *\n * Maintenance tier (`tier === \"maintenance\"`): `llm.maintenanceFallbackPolicy` controls whether\n * expensive models are stripped from automatic fallbacks and whether global fallbacks are merged\n * when `llm.maintenance` is an explicit list (#1226). Unset policy defaults to `cheap-only`.\n */\nexport function resolveReflectionModelAndFallbacks(\n cfg: HybridMemoryConfig,\n tier: CronModelTier,\n primaryModelOverride?: string,\n): { defaultModel: string; fallbackModels: string[] | undefined } {\n const cronCfg = getCronModelConfig(cfg);\n const pref = getLLMModelPreference(cronCfg, tier);\n const defaultModel = pref[0] ?? (tier === \"heavy\" ? OPENAI_HEAVY_CRON_MODEL : OPENAI_DEFAULT_CRON_MODEL);\n\n let chain: string[] = pref.length > 1 ? pref.slice(1) : [];\n\n const maintPolicy = tier === \"maintenance\" ? effectiveMaintenanceFallbackPolicy(cfg) : null;\n const maintenanceArr = cfg.llm?.maintenance;\n const explicitMaintList = Array.isArray(maintenanceArr) ? maintenanceArr : [];\n const explicitMaintenance = explicitMaintList.length > 0;\n const explicitMaintenanceSet =\n tier === \"maintenance\" && explicitMaintenance\n ? new Set(explicitMaintList.map((m) => (typeof m === \"string\" ? m.trim() : \"\")).filter(Boolean))\n : undefined;\n\n if (tier === \"maintenance\" && maintPolicy === \"cheap-only\") {\n chain = filterMaintenanceTierFallbackModels(chain, defaultModel, explicitMaintenanceSet);\n }\n\n const skipGlobalFallbackAppend = tier === \"maintenance\" && maintPolicy === \"explicit-only\" && explicitMaintenance;\n\n if (!cfg.llm && chain.length === 0 && !skipGlobalFallbackAppend) {\n appendUniqueFallbackList(chain, cfg.distill?.fallbackModels, defaultModel);\n } else if (cfg.llm && chain.length === 0 && !skipGlobalFallbackAppend) {\n appendUniqueFallback(chain, cfg.llm.fallbackModel, defaultModel);\n appendUniqueFallbackList(chain, cfg.distill?.fallbackModels, defaultModel);\n }\n\n const primaryOverride = primaryModelOverride?.trim();\n const effectivePrimary = primaryOverride || defaultModel;\n if (primaryOverride) {\n appendUniqueFallback(chain, defaultModel, effectivePrimary);\n appendUniqueFallbackList(chain, pref, effectivePrimary);\n }\n\n if (tier === \"maintenance\" && maintPolicy === \"cheap-only\") {\n chain = filterMaintenanceTierFallbackModels(chain, effectivePrimary, explicitMaintenanceSet);\n }\n\n return { defaultModel, fallbackModels: chain.length > 0 ? chain : undefined };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../config/index.ts"],"sourcesContent":["import { getEnv } from \"../utils/env-manager.js\";\n// Re-export all types\nexport * from \"./types/index.js\";\n\n// Config schema — isolated module so `hybridConfigSchema` is never undefined when the config\n// barrel re-exports parsers (avoids circular init: parsers → … → config/index before `hybridConfigSchema` is set).\nexport { hybridConfigSchema } from \"./hybrid-schema.js\";\n\n// Re-export utilities\nexport {\n DEFAULT_MEMORY_CATEGORIES,\n getMemoryCategories,\n setMemoryCategories,\n isValidCategory,\n PRESET_OVERRIDES,\n isCompactVerbosity,\n} from \"./utils.js\";\n\n// Re-export embedding dimension utilities\nexport { EMBEDDING_DIMENSIONS, OPENAI_MODELS } from \"./parsers/core.js\";\n\n// Re-export vectorDimsForModel and parseVerbosityLevel from parsers/index\nexport { vectorDimsForModel, parseVerbosityLevel } from \"./parsers/index.js\";\n\nimport { resolveSecretRef } from \"./parsers/core.js\";\nimport {\n effectiveMaintenanceFallbackPolicy,\n filterMaintenanceTierFallbackModels,\n} from \"./maintenance-fallback-policy.js\";\n// LLM model utilities\nimport type { CronModelConfig, CronModelTier, HybridMemoryConfig } from \"./types/index.js\";\n\nexport {\n describeMaintenanceFallbackPolicy,\n effectiveMaintenanceFallbackPolicy,\n isExpensiveMaintenanceFallbackModel,\n} from \"./maintenance-fallback-policy.js\";\n\nconst OPENAI_NANO_CRON_MODEL = \"openai/gpt-4.1-nano\";\nconst OPENAI_DEFAULT_CRON_MODEL = \"openai/gpt-4.1-mini\";\nconst OPENAI_HEAVY_CRON_MODEL = \"openai/gpt-5.4\";\nconst GEMINI_NANO_MODEL = \"google/gemini-2.5-flash-lite\";\nconst GEMINI_DEFAULT_MODEL = \"google/gemini-2.5-flash\";\nconst GEMINI_HEAVY_MODEL = \"google/gemini-3.1-pro-preview\";\nconst CLAUDE_NANO_MODEL = \"anthropic/claude-haiku-4-5-20251001\";\nconst CLAUDE_DEFAULT_MODEL = \"anthropic/claude-sonnet-4-6\";\nconst CLAUDE_HEAVY_MODEL = \"anthropic/claude-opus-4-6\";\n\nfunction hasKey(apiKey: string | undefined): boolean {\n return typeof apiKey === \"string\" && apiKey.length >= 10;\n}\n\n/** True if apiKey is present and, for env:/file: SecretRefs, resolvable at runtime (verify / getProvidersWithKeys). */\nfunction hasEffectiveKey(apiKey: string | undefined): boolean {\n if (typeof apiKey !== \"string\" || !hasKey(apiKey)) return false;\n const k = apiKey.trim();\n if (k.startsWith(\"env:\") || k.startsWith(\"file:\")) return resolveSecretRef(k) !== undefined;\n return true;\n}\n\n/** Legacy single-model resolution (for backward compat when no llm config). Used only when no list is built. */\nfunction getDefaultCronModelLegacy(pluginConfig: CronModelConfig | undefined, tier: CronModelTier): string {\n if (!pluginConfig) {\n if (tier === \"heavy\") return OPENAI_HEAVY_CRON_MODEL;\n if (tier === \"nano\") return OPENAI_NANO_CRON_MODEL;\n return OPENAI_DEFAULT_CRON_MODEL;\n }\n if (hasKey(pluginConfig.distill?.apiKey)) {\n const defaultModel = pluginConfig.distill?.defaultModel?.trim();\n // If the user explicitly configured a defaultModel, respect it for all tiers.\n // Only fall back to provider-specific nano/heavy variants when no explicit model is set.\n // Users who want a specific cheap model for nano operations should configure llm.nano instead.\n if (defaultModel) return defaultModel;\n if (tier === \"heavy\") return GEMINI_HEAVY_MODEL;\n if (tier === \"nano\") return GEMINI_NANO_MODEL;\n return GEMINI_DEFAULT_MODEL;\n }\n if (hasKey(pluginConfig.claude?.apiKey)) {\n const defaultModel = pluginConfig.claude?.defaultModel?.trim();\n // Same: respect explicit defaultModel for all tiers; use nano variant only when unset.\n if (defaultModel) return defaultModel;\n if (tier === \"heavy\") return CLAUDE_HEAVY_MODEL;\n if (tier === \"nano\") return CLAUDE_NANO_MODEL;\n return CLAUDE_DEFAULT_MODEL;\n }\n if (hasKey(pluginConfig.embedding?.apiKey)) {\n if (tier === \"heavy\") return OPENAI_HEAVY_CRON_MODEL;\n if (tier === \"nano\") return OPENAI_NANO_CRON_MODEL;\n return OPENAI_DEFAULT_CRON_MODEL;\n }\n if (tier === \"heavy\") return OPENAI_HEAVY_CRON_MODEL;\n if (tier === \"nano\") return OPENAI_NANO_CRON_MODEL;\n return OPENAI_DEFAULT_CRON_MODEL;\n}\n\n/**\n * Preferred provider order for out-of-the-box failover: Research/Heavy favours Gemini (context), then OpenAI, then Claude.\n * Uses OpenClaw-style provider/model IDs so the gateway accepts them. First working model wins at runtime.\n */\nfunction getDefaultPreferredModelList(pluginConfig: CronModelConfig | undefined, tier: CronModelTier): string[] {\n if (!pluginConfig) {\n if (tier === \"heavy\") return [OPENAI_HEAVY_CRON_MODEL];\n if (tier === \"nano\") return [OPENAI_NANO_CRON_MODEL];\n return [OPENAI_DEFAULT_CRON_MODEL];\n }\n const list: string[] = [];\n if (hasKey(pluginConfig.distill?.apiKey)) {\n const m = pluginConfig.distill?.defaultModel?.trim();\n // Respect explicit defaultModel for all tiers; fall back to tier-specific defaults only when unset.\n list.push(\n m || (tier === \"nano\" ? GEMINI_NANO_MODEL : tier === \"heavy\" ? GEMINI_HEAVY_MODEL : GEMINI_DEFAULT_MODEL),\n );\n }\n if (hasKey(pluginConfig.embedding?.apiKey)) {\n if (tier === \"nano\") list.push(OPENAI_NANO_CRON_MODEL);\n else list.push(tier === \"heavy\" ? OPENAI_HEAVY_CRON_MODEL : OPENAI_DEFAULT_CRON_MODEL);\n }\n if (hasKey(pluginConfig.claude?.apiKey)) {\n const m = pluginConfig.claude?.defaultModel?.trim();\n // Respect explicit defaultModel for all tiers; fall back to tier-specific defaults only when unset.\n list.push(\n m || (tier === \"nano\" ? CLAUDE_NANO_MODEL : tier === \"heavy\" ? CLAUDE_HEAVY_MODEL : CLAUDE_DEFAULT_MODEL),\n );\n }\n if (list.length === 0) {\n list.push(getDefaultCronModelLegacy(pluginConfig, tier));\n }\n const distillFallbacks = pluginConfig.distill?.fallbackModels;\n if (Array.isArray(distillFallbacks)) {\n for (const m of distillFallbacks) {\n const t = typeof m === \"string\" ? m.trim() : \"\";\n if (t && !list.includes(t)) list.push(t);\n }\n }\n const fallback = pluginConfig.llm?.fallbackModel?.trim();\n if (fallback && !list.includes(fallback)) {\n list.push(fallback);\n }\n return list;\n}\n\n/**\n * Return ordered list of models to try for an LLM call.\n * - \"nano\": ultra-cheap for autoClassify, HyDE, classifyBeforeWrite, summarize. Falls back to \"default\" if llm.nano is unset.\n * - \"default\": HyDE, classify, reflection, general.\n * - \"heavy\": distill, self-correction, spawn.\n * First working model wins.\n */\nfunction getDisabledProviderSet(pluginConfig: CronModelConfig | undefined): Set<string> {\n const disabled = pluginConfig?.llm?.disabledProviders;\n if (!Array.isArray(disabled) || disabled.length === 0) return new Set();\n return new Set(disabled.map((p) => String(p).trim().toLowerCase()));\n}\n\n/**\n * Infer provider from model name.\n * Supports bare model names (e.g., gemini-2.5-flash -> google, claude-sonnet-4-6 -> anthropic, gpt-4 -> openai).\n */\nfunction inferProviderFromModel(model: string): string {\n if (model.includes(\"/\")) {\n return model.split(\"/\")[0].trim().toLowerCase();\n }\n const bare = model.trim().toLowerCase();\n if (bare.startsWith(\"gemini-\")) return \"google\";\n if (bare.startsWith(\"claude-\")) return \"anthropic\";\n if (bare.startsWith(\"gpt-\") || bare.match(/^o[0-9]/)) return \"openai\";\n return \"openai\";\n}\n\nfunction filterModelsByDisabled(models: string[], disabledSet: Set<string>): string[] {\n if (disabledSet.size === 0) return models;\n return models.filter((m) => {\n const prefix = inferProviderFromModel(m);\n return !disabledSet.has(prefix);\n });\n}\n\n/** Same as getLLMModelPreference but does not exclude disabledProviders. Use for verify table so disabled providers are still listed. */\nexport function getLLMModelPreferenceUnfiltered(\n pluginConfig: CronModelConfig | undefined,\n tier: CronModelTier,\n): string[] {\n if (tier === \"nano\") {\n const nanoList = pluginConfig?.llm?.nano;\n if (Array.isArray(nanoList) && nanoList.length > 0) {\n const trimmed = nanoList.map((m) => (typeof m === \"string\" ? m.trim() : \"\")).filter(Boolean);\n if (trimmed.length > 0) return trimmed;\n }\n return getLLMModelPreferenceUnfiltered(pluginConfig, \"default\");\n }\n if (tier === \"maintenance\") {\n const maintenanceList = pluginConfig?.llm?.maintenance;\n if (Array.isArray(maintenanceList) && maintenanceList.length > 0) {\n const trimmed = maintenanceList.map((m) => (typeof m === \"string\" ? m.trim() : \"\")).filter(Boolean);\n if (trimmed.length > 0) return trimmed;\n }\n return getLLMModelPreferenceUnfiltered(pluginConfig, \"default\");\n }\n const list = tier === \"heavy\" ? pluginConfig?.llm?.heavy : pluginConfig?.llm?.default;\n if (Array.isArray(list) && list.length > 0) {\n const trimmed = list.map((m) => (typeof m === \"string\" ? m.trim() : \"\")).filter(Boolean);\n if (trimmed.length > 0) {\n if (pluginConfig?.llm?.fallbackToDefault) {\n const fallback = pluginConfig.llm.fallbackModel?.trim();\n if (fallback && !trimmed.includes(fallback)) return [...trimmed, fallback];\n }\n return trimmed;\n }\n }\n return getDefaultPreferredModelList(pluginConfig, tier);\n}\n\nexport function getLLMModelPreference(pluginConfig: CronModelConfig | undefined, tier: CronModelTier): string[] {\n const disabledSet = getDisabledProviderSet(pluginConfig);\n const unfiltered = getLLMModelPreferenceUnfiltered(pluginConfig, tier);\n return filterModelsByDisabled(unfiltered, disabledSet);\n}\n\n/**\n * Report which providers have API keys (for verify/transparency).\n * Checks both legacy key fields (distill.apiKey → gemini, embedding.apiKey → openai)\n * and the new llm.providers map so all configured providers are shown.\n */\nexport function getProvidersWithKeys(pluginConfig: CronModelConfig | undefined): string[] {\n if (!pluginConfig) return [];\n const disabledSet = getDisabledProviderSet(pluginConfig);\n const seen = new Set<string>();\n const out: string[] = [];\n\n function add(name: string) {\n const lower = name.toLowerCase();\n if (disabledSet.has(lower)) return;\n if (!seen.has(lower)) {\n seen.add(lower);\n out.push(name);\n }\n }\n\n // Legacy / built-in key fields (resolve env:/file: so GOOGLE_API_KEY etc. count when set)\n if (hasEffectiveKey(pluginConfig.distill?.apiKey)) add(\"google\");\n if (hasEffectiveKey(pluginConfig.embedding?.apiKey)) add(\"openai\");\n if (hasEffectiveKey(pluginConfig.claude?.apiKey)) add(\"anthropic\");\n\n // llm.providers map — any provider with an explicit apiKey\n const providers = pluginConfig.llm?.providers;\n if (providers && typeof providers === \"object\") {\n for (const [prefix, pCfg] of Object.entries(providers)) {\n if (pCfg && hasEffectiveKey(pCfg.apiKey)) add(prefix);\n }\n }\n\n // Env fallbacks so providers show as configured when only env is set (e.g. GOOGLE_API_KEY)\n const googleKey = getEnv(\"GOOGLE_API_KEY\");\n if (!seen.has(\"google\") && typeof googleKey === \"string\" && googleKey.trim().length >= 10) {\n add(\"google\");\n }\n\n const anthropicKey = getEnv(\"ANTHROPIC_API_KEY\");\n if (!seen.has(\"anthropic\") && typeof anthropicKey === \"string\" && anthropicKey.trim().length >= 10) {\n add(\"anthropic\");\n }\n\n return out;\n}\n\n/**\n * Resolve which LLM model to use for a maintenance cron job based on user config.\n * When llm.default/heavy are set, returns the first model in the preference list (gateway-routed).\n * Otherwise legacy: prefer provider the user has configured (Gemini > Claude > OpenAI) > fallback.\n */\nexport function getDefaultCronModel(pluginConfig: CronModelConfig | undefined, tier: CronModelTier): string {\n const preferred = getLLMModelPreference(pluginConfig, tier);\n return preferred[0] ?? (tier === \"heavy\" ? OPENAI_HEAVY_CRON_MODEL : OPENAI_DEFAULT_CRON_MODEL);\n}\n\n/** Build minimal config for getDefaultCronModel from full HybridMemoryConfig (used by cron jobs and self-correction spawn). */\nexport function getCronModelConfig(cfg: HybridMemoryConfig): CronModelConfig {\n return {\n embedding: cfg.embedding,\n distill: cfg.distill,\n reflection: cfg.reflection,\n claude: (cfg as Record<string, unknown>).claude as CronModelConfig[\"claude\"],\n llm: cfg.llm,\n };\n}\n\nfunction appendUniqueFallback(chain: string[], candidate: string | undefined, primary: string): void {\n const t = candidate?.trim();\n if (!t || t === primary || chain.includes(t)) return;\n chain.push(t);\n}\n\nfunction appendUniqueFallbackList(chain: string[], candidates: string[] | undefined, primary: string): void {\n if (!Array.isArray(candidates)) return;\n for (const c of candidates) appendUniqueFallback(chain, c, primary);\n}\n\n/**\n * Resolve default model and fallback list for reflection/cron (default or heavy tier).\n * Single place for getCronModelConfig + getLLMModelPreference + cfg.llm fallback logic.\n *\n * When `llm.*` lists only one model for the tier, fallbacks are also taken from `llm.fallbackModel`\n * and `distill.fallbackModels` (de-duplicated). That way heavy crons using a single Responses API\n * model (e.g. azure-foundry/o3-pro) can still fail over without duplicating the whole preference list\n * (#1034).\n *\n * Maintenance tier (`tier === \"maintenance\"`): `llm.maintenanceFallbackPolicy` controls whether\n * expensive models are stripped from automatic fallbacks and whether global fallbacks are merged\n * when `llm.maintenance` is an explicit list (#1226). Unset policy defaults to `cheap-only`.\n */\nexport function resolveReflectionModelAndFallbacks(\n cfg: HybridMemoryConfig,\n tier: CronModelTier,\n primaryModelOverride?: string,\n): { defaultModel: string; fallbackModels: string[] | undefined } {\n const cronCfg = getCronModelConfig(cfg);\n const pref = getLLMModelPreference(cronCfg, tier);\n const defaultModel = pref[0] ?? (tier === \"heavy\" ? OPENAI_HEAVY_CRON_MODEL : OPENAI_DEFAULT_CRON_MODEL);\n\n let chain: string[] = pref.length > 1 ? pref.slice(1) : [];\n\n const maintPolicy = tier === \"maintenance\" ? effectiveMaintenanceFallbackPolicy(cfg) : null;\n const maintenanceArr = cfg.llm?.maintenance;\n const explicitMaintList = Array.isArray(maintenanceArr) ? maintenanceArr : [];\n const explicitMaintenance = explicitMaintList.length > 0;\n const explicitMaintenanceSet =\n tier === \"maintenance\" && explicitMaintenance\n ? new Set(explicitMaintList.map((m) => (typeof m === \"string\" ? m.trim() : \"\")).filter(Boolean))\n : undefined;\n\n if (tier === \"maintenance\" && maintPolicy === \"cheap-only\") {\n chain = filterMaintenanceTierFallbackModels(chain, defaultModel, explicitMaintenanceSet);\n }\n\n const skipGlobalFallbackAppend = tier === \"maintenance\" && maintPolicy === \"explicit-only\" && explicitMaintenance;\n\n if (!cfg.llm && chain.length === 0 && !skipGlobalFallbackAppend) {\n appendUniqueFallbackList(chain, cfg.distill?.fallbackModels, defaultModel);\n } else if (cfg.llm && chain.length === 0 && !skipGlobalFallbackAppend) {\n appendUniqueFallback(chain, cfg.llm.fallbackModel, defaultModel);\n appendUniqueFallbackList(chain, cfg.distill?.fallbackModels, defaultModel);\n }\n\n const primaryOverride = primaryModelOverride?.trim();\n const effectivePrimary = primaryOverride || defaultModel;\n if (primaryOverride) {\n appendUniqueFallback(chain, defaultModel, effectivePrimary);\n appendUniqueFallbackList(chain, pref, effectivePrimary);\n }\n\n if (tier === \"maintenance\" && maintPolicy === \"cheap-only\") {\n chain = filterMaintenanceTierFallbackModels(chain, effectivePrimary, explicitMaintenanceSet);\n }\n\n return { defaultModel, fallbackModels: chain.length > 0 ? chain : undefined };\n}\n"],"mappings":"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"}
|