akm-cli 0.9.0-rc.1 → 0.9.0-rc.13
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 +1190 -52
- package/README.md +62 -37
- package/SECURITY.md +46 -31
- package/dist/akm +162 -38
- package/dist/akm-migrate +44 -0
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/hints/cli-hints-full.md +268 -118
- package/dist/assets/hints/cli-hints-short.md +87 -24
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
- package/dist/assets/improve-strategies/frequent.json +15 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
- package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
- package/dist/assets/improve-strategies/reflect-distill.json +30 -0
- package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +5 -5
- package/dist/assets/prompts/extract-session.md +2 -6
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
- package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
- package/dist/assets/prompts/reflect-output-repair.md +3 -0
- package/dist/assets/stash-skeleton/README.md +38 -10
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
- package/dist/assets/tasks/core/extract.yml +3 -2
- package/dist/assets/tasks/core/improve.yml +2 -1
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +2 -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 +5 -4
- package/dist/assets/workflows/workflow-template.md +31 -15
- package/dist/cli/invocation.js +279 -0
- package/dist/cli/parse-args.js +5 -90
- package/dist/cli/retired-commands.js +78 -0
- package/dist/cli/shared.js +158 -48
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +747 -293
- package/dist/commands/agent/agent-dispatch.js +19 -18
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +43 -97
- package/dist/commands/completions.js +80 -23
- package/dist/commands/config-cli.js +44 -281
- package/dist/commands/env/env-binding.js +13 -9
- package/dist/commands/env/env-cli.js +76 -159
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +45 -61
- package/dist/commands/env/secret.js +32 -62
- package/dist/commands/feedback-cli.js +179 -85
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +7 -8
- package/dist/commands/health/checks.js +279 -94
- package/dist/commands/health/html-report.js +197 -578
- package/dist/commands/health/improve-metrics.js +277 -246
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +16 -7
- package/dist/commands/health/metrics.js +67 -32
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +508 -0
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +16 -56
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
- package/dist/commands/health/types-improve.js +29 -0
- package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
- package/dist/commands/health/types-result.js +7 -0
- package/dist/commands/health/types-runs.js +4 -0
- package/dist/commands/health/types-session-log.js +4 -0
- package/dist/commands/health/types-windows.js +4 -0
- package/dist/commands/health/types.js +26 -21
- package/dist/commands/health/windows.js +2 -3
- package/dist/commands/health.js +296 -167
- package/dist/commands/improve/anti-collapse.js +5 -5
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +65 -52
- package/dist/commands/improve/consolidate/chunking.js +9 -7
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +454 -1354
- package/dist/commands/improve/content-hash.js +39 -0
- package/dist/commands/improve/distill/content-repair.js +4 -10
- package/dist/commands/improve/distill/promote-memory.js +89 -64
- package/dist/commands/improve/distill/quality-gate.js +118 -42
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +33 -888
- package/dist/commands/improve/distill.js +607 -363
- package/dist/commands/improve/eligibility.js +165 -79
- package/dist/commands/improve/extract-cli.js +35 -126
- package/dist/commands/improve/extract-prompt.js +6 -35
- package/dist/commands/improve/extract.js +640 -391
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +134 -135
- package/dist/commands/improve/improve-result-file.js +30 -50
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +135 -0
- package/dist/commands/improve/improve.js +904 -701
- package/dist/commands/improve/locks.js +64 -111
- package/dist/commands/improve/loop-stages.js +1110 -923
- package/dist/commands/improve/memory/derived-ref.js +124 -0
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
- package/dist/commands/improve/memory/memory-improve.js +25 -37
- package/dist/commands/improve/outcome-loop.js +25 -88
- package/dist/commands/improve/preparation.js +1034 -813
- package/dist/commands/improve/proactive-maintenance.js +34 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +983 -794
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +24 -127
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -34
- package/dist/commands/improve/source-identity.js +28 -0
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +340 -313
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +185 -30
- package/dist/commands/{events.js → log.js} +28 -38
- package/dist/commands/migrate-cli.js +54 -0
- package/dist/commands/migration-tool.js +55 -0
- package/dist/commands/observability-cli.js +70 -208
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +91 -40
- package/dist/commands/proposal/proposal-cli.js +134 -132
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +83 -65
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +105 -88
- package/dist/commands/proposal/repository.js +1303 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
- package/dist/commands/proposal/validators/proposal-validators.js +61 -12
- package/dist/commands/proposal/validators/proposals.js +6 -8
- package/dist/commands/read/curate.js +78 -73
- package/dist/commands/read/knowledge.js +510 -13
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +84 -15
- package/dist/commands/read/search-cli.js +203 -96
- package/dist/commands/read/search.js +126 -94
- package/dist/commands/read/show.js +226 -250
- package/dist/commands/registry-cli.js +34 -60
- package/dist/commands/remember.js +18 -57
- package/dist/commands/sources/add-cli.js +104 -49
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +63 -0
- package/dist/commands/sources/info.js +27 -15
- package/dist/commands/sources/init.js +30 -40
- package/dist/commands/sources/installed-stashes.js +469 -172
- package/dist/commands/sources/schema-repair.js +10 -9
- package/dist/commands/sources/self-update.js +182 -121
- package/dist/commands/sources/source-add.js +169 -178
- package/dist/commands/sources/source-clone.js +144 -41
- package/dist/commands/sources/source-manage.js +94 -59
- package/dist/commands/sources/sources-cli.js +64 -205
- package/dist/commands/sources/stash-cli.js +91 -54
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/tasks-cli.js +106 -104
- package/dist/commands/tasks/tasks.js +445 -262
- package/dist/commands/workflow-cli.js +75 -228
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/activation-policy.js +49 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
- package/dist/core/adapter/adapters/akm-adapter.js +528 -0
- package/dist/core/adapter/adapters/akm-lint.js +392 -0
- package/dist/core/adapter/adapters/akm-metadata.js +387 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
- package/dist/core/adapter/adapters/claude-adapter.js +61 -0
- package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
- package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
- package/dist/core/adapter/adapters/okf-adapter.js +391 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
- package/dist/core/adapter/adapters/shared.js +286 -0
- package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +44 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/akm-markdown.js +30 -0
- package/dist/core/asset/asset-placement.js +243 -0
- package/dist/core/asset/asset-ref.js +110 -79
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +28 -12
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +274 -0
- package/dist/core/asset/stash-meta.js +2 -2
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +281 -86
- package/dist/core/config/config-io.js +42 -128
- package/dist/core/config/config-schema.js +233 -855
- package/dist/core/config/config-sources.js +162 -39
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +126 -37
- package/dist/core/config/config.js +154 -331
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +28 -0
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/experimental.js +47 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +389 -0
- package/dist/core/config/schema/improve.js +94 -0
- package/dist/core/config/schema/index-config.js +176 -0
- package/dist/core/config/schema/output.js +18 -0
- package/dist/core/config/schema/primitives.js +94 -0
- package/dist/core/config/schema/search.js +30 -0
- package/dist/core/config/schema/setup.js +18 -0
- package/dist/core/config/schema/sources-bundles.js +169 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +155 -20
- package/dist/core/errors.js +17 -15
- package/dist/core/events-types.js +4 -0
- package/dist/core/events.js +46 -128
- package/dist/core/extra-params.js +62 -0
- package/dist/core/file-change.js +17 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/fs-txn.js +392 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +167 -0
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +135 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/paths.js +22 -25
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +128 -0
- package/dist/core/redaction.js +392 -0
- package/dist/core/standards/resolve-standards-context.js +36 -65
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +5 -5
- package/dist/core/state/migrations.js +242 -11
- package/dist/core/state-db.js +98 -10
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +303 -0
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +834 -118
- package/dist/indexer/bundle-identity-guard.js +92 -0
- package/dist/indexer/db/graph-db.js +1 -25
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +30 -9
- package/dist/indexer/graph/graph-boost.js +9 -30
- package/dist/indexer/graph/graph-extraction.js +41 -27
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-writer-lock.js +93 -49
- package/dist/indexer/index-written-assets.js +100 -53
- package/dist/indexer/indexer.js +746 -329
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +142 -0
- package/dist/indexer/passes/dir-staleness.js +18 -10
- package/dist/indexer/passes/memory-inference.js +25 -15
- package/dist/indexer/passes/metadata.js +412 -243
- package/dist/indexer/scan/doc-to-entry.js +160 -0
- package/dist/indexer/scan/drain-dir.js +134 -0
- package/dist/indexer/search/db-search.js +292 -108
- package/dist/indexer/search/fts-query.js +64 -0
- package/dist/indexer/search/ranking-contributors.js +145 -25
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +28 -71
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-fields.js +18 -3
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +157 -111
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/usage-events.js +10 -30
- package/dist/indexer/walk/file-context.js +3 -45
- package/dist/indexer/walk/matchers.js +42 -73
- package/dist/indexer/walk/path-resolver.js +11 -5
- package/dist/indexer/walk/walker.js +42 -14
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -58
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +231 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +8 -3
- package/dist/integrations/agent/profiles.js +6 -99
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +78 -13
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +48 -279
- package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
- package/dist/integrations/harnesses/aider/index.js +2 -12
- package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
- package/dist/integrations/harnesses/amazonq/index.js +3 -17
- package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +1 -14
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
- package/dist/integrations/harnesses/codex/index.js +2 -13
- package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
- package/dist/integrations/harnesses/copilot/index.js +1 -13
- package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
- package/dist/integrations/harnesses/gemini/index.js +1 -13
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +31 -33
- package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +1 -18
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
- package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
- package/dist/integrations/harnesses/openhands/index.js +2 -12
- package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
- package/dist/integrations/harnesses/pi/index.js +3 -16
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +38 -34
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +24 -40
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +182 -110
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +21 -9
- package/dist/llm/feature-gate.js +17 -57
- package/dist/llm/graph-extract.js +12 -13
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +45 -30
- package/dist/llm/structured-call.js +16 -8
- package/dist/llm/usage-persist.js +30 -5
- package/dist/llm/usage-telemetry.js +59 -6
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/command-registry.js +27 -0
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +251 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +15 -281
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +58 -84
- package/dist/output/shapes/passthrough.js +8 -40
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/shapes.js +0 -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 +562 -0
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/helpers.js +15 -1375
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +202 -0
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +117 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +332 -0
- package/dist/output/text/workflow.js +1 -2
- package/dist/output/text.js +10 -19
- 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 +15 -25
- package/dist/registry/resolve.js +43 -94
- package/dist/registry/semver.js +43 -0
- package/dist/runtime.js +81 -12
- package/dist/scripts/akm-migrate.js +35529 -0
- package/dist/setup/detect.js +5 -7
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +100 -0
- package/dist/setup/registry-stash-loader.js +3 -3
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +444 -208
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +108 -305
- package/dist/setup/steps/platforms.js +13 -12
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +21 -15
- package/dist/setup/steps/stashdir.js +6 -4
- package/dist/setup/steps/tasks.js +236 -119
- package/dist/setup/steps.js +3 -2
- package/dist/sources/freshness.js +39 -0
- 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 +54 -56
- package/dist/sources/providers/git-stash.js +420 -91
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +47 -22
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +11 -10
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
- package/dist/storage/database.js +60 -4
- package/dist/storage/engines/sqlite-migrations.js +156 -5
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +51 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -32
- package/dist/storage/repositories/index-connection.js +79 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +863 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +167 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
- package/dist/storage/repositories/index-meta-repository.js +49 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +356 -0
- package/dist/storage/repositories/index-vec-repository.js +250 -0
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +317 -75
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +110 -3
- package/dist/storage/repositories/workflow-runs-repository.js +68 -35
- package/dist/tasks/backends/cron.js +169 -46
- package/dist/tasks/backends/exec-utils.js +76 -3
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +292 -55
- package/dist/tasks/backends/schtasks.js +557 -70
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +56 -38
- package/dist/tasks/parser.js +156 -64
- package/dist/tasks/resolve-akm-bin.js +144 -51
- package/dist/tasks/runner.js +377 -209
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +296 -0
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/task-id.js +35 -0
- package/dist/tasks/validator.js +30 -16
- package/dist/workflows/authoring/authoring.js +96 -148
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -20
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +25 -59
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +157 -94
- package/dist/workflows/exec/report.js +365 -200
- package/dist/workflows/exec/run-workflow.js +46 -40
- package/dist/workflows/exec/scheduler.js +12 -41
- package/dist/workflows/exec/step-work.js +239 -205
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/ir/compile.js +141 -283
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/plan-hash.js +40 -5
- package/dist/workflows/ir/schema.js +537 -1
- package/dist/workflows/parser.js +878 -306
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +99 -121
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +200 -113
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +4 -26
- package/dist/workflows/validator.js +52 -30
- package/docs/README.md +42 -78
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +9 -8
- package/docs/migration/release-notes/0.9.0.md +158 -14
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +844 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/data-and-telemetry.md +333 -0
- package/package.json +21 -17
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +4636 -0
- package/schemas/akm-task.json +87 -0
- package/{dist/schemas → schemas}/akm-workflow.json +127 -82
- package/dist/akm-migrate-storage +0 -38
- package/dist/assets/help/help-accept.md +0 -12
- package/dist/assets/help/help-improve.md +0 -84
- package/dist/assets/help/help-proposals.md +0 -17
- package/dist/assets/help/help-propose.md +0 -17
- package/dist/assets/help/help-reject.md +0 -11
- package/dist/assets/profiles/frequent.json +0 -13
- package/dist/assets/profiles/recombine-only.json +0 -21
- package/dist/assets/profiles/reflect-distill.json +0 -30
- package/dist/assets/profiles/synthesize.json +0 -15
- package/dist/assets/prompts/procedural-system.md +0 -44
- package/dist/assets/prompts/recombine-system.md +0 -40
- package/dist/assets/prompts/staleness-detect-system.md +0 -6
- package/dist/assets/tasks/core/backup.yml +0 -4
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/assets/templates/html/default.html +0 -78
- package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
- package/dist/assets/wiki/index-template.md +0 -12
- package/dist/assets/wiki/ingest-workflow-template.md +0 -83
- package/dist/assets/wiki/log-template.md +0 -8
- package/dist/assets/wiki/schema-template.md +0 -61
- package/dist/cli/config-migrate.js +0 -150
- package/dist/cli/config-validate.js +0 -39
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -487
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -276
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/commands/improve/procedural.js +0 -398
- package/dist/commands/improve/recombine.js +0 -818
- package/dist/commands/improve/schema-similarity-gate.js +0 -168
- package/dist/commands/lint/agent-linter.js +0 -44
- package/dist/commands/lint/command-linter.js +0 -44
- package/dist/commands/lint/default-linter.js +0 -16
- package/dist/commands/lint/fact-linter.js +0 -39
- package/dist/commands/lint/knowledge-linter.js +0 -16
- package/dist/commands/lint/memory-linter.js +0 -61
- package/dist/commands/lint/registry.js +0 -41
- package/dist/commands/lint/skill-linter.js +0 -45
- package/dist/commands/lint/task-linter.js +0 -50
- package/dist/commands/lint/workflow-linter.js +0 -81
- package/dist/commands/proposal/legacy-import.js +0 -115
- package/dist/commands/sources/history.js +0 -196
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/commands/wiki-cli.js +0 -292
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -316
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/core/eval/rank-metrics.js +0 -113
- package/dist/core/ripgrep/install.js +0 -163
- package/dist/core/ripgrep/resolve.js +0 -81
- package/dist/indexer/db/db.js +0 -1414
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
- package/dist/llm/call-ai.js +0 -62
- package/dist/llm/memory-infer-impl.js +0 -138
- 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/output/text/wiki.js +0 -16
- package/dist/registry/build-index.js +0 -386
- package/dist/schemas/akm-config.json +0 -14225
- package/dist/scripts/migrate-storage.js +0 -13169
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/setup/legacy-config.js +0 -106
- package/dist/storage/repositories/consolidation-repository.js +0 -38
- package/dist/storage/repositories/recombine-repository.js +0 -213
- package/dist/wiki/wiki-templates.js +0 -15
- package/dist/wiki/wiki.js +0 -1012
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/db.js +0 -350
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -760
- package/dist/workflows/program/project.js +0 -105
- package/docs/data-and-telemetry.md +0 -227
- package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
|
@@ -13,20 +13,29 @@ export { extractInlineRefMentions } from "./inline-refs.js";
|
|
|
13
13
|
// ([claude-code, opencode] — visible in e.g. `extract --auto` result order)
|
|
14
14
|
// is preserved deterministically, independent of HARNESS_REGISTRY declaration
|
|
15
15
|
// order (which is pinned for JSON-schema enum stability).
|
|
16
|
+
//
|
|
17
|
+
// WI-9.7 (H1): `SESSION_LOG_HARNESSES` is `HARNESS_REGISTRY` narrowed by the
|
|
18
|
+
// `isSessionLogHarness` type-predicate (see `../harnesses/types.ts`), so every
|
|
19
|
+
// element's `capabilities.sessionLogs` is the literal `true` and
|
|
20
|
+
// `sessionLogProvider` is a required (non-optional) field — a harness
|
|
21
|
+
// declaring `sessionLogs: true` without a provider is now a compile error at
|
|
22
|
+
// its `HARNESS_REGISTRY` entry, not a throw here. The load-time throw this
|
|
23
|
+
// used to guard (`h.sessionLogProvider?.()` returning undefined) is gone;
|
|
24
|
+
// `h.sessionLogProvider()` cannot be called with no provider to invoke.
|
|
16
25
|
const HARNESSES = [...SESSION_LOG_HARNESSES]
|
|
17
26
|
.sort((a, b) => a.id.localeCompare(b.id))
|
|
18
|
-
.map((h) =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
27
|
+
.map((h) => h.sessionLogProvider());
|
|
28
|
+
// Reverse invariant (kept from #562): every derived provider's runtime `name`
|
|
29
|
+
// — a plain string the provider implementation sets independently of the
|
|
30
|
+
// harness registry (e.g. `ClaudeCodeProvider`'s `"claude-code"`) — must
|
|
31
|
+
// resolve back, via the id-normalization bridge, to a registry harness whose
|
|
32
|
+
// `sessionLogs` capability is set. This is NOT expressible as a compile-time
|
|
33
|
+
// type constraint: `SessionLogHarness.name` is a runtime string with no
|
|
34
|
+
// static link to the `AkmHarness` that produced it, so a typo'd or
|
|
35
|
+
// stale `name` (e.g. copy-pasted from another provider, or renamed on one
|
|
36
|
+
// side only) would only ever surface as a wrong/silent lookup miss much later
|
|
37
|
+
// (health scans, `extract --auto` attribution) rather than here at load time.
|
|
38
|
+
// Kept as a runtime guard for that reason.
|
|
30
39
|
for (const provider of HARNESSES) {
|
|
31
40
|
const harness = getHarness(provider.name);
|
|
32
41
|
if (!harness?.capabilities.sessionLogs) {
|
|
@@ -41,22 +50,6 @@ const ERROR_PATTERNS = /error|failed|exception|cannot|undefined|null pointer|ENO
|
|
|
41
50
|
export function getAvailableHarnesses() {
|
|
42
51
|
return HARNESSES.filter((harness) => harness.isAvailable());
|
|
43
52
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Map each available harness to its `{ harnessName, roots }` watch target,
|
|
46
|
-
* skipping harnesses that expose no roots (absent `watchRoots()` or an empty
|
|
47
|
-
* result). This is the one stable entry point the watcher uses so it never
|
|
48
|
-
* reaches into providers directly.
|
|
49
|
-
*/
|
|
50
|
-
export function getWatchTargets() {
|
|
51
|
-
const targets = [];
|
|
52
|
-
for (const harness of getAvailableHarnesses()) {
|
|
53
|
-
const roots = harness.watchRoots?.() ?? [];
|
|
54
|
-
if (roots.length === 0)
|
|
55
|
-
continue;
|
|
56
|
-
targets.push({ harnessName: harness.name, roots });
|
|
57
|
-
}
|
|
58
|
-
return targets;
|
|
59
|
-
}
|
|
60
53
|
export function normalizeSessionTopic(text) {
|
|
61
54
|
const normalized = text.replace(/\s+/g, " ").trim().toLowerCase();
|
|
62
55
|
if (normalized.length < 10)
|
|
@@ -98,16 +91,13 @@ export function aggregateSessionEvents(events) {
|
|
|
98
91
|
* Collect normalized session events from a set of harnesses for the health
|
|
99
92
|
* candidate scan (#568).
|
|
100
93
|
*
|
|
101
|
-
* Pipeline selection per harness
|
|
102
|
-
* -
|
|
103
|
-
* richer `listSessions()` + `readSession()` pipeline. `readSession` flattens
|
|
94
|
+
* Pipeline selection per harness:
|
|
95
|
+
* - Drive the richer `listSessions()` + `readSession()` pipeline. `readSession` flattens
|
|
104
96
|
* structured content — tool calls, assistant content blocks, thinking,
|
|
105
97
|
* tool_result — into event text (e.g. ClaudeCodeProvider's `parseClaudeEvent`
|
|
106
98
|
* surfaces `[tool:*]` / `[tool_result]` blocks that the legacy flat
|
|
107
99
|
* `readEvents` scan drops entirely). This is what lets health advisories see
|
|
108
100
|
* repeated tool failures / long runs that the flat scan hid.
|
|
109
|
-
* - legacy-only harness (`supportsReadSession === false`): fall back to the
|
|
110
|
-
* legacy flat `readEvents()` scan (behaviour-preserving).
|
|
111
101
|
*
|
|
112
102
|
* Extracted as a pure function (harnesses injected) so it is unit-testable
|
|
113
103
|
* without touching the real on-disk session-log locations.
|
|
@@ -120,19 +110,13 @@ export function aggregateSessionEvents(events) {
|
|
|
120
110
|
* health command (`akm health`, which calls this synchronously) blow past its
|
|
121
111
|
* latency budget. `listSessions()` returns summaries sorted newest-first, so
|
|
122
112
|
* capping to the most-recent N sessions per harness keeps the richer signal
|
|
123
|
-
* for what actually matters (recent activity) while bounding cost.
|
|
124
|
-
* flat-scan path is naturally cheaper and is left uncapped.
|
|
113
|
+
* for what actually matters (recent activity) while bounding cost.
|
|
125
114
|
*/
|
|
126
115
|
const DEFAULT_MAX_SESSIONS_PER_HARNESS = 50;
|
|
127
116
|
export function collectSessionEvents(harnesses, sinceMs, maxSessionsPerHarness = DEFAULT_MAX_SESSIONS_PER_HARNESS) {
|
|
128
117
|
const events = [];
|
|
129
118
|
for (const harness of harnesses) {
|
|
130
119
|
try {
|
|
131
|
-
if (harness.supportsReadSession === false) {
|
|
132
|
-
// Legacy-only harness: only the flat event scan is available.
|
|
133
|
-
events.push(...harness.readEvents({ sinceMs }));
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
120
|
// Rich path: enumerate sessions cheaply, then read each one's full
|
|
137
121
|
// structured event stream. Falls back to readEvents if listSessions
|
|
138
122
|
// surfaces nothing (e.g. a harness that wired readSession but whose
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Shared skeleton for {@link SessionLogHarness} providers (§4.6 dedup).
|
|
6
|
+
*
|
|
7
|
+
* Holds only what the concrete providers genuinely share: safe stat'ing,
|
|
8
|
+
* recursive directory walking, the mtime-filtered file→summary listing loop,
|
|
9
|
+
* the flat JSONL/log line→event scan, and conditional-spread assembly of
|
|
10
|
+
* {@link SessionSummary} refs stamped with the provider's runtime name.
|
|
11
|
+
* Everything platform-specific — file layouts, metadata peeking, SQLite
|
|
12
|
+
* stores, message flattening — stays in the subclasses.
|
|
13
|
+
*/
|
|
14
|
+
import fs from "node:fs";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
export class AbstractSessionLogProvider {
|
|
17
|
+
isAvailable() {
|
|
18
|
+
return fs.existsSync(this.availabilityRoot());
|
|
19
|
+
}
|
|
20
|
+
/** `fs.statSync` that returns `undefined` instead of throwing. */
|
|
21
|
+
statSafe(target) {
|
|
22
|
+
try {
|
|
23
|
+
return fs.statSync(target);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Recursively yield files under `dir` whose basename passes `matches`. */
|
|
30
|
+
*walkFiles(dir, matches) {
|
|
31
|
+
try {
|
|
32
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
33
|
+
const full = path.join(dir, entry.name);
|
|
34
|
+
if (entry.isDirectory())
|
|
35
|
+
yield* this.walkFiles(full, matches);
|
|
36
|
+
else if (matches(entry.name))
|
|
37
|
+
yield full;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// permission errors etc.
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Assemble a {@link SessionSummary} stamped with this provider's name.
|
|
46
|
+
* Timestamps are included whenever defined (0 is valid); `projectHint` /
|
|
47
|
+
* `title` only when non-empty, so absent metadata stays absent.
|
|
48
|
+
*/
|
|
49
|
+
sessionRef(input) {
|
|
50
|
+
return {
|
|
51
|
+
harness: this.name,
|
|
52
|
+
sessionId: input.sessionId,
|
|
53
|
+
filePath: input.filePath,
|
|
54
|
+
...(input.startedAt !== undefined ? { startedAt: input.startedAt } : {}),
|
|
55
|
+
...(input.endedAt !== undefined ? { endedAt: input.endedAt } : {}),
|
|
56
|
+
...(input.projectHint ? { projectHint: input.projectHint } : {}),
|
|
57
|
+
...(input.title ? { title: input.title } : {}),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The shared listing loop: enumerate candidate session files, drop the
|
|
62
|
+
* unstat'able and the ones older than `sinceMs`, summarize the rest, and
|
|
63
|
+
* sort newest-ended first. An enumeration failure (root missing or
|
|
64
|
+
* unreadable) returns what was collected so far rather than throwing.
|
|
65
|
+
*/
|
|
66
|
+
listSessionsFromFiles(input) {
|
|
67
|
+
const summaries = [];
|
|
68
|
+
try {
|
|
69
|
+
for (const filePath of input.enumerate()) {
|
|
70
|
+
const stat = this.statSafe(filePath);
|
|
71
|
+
if (!stat)
|
|
72
|
+
continue;
|
|
73
|
+
if (stat.mtimeMs < input.sinceMs)
|
|
74
|
+
continue;
|
|
75
|
+
const summary = input.summarize(filePath, stat);
|
|
76
|
+
if (summary)
|
|
77
|
+
summaries.push(summary);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Root missing or unreadable — return what we have.
|
|
82
|
+
}
|
|
83
|
+
return summaries.sort((a, b) => (b.endedAt ?? 0) - (a.endedAt ?? 0));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The legacy flat line scan shared by both providers' `readEvents`: parse
|
|
87
|
+
* each line as JSON, pull text/session-id through the per-provider
|
|
88
|
+
* selectors, skip entries whose text is missing or under 10 chars, and
|
|
89
|
+
* fall back to the file mtime when the entry carries no numeric timestamp.
|
|
90
|
+
*/
|
|
91
|
+
*logLineEvents(input) {
|
|
92
|
+
for (const line of input.lines) {
|
|
93
|
+
try {
|
|
94
|
+
const entry = JSON.parse(line);
|
|
95
|
+
const text = input.selectText(entry);
|
|
96
|
+
if (typeof text !== "string" || text.length < 10)
|
|
97
|
+
continue;
|
|
98
|
+
const sessionId = input.selectSessionId(entry);
|
|
99
|
+
yield {
|
|
100
|
+
harness: this.name,
|
|
101
|
+
text,
|
|
102
|
+
ts: typeof entry?.timestamp === "number" ? entry.timestamp : input.fallbackTsMs,
|
|
103
|
+
sessionId: typeof sessionId === "string" ? sessionId : undefined,
|
|
104
|
+
role: typeof entry?.role === "string" ? entry.role : "unknown",
|
|
105
|
+
filePath: input.filePath,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// skip malformed lines
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
package/dist/llm/client.js
CHANGED
|
@@ -4,45 +4,34 @@
|
|
|
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
|
-
import {
|
|
12
|
+
import { formatExtraParamsIssue, validateExtraParams } from "../core/extra-params.js";
|
|
13
|
+
import { parseJsonResponse } from "../core/parse.js";
|
|
14
|
+
import { redactCredentialPatterns, redactSensitiveText } from "../core/redaction.js";
|
|
16
15
|
import { warnVerbose } from "../core/warn.js";
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
// to resolve `parseJsonResponse` and `parseEmbeddedJsonResponse` from this module.
|
|
20
|
-
export { escapeJsonStringControls, parseEmbeddedJsonResponse, parseJsonResponse, stripCodeFences, stripThinkBlocks, } from "../core/parse.js";
|
|
16
|
+
import { DEFAULT_LLM_TIMEOUT_MS } from "../integrations/agent/config.js";
|
|
17
|
+
import { emitLlmUsage, extractUsageTokens, } from "./usage-telemetry.js";
|
|
21
18
|
/** Maximum length of an LLM error response body included in thrown errors. */
|
|
22
19
|
const ERROR_BODY_MAX_LEN = 200;
|
|
20
|
+
/** Stable OpenAI-compatible response-schema name used for every structured call. */
|
|
21
|
+
const JSON_SCHEMA_RESPONSE_NAME = "akm_response";
|
|
23
22
|
/**
|
|
24
23
|
* Redact credential-shaped substrings from an upstream error body before
|
|
25
24
|
* including it in a thrown Error. The body is also trimmed to a fixed length
|
|
26
25
|
* so that a verbose provider response cannot leak large amounts of context.
|
|
27
26
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* - `key-…` / `key_…` shorthand keys
|
|
32
|
-
* - `"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.
|
|
33
30
|
*/
|
|
34
31
|
export function redactErrorBody(input) {
|
|
35
32
|
if (!input)
|
|
36
33
|
return "";
|
|
37
|
-
let out = input
|
|
38
|
-
// Bearer tokens (case-insensitive)
|
|
39
|
-
.replace(/\bBearer\s+[A-Za-z0-9._\-+/=]+/gi, "Bearer [REDACTED]")
|
|
40
|
-
// sk-/sk_ style keys
|
|
41
|
-
.replace(/\bsk[-_][A-Za-z0-9._-]{6,}/g, "[REDACTED]")
|
|
42
|
-
// key-/key_ shorthand keys
|
|
43
|
-
.replace(/\bkey[-_][A-Za-z0-9._-]{6,}/g, "[REDACTED]")
|
|
44
|
-
// JSON-style "api_key": "...", "apiKey": "...", "api-key": "..."
|
|
45
|
-
.replace(/("(?:api[_-]?key|apiKey|authorization|token)"\s*:\s*")([^"]*)(")/gi, "$1[REDACTED]$3");
|
|
34
|
+
let out = redactCredentialPatterns(input);
|
|
46
35
|
if (out.length > ERROR_BODY_MAX_LEN) {
|
|
47
36
|
out = `${out.slice(0, ERROR_BODY_MAX_LEN)}…`;
|
|
48
37
|
}
|
|
@@ -98,6 +87,19 @@ const RETRY_BUDGET_FRACTION = 0.9;
|
|
|
98
87
|
export function sleep(ms) {
|
|
99
88
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
100
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
|
+
}
|
|
101
103
|
/** Compute a uniform jittered backoff in the [200, 800)ms range. */
|
|
102
104
|
function retryBackoffMs() {
|
|
103
105
|
return RETRY_BACKOFF_MIN_MS + Math.random() * (RETRY_BACKOFF_MAX_MS - RETRY_BACKOFF_MIN_MS);
|
|
@@ -178,7 +180,11 @@ export async function chatCompletion(config, messages, options) {
|
|
|
178
180
|
return chatCompletionReal(config, messages, options);
|
|
179
181
|
}
|
|
180
182
|
async function chatCompletionReal(config, messages, options) {
|
|
181
|
-
const effectiveTimeoutMs = options
|
|
183
|
+
const effectiveTimeoutMs = options && Object.hasOwn(options, "timeoutMs")
|
|
184
|
+
? (options.timeoutMs ?? null)
|
|
185
|
+
: Object.hasOwn(config, "timeoutMs")
|
|
186
|
+
? (config.timeoutMs ?? null)
|
|
187
|
+
: DEFAULT_LLM_TIMEOUT_MS;
|
|
182
188
|
const started = Date.now();
|
|
183
189
|
try {
|
|
184
190
|
return await chatCompletionAttempt(config, messages, options, effectiveTimeoutMs);
|
|
@@ -189,8 +195,9 @@ async function chatCompletionReal(config, messages, options) {
|
|
|
189
195
|
// Timeout-budget guard: if the first attempt already burned most of the
|
|
190
196
|
// budget, a second attempt cannot complete — skip the retry.
|
|
191
197
|
const elapsed = Date.now() - started;
|
|
192
|
-
const remaining = effectiveTimeoutMs - elapsed;
|
|
193
|
-
if (
|
|
198
|
+
const remaining = effectiveTimeoutMs === null ? null : effectiveTimeoutMs - elapsed;
|
|
199
|
+
if (effectiveTimeoutMs !== null &&
|
|
200
|
+
(elapsed >= effectiveTimeoutMs * RETRY_BUDGET_FRACTION || (remaining !== null && remaining <= 0))) {
|
|
194
201
|
throw err;
|
|
195
202
|
}
|
|
196
203
|
// Signal the caller so it can bump `retryAttempts` (NOT `failureCount`).
|
|
@@ -199,7 +206,7 @@ async function chatCompletionReal(config, messages, options) {
|
|
|
199
206
|
// authoritative.
|
|
200
207
|
warnVerbose(`[akm] LLM transient failure (${err.code}); retrying once: ${err.message}`);
|
|
201
208
|
const wait = retryBackoffMs();
|
|
202
|
-
await (options?.sleep ?? sleep)
|
|
209
|
+
await waitForRetry(wait, options?.sleep ?? sleep, options?.signal);
|
|
203
210
|
// The retry must not exceed the original budget.
|
|
204
211
|
return await chatCompletionAttempt(config, messages, options, remaining);
|
|
205
212
|
}
|
|
@@ -210,6 +217,11 @@ async function chatCompletionReal(config, messages, options) {
|
|
|
210
217
|
* transient failures.
|
|
211
218
|
*/
|
|
212
219
|
async function chatCompletionAttempt(config, messages, options, timeoutMs) {
|
|
220
|
+
if (config.extraParams !== undefined) {
|
|
221
|
+
const issue = validateExtraParams(config.extraParams)[0];
|
|
222
|
+
if (issue)
|
|
223
|
+
throw new Error(formatExtraParamsIssue("LLM extraParams", issue));
|
|
224
|
+
}
|
|
213
225
|
const headers = { "Content-Type": "application/json" };
|
|
214
226
|
const resolvedKey = resolveSecret(config.apiKey);
|
|
215
227
|
if (resolvedKey) {
|
|
@@ -220,96 +232,142 @@ async function chatCompletionAttempt(config, messages, options, timeoutMs) {
|
|
|
220
232
|
// guess is wrong. Users who need a cap can set llm.maxTokens in config.
|
|
221
233
|
const resolvedMaxTokens = options?.maxTokens ?? config.maxTokens;
|
|
222
234
|
const responseFormat = options?.responseSchema && config.supportsJsonSchema
|
|
223
|
-
? {
|
|
235
|
+
? {
|
|
236
|
+
response_format: {
|
|
237
|
+
type: "json_schema",
|
|
238
|
+
json_schema: { name: JSON_SCHEMA_RESPONSE_NAME, schema: options.responseSchema, strict: true },
|
|
239
|
+
},
|
|
240
|
+
}
|
|
224
241
|
: {};
|
|
225
|
-
|
|
242
|
+
const resolvedEnableThinking = options?.enableThinking ?? config.enableThinking;
|
|
243
|
+
const thinkingParams = resolvedEnableThinking === undefined
|
|
244
|
+
? {}
|
|
245
|
+
: config.provider === "vllm"
|
|
246
|
+
? { chat_template_kwargs: { enable_thinking: resolvedEnableThinking } }
|
|
247
|
+
: { enable_thinking: resolvedEnableThinking };
|
|
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
|
|
226
258
|
// emitted duration covers the full request/response/parse cycle of a single
|
|
227
259
|
// attempt, not the retry-wrapping `chatCompletion`.
|
|
228
260
|
const requestStartedAt = Date.now();
|
|
229
|
-
|
|
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
|
+
};
|
|
230
267
|
try {
|
|
231
|
-
response
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
...(resolvedMaxTokens !== undefined ? { max_tokens: resolvedMaxTokens } : {}),
|
|
239
|
-
...responseFormat,
|
|
240
|
-
...(options?.enableThinking !== undefined
|
|
241
|
-
? { enable_thinking: options.enableThinking }
|
|
242
|
-
: config.enableThinking !== undefined
|
|
243
|
-
? { enable_thinking: config.enableThinking }
|
|
244
|
-
: {}),
|
|
245
|
-
...config.extraParams,
|
|
246
|
-
}),
|
|
247
|
-
}, timeoutMs, options?.signal);
|
|
248
|
-
}
|
|
249
|
-
catch (err) {
|
|
250
|
-
// fetchWithTimeout throws a plain Error with a message containing
|
|
251
|
-
// "timed out" for AbortController-driven timeouts, or "aborted" for
|
|
252
|
-
// caller-driven cancellations. Map both to typed LlmCallError.
|
|
253
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
254
|
-
if (err instanceof DOMException && err.name === "AbortError") {
|
|
255
|
-
throw new LlmCallError(`Request timed out 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);
|
|
256
275
|
}
|
|
257
|
-
|
|
258
|
-
|
|
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");
|
|
259
291
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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);
|
|
268
316
|
}
|
|
269
|
-
if
|
|
270
|
-
|
|
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
|
+
});
|
|
271
326
|
}
|
|
272
|
-
|
|
273
|
-
|
|
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;
|
|
274
334
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
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;
|
|
287
361
|
}
|
|
288
|
-
catch {
|
|
289
|
-
|
|
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;
|
|
290
370
|
}
|
|
291
|
-
// Per-call usage telemetry (#576). Best-effort and fully isolated: a missing
|
|
292
|
-
// or garbled usage block still records duration + model, and a throwing sink
|
|
293
|
-
// can never fail the call (emitLlmUsage swallows its own errors). The stage
|
|
294
|
-
// is supplied ambiently by emitLlmUsage; no `stage` param is threaded here.
|
|
295
|
-
emitLlmUsage({
|
|
296
|
-
model: typeof json.model === "string" && json.model ? json.model : config.model,
|
|
297
|
-
durationMs: Date.now() - requestStartedAt,
|
|
298
|
-
finishReason: typeof json.choices?.[0]?.finish_reason === "string" ? json.choices[0].finish_reason : undefined,
|
|
299
|
-
...extractUsageTokens(json.usage),
|
|
300
|
-
});
|
|
301
|
-
const content = (json.choices?.[0]?.message?.content ?? "").trim();
|
|
302
|
-
const reasoning = (json.choices?.[0]?.message?.reasoning_content ?? "").trim();
|
|
303
|
-
return content || reasoning;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Strip `<think>` blocks, code fences, and escape control characters in JSON
|
|
307
|
-
* strings. Thin wrapper kept for backward compatibility with call sites that
|
|
308
|
-
* import `stripJsonFences` from this module. New code should prefer the
|
|
309
|
-
* granular helpers from `../core/parse`.
|
|
310
|
-
*/
|
|
311
|
-
export function stripJsonFences(raw) {
|
|
312
|
-
return escapeJsonStringControls(stripCodeFences(stripThinkBlocks(raw)));
|
|
313
371
|
}
|
|
314
372
|
// ── Availability check ──────────────────────────────────────────────────────
|
|
315
373
|
/**
|
|
@@ -325,6 +383,16 @@ export async function isLlmAvailable(config) {
|
|
|
325
383
|
}
|
|
326
384
|
}
|
|
327
385
|
// ── Capability probe ────────────────────────────────────────────────────────
|
|
386
|
+
const CAPABILITY_PROBE_JSON_SCHEMA = {
|
|
387
|
+
type: "object",
|
|
388
|
+
properties: {
|
|
389
|
+
ok: { type: "boolean", const: true },
|
|
390
|
+
ingest: { type: "boolean", const: true },
|
|
391
|
+
lint: { type: "boolean", const: true },
|
|
392
|
+
},
|
|
393
|
+
required: ["ok", "ingest", "lint"],
|
|
394
|
+
additionalProperties: false,
|
|
395
|
+
};
|
|
328
396
|
/**
|
|
329
397
|
* Ask the model to emit a strict JSON object so we know whether the knowledge
|
|
330
398
|
* wiki ingest/lint flows can rely on structured output. Failure is non-fatal —
|
|
@@ -332,7 +400,7 @@ export async function isLlmAvailable(config) {
|
|
|
332
400
|
*/
|
|
333
401
|
export async function probeLlmCapabilities(config) {
|
|
334
402
|
try {
|
|
335
|
-
const raw = await chatCompletion(config, [
|
|
403
|
+
const raw = await chatCompletion({ ...config, supportsJsonSchema: true }, [
|
|
336
404
|
{
|
|
337
405
|
role: "system",
|
|
338
406
|
content: "You return only valid JSON. No prose, no markdown fences.",
|
|
@@ -341,13 +409,17 @@ export async function probeLlmCapabilities(config) {
|
|
|
341
409
|
role: "user",
|
|
342
410
|
content: 'Return exactly this JSON object and nothing else: {"ok": true, "ingest": true, "lint": true}',
|
|
343
411
|
},
|
|
344
|
-
], { maxTokens: 64, temperature: 0 });
|
|
412
|
+
], { maxTokens: 64, temperature: 0, responseSchema: CAPABILITY_PROBE_JSON_SCHEMA });
|
|
345
413
|
if (!raw)
|
|
346
414
|
return { reachable: false, structuredOutput: false, error: "empty response" };
|
|
347
415
|
const parsed = parseJsonResponse(raw);
|
|
348
416
|
return {
|
|
349
417
|
reachable: true,
|
|
350
|
-
structuredOutput: Boolean(parsed &&
|
|
418
|
+
structuredOutput: Boolean(parsed &&
|
|
419
|
+
Object.keys(parsed).length === 3 &&
|
|
420
|
+
parsed.ok === true &&
|
|
421
|
+
parsed.ingest === true &&
|
|
422
|
+
parsed.lint === true),
|
|
351
423
|
};
|
|
352
424
|
}
|
|
353
425
|
catch (err) {
|
|
@@ -49,7 +49,7 @@ export function deterministicEmbed(text, dim = DETERMINISTIC_EMBED_DIM) {
|
|
|
49
49
|
const idx = h % dim;
|
|
50
50
|
// Use a higher bit for the sign so it is independent of the bucket index.
|
|
51
51
|
const sign = (h >>> 16) & 1 ? 1 : -1;
|
|
52
|
-
vec[idx]
|
|
52
|
+
vec[idx] = vec[idx] + sign;
|
|
53
53
|
}
|
|
54
54
|
let norm = 0;
|
|
55
55
|
for (const v of vec)
|
|
@@ -61,6 +61,6 @@ export function deterministicEmbed(text, dim = DETERMINISTIC_EMBED_DIM) {
|
|
|
61
61
|
return vec;
|
|
62
62
|
}
|
|
63
63
|
for (let i = 0; i < dim; i++)
|
|
64
|
-
vec[i]
|
|
64
|
+
vec[i] = vec[i] / norm;
|
|
65
65
|
return vec;
|
|
66
66
|
}
|