akm-cli 0.10.261012-beta → 0.10.261014-beta
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 +710 -3
- package/README.md +15 -0
- package/SECURITY.md +11 -10
- package/STABILITY.md +47 -51
- package/dist/assets/hints/cli-hints-full.md +21 -19
- package/dist/assets/hints/cli-hints-short.md +3 -4
- package/dist/assets/opencode/akm-plugin.js +177 -0
- package/dist/assets/stash-skeleton/README.md +1 -1
- package/dist/assets/tasks/core/improve.yml +1 -1
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
- package/dist/assets/ui/config.js +27 -10
- package/dist/assets/workflows/workflow-template.md +2 -2
- package/dist/cli/clack.js +3 -1
- package/dist/cli/selection.js +33 -0
- package/dist/cli/shared.js +14 -1
- package/dist/cli/unknown-flags.js +6 -37
- package/dist/cli.js +69 -48
- package/dist/commands/agent/agent-dispatch.js +17 -25
- package/dist/commands/agent/contribute-cli.js +9 -8
- package/dist/commands/command/command-cli.js +4 -8
- package/dist/commands/command/command-execution.js +25 -39
- package/dist/commands/command/execution-source-loader.js +10 -14
- package/dist/commands/completions.js +1 -1
- package/dist/commands/config-cli.js +14 -5
- package/dist/commands/env/child-env.js +12 -14
- package/dist/commands/env/env-binding.js +47 -58
- package/dist/commands/env/env-cli.js +22 -24
- package/dist/commands/env/env.js +10 -58
- package/dist/commands/env/secret-cli.js +11 -29
- package/dist/commands/env/secret.js +3 -10
- package/dist/commands/health/checks.js +10 -849
- package/dist/commands/health/connections-and-harnesses-check.js +109 -0
- package/dist/commands/health/egress.js +3 -3
- package/dist/commands/health/html-report.js +9 -10
- package/dist/commands/health/plugin-staleness.js +18 -11
- package/dist/commands/health/report-view-model.js +16 -12
- package/dist/commands/health/scheduler-binary.js +1 -1
- package/dist/commands/health/semantic-search-check.js +85 -0
- package/dist/commands/health/type-directory-check.js +0 -3
- package/dist/commands/health.js +30 -42
- package/dist/commands/improve/consolidate/pair-pass.js +10 -25
- package/dist/commands/improve/consolidate.js +10 -15
- package/dist/commands/improve/distill.js +5 -17
- package/dist/commands/improve/eligibility.js +1 -3
- package/dist/commands/improve/execution.js +37 -40
- package/dist/commands/improve/extract-cli.js +6 -11
- package/dist/commands/improve/extract-prompt.js +2 -2
- package/dist/commands/improve/extract.js +67 -97
- package/dist/commands/improve/improve-cli.js +22 -128
- package/dist/commands/improve/improve-report.js +1 -1
- package/dist/commands/improve/improve-strategies.js +25 -108
- package/dist/commands/improve/improve.js +10 -14
- package/dist/commands/improve/loop-stages.js +3 -0
- package/dist/commands/improve/memory/memory-improve.js +1 -1
- package/dist/commands/improve/preparation.js +8 -13
- package/dist/commands/improve/reflect.js +203 -332
- package/dist/commands/improve/retrieval-scope.js +1 -1
- package/dist/commands/improve/session-asset.js +3 -2
- package/dist/commands/improve/stage.js +87 -115
- package/dist/commands/lint/base-linter.js +3 -3
- package/dist/commands/lint/env-key-rules.js +7 -6
- package/dist/commands/lint/index.js +3 -3
- package/dist/commands/models-cli.js +103 -63
- package/dist/commands/proposal/drain.js +26 -39
- package/dist/commands/proposal/proposal-cli.js +14 -18
- package/dist/commands/proposal/propose-cli.js +4 -2
- package/dist/commands/proposal/propose.js +37 -64
- package/dist/commands/proposal/repository.js +17 -17
- package/dist/commands/proposal/validators/proposal-validators.js +3 -6
- package/dist/commands/read/curate.js +10 -6
- package/dist/commands/read/registry-search.js +2 -48
- package/dist/commands/read/search-cli.js +1 -8
- package/dist/commands/read/search.js +5 -6
- package/dist/commands/read/show.js +6 -29
- package/dist/commands/remember.js +25 -40
- package/dist/commands/sources/add-cli.js +8 -63
- package/dist/commands/sources/bundle-cli.js +8 -9
- package/dist/commands/sources/bundle-config-ops.js +2 -2
- package/dist/commands/sources/info.js +12 -1
- package/dist/commands/sources/init.js +1 -1
- package/dist/commands/sources/installed-stashes.js +119 -63
- package/dist/commands/sources/migration-help.js +1 -1
- package/dist/commands/sources/plugin-upgrade.js +8 -15
- package/dist/commands/sources/schema-repair.js +4 -10
- package/dist/commands/sources/source-add.js +2 -2
- package/dist/commands/sources/source-clone.js +31 -7
- package/dist/commands/sources/source-manage.js +4 -4
- package/dist/commands/targets.js +175 -0
- package/dist/commands/tasks/explain.js +104 -69
- package/dist/commands/tasks/tasks-cli.js +9 -11
- package/dist/commands/tasks/tasks.js +75 -97
- package/dist/commands/ui/api.js +11 -3
- package/dist/commands/ui/redact.js +5 -31
- package/dist/commands/ui/workspace-actions.js +1 -1
- package/dist/commands/workflow/plan.js +48 -9
- package/dist/commands/workflow-cli.js +40 -45
- package/dist/core/adapter/adapters/agent-skills-adapter.js +10 -11
- package/dist/core/adapter/adapters/akm-adapter.js +36 -41
- package/dist/core/adapter/adapters/akm-lint.js +10 -12
- package/dist/core/adapter/adapters/akm-metadata.js +2 -2
- package/dist/core/adapter/adapters/akm-task-adapter.js +8 -9
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +5 -5
- package/dist/core/adapter/adapters/claude-adapter.js +1 -1
- package/dist/core/adapter/adapters/dotenv-adapter.js +7 -6
- package/dist/core/adapter/adapters/generic-files-adapter.js +5 -5
- package/dist/core/adapter/adapters/index.js +3 -4
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +12 -14
- package/dist/core/adapter/adapters/okf-adapter.js +8 -10
- package/dist/core/adapter/adapters/opencode-adapter.js +1 -1
- package/dist/core/adapter/adapters/shared.js +3 -3
- package/dist/core/adapter/adapters/tool-dir-shared.js +7 -25
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +3 -3
- package/dist/core/adapter/detect-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +13 -35
- package/dist/core/adapter/registry.js +1 -1
- package/dist/core/adapter/validate-context.js +2 -4
- package/dist/core/asset/asset-placement.js +1 -1
- package/dist/core/asset/asset-ref.js +3 -3
- package/dist/core/asset/resolve-ref.js +5 -0
- package/dist/core/bundle-rename.js +12 -4
- package/dist/core/closest-match.js +37 -0
- package/dist/core/common.js +37 -57
- package/dist/core/config/config-io.js +26 -18
- package/dist/core/config/config-schema.js +19 -106
- package/dist/core/config/config-sources.js +3 -3
- package/dist/core/config/config-types.js +4 -4
- package/dist/core/config/config-walker.js +50 -77
- package/dist/core/config/config.js +438 -109
- package/dist/core/config/convert-engine-references.js +114 -0
- package/dist/core/config/convert-engines-shared.js +40 -0
- package/dist/core/config/convert-engines.js +300 -0
- package/dist/core/config/convert-models-overlay.js +137 -0
- package/dist/core/config/credentials.js +304 -0
- package/dist/core/config/engine-semantics.js +3 -3
- package/dist/core/config/migrate-keys.js +222 -0
- package/dist/core/config/model-aliases.js +37 -0
- package/dist/core/config/models-file.js +34 -0
- package/dist/core/config/retired-engines.js +53 -0
- package/dist/core/config/schema/connections.js +41 -0
- package/dist/core/config/schema/embedding.js +2 -2
- package/dist/core/config/schema/harnesses.js +41 -0
- package/dist/core/config/schema/improve-processes.js +9 -28
- package/dist/core/config/schema/improve.js +36 -1
- package/dist/core/config/schema/index-config.js +18 -20
- package/dist/core/config/schema/primitives.js +42 -17
- package/dist/core/config/schema/search.js +6 -11
- package/dist/core/config/schema/sources-bundles.js +9 -9
- package/dist/core/config/schema/workflow.js +2 -6
- package/dist/core/config/unusable-entries.js +66 -0
- package/dist/core/content-safety.js +3 -6
- package/dist/core/endpoint-url.js +47 -0
- package/dist/core/env-secret-ref.js +84 -73
- package/dist/core/errors.js +10 -16
- package/dist/core/extra-params.js +3 -3
- package/dist/core/improve-result.js +8 -9
- package/dist/core/json-schema.js +1 -1
- package/dist/core/lesson-lint.js +1 -1
- package/dist/core/llm-inference.js +80 -0
- package/dist/core/parse.js +2 -2
- package/dist/core/paths.js +33 -10
- package/dist/core/recognition-util.js +8 -10
- package/dist/core/redaction.js +94 -55
- package/dist/core/ref-token.js +82 -0
- package/dist/core/secret-value.js +14 -0
- package/dist/core/state/migrations.js +17 -22
- package/dist/core/structured.js +2 -68
- package/dist/core/subprocess.js +63 -22
- package/dist/core/type-presentation.js +10 -14
- package/dist/core/write-source.js +20 -4
- package/dist/execution/input-contract.js +3 -6
- package/dist/execution/notices.js +49 -0
- package/dist/execution/resolved-request.js +24 -40
- package/dist/execution/source.js +21 -45
- package/dist/execution/target-ref.js +2 -2
- package/dist/indexer/bundle-identity-guard.js +6 -5
- package/dist/indexer/ensure-index.js +1 -1
- package/dist/indexer/index-writer-lock.js +1 -1
- package/dist/indexer/indexer.js +46 -42
- package/dist/indexer/installations.js +12 -22
- package/dist/indexer/lookup/adapter-concept-owner.js +40 -14
- package/dist/indexer/materialize-embeddings.js +20 -16
- package/dist/indexer/passes/memory-inference.js +21 -50
- package/dist/indexer/passes/metadata.js +5 -5
- package/dist/indexer/scan/doc-to-entry.js +1 -1
- package/dist/indexer/scan/drain-dir.js +9 -11
- package/dist/indexer/search/db-search.js +9 -7
- package/dist/indexer/search/search-source.js +42 -22
- package/dist/indexer/usage/usage-events.js +2 -3
- package/dist/indexer/walk/index-context.js +2 -1
- package/dist/indexer/walk/matchers.js +3 -11
- package/dist/indexer/walk/path-resolver.js +13 -68
- package/dist/indexer/walk/walker.js +32 -26
- package/dist/integrations/agent/akm-read-tools.js +81 -0
- package/dist/integrations/agent/config.js +1 -1
- package/dist/integrations/agent/detect.js +32 -36
- package/dist/integrations/agent/execution.js +130 -428
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +24 -28
- package/dist/integrations/agent/prompts.js +17 -30
- package/dist/integrations/agent/request-lowering.js +67 -101
- package/dist/integrations/agent/resolution.js +332 -0
- package/dist/integrations/agent/runner-dispatch.js +156 -181
- package/dist/integrations/agent/runner.js +20 -70
- package/dist/integrations/agent/runtime-port.js +4 -0
- package/dist/integrations/agent/runtime.js +10 -0
- package/dist/integrations/agent/spawn.js +65 -190
- package/dist/integrations/harnesses/aider/index.js +19 -39
- package/dist/integrations/harnesses/amazonq/index.js +17 -32
- package/dist/integrations/harnesses/claude/index.js +59 -28
- package/dist/integrations/harnesses/claude/session-log.js +7 -5
- package/dist/integrations/harnesses/codex/index.js +19 -31
- package/dist/integrations/harnesses/copilot/index.js +17 -35
- package/dist/integrations/harnesses/gemini/index.js +18 -34
- package/dist/integrations/harnesses/harness.js +36 -0
- package/dist/integrations/harnesses/index.js +20 -51
- package/dist/integrations/harnesses/opencode/agent-builder.js +132 -100
- package/dist/integrations/harnesses/opencode/index.js +11 -33
- package/dist/integrations/harnesses/opencode/roots.js +50 -0
- package/dist/integrations/harnesses/opencode/runtime/binary.js +206 -0
- package/dist/integrations/harnesses/opencode/runtime/command.js +152 -0
- package/dist/integrations/harnesses/opencode/runtime/index.js +177 -0
- package/dist/integrations/harnesses/opencode/runtime/tar.js +107 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +15 -7
- package/dist/integrations/harnesses/opencode/session-log-v2.js +72 -48
- package/dist/integrations/harnesses/opencode/session-log.js +58 -137
- package/dist/integrations/harnesses/opencode/version.js +34 -53
- package/dist/integrations/harnesses/openhands/index.js +13 -37
- package/dist/integrations/harnesses/pi/index.js +21 -32
- package/dist/integrations/lockfile.js +1 -1
- package/dist/integrations/session-logs/index.js +11 -31
- package/dist/llm/client.js +93 -111
- package/dist/llm/embedder.js +19 -34
- package/dist/llm/embedders/connection.js +31 -0
- package/dist/llm/embedders/local-model-files.js +56 -0
- package/dist/llm/embedders/local.js +146 -115
- package/dist/llm/embedders/remote.js +26 -23
- package/dist/llm/embedders/types.js +1 -1
- package/dist/llm/index-passes.js +33 -39
- package/dist/llm/memory-infer.js +67 -77
- package/dist/llm/model-list.js +35 -0
- package/dist/llm/rerank-client.js +8 -14
- package/dist/llm/structured-call.js +45 -99
- package/dist/llm/structured.js +60 -0
- package/dist/output/renderers.js +2 -8
- package/dist/output/shapes/helpers.js +18 -44
- package/dist/output/shapes/passthrough.js +1 -0
- package/dist/output/shapes.js +1 -7
- package/dist/output/text/command-format.js +41 -39
- package/dist/output/text/health-format.js +8 -2
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +12 -0
- package/dist/output/text/models.js +3 -2
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +16 -28
- package/dist/output/text/show-format.js +0 -2
- package/dist/output/text/targets-table.js +70 -0
- package/dist/output/text/workflow-format.js +44 -15
- package/dist/output/text.js +1 -1
- package/dist/registry/providers/skills-sh.js +1 -28
- package/dist/registry/providers/static-index.js +1 -71
- package/dist/runtime.js +6 -2
- package/dist/scripts/akm-migrate-node.js +47095 -44905
- package/dist/scripts/akm-migrate.js +46946 -44755
- package/dist/setup/detect.js +28 -273
- package/dist/setup/endpoint.js +36 -0
- package/dist/setup/semantic-assets.js +13 -19
- package/dist/setup/setup-flags.js +77 -0
- package/dist/setup/setup-plan.js +144 -0
- package/dist/setup/setup.js +134 -358
- package/dist/setup/steps/connection-shared.js +49 -101
- package/dist/setup/steps/connection.js +121 -524
- package/dist/setup/steps/embeddings.js +151 -0
- package/dist/setup/steps/harnesses.js +118 -0
- package/dist/setup/steps/platforms.js +2 -81
- package/dist/setup/steps/tasks.js +1 -2
- package/dist/setup/steps.js +10 -0
- package/dist/setup/summary.js +67 -0
- package/dist/sources/freshness.js +16 -21
- package/dist/sources/providers/git-provider.js +2 -9
- package/dist/sources/providers/provider-utils.js +13 -5
- package/dist/sources/resolve.js +12 -16
- package/dist/sources/snapshot-fetchers/robots.js +11 -12
- package/dist/sources/snapshot-fetchers/secret-seam.js +2 -4
- package/dist/sources/snapshot-fetchers/website-ingest.js +8 -15
- package/dist/sources/snapshot-fetchers/x.js +1 -1
- package/dist/standalone/onnxruntime-library.js +52 -0
- package/dist/storage/repositories/improve-ledger-repository.js +1 -1
- package/dist/storage/repositories/improve-runs-repository.js +0 -13
- package/dist/storage/repositories/index-entries-repository.js +2 -2
- package/dist/storage/repositories/proposals-repository.js +2 -2
- package/dist/storage/repositories/task-history-repository.js +2 -2
- package/dist/storage/repositories/workflow-runs-repository.js +44 -129
- package/dist/storage/sqlite-read-snapshot.js +33 -29
- package/dist/tasks/embedded.js +1 -1
- package/dist/tasks/log-redaction.js +7 -119
- package/dist/tasks/prepare/prepare-support.js +8 -7
- package/dist/tasks/prepare/prepare.js +8 -9
- package/dist/tasks/prepare/script-capture.js +9 -25
- package/dist/tasks/run/attempt-lifecycle.js +17 -35
- package/dist/tasks/run/load-task.js +54 -27
- package/dist/tasks/run/run-command-task.js +15 -10
- package/dist/tasks/run/run-native-task.js +8 -21
- package/dist/tasks/run/run-task.js +5 -8
- package/dist/tasks/run/run-workflow-task.js +14 -21
- package/dist/tasks/run/task-history.js +9 -17
- package/dist/tasks/run/task-log.js +1 -5
- package/dist/tasks/scheduler-invocation.js +13 -18
- package/dist/tasks/scheduler-sync.js +0 -1
- package/dist/tasks/source/bounded-document.js +31 -117
- package/dist/tasks/source/parse-task-source.js +0 -1
- package/dist/tasks/source/project-v4.js +5 -3
- package/dist/tasks/source/task-input-diagnostics.js +3 -4
- package/dist/tasks/source/task-source-v4.js +48 -72
- package/dist/tasks/source-v3.js +2 -5
- package/dist/tasks/task-run-reserved-flags.js +1 -2
- package/dist/workflows/authoring/authoring.js +2 -7
- package/dist/workflows/compile.js +1 -15
- package/dist/workflows/concurrency-policy.js +4 -4
- package/dist/workflows/exec/child-workflow.js +1 -4
- package/dist/workflows/exec/dispatch-redaction.js +35 -86
- package/dist/workflows/exec/environment.js +13 -77
- package/dist/workflows/exec/exec-unit.js +14 -55
- package/dist/workflows/exec/frozen-judge.js +26 -28
- package/dist/workflows/exec/native-executor.js +126 -71
- package/dist/workflows/exec/run-workflow.js +38 -42
- package/dist/workflows/exec/step-work.js +13 -17
- package/dist/workflows/exec/unit-dispatch.js +7 -21
- package/dist/workflows/freeze/environment.js +14 -119
- package/dist/workflows/freeze/freeze.js +14 -33
- package/dist/workflows/freeze/step-values.js +6 -13
- package/dist/workflows/freeze/targets/child-workflow.js +3 -5
- package/dist/workflows/freeze/targets/command.js +9 -15
- package/dist/workflows/freeze/targets/shell.js +0 -3
- package/dist/workflows/freeze/task-bindings.js +0 -1
- package/dist/workflows/parser.js +50 -59
- package/dist/workflows/plan.js +8 -2
- package/dist/workflows/renderer.js +83 -9
- package/dist/workflows/resource-limits.js +2 -2
- package/dist/workflows/runtime/run-plan.js +38 -23
- package/dist/workflows/runtime/runs.js +55 -93
- package/dist/workflows/runtime/workflow-asset-loader.js +55 -86
- package/dist/workflows/source-files.js +7 -19
- package/docs/README.md +10 -16
- package/docs/architecture/README.md +2 -37
- package/docs/architecture/adapters.md +2 -2
- package/docs/architecture/akm-core-principles.md +256 -118
- package/docs/architecture/architecture.md +283 -99
- package/docs/architecture/improvement.md +8 -2
- package/docs/architecture/internals/classification.md +1 -3
- package/docs/architecture/internals/fresh-host-rebuild-runbook.md +7 -6
- package/docs/architecture/internals/health-advisories.md +35 -74
- package/docs/architecture/internals/improve-workflow.md +27 -26
- package/docs/architecture/internals/indexing.md +3 -3
- package/docs/architecture/internals/storage-locations.md +48 -15
- package/docs/architecture/persisted-data-compat.md +10 -6
- package/docs/architecture/specs/okf-support.md +9 -11
- package/docs/architecture/specs/ref.md +7 -9
- package/docs/architecture/testing/testing-workflow.md +172 -52
- package/docs/architecture/workflow-engine.md +51 -34
- package/docs/guides/README.md +0 -1
- package/docs/guides/author-bundles.md +15 -20
- package/docs/guides/author-workflows.md +93 -71
- package/docs/guides/bundles.md +20 -16
- package/docs/guides/discover-and-load.md +1 -1
- package/docs/guides/getting-started.md +49 -3
- package/docs/guides/improve-the-library.md +10 -4
- package/docs/guides/recipes/headless-install.md +11 -16
- package/docs/guides/run-workflows.md +29 -20
- package/docs/guides/scheduling.md +2 -2
- package/docs/guides/use-with-any-agent.md +20 -22
- package/docs/integration/bundling-akm.md +19 -9
- package/docs/maintainers/README.md +2 -6
- package/docs/maintainers/release-checklist.md +73 -126
- package/docs/migration/README.md +10 -3
- package/docs/migration/release-notes/0.10.0.md +81 -16
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.9.0.md +1 -1
- package/docs/migration/release-notes/README.md +1 -1
- package/docs/migration/v0.9-to-v0.10.md +300 -60
- package/docs/migration/v0.9.1-to-v0.9.2.md +6 -5
- package/docs/posts/config-v2-lessons-16.md +1 -1
- package/docs/posts/llm-mode-reflect-13.md +1 -1
- package/docs/posts/release-0.6.0.md +11 -11
- package/docs/posts/release-0.8.0.md +4 -4
- package/docs/posts/workflows-vaults-09.md +1 -1
- package/docs/reference/README.md +1 -1
- package/docs/reference/asset-types.md +2 -2
- package/docs/reference/cli.md +477 -388
- package/docs/reference/configuration.md +569 -550
- package/docs/reference/data-and-telemetry.md +9 -6
- package/docs/reference/env-and-secrets.md +72 -15
- package/docs/reference/refs.md +3 -20
- package/docs/reference/registry.md +12 -38
- package/docs/reference/supported-formats.md +1 -1
- package/docs/reference/tasks.md +22 -11
- package/docs/reference/ui-api.md +14 -9
- package/docs/reference/workflow-schema.md +199 -154
- package/docs/reference/workflows.md +4 -6
- package/package.json +9 -11
- package/schemas/akm-config.json +1696 -2922
- package/schemas/akm-task.json +4 -4
- package/schemas/akm-workflow.json +36 -9
- package/ROADMAP.md +0 -112
- package/dist/assets/models.json +0 -35
- package/dist/commands/health/engine-usage.js +0 -45
- package/dist/commands/sources/dangerous-env-audit.js +0 -134
- package/dist/core/activation-policy.js +0 -67
- package/dist/core/config/schema/engines.js +0 -160
- package/dist/core/config/schema/execution.js +0 -23
- package/dist/core/spawn-env.js +0 -268
- package/dist/execution/directory-identity.js +0 -78
- package/dist/integrations/agent/builder-shared.js +0 -33
- package/dist/integrations/agent/builders.js +0 -43
- package/dist/integrations/agent/engine-fallback.js +0 -59
- package/dist/integrations/agent/engine-resolution.js +0 -333
- package/dist/integrations/agent/model-map.js +0 -475
- package/dist/integrations/harnesses/aider/agent-builder.js +0 -107
- package/dist/integrations/harnesses/aider/result-extractor.js +0 -53
- package/dist/integrations/harnesses/amazonq/agent-builder.js +0 -138
- package/dist/integrations/harnesses/amazonq/result-extractor.js +0 -48
- package/dist/integrations/harnesses/claude/agent-builder.js +0 -106
- package/dist/integrations/harnesses/claude/config-import.js +0 -67
- package/dist/integrations/harnesses/claude/result-extractor.js +0 -67
- package/dist/integrations/harnesses/codex/agent-builder.js +0 -150
- package/dist/integrations/harnesses/codex/result-extractor.js +0 -110
- package/dist/integrations/harnesses/copilot/agent-builder.js +0 -117
- package/dist/integrations/harnesses/copilot/result-extractor.js +0 -178
- package/dist/integrations/harnesses/gemini/agent-builder.js +0 -114
- package/dist/integrations/harnesses/gemini/result-extractor.js +0 -149
- package/dist/integrations/harnesses/opencode/config-import.js +0 -149
- package/dist/integrations/harnesses/opencode/model-config.js +0 -33
- package/dist/integrations/harnesses/opencode/model-work-agent.js +0 -115
- package/dist/integrations/harnesses/opencode/session-log-types.js +0 -12
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -44
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -1052
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +0 -199
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +0 -254
- package/dist/integrations/harnesses/opencode-sdk/wire.js +0 -66
- package/dist/integrations/harnesses/openhands/agent-builder.js +0 -120
- package/dist/integrations/harnesses/openhands/result-extractor.js +0 -135
- package/dist/integrations/harnesses/pi/agent-builder.js +0 -89
- package/dist/integrations/harnesses/pi/result-extractor.js +0 -168
- package/dist/integrations/harnesses/shared.js +0 -18
- package/dist/integrations/harnesses/types.js +0 -55
- package/dist/llm/feature-gate.js +0 -115
- package/dist/output/shapes/models-list.js +0 -16
- package/dist/output/shapes/registry-search.js +0 -10
- package/dist/setup/detected-engines.js +0 -136
- package/dist/setup/engine-config.js +0 -97
- package/dist/setup/harness-config-import.js +0 -47
- package/dist/setup/providers.js +0 -14
- package/dist/setup/steps/semantic.js +0 -39
- package/dist/workflows/authoring/scope-key.js +0 -79
- package/dist/workflows/exec/lowering-notices.js +0 -23
- package/dist/workflows/source-semantics.js +0 -110
- package/docs/architecture/0.10-process-rules.md +0 -832
- package/docs/architecture/akm-architecture-decision-history.md +0 -2055
- package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +0 -550
- package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +0 -72
- package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +0 -142
- package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +0 -189
- package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +0 -97
- package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +0 -108
- package/docs/architecture/decisions/0006-task-source-version-routing.md +0 -124
- package/docs/architecture/decisions/0007-workflow-composition-bounds.md +0 -83
- package/docs/architecture/decisions/0008-task-binding-normalization.md +0 -88
- package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +0 -80
- package/docs/architecture/decisions/0010-driver-protocol-cut.md +0 -36
- package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +0 -125
- package/docs/architecture/decisions/README.md +0 -62
- package/docs/architecture/internals/functional-contract-patterns.md +0 -340
- package/docs/architecture/internals/registry-network-boundary.md +0 -57
- package/docs/architecture/internals/search.md +0 -248
- package/docs/architecture/reviews/env-secret-access.md +0 -319
- package/docs/architecture/runtime-boundary-design.md +0 -153
- package/docs/architecture/specs/0.9.0-close-out-plan.md +0 -361
- package/docs/architecture/specs/0.9.0-decisions.md +0 -532
- package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +0 -745
- package/docs/architecture/specs/0.9.0-open-items-register.md +0 -135
- package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +0 -740
- package/docs/architecture/specs/0.9.0-release-surface-review.md +0 -636
- package/docs/architecture/specs/agent-command-engine-model-design.md +0 -513
- package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +0 -501
- package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +0 -291
- package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +0 -2059
- package/docs/architecture/specs/di-seams-plan.md +0 -539
- package/docs/architecture/specs/driver-protocol-keep-or-cut.md +0 -275
- package/docs/architecture/specs/fact-asset-type.md +0 -142
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +0 -634
- package/docs/architecture/specs/reviews/task-workflow-unification/README.md +0 -72
- package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +0 -152
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +0 -352
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +0 -300
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +0 -402
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +0 -758
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +0 -645
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +0 -602
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +0 -27
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +0 -27
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +0 -74
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +0 -15
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +0 -132
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +0 -147
- package/docs/architecture/specs/stash-conventions-code-spec.md +0 -275
- package/docs/architecture/specs/stash-organization-conventions.md +0 -377
- package/docs/architecture/specs/task-workflow-format-unification.md +0 -721
- package/docs/architecture/specs/workflow-engine-buy-vs-build.md +0 -231
- package/docs/architecture/specs/workflow-format-unification.md +0 -432
- package/docs/architecture/testing/manual-testing-checklist.md +0 -3411
- package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +0 -924
- package/docs/architecture/testing/task-workflow-manual-tests.md +0 -1720
- package/docs/guides/claude-code-vs-akm-workflows.md +0 -29
- package/docs/guides/knowledge-management.md +0 -18
- package/docs/maintainers/curate-workmap.md +0 -335
- package/docs/migration/v0.5-to-v0.6.md +0 -759
- package/docs/migration/v0.7-to-v0.8.md +0 -1378
- package/docs/plans/0.9.2-agent-command-workflow-plan.md +0 -423
|
@@ -2,535 +2,132 @@
|
|
|
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
|
-
* Setup
|
|
6
|
-
*
|
|
5
|
+
* Setup step 3: the connection. An endpoint, a key, and one model per alias
|
|
6
|
+
* picked from the models the endpoint itself lists.
|
|
7
7
|
*/
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const embeddingModels = ollama.models.filter((m) => m.includes("embed") || m.includes("nomic") || m.includes("minilm") || m.includes("bge"));
|
|
32
|
-
const hasEmbeddingModels = embeddingModels.length > 0;
|
|
33
|
-
let embedding;
|
|
34
|
-
const embeddingOptions = [];
|
|
35
|
-
for (const m of embeddingModels) {
|
|
36
|
-
embeddingOptions.push({ value: m, label: m, hint: "Ollama" });
|
|
37
|
-
}
|
|
38
|
-
embeddingOptions.push({
|
|
39
|
-
value: "local",
|
|
40
|
-
label: "Built-in local embeddings",
|
|
41
|
-
hint: "no server needed",
|
|
42
|
-
});
|
|
43
|
-
if (current.embedding) {
|
|
44
|
-
embeddingOptions.push({
|
|
45
|
-
value: "keep",
|
|
46
|
-
label: `Keep current: ${current.embedding.provider ?? current.embedding.endpoint}`,
|
|
47
|
-
hint: current.embedding.model,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
const embChoice = await prompt(() => p.select({
|
|
51
|
-
message: "Which embedding provider should akm use?",
|
|
52
|
-
options: embeddingOptions,
|
|
53
|
-
initialValue: hasEmbeddingModels ? embeddingModels[0] : "local",
|
|
54
|
-
}));
|
|
55
|
-
if (embChoice === "keep") {
|
|
56
|
-
embedding = current.embedding;
|
|
57
|
-
}
|
|
58
|
-
else if (embChoice !== "local") {
|
|
59
|
-
// Ask for dimension — different models produce different sizes.
|
|
60
|
-
// Common dimensions: nomic-embed-text=768, mxbai-embed-large=1024,
|
|
61
|
-
// all-minilm/bge-small=384. Default based on selected model.
|
|
62
|
-
const knownDims = {
|
|
63
|
-
nomic: 768,
|
|
64
|
-
mxbai: 1024,
|
|
65
|
-
minilm: 384,
|
|
66
|
-
bge: 384,
|
|
67
|
-
qwen3: 1024,
|
|
68
|
-
};
|
|
69
|
-
const guessedDim = Object.entries(knownDims).find(([k]) => embChoice.includes(k))?.[1] ?? 384;
|
|
70
|
-
p.note("Embedding dimension must match the model. Common values: 384 (BGE small), 768 (BGE base), 1024 (BGE large). Press Enter to accept the detected default.", "Embedding dimension");
|
|
71
|
-
const dimChoice = await prompt(() => p.text({
|
|
72
|
-
message: `Embedding dimension for ${embChoice}:`,
|
|
73
|
-
placeholder: String(guessedDim),
|
|
74
|
-
defaultValue: String(guessedDim),
|
|
75
|
-
validate: (v) => {
|
|
76
|
-
const n = Number(v);
|
|
77
|
-
if (!Number.isInteger(n) || n <= 0)
|
|
78
|
-
return "Must be a positive integer";
|
|
79
|
-
},
|
|
80
|
-
}));
|
|
81
|
-
embedding = {
|
|
82
|
-
provider: "ollama",
|
|
83
|
-
endpoint: `${ollama.endpoint}/v1/embeddings`,
|
|
84
|
-
model: embChoice,
|
|
85
|
-
dimension: Number(dimChoice),
|
|
86
|
-
};
|
|
87
|
-
p.note([
|
|
88
|
-
"Recommended Qwen embedding models (modern, high context support):",
|
|
89
|
-
" • qwen3-embedding-0.6b — fast and lightweight (ollama pull qwen3-embedding-0.6b)",
|
|
90
|
-
" • qwen3-embedding-4b — higher quality (ollama pull qwen3-embedding-4b)",
|
|
91
|
-
"",
|
|
92
|
-
"For long documents (wiki pages, large files), set context length to avoid 400 errors:",
|
|
93
|
-
" akm config set embedding.contextLength 8192",
|
|
94
|
-
].join("\n"), "Embedding tips");
|
|
95
|
-
}
|
|
96
|
-
// else: undefined → use built-in local
|
|
97
|
-
// Surface Ollama details to the LLM step so it can offer Ollama as a preset.
|
|
98
|
-
const ollamaChatModels = ollama.models.filter((m) => !embeddingModels.includes(m));
|
|
99
|
-
return { embedding, ollamaEndpoint: ollama.endpoint, ollamaChatModels };
|
|
8
|
+
import { defaultConnection } from "../../core/config/config.js";
|
|
9
|
+
import { apiKeyReference, resolveApiKey, storedCredential } from "../../core/config/credentials.js";
|
|
10
|
+
import { entryModel, STANDARD_ALIASES } from "../../core/config/model-aliases.js";
|
|
11
|
+
import { sameEndpoint } from "../../core/endpoint-url.js";
|
|
12
|
+
import { UsageError } from "../../core/errors.js";
|
|
13
|
+
import { redactUrlCredentials } from "../../core/redaction.js";
|
|
14
|
+
import { warn } from "../../core/warn.js";
|
|
15
|
+
import { isEmbeddingModel } from "../../llm/model-list.js";
|
|
16
|
+
import { listModels, pickModel, promptApiKey, promptEndpoint, promptModelName, warnUser } from "./connection-shared.js";
|
|
17
|
+
const NOTHING = { listed: [], addedDefault: false };
|
|
18
|
+
/** The key to list models with now: the one just supplied, else the connection's own when the endpoint is its own. */
|
|
19
|
+
function listingKey(key, existing, name, endpoint) {
|
|
20
|
+
if (key && "pasted" in key)
|
|
21
|
+
return key.pasted;
|
|
22
|
+
if (key) {
|
|
23
|
+
const value = process.env[key.env]?.trim();
|
|
24
|
+
if (!value)
|
|
25
|
+
warn(`[akm setup] ${key.env} is not set; listing models without a key.`);
|
|
26
|
+
return value || undefined;
|
|
27
|
+
}
|
|
28
|
+
return existing && sameEndpoint(existing.endpoint, endpoint)
|
|
29
|
+
? resolveApiKey(existing.apiKey, { connection: name }, existing.endpoint, process.env, true)
|
|
30
|
+
: undefined;
|
|
100
31
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
label: "Anthropic Claude (OpenAI SDK compat beta)",
|
|
105
|
-
endpoint: "https://api.anthropic.com/v1/chat/completions",
|
|
106
|
-
defaultModel: "claude-sonnet-4-5",
|
|
107
|
-
hint: "beta OpenAI-compat layer; set AKM_LLM_API_KEY; override the model if the default is unavailable",
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
value: "openai",
|
|
111
|
-
label: "OpenAI",
|
|
112
|
-
endpoint: "https://api.openai.com/v1/chat/completions",
|
|
113
|
-
defaultModel: "gpt-4o-mini",
|
|
114
|
-
hint: "AKM_LLM_API_KEY required",
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
value: "google",
|
|
118
|
-
label: "Google Gemini (OpenAI-compat)",
|
|
119
|
-
endpoint: "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",
|
|
120
|
-
defaultModel: "gemini-2.0-flash",
|
|
121
|
-
hint: "OpenAI-compat endpoint, AKM_LLM_API_KEY required",
|
|
122
|
-
},
|
|
123
|
-
];
|
|
124
|
-
/**
|
|
125
|
-
* Step 3a: pick an LLM provider. Used for LLM-gated background features
|
|
126
|
-
* (e.g. memory inference).
|
|
127
|
-
*
|
|
128
|
-
* @internal Exported for testing only.
|
|
129
|
-
*/
|
|
130
|
-
export async function stepLlm(current, ollamaEndpoint, ollamaChatModels, lmStudio, harnessConfigs) {
|
|
131
|
-
// Build "Import from <Harness>" options and prepend them before LLM_PRESETS
|
|
132
|
-
const harnessOptions = (harnessConfigs ?? []).map((h) => ({
|
|
133
|
-
value: `harness:${h.harnessName}`,
|
|
134
|
-
label: `Import from ${h.harnessName}`,
|
|
135
|
-
hint: [h.provider, h.model].filter(Boolean).join(" / ") || "detected",
|
|
136
|
-
}));
|
|
137
|
-
const options = [
|
|
138
|
-
...harnessOptions,
|
|
139
|
-
...LLM_PRESETS.map((preset) => ({
|
|
140
|
-
value: preset.value,
|
|
141
|
-
label: preset.label,
|
|
142
|
-
hint: preset.hint,
|
|
143
|
-
})),
|
|
144
|
-
];
|
|
145
|
-
const ollamaAvailable = Boolean(ollamaEndpoint && ollamaChatModels && ollamaChatModels.length > 0);
|
|
146
|
-
if (ollamaAvailable) {
|
|
147
|
-
options.push({
|
|
148
|
-
value: "ollama",
|
|
149
|
-
label: "Ollama (local)",
|
|
150
|
-
hint: ollamaChatModels?.[0] ?? "local",
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
options.push({ value: "lmstudio", label: "LM Studio / local server", hint: lmStudioOptionHint(lmStudio) });
|
|
154
|
-
options.push({ value: "custom", label: "Custom OpenAI-compatible endpoint" });
|
|
155
|
-
options.push({ value: "none", label: "Skip LLM", hint: "LLM-gated background features stay disabled" });
|
|
156
|
-
const currentLlm = readCurrentLlmEngine(current);
|
|
157
|
-
if (currentLlm) {
|
|
158
|
-
options.push(keepCurrentOption(currentLlm));
|
|
159
|
-
}
|
|
160
|
-
const initialValue = currentLlm ? "keep" : ollamaAvailable ? "ollama" : (LLM_PRESETS[0]?.value ?? "none");
|
|
161
|
-
const choice = await prompt(() => p.select({
|
|
162
|
-
message: "Configure an LLM for background features:",
|
|
163
|
-
options,
|
|
164
|
-
initialValue,
|
|
165
|
-
}));
|
|
166
|
-
if (choice === "keep")
|
|
167
|
-
return cloneLlmConnection(currentLlm);
|
|
168
|
-
if (choice === "none")
|
|
169
|
-
return undefined;
|
|
170
|
-
// Handle "Import from <Harness>" choices
|
|
171
|
-
if (typeof choice === "string" && choice.startsWith("harness:")) {
|
|
172
|
-
const harness = (harnessConfigs ?? []).find((h) => `harness:${h.harnessName}` === choice);
|
|
173
|
-
if (!harness)
|
|
174
|
-
return undefined;
|
|
175
|
-
// Show a summary before accepting
|
|
176
|
-
p.log.info(`Importing LLM config from ${harness.harnessName}: ` +
|
|
177
|
-
[harness.provider, harness.model, harness.baseUrl].filter(Boolean).join(", "));
|
|
178
|
-
if (!harness.baseUrl || !harness.model) {
|
|
179
|
-
p.log.warn(`Skipping ${harness.harnessName}: no complete endpoint/model was detected.`);
|
|
180
|
-
return undefined;
|
|
181
|
-
}
|
|
182
|
-
const verified = await verifyOpenAiCompatibleEndpoint({
|
|
183
|
-
endpoint: harness.baseUrl,
|
|
184
|
-
model: harness.model,
|
|
185
|
-
apiKeyEnvVar: harness.apiKeyEnvVar,
|
|
186
|
-
});
|
|
187
|
-
if (!verified.ok) {
|
|
188
|
-
p.log.warn(`Skipping ${harness.harnessName}: ${verified.reason}. Fix its endpoint/credential and retry setup.`);
|
|
189
|
-
return undefined;
|
|
190
|
-
}
|
|
191
|
-
const llmConfig = {
|
|
192
|
-
endpoint: verified.endpoint,
|
|
193
|
-
model: harness.model ?? "",
|
|
194
|
-
temperature: 0.3,
|
|
195
|
-
...(harness.apiKeyEnvVar ? { apiKey: `\${${harness.apiKeyEnvVar}}` } : {}),
|
|
196
|
-
};
|
|
197
|
-
if (harness.provider)
|
|
198
|
-
llmConfig.provider = harness.provider;
|
|
199
|
-
return llmConfig;
|
|
200
|
-
}
|
|
201
|
-
let llm;
|
|
202
|
-
if (choice === "ollama") {
|
|
203
|
-
const modelChoice = await prompt(() => p.select({
|
|
204
|
-
message: "Which Ollama model?",
|
|
205
|
-
options: (ollamaChatModels ?? []).map((m) => ({ value: m, label: m })),
|
|
206
|
-
initialValue: ollamaChatModels?.[0],
|
|
207
|
-
}));
|
|
208
|
-
llm = llmConnection("ollama", `${ollamaEndpoint}/v1/chat/completions`, modelChoice);
|
|
209
|
-
}
|
|
210
|
-
else if (choice === "lmstudio") {
|
|
211
|
-
const currentLmsLlm = currentLlm?.provider === "lmstudio" ? currentLlm : undefined;
|
|
212
|
-
const defaultEndpoint = currentLmsLlm?.endpoint ??
|
|
213
|
-
(lmStudio?.endpoint ? `${lmStudio.endpoint}/v1/chat/completions` : "http://localhost:1234/v1/chat/completions");
|
|
214
|
-
const endpoint = await promptEndpointUrl({ placeholder: defaultEndpoint, defaultValue: defaultEndpoint });
|
|
215
|
-
const model = await promptLmStudioModel(lmStudio, currentLmsLlm?.model);
|
|
216
|
-
llm = llmConnection("lmstudio", endpoint.trim(), model.trim());
|
|
217
|
-
}
|
|
218
|
-
else if (choice === "custom") {
|
|
219
|
-
const currentCustomLlm = currentLlm?.provider === "custom" ? currentLlm : undefined;
|
|
220
|
-
const endpoint = await promptEndpointUrl({
|
|
221
|
-
message: "OpenAI-compatible chat completions endpoint:",
|
|
222
|
-
placeholder: currentCustomLlm?.endpoint ?? "https://your-host/v1/chat/completions",
|
|
223
|
-
defaultValue: currentCustomLlm?.endpoint,
|
|
224
|
-
schemeMessage: "Endpoint must start with http:// or https://",
|
|
225
|
-
});
|
|
226
|
-
const model = await promptModelName({
|
|
227
|
-
placeholder: currentCustomLlm?.model ?? "gpt-4o-mini",
|
|
228
|
-
defaultValue: currentCustomLlm?.model,
|
|
229
|
-
});
|
|
230
|
-
llm = llmConnection("custom", endpoint.trim(), model.trim());
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
const preset = LLM_PRESETS.find((p) => p.value === choice);
|
|
234
|
-
if (!preset)
|
|
235
|
-
return undefined;
|
|
236
|
-
const model = await promptModelName({
|
|
237
|
-
message: `Model for ${preset.label}:`,
|
|
238
|
-
placeholder: preset.defaultModel,
|
|
239
|
-
defaultValue: preset.defaultModel,
|
|
240
|
-
});
|
|
241
|
-
llm = llmConnection(preset.value, preset.endpoint, model.trim() || preset.defaultModel);
|
|
242
|
-
}
|
|
243
|
-
// Remind the user about API key placement. We do not offer a "store in config"
|
|
244
|
-
// option because saveConfig() strips apiKey fields before writing — persisting
|
|
245
|
-
// secrets would need an encrypted/secure store that we don't ship.
|
|
246
|
-
const needsKey = llm.provider !== "ollama" && !llm.endpoint.includes("localhost");
|
|
247
|
-
if (needsKey && !process.env.AKM_LLM_API_KEY) {
|
|
248
|
-
p.log.info("This provider requires an API key. Set AKM_LLM_API_KEY in your shell (e.g. `export AKM_LLM_API_KEY=...`) before running `akm index`.");
|
|
249
|
-
}
|
|
250
|
-
// Capability probe — best-effort, never blocks setup.
|
|
251
|
-
await probeLlmConnection(llm);
|
|
252
|
-
return llm;
|
|
32
|
+
/** Whether the connection has a key of its own: a `$VAR` it references, or one stored for it, at whatever endpoint. */
|
|
33
|
+
function holdsKey(existing, name) {
|
|
34
|
+
return apiKeyReference(existing.apiKey) !== undefined || storedCredential({ connection: name }) !== undefined;
|
|
253
35
|
}
|
|
254
|
-
/**
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
spin.start("Detecting local services...");
|
|
270
|
-
const [ollama, lmStudio] = await Promise.all([detectOllama(), detectLMStudio()]);
|
|
271
|
-
const detectedServices = [
|
|
272
|
-
ollama.available ? `Ollama at ${ollama.endpoint}` : null,
|
|
273
|
-
lmStudio.available ? `LM Studio at ${lmStudio.endpoint}` : null,
|
|
274
|
-
]
|
|
275
|
-
.filter(Boolean)
|
|
276
|
-
.join(", ");
|
|
277
|
-
spin.stop(detectedServices ? `Detected: ${detectedServices}` : "No local services detected");
|
|
278
|
-
const ollamaEndpoint = ollama.available ? ollama.endpoint : undefined;
|
|
279
|
-
const providerOptions = [];
|
|
280
|
-
if (ollama.available) {
|
|
281
|
-
providerOptions.push({
|
|
282
|
-
value: "ollama",
|
|
283
|
-
label: "Ollama (local)",
|
|
284
|
-
hint: `detected at ${ollama.endpoint}`,
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
providerOptions.push({ value: "openai", label: "OpenAI", hint: "requires AKM_LLM_API_KEY" }, { value: "lmstudio", label: "LM Studio / local server", hint: lmStudioOptionHint(lmStudio) }, { value: "custom", label: "Custom OpenAI-compatible endpoint" }, { value: "skip", label: "Skip — disable enrichment features" });
|
|
288
|
-
const currentLlmSmall = readCurrentLlmEngine(current);
|
|
289
|
-
if (currentLlmSmall) {
|
|
290
|
-
providerOptions.push(keepCurrentOption(currentLlmSmall));
|
|
291
|
-
}
|
|
292
|
-
const initialValue = currentLlmSmall ? "keep" : ollama.available ? "ollama" : "openai";
|
|
293
|
-
const providerChoice = await prompt(() => p.select({
|
|
294
|
-
message: "Provider:",
|
|
295
|
-
options: providerOptions,
|
|
296
|
-
initialValue,
|
|
297
|
-
}));
|
|
298
|
-
if (providerChoice === "keep") {
|
|
299
|
-
return { llm: cloneLlmConnection(currentLlmSmall), skipped: false, ollamaEndpoint };
|
|
300
|
-
}
|
|
301
|
-
if (providerChoice === "skip") {
|
|
302
|
-
p.note([
|
|
303
|
-
"Enrichment features disabled:",
|
|
304
|
-
" • akm improve — lesson generation",
|
|
305
|
-
" • akm remember --enrich",
|
|
306
|
-
"",
|
|
307
|
-
"You can configure this later with `akm setup`.",
|
|
308
|
-
].join("\n"), "Warning");
|
|
309
|
-
return { llm: undefined, skipped: true, ollamaEndpoint };
|
|
310
|
-
}
|
|
311
|
-
let llm;
|
|
312
|
-
if (providerChoice === "ollama") {
|
|
313
|
-
const ollamaChatModels = ollama.models.filter((m) => !m.includes("embed") && !m.includes("nomic") && !m.includes("minilm") && !m.includes("bge"));
|
|
314
|
-
let model;
|
|
315
|
-
if (ollamaChatModels.length > 0) {
|
|
316
|
-
model = await prompt(() => p.select({
|
|
317
|
-
message: "Model name:",
|
|
318
|
-
options: [
|
|
319
|
-
...ollamaChatModels.map((m) => ({ value: m, label: m })),
|
|
320
|
-
{ value: "__custom__", label: "Enter a model name manually..." },
|
|
321
|
-
],
|
|
322
|
-
initialValue: ollamaChatModels[0],
|
|
323
|
-
}));
|
|
324
|
-
if (model === "__custom__") {
|
|
325
|
-
model = await promptModelName({ placeholder: "llama3.2" });
|
|
36
|
+
/** One model per alias: the connection's current pick is kept; the others are chosen from the endpoint's list, or typed. */
|
|
37
|
+
async function pickAliases(existing, listed, interactive) {
|
|
38
|
+
const current = (alias) => {
|
|
39
|
+
const entry = existing?.models?.[alias];
|
|
40
|
+
return entry === undefined ? undefined : entryModel(entry);
|
|
41
|
+
};
|
|
42
|
+
const chat = listed.filter((model) => !isEmbeddingModel(model));
|
|
43
|
+
const pool = chat.length > 0 ? chat : [...listed];
|
|
44
|
+
const picks = {};
|
|
45
|
+
if (pool.length > 0) {
|
|
46
|
+
for (const alias of STANDARD_ALIASES) {
|
|
47
|
+
const held = current(alias);
|
|
48
|
+
if (!interactive) {
|
|
49
|
+
picks[alias] = held ?? pool[0];
|
|
50
|
+
continue;
|
|
326
51
|
}
|
|
52
|
+
const options = held !== undefined && !pool.includes(held) ? [held, ...pool] : pool;
|
|
53
|
+
picks[alias] = await pickModel(`Model for "${alias}":`, options, held ?? pool[0]);
|
|
327
54
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
if (!process.env.AKM_LLM_API_KEY) {
|
|
342
|
-
p.log.info("Set AKM_LLM_API_KEY in your shell before running `akm index`.");
|
|
343
|
-
}
|
|
344
|
-
llm = llmConnection("openai", "https://api.openai.com/v1/chat/completions", model.trim() || currentOpenAiModel);
|
|
345
|
-
}
|
|
346
|
-
else if (providerChoice === "lmstudio") {
|
|
347
|
-
const currentLmsEndpoint = currentLlmSmall?.provider === "lmstudio"
|
|
348
|
-
? (currentLlmSmall.endpoint ?? `${lmStudio.endpoint}/v1/chat/completions`)
|
|
349
|
-
: `${lmStudio.endpoint}/v1/chat/completions`;
|
|
350
|
-
const currentLmsModel = currentLlmSmall?.provider === "lmstudio" ? currentLlmSmall.model : undefined;
|
|
351
|
-
const endpoint = await promptEndpointUrl({ placeholder: currentLmsEndpoint, defaultValue: currentLmsEndpoint });
|
|
352
|
-
const model = await promptLmStudioModel(lmStudio, currentLmsModel);
|
|
353
|
-
llm = llmConnection("lmstudio", endpoint.trim(), model.trim());
|
|
354
|
-
}
|
|
355
|
-
else {
|
|
356
|
-
// custom
|
|
357
|
-
const currentCustomEndpoint = currentLlmSmall?.provider === "custom" ? currentLlmSmall.endpoint : undefined;
|
|
358
|
-
const currentCustomModel = currentLlmSmall?.provider === "custom" ? currentLlmSmall.model : undefined;
|
|
359
|
-
const endpoint = await promptEndpointUrl({
|
|
360
|
-
message: "OpenAI-compatible chat completions endpoint:",
|
|
361
|
-
placeholder: currentCustomEndpoint ?? "https://your-host/v1/chat/completions",
|
|
362
|
-
defaultValue: currentCustomEndpoint,
|
|
363
|
-
});
|
|
364
|
-
const model = await promptModelName({
|
|
365
|
-
placeholder: currentCustomModel ?? "gpt-4o-mini",
|
|
366
|
-
defaultValue: currentCustomModel,
|
|
367
|
-
});
|
|
368
|
-
const apiKeyInput = await promptApiKeyEnvVarName();
|
|
369
|
-
llm = llmConnection("custom", endpoint.trim(), model.trim(), apiKeyInput?.trim() ? { apiKey: `\${${apiKeyInput.trim()}}` } : {});
|
|
370
|
-
}
|
|
371
|
-
// Best-effort probe — never blocks setup.
|
|
372
|
-
await probeLlmConnection(llm);
|
|
373
|
-
return { llm, skipped: false, ollamaEndpoint };
|
|
55
|
+
return picks;
|
|
56
|
+
}
|
|
57
|
+
// The endpoint listed nothing: a model typed by hand answers every alias that has none yet.
|
|
58
|
+
const missing = STANDARD_ALIASES.filter((alias) => current(alias) === undefined);
|
|
59
|
+
if (!interactive || missing.length === 0)
|
|
60
|
+
return picks;
|
|
61
|
+
const typed = await promptModelName({
|
|
62
|
+
message: "Model name (the endpoint could not list its models; change it later with `akm models set`):",
|
|
63
|
+
initialValue: STANDARD_ALIASES.map(current).find((model) => model !== undefined),
|
|
64
|
+
});
|
|
65
|
+
for (const alias of missing)
|
|
66
|
+
picks[alias] = typed;
|
|
67
|
+
return picks;
|
|
374
68
|
}
|
|
375
|
-
/**
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
].join("
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
const
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if (
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
}
|
|
417
|
-
const initialAgentValue = currentAgentBlock
|
|
418
|
-
? "keep"
|
|
419
|
-
: availableClis.length > 0 && smallModel.skipped
|
|
420
|
-
? "cli-agent"
|
|
421
|
-
: !smallModel.skipped && smallModel.llm
|
|
422
|
-
? "same-connection"
|
|
423
|
-
: availableClis.length > 0
|
|
424
|
-
? "cli-agent"
|
|
425
|
-
: "none";
|
|
426
|
-
const agentChoice = await prompt(() => p.select({
|
|
427
|
-
message: "How do you want to run agent commands?",
|
|
428
|
-
options: agentOptions,
|
|
429
|
-
initialValue: initialAgentValue,
|
|
430
|
-
}));
|
|
431
|
-
if (agentChoice === "keep") {
|
|
432
|
-
return currentAgentBlock;
|
|
433
|
-
}
|
|
434
|
-
if (agentChoice === "none") {
|
|
435
|
-
p.note([
|
|
436
|
-
"Agentic features disabled:",
|
|
437
|
-
' • akm proposal new — will show "no agent configured" error',
|
|
438
|
-
' • akm improve — will show "no agent configured" error',
|
|
439
|
-
' • akm task run — will show "no agent configured" error',
|
|
440
|
-
"",
|
|
441
|
-
"You can configure this later with `akm setup`.",
|
|
442
|
-
].join("\n"), "Warning");
|
|
443
|
-
return { disabled: true };
|
|
444
|
-
}
|
|
445
|
-
if (agentChoice === "same-connection") {
|
|
446
|
-
if (smallModel.skipped || !smallModel.llm) {
|
|
447
|
-
p.log.warn("You skipped the small model connection. Configure one to use the same connection. Falling back to 'new connection'.");
|
|
448
|
-
// Fall through to new-connection flow
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
const baseEndpoint = smallModel.llm.endpoint.replace("/v1/chat/completions", "");
|
|
452
|
-
p.log.info(`Endpoint: ${baseEndpoint} (from Step 1)`);
|
|
453
|
-
const profileName = `${smallModel.llm.provider ?? "default"}-agent`;
|
|
454
|
-
// Pre-populate from existing agent profile for this provider, if any.
|
|
455
|
-
const existingAgentModel = currentAgentBlock?.engines?.[profileName]?.model ?? smallModel.llm.model ?? undefined;
|
|
456
|
-
const agentModel = await promptModelName({
|
|
457
|
-
message: "Model to use for agent tasks (same model is fine, larger models work better):",
|
|
458
|
-
placeholder: existingAgentModel ?? "qwen2.5-coder:32b",
|
|
459
|
-
defaultValue: existingAgentModel,
|
|
460
|
-
});
|
|
461
|
-
return {
|
|
462
|
-
...(currentAgentBlock ?? {}),
|
|
463
|
-
engines: {
|
|
464
|
-
...(currentAgentBlock?.engines ?? {}),
|
|
465
|
-
[profileName]: {
|
|
466
|
-
...(currentAgentBlock?.engines?.[profileName] ?? {}),
|
|
467
|
-
kind: "agent",
|
|
468
|
-
platform: "opencode-sdk",
|
|
469
|
-
model: agentModel.trim(),
|
|
470
|
-
...(current.defaults?.llmEngine ? { llmEngine: current.defaults.llmEngine } : {}),
|
|
471
|
-
},
|
|
472
|
-
},
|
|
473
|
-
default: profileName,
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
if (agentChoice === "cli-agent") {
|
|
478
|
-
if (availableClis.length === 0) {
|
|
479
|
-
p.log.warn("No agent CLIs detected on PATH.");
|
|
480
|
-
return currentAgentBlock;
|
|
69
|
+
/** One warning for the picks setup keeps that the endpoint, which did list its models, does not serve. */
|
|
70
|
+
function warnOfUnlistedPicks(existing, picks, listed, endpoint, interactive) {
|
|
71
|
+
if (listed.length === 0)
|
|
72
|
+
return;
|
|
73
|
+
const kept = new Set();
|
|
74
|
+
for (const [alias, pick] of Object.entries(picks)) {
|
|
75
|
+
const held = existing?.models?.[alias];
|
|
76
|
+
if (held !== undefined && entryModel(held) === pick && !listed.includes(pick))
|
|
77
|
+
kept.add(pick);
|
|
78
|
+
}
|
|
79
|
+
if (kept.size === 0)
|
|
80
|
+
return;
|
|
81
|
+
const names = [...kept].map((model) => `"${model}"`).join(", ");
|
|
82
|
+
warnUser(`Keeping ${names}: ${redactUrlCredentials(endpoint)} does not list ${kept.size === 1 ? "it" : "them"}. Change a pick with \`akm models set\`.`, interactive);
|
|
83
|
+
}
|
|
84
|
+
export async function stepConnection(input) {
|
|
85
|
+
const { current, flags, interactive } = input;
|
|
86
|
+
const name = flags.name ?? defaultConnection(current)?.name ?? "default";
|
|
87
|
+
const existing = current.connections?.[name];
|
|
88
|
+
const flagged = flags.endpoint !== undefined || flags.apiKeyEnv !== undefined || flags.name !== undefined;
|
|
89
|
+
const local = input.localServers.find((server) => server.available);
|
|
90
|
+
const detected = local ? `${local.baseUrl}/v1` : undefined;
|
|
91
|
+
const needed = flagged ||
|
|
92
|
+
(interactive
|
|
93
|
+
? existing !== undefined || !input.modelCallsOnHarness
|
|
94
|
+
: existing === undefined && !input.modelCallsOnHarness && detected !== undefined);
|
|
95
|
+
if (!needed)
|
|
96
|
+
return NOTHING;
|
|
97
|
+
let endpoint = flags.endpoint;
|
|
98
|
+
if (endpoint === undefined) {
|
|
99
|
+
const start = existing?.endpoint ?? detected;
|
|
100
|
+
endpoint = interactive
|
|
101
|
+
? await promptEndpoint({
|
|
102
|
+
message: "Endpoint URL of an OpenAI-compatible server (blank for none):",
|
|
103
|
+
...(start ? { initialValue: start } : {}),
|
|
104
|
+
})
|
|
105
|
+
: start;
|
|
106
|
+
}
|
|
107
|
+
if (endpoint === undefined) {
|
|
108
|
+
if (flagged) {
|
|
109
|
+
throw new UsageError(`There is no connection "${name}" to update. Pass --endpoint to add one.`, "MISSING_REQUIRED_ARGUMENT");
|
|
481
110
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
})
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
const
|
|
500
|
-
const
|
|
501
|
-
|
|
502
|
-
const
|
|
503
|
-
|
|
504
|
-
placeholder: currentNewEndpoint ?? "https://your-host/v1/chat/completions",
|
|
505
|
-
defaultValue: currentNewEndpoint,
|
|
506
|
-
});
|
|
507
|
-
const newApiKeyInput = await promptApiKeyEnvVarName();
|
|
508
|
-
const newModel = await promptModelName({
|
|
509
|
-
message: "Model name (larger is better, e.g. gpt-4o):",
|
|
510
|
-
placeholder: currentNewModel ?? "gpt-4o",
|
|
511
|
-
defaultValue: currentNewModel,
|
|
512
|
-
});
|
|
513
|
-
const llmEngineName = "custom-llm";
|
|
514
|
-
const agentEngineName = "custom-agent";
|
|
515
|
-
const customProfile = {
|
|
516
|
-
kind: "agent",
|
|
517
|
-
platform: "opencode-sdk",
|
|
518
|
-
llmEngine: llmEngineName,
|
|
519
|
-
model: newModel.trim(),
|
|
520
|
-
};
|
|
521
|
-
return {
|
|
522
|
-
...(currentAgentBlock ?? {}),
|
|
523
|
-
engines: {
|
|
524
|
-
...(currentAgentBlock?.engines ?? {}),
|
|
525
|
-
[llmEngineName]: {
|
|
526
|
-
kind: "llm",
|
|
527
|
-
provider: "custom",
|
|
528
|
-
endpoint: newEndpoint.trim(),
|
|
529
|
-
model: newModel.trim(),
|
|
530
|
-
...(newApiKeyInput?.trim() ? { apiKey: `\${${newApiKeyInput.trim()}}` } : {}),
|
|
531
|
-
},
|
|
532
|
-
[agentEngineName]: customProfile,
|
|
533
|
-
},
|
|
534
|
-
default: agentEngineName,
|
|
535
|
-
};
|
|
111
|
+
return NOTHING;
|
|
112
|
+
}
|
|
113
|
+
// A key belongs to the endpoint it was given for, so the current one is offered for that endpoint alone.
|
|
114
|
+
const sameServer = existing !== undefined && sameEndpoint(existing.endpoint, endpoint);
|
|
115
|
+
let key;
|
|
116
|
+
if (flags.apiKeyEnv !== undefined) {
|
|
117
|
+
key = { env: flags.apiKeyEnv };
|
|
118
|
+
}
|
|
119
|
+
else if (interactive) {
|
|
120
|
+
const hasKey = sameServer && resolveApiKey(existing?.apiKey, { connection: name }, endpoint, process.env, true) !== undefined;
|
|
121
|
+
const typed = await promptApiKey(hasKey ? "API key (blank keeps the current one)" : "API key (blank for none)");
|
|
122
|
+
if (typed)
|
|
123
|
+
key = { pasted: typed };
|
|
124
|
+
}
|
|
125
|
+
if (key === undefined && existing && !sameServer && holdsKey(existing, name)) {
|
|
126
|
+
warnUser(`The endpoint of "${name}" changed, so its current key is not used with ${redactUrlCredentials(endpoint)}. Give the new endpoint's key with --api-key-env (or at the prompt).`, interactive);
|
|
127
|
+
}
|
|
128
|
+
const listed = input.probe ? await listModels(endpoint, listingKey(key, existing, name, endpoint), interactive) : [];
|
|
129
|
+
const picks = await pickAliases(existing, listed, interactive);
|
|
130
|
+
warnOfUnlistedPicks(existing, picks, listed, endpoint, interactive);
|
|
131
|
+
const addedDefault = existing === undefined && (name === "default" || Object.keys(current.connections ?? {}).length === 0);
|
|
132
|
+
return { answer: { name, endpoint, ...(key ? { key } : {}), picks }, listed, addedDefault };
|
|
536
133
|
}
|