akm-cli 0.9.0-rc.9 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1063 -44
- package/README.md +51 -25
- package/SECURITY.md +14 -1
- package/STABILITY.md +497 -0
- package/dist/akm +148 -35
- package/dist/{akm-migrate-storage → akm-migrate} +6 -9
- package/dist/assets/hints/cli-hints-full.md +223 -95
- package/dist/assets/hints/cli-hints-short.md +85 -22
- package/dist/assets/improve-strategies/default.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/stash-skeleton/README.md +6 -5
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
- package/dist/assets/tasks/core/extract.yml +1 -1
- package/dist/assets/tasks/core/version-check.yml +1 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +1 -3
- package/dist/assets/workflows/workflow-template.md +32 -15
- package/dist/cli/invocation.js +40 -15
- package/dist/cli/parse-args.js +0 -22
- package/dist/cli/retired-commands.js +121 -0
- package/dist/cli/shared.js +154 -22
- package/dist/cli/unknown-flags.js +236 -0
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +696 -258
- package/dist/commands/agent/agent-dispatch.js +14 -3
- package/dist/commands/agent/contribute-cli.js +73 -88
- package/dist/commands/completions.js +79 -22
- package/dist/commands/config-cli.js +17 -150
- package/dist/commands/env/env-cli.js +59 -143
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +36 -66
- package/dist/commands/env/secret.js +24 -57
- package/dist/commands/feedback-cli.js +141 -87
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +3 -4
- package/dist/commands/health/checks.js +85 -23
- package/dist/commands/health/html-report.js +7 -10
- package/dist/commands/health/improve-metrics.js +25 -83
- package/dist/commands/health/md-report.js +5 -9
- package/dist/commands/health/metrics.js +62 -20
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +4 -5
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +3 -48
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/commands/health/types-improve.js +7 -0
- package/dist/commands/health.js +99 -28
- package/dist/commands/improve/anti-collapse.js +2 -2
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +41 -40
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +140 -1000
- package/dist/commands/improve/distill/promote-memory.js +12 -12
- package/dist/commands/improve/distill/quality-gate.js +6 -6
- package/dist/commands/improve/distill.js +58 -69
- package/dist/commands/improve/eligibility.js +95 -55
- package/dist/commands/improve/extract-cli.js +14 -133
- package/dist/commands/improve/improve-cli.js +98 -114
- package/dist/commands/improve/improve-result-file.js +1 -28
- package/dist/commands/improve/improve-strategies.js +8 -5
- package/dist/commands/improve/improve.js +128 -91
- package/dist/commands/improve/loop-stages.js +182 -20
- package/dist/commands/improve/memory/derived-ref.js +45 -43
- package/dist/commands/improve/memory/memory-belief.js +1 -1
- package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
- package/dist/commands/improve/memory/memory-improve.js +6 -5
- package/dist/commands/improve/outcome-loop.js +22 -65
- package/dist/commands/improve/preparation.js +114 -123
- package/dist/commands/improve/proactive-maintenance.js +2 -5
- package/dist/commands/improve/reflect.js +56 -160
- package/dist/commands/improve/salience.js +11 -122
- package/dist/commands/improve/source-identity.js +10 -38
- package/dist/commands/lint/base-linter.js +20 -124
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +249 -43
- package/dist/commands/{events.js → log.js} +33 -38
- package/dist/commands/migrate-cli.js +92 -12
- package/dist/commands/migration-tool.js +46 -0
- package/dist/commands/observability-cli.js +70 -209
- package/dist/commands/proposal/drain.js +101 -29
- package/dist/commands/proposal/proposal-cli.js +76 -48
- package/dist/commands/proposal/proposal.js +54 -18
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +23 -15
- package/dist/commands/proposal/repository.js +701 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
- package/dist/commands/proposal/validators/proposal-validators.js +55 -7
- package/dist/commands/proposal/validators/proposals.js +4 -7
- package/dist/commands/read/curate.js +34 -53
- package/dist/commands/read/knowledge.js +150 -95
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +42 -15
- package/dist/commands/read/search-cli.js +180 -78
- package/dist/commands/read/search.js +58 -43
- package/dist/commands/read/show.js +197 -141
- package/dist/commands/registry-cli.js +12 -51
- package/dist/commands/remember.js +14 -57
- package/dist/commands/sources/add-cli.js +100 -31
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +7 -2
- package/dist/commands/sources/info.js +18 -5
- package/dist/commands/sources/init.js +12 -12
- package/dist/commands/sources/installed-stashes.js +382 -98
- package/dist/commands/sources/schema-repair.js +3 -2
- package/dist/commands/sources/self-update.js +131 -38
- package/dist/commands/sources/source-add.js +72 -17
- package/dist/commands/sources/source-clone.js +129 -45
- package/dist/commands/sources/source-manage.js +43 -23
- package/dist/commands/sources/sources-cli.js +57 -208
- package/dist/commands/sources/stash-cli.js +46 -53
- package/dist/commands/tasks/tasks-cli.js +91 -97
- package/dist/commands/tasks/tasks.js +276 -421
- package/dist/commands/workflow-cli.js +175 -450
- package/dist/core/adapter/adapters/akm-adapter.js +47 -28
- package/dist/core/adapter/adapters/akm-lint.js +42 -27
- package/dist/core/adapter/adapters/akm-metadata.js +15 -44
- package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
- package/dist/core/adapter/adapters/index.js +6 -6
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
- package/dist/core/adapter/adapters/okf-adapter.js +187 -19
- package/dist/core/adapter/adapters/shared.js +3 -19
- package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +6 -4
- package/dist/core/adapter/validate-context.js +214 -0
- package/dist/core/asset/akm-markdown.js +63 -0
- package/dist/core/asset/asset-placement.js +20 -6
- package/dist/core/asset/asset-ref.js +11 -9
- package/dist/core/asset/frontmatter-lint.js +30 -0
- package/dist/core/asset/frontmatter.js +25 -9
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +89 -18
- package/dist/core/asset/stash-meta.js +1 -1
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +152 -38
- package/dist/core/config/config-io.js +12 -1
- package/dist/core/config/config-schema.js +35 -8
- package/dist/core/config/config-sources.js +55 -11
- package/dist/core/config/config-walker.js +25 -9
- package/dist/core/config/config.js +9 -48
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +5 -1
- package/dist/core/config/schema/experimental.js +30 -0
- package/dist/core/config/schema/improve-processes.js +0 -6
- package/dist/core/config/schema/improve.js +21 -3
- package/dist/core/config/schema/index-config.js +8 -15
- package/dist/core/config/schema/output.js +4 -1
- package/dist/core/config/schema/setup.js +9 -18
- package/dist/core/config/schema/sources-bundles.js +49 -33
- package/dist/core/config/schema/workflow.js +3 -3
- package/dist/core/env-secret-ref.js +76 -46
- package/dist/core/errors.js +18 -12
- package/dist/core/events.js +46 -128
- package/dist/core/file-change.js +6 -5
- package/dist/core/fs-txn.js +83 -7
- package/dist/core/git-message.js +2 -2
- package/dist/core/improve-result.js +1 -100
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +2 -1
- package/dist/core/migration-operation.js +16 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/parse.js +4 -1
- package/dist/core/paths.js +17 -20
- package/dist/core/recognition-util.js +12 -14
- package/dist/core/redaction.js +34 -0
- package/dist/core/standards/resolve-standards-context.js +2 -14
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +2 -2
- package/dist/core/state/migrations.js +41 -18
- package/dist/core/state-db.js +5 -14
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +6 -4
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/type-presentation.js +3 -3
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +771 -95
- package/dist/indexer/bundle-identity-guard.js +3 -2
- package/dist/indexer/db/graph-db.js +0 -24
- package/dist/indexer/ensure-index.js +1 -0
- package/dist/indexer/graph/graph-boost.js +9 -34
- package/dist/indexer/graph/graph-extraction.js +8 -5
- package/dist/indexer/index-writer-lock.js +53 -17
- package/dist/indexer/index-written-assets.js +16 -22
- package/dist/indexer/indexer.js +497 -239
- package/dist/indexer/installations.js +14 -96
- package/dist/indexer/passes/dir-staleness.js +16 -9
- package/dist/indexer/passes/memory-inference.js +11 -9
- package/dist/indexer/passes/metadata.js +113 -47
- package/dist/indexer/scan/doc-to-entry.js +38 -1
- package/dist/indexer/scan/drain-dir.js +13 -23
- package/dist/indexer/search/db-search.js +99 -54
- package/dist/indexer/search/fts-query.js +47 -24
- package/dist/indexer/search/ranking-contributors.js +42 -20
- package/dist/indexer/search/ranking.js +18 -99
- package/dist/indexer/search/search-fields.js +7 -2
- package/dist/indexer/search/search-source.js +82 -93
- package/dist/indexer/usage/usage-events.js +0 -89
- package/dist/indexer/walk/file-context.js +2 -1
- package/dist/indexer/walk/matchers.js +30 -43
- package/dist/indexer/walk/path-resolver.js +7 -2
- package/dist/indexer/walk/walker.js +38 -12
- package/dist/integrations/agent/builders.js +0 -6
- package/dist/integrations/agent/config.js +2 -2
- package/dist/integrations/agent/detect.js +49 -19
- package/dist/integrations/agent/engine-fallback.js +76 -0
- package/dist/integrations/agent/profiles.js +14 -0
- package/dist/integrations/agent/prompts.js +12 -8
- package/dist/integrations/agent/runner-dispatch.js +4 -2
- package/dist/integrations/agent/runner.js +0 -1
- package/dist/integrations/agent/spawn.js +5 -6
- package/dist/integrations/github.js +1 -1
- package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
- package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
- package/dist/integrations/harnesses/claude/session-log.js +0 -10
- package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
- package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
- package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
- package/dist/integrations/harnesses/index.js +3 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
- package/dist/integrations/harnesses/opencode/session-log.js +0 -15
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
- package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
- package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
- package/dist/integrations/lockfile.js +88 -7
- package/dist/integrations/session-logs/index.js +3 -28
- package/dist/llm/client.js +136 -100
- package/dist/llm/embedders/remote.js +13 -5
- package/dist/llm/feature-gate.js +4 -12
- package/dist/llm/graph-extract.js +5 -11
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +5 -7
- package/dist/llm/structured-call.js +1 -1
- package/dist/llm/usage-persist.js +26 -5
- package/dist/llm/usage-telemetry.js +25 -2
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +259 -0
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -36
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +56 -83
- package/dist/output/shapes/migrate.js +8 -0
- package/dist/output/shapes/passthrough.js +7 -41
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes.js +2 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +164 -96
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/health-format.js +103 -0
- package/dist/output/text/health.js +7 -0
- package/dist/output/text/helpers.js +10 -8
- package/dist/output/text/lint-format.js +43 -0
- package/dist/output/text/{save.js → lint.js} +2 -2
- package/dist/output/text/migrate.js +88 -0
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +44 -72
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +15 -7
- package/dist/output/text/status-list.js +32 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +24 -203
- package/dist/output/text/workflow.js +1 -7
- package/dist/output/text.js +16 -17
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +13 -23
- package/dist/registry/resolve.js +42 -7
- package/dist/registry/semver.js +34 -84
- package/dist/runtime.js +2 -23
- package/dist/scripts/akm-migrate-node.js +60290 -0
- package/dist/scripts/akm-migrate.js +59628 -0
- package/dist/setup/detect.js +42 -15
- package/dist/setup/registry-stash-loader.js +2 -2
- package/dist/setup/setup.js +236 -136
- package/dist/setup/steps/connection.js +7 -9
- package/dist/setup/steps/platforms.js +9 -9
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +12 -13
- package/dist/setup/steps/stashdir.js +2 -3
- package/dist/setup/steps/tasks.js +237 -120
- package/dist/sources/freshness.js +1 -1
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +25 -23
- package/dist/sources/providers/git-stash.js +395 -106
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +7 -4
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +6 -1
- package/dist/sources/resolve.js +6 -5
- package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
- package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
- package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
- package/dist/sources/snapshot-fetchers/github.js +100 -0
- package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
- package/dist/sources/snapshot-fetchers/registry.js +17 -1
- package/dist/sources/snapshot-fetchers/robots.js +348 -0
- package/dist/sources/snapshot-fetchers/rss.js +282 -0
- package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
- package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
- package/dist/sources/snapshot-fetchers/x.js +910 -0
- package/dist/storage/database.js +7 -0
- package/dist/storage/engines/sqlite-migrations.js +23 -111
- package/dist/storage/managed-db.js +2 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +27 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -12
- package/dist/storage/repositories/index-connection.js +17 -6
- package/dist/storage/repositories/index-entries-repository.js +151 -240
- package/dist/storage/repositories/index-entry-mapper.js +15 -11
- package/dist/storage/repositories/index-fts-repository.js +5 -2
- package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
- package/dist/storage/repositories/index-meta-repository.js +2 -3
- package/dist/storage/repositories/index-schema.js +10 -25
- package/dist/storage/repositories/index-utility-repository.js +15 -28
- package/dist/storage/repositories/index-vec-repository.js +6 -1
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +296 -59
- package/dist/storage/repositories/registry-cache.js +19 -0
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +15 -13
- package/dist/storage/repositories/workflow-runs-repository.js +52 -40
- package/dist/tasks/backends/cron.js +105 -15
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +85 -38
- package/dist/tasks/backends/schtasks.js +135 -15
- package/dist/tasks/embedded.js +56 -40
- package/dist/tasks/parser.js +7 -157
- package/dist/tasks/resolve-akm-bin.js +137 -59
- package/dist/tasks/runner.js +79 -42
- package/dist/tasks/scheduler-invocation.js +220 -10
- package/dist/tasks/schema.js +24 -1
- package/dist/tasks/task-id.js +1 -3
- package/dist/tasks/validator.js +20 -6
- package/dist/workflows/authoring/authoring.js +94 -143
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/exec/frozen-judge.js +28 -2
- package/dist/workflows/exec/native-executor.js +77 -57
- package/dist/workflows/exec/param-secrets.js +9 -9
- package/dist/workflows/exec/run-workflow.js +133 -79
- package/dist/workflows/exec/step-work.js +219 -346
- package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
- package/dist/workflows/ir/compile.js +141 -270
- package/dist/workflows/ir/freeze.js +40 -30
- package/dist/workflows/ir/params.js +135 -11
- package/dist/workflows/ir/plan-hash.js +1 -1
- package/dist/workflows/ir/schema.js +25 -26
- package/dist/workflows/parser.js +872 -307
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +95 -68
- package/dist/workflows/resource-limits.js +2 -0
- package/dist/workflows/runtime/checkin.js +3 -3
- package/dist/workflows/runtime/plan-classifier.js +16 -75
- package/dist/workflows/runtime/runs.js +186 -127
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +2 -2
- package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +30 -36
- package/dist/workflows/validator.js +21 -62
- package/docs/README.md +68 -0
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.7.0.md +11 -11
- package/docs/migration/release-notes/0.9.0.md +208 -27
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +564 -208
- package/docs/migration/v0.9.0-troubleshooting.md +561 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/cli.md +2253 -0
- package/docs/reference/configuration.md +358 -0
- package/docs/reference/data-and-telemetry.md +105 -42
- package/docs/reference/workflows.md +647 -0
- package/package.json +22 -11
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +81 -128
- package/schemas/akm-workflow.json +74 -73
- package/dist/assets/tasks/core/backup.yml +0 -5
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/cli/config-migrate.js +0 -1878
- package/dist/cli/config-validate.js +0 -41
- package/dist/commands/backup-cli.js +0 -56
- package/dist/commands/bundle/bundle-cli.js +0 -68
- package/dist/commands/bundle/bundle.js +0 -219
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -489
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/mv-cli.js +0 -1221
- package/dist/commands/sources/history.js +0 -201
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/core/migration-backup.js +0 -1231
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/migrate/legacy/config-source-migration.js +0 -257
- package/dist/migrate/legacy/content-migration.js +0 -350
- package/dist/migrate/legacy/legacy-layout.js +0 -779
- package/dist/migrate/legacy/legacy-paths.js +0 -25
- package/dist/migrate/legacy/legacy-stash-json.js +0 -80
- package/dist/migrate/legacy/proposal-fs-import.js +0 -168
- package/dist/migrate/legacy/task-target-ref-migration.js +0 -278
- package/dist/migrate/legacy/three-db-cutover.js +0 -845
- package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
- package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
- package/dist/migrate/legacy-ref-grammar.js +0 -214
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/registry/build-index.js +0 -382
- package/dist/schemas/akm-config.json +0 -4704
- package/dist/schemas/akm-task.json +0 -87
- package/dist/schemas/akm-workflow.json +0 -372
- package/dist/scripts/migrate-storage.js +0 -3816
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/cli.js +0 -53
- package/dist/workflows/exec/brief.js +0 -481
- package/dist/workflows/exec/report.js +0 -1460
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -813
- package/dist/workflows/program/project.js +0 -104
package/dist/llm/client.js
CHANGED
|
@@ -4,23 +4,17 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* Low-level OpenAI-compatible chat completions client and capability probing.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* check) separate from higher-level metadata-enhancement workflows.
|
|
10
|
-
*
|
|
11
|
-
* `llm.ts` re-exports everything from this module for backward compatibility.
|
|
7
|
+
* Keeps transport-layer concerns (HTTP request, response parsing, capability
|
|
8
|
+
* probing, and availability checks) separate from higher-level workflows.
|
|
12
9
|
*/
|
|
13
|
-
import { fetchWithTimeout } from "../core/common.js";
|
|
10
|
+
import { fetchWithTimeout, readBodyWithByteCap } from "../core/common.js";
|
|
14
11
|
import { resolveSecret } from "../core/config/config.js";
|
|
15
12
|
import { formatExtraParamsIssue, validateExtraParams } from "../core/extra-params.js";
|
|
16
|
-
import {
|
|
17
|
-
import { redactSensitiveText } from "../core/redaction.js";
|
|
13
|
+
import { parseJsonResponse } from "../core/parse.js";
|
|
14
|
+
import { redactCredentialPatterns, redactSensitiveText } from "../core/redaction.js";
|
|
18
15
|
import { warnVerbose } from "../core/warn.js";
|
|
19
16
|
import { DEFAULT_LLM_TIMEOUT_MS } from "../integrations/agent/config.js";
|
|
20
|
-
import { emitLlmUsage, extractUsageTokens } from "./usage-telemetry.js";
|
|
21
|
-
// Re-export shared parse utilities so existing importers of `client.ts` continue
|
|
22
|
-
// to resolve `parseJsonResponse` and `parseEmbeddedJsonResponse` from this module.
|
|
23
|
-
export { escapeJsonStringControls, parseEmbeddedJsonResponse, parseJsonResponse, stripCodeFences, stripThinkBlocks, } from "../core/parse.js";
|
|
17
|
+
import { emitLlmUsage, extractUsageTokens, } from "./usage-telemetry.js";
|
|
24
18
|
/** Maximum length of an LLM error response body included in thrown errors. */
|
|
25
19
|
const ERROR_BODY_MAX_LEN = 200;
|
|
26
20
|
/** Stable OpenAI-compatible response-schema name used for every structured call. */
|
|
@@ -30,24 +24,14 @@ const JSON_SCHEMA_RESPONSE_NAME = "akm_response";
|
|
|
30
24
|
* including it in a thrown Error. The body is also trimmed to a fixed length
|
|
31
25
|
* so that a verbose provider response cannot leak large amounts of context.
|
|
32
26
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* - `key-…` / `key_…` shorthand keys
|
|
37
|
-
* - `"api_key": "…"` / `"apiKey": "…"` JSON fields
|
|
27
|
+
* The pattern set itself lives in {@link redactCredentialPatterns}
|
|
28
|
+
* (src/core/redaction.ts) so other output paths (e.g. task run logs) can
|
|
29
|
+
* reuse it without this function's length cap.
|
|
38
30
|
*/
|
|
39
31
|
export function redactErrorBody(input) {
|
|
40
32
|
if (!input)
|
|
41
33
|
return "";
|
|
42
|
-
let out = input
|
|
43
|
-
// Bearer tokens (case-insensitive)
|
|
44
|
-
.replace(/\bBearer\s+[A-Za-z0-9._\-+/=]+/gi, "Bearer [REDACTED]")
|
|
45
|
-
// sk-/sk_ style keys
|
|
46
|
-
.replace(/\bsk[-_][A-Za-z0-9._-]{6,}/g, "[REDACTED]")
|
|
47
|
-
// key-/key_ shorthand keys
|
|
48
|
-
.replace(/\bkey[-_][A-Za-z0-9._-]{6,}/g, "[REDACTED]")
|
|
49
|
-
// JSON-style "api_key": "...", "apiKey": "...", "api-key": "..."
|
|
50
|
-
.replace(/("(?:api[_-]?key|apiKey|authorization|token)"\s*:\s*")([^"]*)(")/gi, "$1[REDACTED]$3");
|
|
34
|
+
let out = redactCredentialPatterns(input);
|
|
51
35
|
if (out.length > ERROR_BODY_MAX_LEN) {
|
|
52
36
|
out = `${out.slice(0, ERROR_BODY_MAX_LEN)}…`;
|
|
53
37
|
}
|
|
@@ -103,6 +87,19 @@ const RETRY_BUDGET_FRACTION = 0.9;
|
|
|
103
87
|
export function sleep(ms) {
|
|
104
88
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
105
89
|
}
|
|
90
|
+
async function waitForRetry(ms, wait, signal) {
|
|
91
|
+
if (!signal)
|
|
92
|
+
return wait(ms);
|
|
93
|
+
if (signal.aborted)
|
|
94
|
+
throw new LlmCallError("LLM request aborted", "aborted");
|
|
95
|
+
await new Promise((resolve, reject) => {
|
|
96
|
+
const onAbort = () => reject(new LlmCallError("LLM request aborted", "aborted"));
|
|
97
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
98
|
+
wait(ms)
|
|
99
|
+
.then(resolve, reject)
|
|
100
|
+
.finally(() => signal.removeEventListener("abort", onAbort));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
106
103
|
/** Compute a uniform jittered backoff in the [200, 800)ms range. */
|
|
107
104
|
function retryBackoffMs() {
|
|
108
105
|
return RETRY_BACKOFF_MIN_MS + Math.random() * (RETRY_BACKOFF_MAX_MS - RETRY_BACKOFF_MIN_MS);
|
|
@@ -209,7 +206,7 @@ async function chatCompletionReal(config, messages, options) {
|
|
|
209
206
|
// authoritative.
|
|
210
207
|
warnVerbose(`[akm] LLM transient failure (${err.code}); retrying once: ${err.message}`);
|
|
211
208
|
const wait = retryBackoffMs();
|
|
212
|
-
await (options?.sleep ?? sleep)
|
|
209
|
+
await waitForRetry(wait, options?.sleep ?? sleep, options?.signal);
|
|
213
210
|
// The retry must not exceed the original budget.
|
|
214
211
|
return await chatCompletionAttempt(config, messages, options, remaining);
|
|
215
212
|
}
|
|
@@ -248,90 +245,129 @@ async function chatCompletionAttempt(config, messages, options, timeoutMs) {
|
|
|
248
245
|
: config.provider === "vllm"
|
|
249
246
|
? { chat_template_kwargs: { enable_thinking: resolvedEnableThinking } }
|
|
250
247
|
: { enable_thinking: resolvedEnableThinking };
|
|
251
|
-
|
|
248
|
+
const requestBody = JSON.stringify({
|
|
249
|
+
model: config.model,
|
|
250
|
+
messages,
|
|
251
|
+
temperature: options?.temperature ?? config.temperature ?? 0.3,
|
|
252
|
+
...(resolvedMaxTokens !== undefined ? { max_tokens: resolvedMaxTokens } : {}),
|
|
253
|
+
...responseFormat,
|
|
254
|
+
...thinkingParams,
|
|
255
|
+
...config.extraParams,
|
|
256
|
+
});
|
|
257
|
+
// Wall-clock start for per-attempt usage telemetry (#576). Captured here so the
|
|
252
258
|
// emitted duration covers the full request/response/parse cycle of a single
|
|
253
259
|
// attempt, not the retry-wrapping `chatCompletion`.
|
|
254
260
|
const requestStartedAt = Date.now();
|
|
255
|
-
|
|
261
|
+
const requestDeadlineAt = timeoutMs === null ? null : requestStartedAt + timeoutMs;
|
|
262
|
+
const remainingAttemptMs = () => requestDeadlineAt === null ? undefined : Math.max(0, requestDeadlineAt - Date.now());
|
|
263
|
+
let terminalFields = {
|
|
264
|
+
model: config.model,
|
|
265
|
+
modelSource: "configured",
|
|
266
|
+
};
|
|
256
267
|
try {
|
|
257
|
-
response
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
...(resolvedMaxTokens !== undefined ? { max_tokens: resolvedMaxTokens } : {}),
|
|
265
|
-
...responseFormat,
|
|
266
|
-
...thinkingParams,
|
|
267
|
-
...config.extraParams,
|
|
268
|
-
}),
|
|
269
|
-
}, timeoutMs, options?.signal);
|
|
270
|
-
}
|
|
271
|
-
catch (err) {
|
|
272
|
-
// fetchWithTimeout throws a plain Error with a message containing
|
|
273
|
-
// "timed out" for AbortController-driven timeouts, or "aborted" for
|
|
274
|
-
// caller-driven cancellations. Map both to typed LlmCallError.
|
|
275
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
276
|
-
if (err instanceof DOMException && err.name === "AbortError") {
|
|
277
|
-
throw new LlmCallError(`Request timed out${timeoutMs === null ? "" : ` after ${timeoutMs}ms`}`, "timeout");
|
|
268
|
+
let response;
|
|
269
|
+
try {
|
|
270
|
+
response = await fetchWithTimeout(config.endpoint, {
|
|
271
|
+
method: "POST",
|
|
272
|
+
headers,
|
|
273
|
+
body: requestBody,
|
|
274
|
+
}, timeoutMs, options?.signal);
|
|
278
275
|
}
|
|
279
|
-
|
|
280
|
-
|
|
276
|
+
catch (err) {
|
|
277
|
+
// fetchWithTimeout throws a plain Error with a message containing
|
|
278
|
+
// "timed out" for AbortController-driven timeouts, or "aborted" for
|
|
279
|
+
// caller-driven cancellations. Map both to typed LlmCallError.
|
|
280
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
281
|
+
if (options?.signal?.aborted || msg.includes("Request aborted")) {
|
|
282
|
+
throw new LlmCallError("LLM request aborted", "aborted");
|
|
283
|
+
}
|
|
284
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
285
|
+
throw new LlmCallError(`Request timed out${timeoutMs === null ? "" : ` after ${timeoutMs}ms`}`, "timeout");
|
|
286
|
+
}
|
|
287
|
+
if (msg.includes("timed out")) {
|
|
288
|
+
throw new LlmCallError(`Request timed out${timeoutMs === null ? "" : ` after ${timeoutMs}ms`}`, "timeout");
|
|
289
|
+
}
|
|
290
|
+
throw new LlmCallError(`Network error: ${msg}`, "network_error");
|
|
281
291
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
292
|
+
if (!response.ok) {
|
|
293
|
+
const rawBody = await readBodyWithByteCap(response, undefined, {
|
|
294
|
+
...(requestDeadlineAt === null ? {} : { bodyTimeoutMs: remainingAttemptMs() }),
|
|
295
|
+
signal: options?.signal,
|
|
296
|
+
}).catch((err) => {
|
|
297
|
+
if (options?.signal?.aborted)
|
|
298
|
+
throw new LlmCallError("LLM response read aborted", "aborted");
|
|
299
|
+
if (err instanceof Error && err.name === "BodyReadTimeoutError") {
|
|
300
|
+
throw new LlmCallError("LLM response body read timed out", "timeout");
|
|
301
|
+
}
|
|
302
|
+
return "";
|
|
303
|
+
});
|
|
304
|
+
const safeBody = redactSensitiveText(redactErrorBody(rawBody), resolvedKey ? [resolvedKey] : []);
|
|
305
|
+
const status = response.status;
|
|
306
|
+
if (status === 429) {
|
|
307
|
+
throw new LlmCallError(`LLM request rate limited (429) ${config.endpoint}: ${safeBody}`, "rate_limited", status);
|
|
308
|
+
}
|
|
309
|
+
if (status >= 500 && isHtmlResponse(rawBody)) {
|
|
310
|
+
throw new LlmCallError(`LLM provider returned HTML instead of JSON (${status}) ${config.endpoint}: ${redactSensitiveText(htmlExcerpt(rawBody), resolvedKey ? [resolvedKey] : [])}`, "provider_html_error", status);
|
|
311
|
+
}
|
|
312
|
+
if (status >= 500) {
|
|
313
|
+
throw new LlmCallError(`LLM provider error (${status}) ${config.endpoint}: ${safeBody}`, "provider_error", status);
|
|
314
|
+
}
|
|
315
|
+
throw new LlmCallError(`LLM request failed (${status}) ${config.endpoint}: ${safeBody}`, "provider_error", status);
|
|
290
316
|
}
|
|
291
|
-
if
|
|
292
|
-
|
|
317
|
+
// A 2xx response is still an error if the body is HTML where JSON was
|
|
318
|
+
// expected (e.g. a provider serving its web UI). Read the raw body first so
|
|
319
|
+
// we can categorize an HTML page distinctly from a malformed-JSON parse_error.
|
|
320
|
+
let rawOkBody;
|
|
321
|
+
try {
|
|
322
|
+
rawOkBody = await readBodyWithByteCap(response, undefined, {
|
|
323
|
+
...(requestDeadlineAt === null ? {} : { bodyTimeoutMs: remainingAttemptMs() }),
|
|
324
|
+
signal: options?.signal,
|
|
325
|
+
});
|
|
293
326
|
}
|
|
294
|
-
|
|
295
|
-
|
|
327
|
+
catch (err) {
|
|
328
|
+
if (options?.signal?.aborted)
|
|
329
|
+
throw new LlmCallError("LLM response read aborted", "aborted");
|
|
330
|
+
if (err instanceof Error && err.name === "BodyReadTimeoutError") {
|
|
331
|
+
throw new LlmCallError("LLM response body read timed out", "timeout");
|
|
332
|
+
}
|
|
333
|
+
throw err;
|
|
296
334
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
335
|
+
if (isHtmlResponse(rawOkBody)) {
|
|
336
|
+
throw new LlmCallError(`LLM provider returned HTML instead of JSON (${response.status}) ${config.endpoint}: ${redactSensitiveText(htmlExcerpt(rawOkBody), resolvedKey ? [resolvedKey] : [])}`, "provider_html_error", response.status);
|
|
337
|
+
}
|
|
338
|
+
let json;
|
|
339
|
+
try {
|
|
340
|
+
json = JSON.parse(rawOkBody);
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
throw new LlmCallError(`LLM response was not valid JSON ${config.endpoint}: ${redactSensitiveText(redactErrorBody(rawOkBody), resolvedKey ? [resolvedKey] : [])}`, "parse_error", response.status);
|
|
344
|
+
}
|
|
345
|
+
const responseModel = typeof json.model === "string" && json.model.trim().length > 0 ? json.model : undefined;
|
|
346
|
+
terminalFields = {
|
|
347
|
+
model: responseModel ?? config.model,
|
|
348
|
+
modelSource: responseModel === undefined ? "configured" : "response",
|
|
349
|
+
finishReason: typeof json.choices?.[0]?.finish_reason === "string" ? json.choices[0].finish_reason : undefined,
|
|
350
|
+
...extractUsageTokens(json.usage),
|
|
351
|
+
};
|
|
352
|
+
const content = (json.choices?.[0]?.message?.content ?? "").trim();
|
|
353
|
+
const reasoning = (json.choices?.[0]?.message?.reasoning_content ?? "").trim();
|
|
354
|
+
const result = redactSensitiveText(content || reasoning, resolvedKey ? [resolvedKey] : []);
|
|
355
|
+
emitLlmUsage({
|
|
356
|
+
...terminalFields,
|
|
357
|
+
outcome: "success",
|
|
358
|
+
durationMs: Date.now() - requestStartedAt,
|
|
359
|
+
});
|
|
360
|
+
return result;
|
|
309
361
|
}
|
|
310
|
-
catch {
|
|
311
|
-
|
|
362
|
+
catch (err) {
|
|
363
|
+
emitLlmUsage({
|
|
364
|
+
...terminalFields,
|
|
365
|
+
outcome: "error",
|
|
366
|
+
durationMs: Date.now() - requestStartedAt,
|
|
367
|
+
errorCode: err instanceof LlmCallError ? err.code : "unknown_error",
|
|
368
|
+
});
|
|
369
|
+
throw err;
|
|
312
370
|
}
|
|
313
|
-
// Per-call usage telemetry (#576). Best-effort and fully isolated: a missing
|
|
314
|
-
// or garbled usage block still records duration + model, and a throwing sink
|
|
315
|
-
// can never fail the call (emitLlmUsage swallows its own errors). The stage
|
|
316
|
-
// is supplied ambiently by emitLlmUsage; no `stage` param is threaded here.
|
|
317
|
-
emitLlmUsage({
|
|
318
|
-
model: typeof json.model === "string" && json.model ? json.model : config.model,
|
|
319
|
-
durationMs: Date.now() - requestStartedAt,
|
|
320
|
-
finishReason: typeof json.choices?.[0]?.finish_reason === "string" ? json.choices[0].finish_reason : undefined,
|
|
321
|
-
...extractUsageTokens(json.usage),
|
|
322
|
-
});
|
|
323
|
-
const content = (json.choices?.[0]?.message?.content ?? "").trim();
|
|
324
|
-
const reasoning = (json.choices?.[0]?.message?.reasoning_content ?? "").trim();
|
|
325
|
-
return redactSensitiveText(content || reasoning, resolvedKey ? [resolvedKey] : []);
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Strip `<think>` blocks, code fences, and escape control characters in JSON
|
|
329
|
-
* strings. Thin wrapper kept for backward compatibility with call sites that
|
|
330
|
-
* import `stripJsonFences` from this module. New code should prefer the
|
|
331
|
-
* granular helpers from `../core/parse`.
|
|
332
|
-
*/
|
|
333
|
-
export function stripJsonFences(raw) {
|
|
334
|
-
return escapeJsonStringControls(stripCodeFences(stripThinkBlocks(raw)));
|
|
335
371
|
}
|
|
336
372
|
// ── Availability check ──────────────────────────────────────────────────────
|
|
337
373
|
/**
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Calls the configured `/embeddings` endpoint and L2-normalizes the returned
|
|
8
8
|
* vectors so the scoring pipeline's L2-to-cosine conversion is correct.
|
|
9
9
|
*/
|
|
10
|
-
import { fetchWithTimeout, isHttpUrl } from "../../core/common.js";
|
|
10
|
+
import { fetchWithTimeout, isHttpUrl, readBodyWithByteCap } from "../../core/common.js";
|
|
11
11
|
import { resolveSecret } from "../../core/config/config.js";
|
|
12
12
|
const DEFAULT_REMOTE_BATCH_SIZE = 100;
|
|
13
13
|
/** Cheap token estimator: 4 chars ≈ 1 token. Used in verbose logging and error messages. */
|
|
@@ -49,10 +49,14 @@ export class RemoteEmbedder {
|
|
|
49
49
|
body: JSON.stringify(body),
|
|
50
50
|
}, 30_000, signal);
|
|
51
51
|
if (!response.ok) {
|
|
52
|
-
const errBody = await response
|
|
52
|
+
const errBody = await readBodyWithByteCap(response, undefined, { bodyTimeoutMs: 30_000, signal }).catch((err) => {
|
|
53
|
+
if (signal?.aborted)
|
|
54
|
+
throw err;
|
|
55
|
+
return "";
|
|
56
|
+
});
|
|
53
57
|
throw new Error(`Embedding request failed (${response.status}): ${errBody}`);
|
|
54
58
|
}
|
|
55
|
-
const json = (await response
|
|
59
|
+
const json = JSON.parse(await readBodyWithByteCap(response, undefined, { bodyTimeoutMs: 30_000, signal }));
|
|
56
60
|
if (!json.data?.[0]?.embedding) {
|
|
57
61
|
throw new Error(`Unexpected embedding response format: missing data[0].embedding.${embeddingEndpointPathHint(this.endpoint)}`);
|
|
58
62
|
}
|
|
@@ -85,10 +89,14 @@ export class RemoteEmbedder {
|
|
|
85
89
|
body: JSON.stringify(body),
|
|
86
90
|
}, 30_000, signal);
|
|
87
91
|
if (!response.ok) {
|
|
88
|
-
const respBody = await response
|
|
92
|
+
const respBody = await readBodyWithByteCap(response, undefined, { bodyTimeoutMs: 30_000, signal }).catch((err) => {
|
|
93
|
+
if (signal?.aborted)
|
|
94
|
+
throw err;
|
|
95
|
+
return "";
|
|
96
|
+
});
|
|
89
97
|
throw new Error(`Embedding batch request failed (${response.status}): ${respBody}`);
|
|
90
98
|
}
|
|
91
|
-
const json = (await response
|
|
99
|
+
const json = JSON.parse(await readBodyWithByteCap(response, undefined, { bodyTimeoutMs: 30_000, signal }));
|
|
92
100
|
if (!json.data || json.data.length !== batch.length) {
|
|
93
101
|
throw new Error(`Unexpected embedding batch response: expected ${batch.length} embeddings, got ${json.data?.length ?? 0}.${embeddingEndpointPathHint(this.endpoint)}`);
|
|
94
102
|
}
|
package/dist/llm/feature-gate.js
CHANGED
|
@@ -3,16 +3,11 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
5
|
* For each feature key, return the effective enabled state by reading the
|
|
6
|
-
* 0.9.0 config shape.
|
|
6
|
+
* 0.9.0 config shape.
|
|
7
7
|
*/
|
|
8
|
-
// Defaults below mirror the legacy LlmFeatureFlags docstrings so existing
|
|
9
|
-
// behaviour is preserved when a config is silent on a flag.
|
|
10
8
|
const FEATURE_LOCATION = {
|
|
11
|
-
// Legacy default: true
|
|
12
9
|
memory_inference: (cfg) => cfg.index?.memory?.enabled ?? true,
|
|
13
|
-
// Legacy default: true
|
|
14
10
|
graph_extraction: (cfg) => cfg.index?.graph?.enabled ?? true,
|
|
15
|
-
// Legacy default: false
|
|
16
11
|
metadata_enhance: (cfg) => cfg.index?.metadataEnhance?.enabled ?? false,
|
|
17
12
|
// Always on at the LLM-wrapper level. Enablement is decided ONCE at the
|
|
18
13
|
// extract entry point (`akmExtract`): the `extract.enabled` process toggle
|
|
@@ -26,8 +21,7 @@ const FEATURE_LOCATION = {
|
|
|
26
21
|
/**
|
|
27
22
|
* Pure predicate: is the named feature gate enabled in `config`?
|
|
28
23
|
*
|
|
29
|
-
* Reads from the unified 0.9.0 config shape.
|
|
30
|
-
* `LlmFeatureFlags` docstring defaults.
|
|
24
|
+
* Reads from the unified 0.9.0 config shape.
|
|
31
25
|
*/
|
|
32
26
|
export function isLlmFeatureEnabled(config, feature, improveEnabled) {
|
|
33
27
|
if (!config)
|
|
@@ -71,10 +65,8 @@ export async function tryLlmFeature(feature, config, fn, fallback, opts) {
|
|
|
71
65
|
}
|
|
72
66
|
}
|
|
73
67
|
/**
|
|
74
|
-
* Section-agnostic process gate
|
|
75
|
-
*
|
|
76
|
-
* call sites that knew the (section, processName) pair don't all need to
|
|
77
|
-
* relearn the new mapping.
|
|
68
|
+
* Section-agnostic process gate that maps process identifiers to their current
|
|
69
|
+
* config locations.
|
|
78
70
|
*
|
|
79
71
|
* For unknown (section, processName) pairs the result is `false`.
|
|
80
72
|
*/
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Given a single asset body (typically a `memory:` or `knowledge:` file),
|
|
8
8
|
* asks the configured LLM to surface the entities mentioned in it and the
|
|
9
9
|
* relations between them. The pass itself
|
|
10
|
-
* (`src/indexer/graph-extraction.ts`) is responsible for deciding which
|
|
10
|
+
* (`src/indexer/graph/graph-extraction.ts`) is responsible for deciding which
|
|
11
11
|
* files to extract, persisting the resulting nodes/edges to the index DB,
|
|
12
12
|
* and feeding the graph data into the FTS5+boosts
|
|
13
13
|
* search pipeline as a single boost component.
|
|
@@ -15,16 +15,15 @@
|
|
|
15
15
|
* This module is intentionally tiny and stateless so tests can stub it via
|
|
16
16
|
* `mock.module("../src/llm/graph-extract", ...)` without hitting a network.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* the connection via `resolveIndexPassLLM("graph", config)` and pass it
|
|
21
|
-
* straight through.
|
|
18
|
+
* The LLM connection comes from the selected named engine. Callers obtain it
|
|
19
|
+
* via `resolveIndexPassLLM("graph", config)` and pass it straight through.
|
|
22
20
|
*/
|
|
23
21
|
import systemPromptTemplate from "../assets/prompts/graph-extract-system.md" with { type: "text" };
|
|
24
22
|
import userPromptTemplate from "../assets/prompts/graph-extract-user-prompt.md" with { type: "text" };
|
|
25
23
|
import { toErrorMessage } from "../core/common.js";
|
|
24
|
+
import { parseEmbeddedJsonResponse } from "../core/parse.js";
|
|
26
25
|
import { warn, warnVerbose } from "../core/warn.js";
|
|
27
|
-
import { chatCompletion, isContextSizeError
|
|
26
|
+
import { chatCompletion, isContextSizeError } from "./client.js";
|
|
28
27
|
import { tryLlmFeature } from "./feature-gate.js";
|
|
29
28
|
import { callStructured } from "./structured-call.js";
|
|
30
29
|
/**
|
|
@@ -47,11 +46,6 @@ const SYSTEM_PROMPT = systemPromptTemplate;
|
|
|
47
46
|
const USER_PROMPT_PREFIX = userPromptTemplate
|
|
48
47
|
.replace("{{MAX_ENTITIES}}", String(MAX_ENTITIES_PER_ASSET))
|
|
49
48
|
.replace("{{MAX_RELATIONS}}", String(MAX_RELATIONS_PER_ASSET));
|
|
50
|
-
// `isContextSizeError` is defined in `./client` and re-exported here so the
|
|
51
|
-
// graph extractor and the retry classifier (`isRetryable`) share one
|
|
52
|
-
// definition (#496). Re-exported (not just imported) to preserve existing
|
|
53
|
-
// importers of this module — including its unit test.
|
|
54
|
-
export { isContextSizeError } from "./client.js";
|
|
55
49
|
const GENERIC_ENTITIES = new Set([
|
|
56
50
|
"agent",
|
|
57
51
|
"application",
|
package/dist/llm/memory-infer.js
CHANGED
|
@@ -1,4 +1,147 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* LLM helper for the `akm index` memory-inference pass (#201).
|
|
6
|
+
*
|
|
7
|
+
* Compresses a single memory body into one higher-signal derived memory. The
|
|
8
|
+
* pass itself (in `src/indexer/passes/memory-inference.ts`) is responsible for
|
|
9
|
+
* deciding which memories are pending, persisting the derived memory with the
|
|
10
|
+
* correct frontmatter (`inferred: true`, `source: <parent-ref>`), and marking
|
|
11
|
+
* the parent as processed for idempotency.
|
|
12
|
+
*
|
|
13
|
+
* This module is intentionally tiny and stateless so tests can stub it via
|
|
14
|
+
* `mock.module("../src/llm/memory-infer", ...)` without hitting a network.
|
|
15
|
+
*
|
|
16
|
+
* The LLM connection comes from the selected named engine. Callers obtain it
|
|
17
|
+
* via `resolveIndexPassLLM("memory", config)` and pass it straight through.
|
|
18
|
+
*/
|
|
19
|
+
import memoryInferSystemPrompt from "../assets/prompts/memory-infer-system.md" with { type: "text" };
|
|
20
|
+
import memoryInferUserPrompt from "../assets/prompts/memory-infer-user.md" with { type: "text" };
|
|
21
|
+
import { toErrorMessage } from "../core/common.js";
|
|
22
|
+
import { parseEmbeddedJsonResponse } from "../core/parse.js";
|
|
23
|
+
import { warn } from "../core/warn.js";
|
|
24
|
+
import { callStructured } from "./structured-call.js";
|
|
25
|
+
/** Hard cap on body chars sent to the model — pragmatic and matches `runLlmEnrich`. */
|
|
26
|
+
const MAX_BODY_CHARS = 4000;
|
|
27
|
+
const SYSTEM_PROMPT = memoryInferSystemPrompt;
|
|
28
|
+
const USER_PROMPT_PREFIX = memoryInferUserPrompt;
|
|
29
|
+
const PROMPT_PLACEHOLDERS = new Set([
|
|
30
|
+
"short title string",
|
|
31
|
+
"one sentence summary string",
|
|
32
|
+
"tag1",
|
|
33
|
+
"tag2",
|
|
34
|
+
"search phrase 1",
|
|
35
|
+
"search phrase 2",
|
|
36
|
+
"2-3 sentence compressed body preserving key facts verbatim",
|
|
37
|
+
]);
|
|
38
|
+
/**
|
|
39
|
+
* Strict JSON Schema for the derived-memory payload. Sent to providers that
|
|
40
|
+
* opt in via `ChatCompletionConfig.supportsJsonSchema = true`; the client
|
|
41
|
+
* silently drops the schema for providers that don't.
|
|
42
|
+
*
|
|
43
|
+
* Extends the responseSchema lift (PR 1, asset-writers-investigation §5) to
|
|
44
|
+
* the memory-inference path. Mirrors the validation gate below
|
|
45
|
+
* (title/description/content + non-empty tags/searchHints) so a
|
|
46
|
+
* schema-compliant response is guaranteed to pass the downstream check
|
|
47
|
+
* — no more "incomplete derived memory payload from LLM; skipping memory"
|
|
48
|
+
* for shape-only failures.
|
|
49
|
+
*/
|
|
50
|
+
const DERIVED_MEMORY_JSON_SCHEMA = {
|
|
51
|
+
type: "object",
|
|
52
|
+
properties: {
|
|
53
|
+
title: { type: "string", minLength: 1 },
|
|
54
|
+
description: { type: "string", minLength: 1 },
|
|
55
|
+
content: { type: "string", minLength: 1 },
|
|
56
|
+
tags: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 8 },
|
|
57
|
+
searchHints: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 6 },
|
|
58
|
+
},
|
|
59
|
+
required: ["title", "description", "content", "tags", "searchHints"],
|
|
60
|
+
additionalProperties: false,
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Compress a single memory body into one derived memory via the configured LLM.
|
|
64
|
+
*
|
|
65
|
+
* Returns `undefined` on any failure (timeout, invalid JSON, empty response).
|
|
66
|
+
* Errors are logged via `warn()` but never thrown — a failed split for one memory
|
|
67
|
+
* must not abort the rest of the index pass.
|
|
68
|
+
*
|
|
69
|
+
* Routes through `callStructured({ feature: "memory_inference", ... })` so the
|
|
70
|
+
* feature gate, error classification, and onFallback hook are honoured uniformly
|
|
71
|
+
* (Fix C5).
|
|
72
|
+
*/
|
|
73
|
+
export async function compressMemoryToDerivedMemory(llmConfig, body, signal, akmConfig, onFallback, telemetry, onRetryAttempt) {
|
|
74
|
+
const trimmedBody = body.trim();
|
|
75
|
+
if (!trimmedBody)
|
|
76
|
+
return undefined;
|
|
77
|
+
const userPrompt = `${USER_PROMPT_PREFIX}${trimmedBody.slice(0, MAX_BODY_CHARS)}`;
|
|
78
|
+
// Memory inference is always gated: no config closes the gate instead of
|
|
79
|
+
// taking callStructured's ungated path for direct callers.
|
|
80
|
+
if (!akmConfig) {
|
|
81
|
+
onFallback?.({ feature: "memory_inference", reason: "disabled" });
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
return callStructured({
|
|
85
|
+
feature: "memory_inference",
|
|
86
|
+
akmConfig,
|
|
87
|
+
config: llmConfig,
|
|
88
|
+
messages: [
|
|
89
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
90
|
+
{ role: "user", content: userPrompt },
|
|
91
|
+
],
|
|
92
|
+
request: {
|
|
93
|
+
temperature: 0.1,
|
|
94
|
+
timeoutMs: llmConfig.timeoutMs,
|
|
95
|
+
signal,
|
|
96
|
+
responseSchema: DERIVED_MEMORY_JSON_SCHEMA,
|
|
97
|
+
onRetryAttempt,
|
|
98
|
+
},
|
|
99
|
+
parse: (raw) => {
|
|
100
|
+
if (!raw)
|
|
101
|
+
return undefined;
|
|
102
|
+
const parsed = parseEmbeddedJsonResponse(raw);
|
|
103
|
+
if (!parsed) {
|
|
104
|
+
warn("memory inference: invalid JSON response from LLM; skipping memory.");
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const title = typeof parsed.title === "string" ? parsed.title.trim() : "";
|
|
108
|
+
const description = typeof parsed.description === "string" ? parsed.description.trim() : "";
|
|
109
|
+
const content = typeof parsed.content === "string" ? parsed.content.trim() : "";
|
|
110
|
+
const tags = Array.isArray(parsed.tags)
|
|
111
|
+
? parsed.tags
|
|
112
|
+
.filter((t) => typeof t === "string")
|
|
113
|
+
.map((t) => t.trim())
|
|
114
|
+
.filter(Boolean)
|
|
115
|
+
.slice(0, 8)
|
|
116
|
+
: [];
|
|
117
|
+
const searchHints = Array.isArray(parsed.searchHints)
|
|
118
|
+
? parsed.searchHints
|
|
119
|
+
.filter((h) => typeof h === "string")
|
|
120
|
+
.map((h) => h.trim())
|
|
121
|
+
.filter(Boolean)
|
|
122
|
+
.slice(0, 6)
|
|
123
|
+
: [];
|
|
124
|
+
if (!title || !description || !content || tags.length === 0 || searchHints.length === 0) {
|
|
125
|
+
warn("memory inference: incomplete derived memory payload from LLM; skipping memory.");
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
if ([title, description, content, ...tags, ...searchHints].some((value) => PROMPT_PLACEHOLDERS.has(value.toLowerCase()))) {
|
|
129
|
+
warn("memory inference: prompt placeholder response from LLM; skipping memory.");
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
return { title, description, tags, searchHints, content };
|
|
133
|
+
},
|
|
134
|
+
onError: (cls, err) => {
|
|
135
|
+
if (cls === "html") {
|
|
136
|
+
if (telemetry)
|
|
137
|
+
telemetry.htmlErrorCount = (telemetry.htmlErrorCount ?? 0) + 1;
|
|
138
|
+
warn(`memory inference: provider returned HTML instead of JSON; skipping memory: ${toErrorMessage(err)}`);
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
warn(`memory inference failed: ${toErrorMessage(err)}`);
|
|
142
|
+
return undefined;
|
|
143
|
+
},
|
|
144
|
+
fallback: undefined,
|
|
145
|
+
onFallback,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* LLM-driven metadata enhancement for stash entries.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* transport client in `client.ts`.
|
|
7
|
+
* Keeps the higher-level workflow for improving descriptions, tags, and search
|
|
8
|
+
* hints separate from the low-level transport client.
|
|
10
9
|
*/
|
|
11
10
|
import metadataEnhanceSystemPrompt from "../assets/prompts/metadata-enhance-system.md" with { type: "text" };
|
|
12
|
-
import { parseJsonResponse } from "
|
|
11
|
+
import { parseJsonResponse } from "../core/parse.js";
|
|
13
12
|
import { callStructured } from "./structured-call.js";
|
|
14
13
|
const SYSTEM_PROMPT = metadataEnhanceSystemPrompt;
|
|
15
14
|
/**
|
|
@@ -20,9 +19,8 @@ const SYSTEM_PROMPT = metadataEnhanceSystemPrompt;
|
|
|
20
19
|
* `tryLlmFeature("metadata_enhance", ...)` so the feature gate is honoured: a
|
|
21
20
|
* closed gate yields `{ status: "skipped" }` and a thrown/timed-out call yields
|
|
22
21
|
* `{ status: "failed" }` — neither is reported as an enrichment. When
|
|
23
|
-
* `akmConfig` is `undefined` the gate is bypassed entirely
|
|
24
|
-
* unconditionally and errors propagate to
|
|
25
|
-
* by direct callers such as tests).
|
|
22
|
+
* `akmConfig` is `undefined` the gate is bypassed entirely: the LLM call runs
|
|
23
|
+
* unconditionally and errors propagate to direct callers such as tests.
|
|
26
24
|
*/
|
|
27
25
|
export async function enhanceMetadata(config, entry, fileContent, signal, akmConfig) {
|
|
28
26
|
const contextParts = [`Name: ${entry.name}`, `Type: ${entry.type}`];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import { chatCompletion, isContextSizeError, LlmCallError } from "./client.js";
|
|
4
|
+
import { chatCompletion, isContextSizeError, LlmCallError, } from "./client.js";
|
|
5
5
|
import { tryLlmFeature } from "./feature-gate.js";
|
|
6
6
|
/**
|
|
7
7
|
* Classify a thrown LLM error into one of the three buckets. This is the single
|