akm-cli 0.9.1 → 0.9.2-alpha.2
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 +103 -28
- package/README.md +3 -1
- package/SECURITY.md +1 -1
- package/STABILITY.md +1 -1
- package/dist/akm +2 -2
- package/dist/akm-migrate +2 -2
- package/dist/assets/hints/cli-hints-full.md +14 -9
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/models.json +35 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +3 -4
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +1 -3
- package/dist/assets/tasks/core/extract.yml +6 -5
- package/dist/assets/tasks/core/improve.yml +6 -5
- package/dist/assets/tasks/core/index-refresh.yml +6 -5
- package/dist/assets/tasks/core/sync.yml +6 -5
- package/dist/assets/tasks/core/version-check.yml +6 -5
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
- package/dist/cli/confirm.js +2 -2
- package/dist/cli/parse-args.js +3 -24
- package/dist/cli/retired-commands.js +1 -1
- package/dist/cli/shared.js +2 -2
- package/dist/cli.js +11 -9
- package/dist/commands/agent/agent-dispatch.js +55 -89
- package/dist/commands/agent/contribute-cli.js +12 -45
- package/dist/commands/command/builtin-action.js +32 -0
- package/dist/commands/command/command-cli.js +99 -0
- package/dist/commands/command/command-execution.js +308 -0
- package/dist/commands/command/execution-source-loader.js +176 -0
- package/dist/commands/command/portable-template.js +60 -0
- package/dist/commands/config-cli.js +10 -4
- package/dist/commands/env/env.js +4 -2
- package/dist/commands/feedback-cli.js +1 -1
- package/dist/commands/health/checks.js +241 -29
- package/dist/commands/health/html-report.js +0 -14
- package/dist/commands/health/report-view-model.js +0 -1
- package/dist/commands/health/surfaces.js +6 -7
- package/dist/commands/health/types.js +0 -2
- package/dist/commands/health.js +63 -18
- package/dist/commands/improve/collapse-detector.js +5 -6
- package/dist/commands/improve/consolidate.js +251 -214
- package/dist/commands/improve/distill/promote-memory.js +71 -34
- package/dist/commands/improve/distill/quality-gate.js +17 -5
- package/dist/commands/improve/distill.js +232 -155
- package/dist/commands/improve/eligibility.js +112 -79
- package/dist/commands/improve/execution.js +57 -0
- package/dist/commands/improve/extract-cli.js +5 -5
- package/dist/commands/improve/extract-prompt.js +64 -22
- package/dist/commands/improve/extract.js +608 -360
- package/dist/commands/improve/improve-strategies.js +43 -14
- package/dist/commands/improve/improve.js +249 -29
- package/dist/commands/improve/loop-stages.js +11 -17
- package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
- package/dist/commands/improve/outcome-loop.js +22 -38
- package/dist/commands/improve/planner.js +134 -0
- package/dist/commands/improve/preparation.js +730 -409
- package/dist/commands/improve/reflect.js +386 -223
- package/dist/commands/improve/run-context.js +3 -4
- package/dist/commands/improve/salience.js +6 -58
- package/dist/commands/improve/session-asset.js +12 -12
- package/dist/commands/lint/index.js +101 -29
- package/dist/commands/migrate-cli.js +11 -69
- package/dist/commands/migration-tool.js +6 -9
- package/dist/commands/models-cli.js +27 -0
- package/dist/commands/proposal/drain.js +258 -186
- package/dist/commands/proposal/proposal-cli.js +32 -10
- package/dist/commands/proposal/proposal.js +2 -5
- package/dist/commands/proposal/propose.js +192 -172
- package/dist/commands/proposal/repository.js +54 -91
- package/dist/commands/proposal/validators/proposal-validators.js +9 -7
- package/dist/commands/read/curate.js +53 -22
- package/dist/commands/read/registry-search.js +25 -9
- package/dist/commands/read/remember-cli.js +14 -2
- package/dist/commands/read/search.js +10 -4
- package/dist/commands/read/show.js +139 -153
- package/dist/commands/registry-cli.js +16 -7
- package/dist/commands/remember.js +33 -18
- package/dist/commands/sources/add-cli.js +19 -178
- package/dist/commands/sources/bundle-cli.js +15 -3
- package/dist/commands/sources/dangerous-env-audit.js +135 -0
- package/dist/commands/sources/info.js +2 -1
- package/dist/commands/sources/installed-stashes.js +901 -177
- package/dist/commands/sources/schema-repair.js +174 -95
- package/dist/commands/sources/self-update.js +30 -74
- package/dist/commands/sources/source-add.js +3 -5
- package/dist/commands/sources/sources-cli.js +2 -15
- package/dist/commands/sources/update-transaction.js +220 -0
- package/dist/commands/tasks/tasks-cli.js +3 -3
- package/dist/commands/tasks/tasks.js +736 -317
- package/dist/commands/workflow-cli.js +2 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
- package/dist/core/adapter/adapters/akm-adapter.js +85 -35
- package/dist/core/adapter/adapters/akm-lint.js +54 -39
- package/dist/core/adapter/adapters/akm-metadata.js +45 -45
- package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
- package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
- package/dist/core/adapter/adapters/index.js +0 -9
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
- package/dist/core/adapter/adapters/okf-adapter.js +4 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
- package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
- package/dist/core/adapter/execution-source.js +308 -0
- package/dist/core/adapter/recognize-match.js +36 -13
- package/dist/core/adapter/registry.js +0 -9
- package/dist/core/asset/stash-meta.js +94 -4
- package/dist/core/common.js +6 -11
- package/dist/core/config/config-io.js +3 -3
- package/dist/core/config/config-schema.js +18 -40
- package/dist/core/config/config-sources.js +11 -21
- package/dist/core/config/config-walker.js +31 -13
- package/dist/core/config/config.js +23 -26
- package/dist/core/config/schema/engines.js +8 -7
- package/dist/core/config/schema/improve-processes.js +29 -5
- package/dist/core/config/schema/index-config.js +0 -27
- package/dist/core/config/schema/primitives.js +1 -23
- package/dist/core/config/schema/sources-bundles.js +13 -16
- package/dist/core/errors.js +2 -0
- package/dist/core/events.js +68 -32
- package/dist/core/extra-params.js +1 -0
- package/dist/core/improve-result.js +315 -0
- package/dist/core/lesson-lint.js +0 -6
- package/dist/core/maintenance-barrier.js +4 -4
- package/dist/core/network-policy.js +152 -0
- package/dist/core/paths.js +1 -1
- package/dist/core/recognition-util.js +4 -4
- package/dist/core/registry-url.js +456 -0
- package/dist/core/state/migrations.js +161 -47
- package/dist/core/state-db.js +453 -80
- package/dist/core/system-error.js +32 -0
- package/dist/core/time.js +2 -12
- package/dist/core/write-source.js +0 -18
- package/dist/execution/directory-identity.js +52 -0
- package/dist/execution/executable-identity.js +107 -0
- package/dist/execution/guarded-source.js +398 -0
- package/dist/execution/json.js +95 -0
- package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
- package/dist/execution/record.js +55 -0
- package/dist/execution/resolved-request.js +730 -0
- package/dist/execution/source.js +320 -0
- package/dist/indexer/bundle-identity-guard.js +5 -4
- package/dist/indexer/db/graph-db.js +33 -0
- package/dist/indexer/graph/graph-boost.js +3 -4
- package/dist/indexer/graph/graph-extraction.js +562 -373
- package/dist/indexer/index-written-assets.js +78 -39
- package/dist/indexer/indexer.js +471 -432
- package/dist/indexer/installations.js +6 -0
- package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
- package/dist/indexer/materialize-embeddings.js +155 -0
- package/dist/indexer/passes/memory-inference.js +227 -174
- package/dist/indexer/passes/metadata.js +263 -118
- package/dist/indexer/scan/doc-to-entry.js +7 -10
- package/dist/indexer/scan/drain-dir.js +51 -23
- package/dist/indexer/search/db-search.js +156 -50
- package/dist/indexer/search/fts-query.js +40 -40
- package/dist/indexer/search/ranking.js +36 -1
- package/dist/indexer/search/search-attribution.js +3 -1
- package/dist/indexer/search/search-fields.js +23 -14
- package/dist/indexer/search/search-hit-enrichers.js +1 -1
- package/dist/indexer/search/search-source.js +7 -16
- package/dist/indexer/search/semantic-status.js +10 -1
- package/dist/indexer/usage/show-usage.js +105 -0
- package/dist/indexer/usage/usage-events.js +7 -2
- package/dist/indexer/walk/matchers.js +40 -10
- package/dist/indexer/walk/path-resolver.js +5 -2
- package/dist/indexer/walk/walker.js +20 -2
- package/dist/integrations/agent/builder-shared.js +3 -6
- package/dist/integrations/agent/conversation-fallback.js +16 -0
- package/dist/integrations/agent/engine-resolution.js +87 -87
- package/dist/integrations/agent/execution-cascade.js +566 -0
- package/dist/integrations/agent/execution-definitions.js +211 -0
- package/dist/integrations/agent/execution-lowering.js +811 -0
- package/dist/integrations/agent/execution-preparation.js +67 -0
- package/dist/integrations/agent/index.js +0 -2
- package/dist/integrations/agent/inline-execution.js +74 -0
- package/dist/integrations/agent/model-map.js +515 -0
- package/dist/integrations/agent/persona-fallback.js +30 -0
- package/dist/integrations/agent/request-lowering.js +186 -0
- package/dist/integrations/agent/runner-dispatch.js +230 -37
- package/dist/integrations/agent/runner.js +12 -83
- package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
- package/dist/integrations/harnesses/aider/index.js +0 -1
- package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
- package/dist/integrations/harnesses/amazonq/index.js +0 -1
- package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
- package/dist/integrations/harnesses/claude/index.js +1 -5
- package/dist/integrations/harnesses/claude/session-log.js +3 -33
- package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
- package/dist/integrations/harnesses/codex/index.js +0 -1
- package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
- package/dist/integrations/harnesses/copilot/index.js +0 -1
- package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
- package/dist/integrations/harnesses/gemini/index.js +0 -1
- package/dist/integrations/harnesses/index.js +4 -44
- package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
- package/dist/integrations/harnesses/opencode/index.js +0 -2
- package/dist/integrations/harnesses/opencode/session-log.js +14 -204
- package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
- package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
- package/dist/integrations/harnesses/openhands/index.js +0 -1
- package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
- package/dist/integrations/harnesses/pi/index.js +0 -1
- package/dist/integrations/harnesses/shared.js +0 -1
- package/dist/integrations/harnesses/types.js +1 -3
- package/dist/integrations/lockfile.js +82 -79
- package/dist/integrations/session-logs/index.js +6 -17
- package/dist/integrations/session-logs/provider-base.js +1 -29
- package/dist/llm/client.js +10 -5
- package/dist/llm/embedder.js +6 -7
- package/dist/llm/embedders/local.js +37 -88
- package/dist/llm/embedders/types.js +1 -1
- package/dist/llm/graph-extract.js +75 -50
- package/dist/llm/index-passes.js +43 -5
- package/dist/llm/memory-infer.js +8 -6
- package/dist/llm/metadata-enhance.js +5 -3
- package/dist/llm/structured-call.js +122 -25
- package/dist/output/format-exempt.js +1 -1
- package/dist/output/render-registry.js +0 -16
- package/dist/output/renderers.js +12 -7
- package/dist/output/shapes/curate.js +1 -0
- package/dist/output/shapes/helpers.js +10 -2
- package/dist/output/shapes/passthrough.js +2 -0
- package/dist/output/text/command-format.js +31 -33
- package/dist/output/text/health-format.js +1 -29
- package/dist/output/text/migrate.js +6 -56
- package/dist/output/text/proposal-format.js +16 -1
- package/dist/output/text/workflow-format.js +16 -0
- package/dist/registry/network.js +279 -0
- package/dist/registry/pinned-request-helper.js +247 -0
- package/dist/registry/pinned-transport.js +717 -0
- package/dist/registry/providers/skills-sh.js +18 -6
- package/dist/registry/providers/static-index.js +20 -7
- package/dist/registry/resolve.js +53 -28
- package/dist/scripts/akm-migrate-node.js +19334 -52269
- package/dist/scripts/akm-migrate.js +19270 -51612
- package/dist/setup/registry-stash-loader.js +64 -20
- package/dist/setup/semantic-assets.js +9 -34
- package/dist/setup/setup.js +12 -30
- package/dist/setup/source-identity.js +17 -0
- package/dist/setup/steps/sources.js +36 -15
- package/dist/setup/steps/tasks.js +39 -11
- package/dist/sources/providers/git-provider.js +3 -3
- package/dist/sources/providers/npm.js +2 -2
- package/dist/sources/providers/provider-utils.js +4 -3
- package/dist/sources/providers/website.js +11 -7
- package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
- package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
- package/dist/sources/website-url.js +73 -0
- package/dist/storage/engines/sqlite-migrations.js +81 -26
- package/dist/storage/managed-db.js +27 -24
- package/dist/storage/repositories/events-repository.js +3 -0
- package/dist/storage/repositories/index-connection.js +42 -10
- package/dist/storage/repositories/index-entries-repository.js +203 -229
- package/dist/storage/repositories/index-entry-mapper.js +8 -12
- package/dist/storage/repositories/index-entry-schema.js +255 -0
- package/dist/storage/repositories/index-fts-repository.js +64 -71
- package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
- package/dist/storage/repositories/index-meta-repository.js +0 -11
- package/dist/storage/repositories/index-schema.js +74 -350
- package/dist/storage/repositories/index-utility-repository.js +12 -17
- package/dist/storage/repositories/index-vec-repository.js +56 -7
- package/dist/storage/repositories/proposals-repository.js +4 -127
- package/dist/storage/repositories/registry-cache.js +2 -1
- package/dist/storage/repositories/task-history-repository.js +20 -40
- package/dist/storage/repositories/workflow-runs-repository.js +228 -129
- package/dist/storage/sqlite-read-snapshot.js +148 -0
- package/dist/tasks/backends/cron.js +170 -42
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +787 -202
- package/dist/tasks/backends/schtasks.js +282 -83
- package/dist/tasks/embedded.js +7 -7
- package/dist/tasks/frozen-script.js +50 -0
- package/dist/tasks/resolve-akm-bin.js +5 -1
- package/dist/tasks/runner.js +239 -251
- package/dist/tasks/runtime-v3.js +281 -0
- package/dist/tasks/scheduler-binding.js +272 -0
- package/dist/tasks/scheduler-invocation.js +57 -43
- package/dist/tasks/scheduler-sync.js +654 -0
- package/dist/tasks/source-v3.js +752 -0
- package/dist/tasks/standalone-script-entry.js +5 -0
- package/dist/tasks/task-id.js +29 -0
- package/dist/workflows/authoring/authoring.js +15 -32
- package/dist/workflows/exec/dispatch-redaction.js +14 -8
- package/dist/workflows/exec/exec-unit.js +7 -28
- package/dist/workflows/exec/frozen-judge.js +57 -89
- package/dist/workflows/exec/lowering-notices.js +23 -0
- package/dist/workflows/exec/native-executor.js +301 -458
- package/dist/workflows/exec/param-secrets.js +4 -3
- package/dist/workflows/exec/run-workflow.js +26 -32
- package/dist/workflows/exec/step-work.js +105 -109
- package/dist/workflows/exec/unit-dispatch.js +103 -27
- package/dist/workflows/exec/unit-writer.js +3 -3
- package/dist/workflows/exec/worktree.js +2 -2
- package/dist/workflows/ir/compile.js +86 -72
- package/dist/workflows/ir/environment-v4.js +328 -0
- package/dist/workflows/ir/freeze-v4.js +122 -0
- package/dist/workflows/ir/plan-hash.js +13 -7
- package/dist/workflows/ir/schema-v4.js +525 -0
- package/dist/workflows/ir/schema.js +25 -284
- package/dist/workflows/ir/source-freeze-v4.js +506 -0
- package/dist/workflows/parser.js +27 -24
- package/dist/workflows/program/schema.js +1 -2
- package/dist/workflows/renderer.js +42 -29
- package/dist/workflows/resource-limits.js +4 -5
- package/dist/workflows/runtime/agent-identity.js +11 -13
- package/dist/workflows/runtime/plan-classifier.js +8 -8
- package/dist/workflows/runtime/runs.js +27 -43
- package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
- package/dist/workflows/source-files.js +373 -0
- package/dist/workflows/source-ir/compile.js +196 -0
- package/dist/workflows/source-ir/github-yaml.js +577 -0
- package/dist/workflows/source-ir/ordering.js +38 -0
- package/dist/workflows/source-ir/program.js +50 -0
- package/dist/workflows/source-ir/result.js +26 -0
- package/dist/workflows/source-ir/schema.js +772 -0
- package/dist/workflows/source-ir/semantics.js +242 -0
- package/dist/workflows/source-ir/uses.js +14 -0
- package/docs/README.md +2 -0
- package/docs/migration/README.md +3 -1
- package/docs/migration/release-notes/0.9.2.md +55 -0
- package/docs/migration/release-notes/README.md +5 -0
- package/docs/migration/v0.8-to-v0.9.md +76 -1077
- package/docs/migration/v0.9.0-troubleshooting.md +104 -516
- package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
- package/docs/reference/README.md +1 -0
- package/docs/reference/cli.md +230 -98
- package/docs/reference/configuration.md +159 -36
- package/docs/reference/data-and-telemetry.md +19 -1
- package/docs/reference/supported-formats.md +23 -3
- package/docs/reference/tasks.md +182 -0
- package/docs/reference/workflow-schema.md +91 -40
- package/docs/reference/workflows.md +33 -6
- package/package.json +10 -6
- package/schemas/akm-config.json +372 -224
- package/schemas/akm-task.json +324 -80
- package/schemas/akm-workflow.json +6 -9
- package/dist/core/migration-operation.js +0 -75
- package/dist/integrations/agent/model-aliases.js +0 -74
- package/dist/tasks/parser.js +0 -380
- package/dist/tasks/schema.js +0 -123
- package/dist/tasks/validator.js +0 -80
- package/dist/workflows/ir/freeze.js +0 -320
- package/dist/workflows/runtime/document-cache.js +0 -13
|
@@ -25,12 +25,10 @@
|
|
|
25
25
|
* - Top-level uses `.passthrough()` so unknown future keys round-trip intact on
|
|
26
26
|
* read; `sanitizeConfigForWrite` decides what to persist.
|
|
27
27
|
* - Most nested sub-objects use `.catch(undefined)` so malformed entries are
|
|
28
|
-
* silently dropped
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* `stashes[]` key. Both have explicit migration paths; silently dropping
|
|
33
|
-
* would mask user data loss.
|
|
28
|
+
* silently dropped to keep cold-start working when a user has a field-level
|
|
29
|
+
* typo in an optional section.
|
|
30
|
+
* - Unsupported top-level source shapes and provider kinds are hard-rejected;
|
|
31
|
+
* silently dropping them would mask user data loss.
|
|
34
32
|
* - UNKNOWN-KEY POLICY: object schemas use passthrough (unknown keys are
|
|
35
33
|
* preserved and ignored, NOT rejected). akm runs across multiple installed
|
|
36
34
|
* versions sharing one config.json; a newer version writes keys an older
|
|
@@ -51,7 +49,7 @@ import { FeedbackConfigSchema } from "./schema/feedback.js";
|
|
|
51
49
|
import { ImproveConfigSchema } from "./schema/improve.js";
|
|
52
50
|
import { IndexConfigSchema } from "./schema/index-config.js";
|
|
53
51
|
import { OutputConfigSchema } from "./schema/output.js";
|
|
54
|
-
import { CURRENT_CONFIG_VERSION, engineName,
|
|
52
|
+
import { CURRENT_CONFIG_VERSION, engineName, nonEmptyString, nonNegativeNumber } from "./schema/primitives.js";
|
|
55
53
|
import { SearchConfigSchema } from "./schema/search.js";
|
|
56
54
|
import { SetupConfigSchema } from "./schema/setup.js";
|
|
57
55
|
import { BundlesConfigSchema, RegistryConfigEntrySchema } from "./schema/sources-bundles.js";
|
|
@@ -85,33 +83,21 @@ export const DefaultsSchema = z
|
|
|
85
83
|
* with cross-field refinements (`.superRefine()`).
|
|
86
84
|
*
|
|
87
85
|
* All fields validate loudly — typos and shape errors throw at load time. The
|
|
88
|
-
*
|
|
89
|
-
* configuration loss
|
|
90
|
-
* one-time 0.7→0.8 input transforms before the schema sees the value.
|
|
86
|
+
* the removed parser's warn-and-drop tolerance was a source of silent
|
|
87
|
+
* configuration loss. There is no pre-schema compatibility transform.
|
|
91
88
|
*/
|
|
92
89
|
export const AkmConfigShape = {
|
|
93
90
|
configVersion: z.literal(CURRENT_CONFIG_VERSION),
|
|
94
91
|
engines: EnginesSchema.optional(),
|
|
95
92
|
defaults: DefaultsSchema.optional(),
|
|
96
|
-
// Global model-alias tiers: alias → platform → exact model string, with a
|
|
97
|
-
// reserved `"*"` platform key as fallback. Lets workflows/callers name a
|
|
98
|
-
// semantic tier ("fast", "deep") that resolves per-harness at dispatch
|
|
99
|
-
// time. Values are literal model strings, never other aliases (one
|
|
100
|
-
// resolution level). Platform keys match the platform string a command
|
|
101
|
-
// builder resolves against ("claude", "opencode", "opencode-sdk", or a
|
|
102
|
-
// custom profile's name for the default builder) — unknown keys are inert.
|
|
103
|
-
// Precedence: profile modelAliases > this table > built-in aliases.
|
|
104
|
-
modelAliases: GlobalModelAliasesSchema.optional(),
|
|
105
93
|
semanticSearchMode: z.enum(["off", "auto"]).default("off"),
|
|
106
94
|
embedding: EmbeddingConnectionConfigSchema.optional(),
|
|
107
95
|
index: IndexConfigSchema.optional(),
|
|
108
96
|
registries: z.array(RegistryConfigEntrySchema).optional(),
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
// shape before validation. `defaultBundle` names the primary bundle (spec
|
|
114
|
-
// §11.1 short-ref resolution / D-R4).
|
|
97
|
+
// `bundles` + `defaultBundle` are the only source configuration shape. The
|
|
98
|
+
// retired `stashDir`/`sources[]`/`installed[]` keys are rejected at load;
|
|
99
|
+
// there is no runtime config translator. `defaultBundle` names the primary
|
|
100
|
+
// bundle used for short-ref resolution.
|
|
115
101
|
bundles: BundlesConfigSchema.optional(),
|
|
116
102
|
defaultBundle: nonEmptyString.optional(),
|
|
117
103
|
output: OutputConfigSchema.optional(),
|
|
@@ -128,17 +114,14 @@ export const AkmConfigShape = {
|
|
|
128
114
|
};
|
|
129
115
|
export const AkmConfigBaseSchema = z.object(AkmConfigShape).passthrough();
|
|
130
116
|
/**
|
|
131
|
-
* Per-key overrides for
|
|
132
|
-
* shape rejection below. Keys without an entry fall back to the shared
|
|
133
|
-
* "retired pre-cutover source shape" message, which already names the
|
|
134
|
-
* replacement (bundles) and the migration command.
|
|
117
|
+
* Per-key overrides for unsupported pre-cutover source shapes.
|
|
135
118
|
*/
|
|
136
119
|
const RETIRED_SOURCE_SHAPE_KEY_MESSAGES = {
|
|
137
|
-
stashDir: "stashDir is
|
|
120
|
+
stashDir: "stashDir is not supported; configure `bundles`, or use `akm config path --all` / `akm info` to inspect current paths.",
|
|
138
121
|
};
|
|
139
122
|
export const AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) => {
|
|
140
123
|
const raw = config;
|
|
141
|
-
for (const key of ["profiles", "llm", "agent", "features", "stashes"]) {
|
|
124
|
+
for (const key of ["profiles", "llm", "agent", "features", "stashes", "modelAliases"]) {
|
|
142
125
|
if (key in raw) {
|
|
143
126
|
ctx.addIssue({
|
|
144
127
|
code: z.ZodIssueCode.custom,
|
|
@@ -157,19 +140,14 @@ export const AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) =>
|
|
|
157
140
|
message: "bindings is not supported in 0.9.0 (Tier B); it is neither emitted nor accepted",
|
|
158
141
|
});
|
|
159
142
|
}
|
|
160
|
-
//
|
|
161
|
-
// `
|
|
162
|
-
// `defaultBundle` fully supersede it. A pre-cutover config never loads through
|
|
163
|
-
// this validated path; the migrator ({@link migrateConfigSourcesToBundles})
|
|
164
|
-
// normalizes old→bundles BEFORE validation, and `inspectConfig` classifies an
|
|
165
|
-
// old-shape-alone config "old" (migration-eligible) via that same normalize.
|
|
143
|
+
// Only the current source shape enters the runtime. There is no config
|
|
144
|
+
// compatibility path; `bundles` + `defaultBundle` fully supersede these keys.
|
|
166
145
|
for (const key of ["stashDir", "sources", "installed"]) {
|
|
167
146
|
if (key in raw && raw[key] !== undefined) {
|
|
168
147
|
ctx.addIssue({
|
|
169
148
|
code: z.ZodIssueCode.custom,
|
|
170
149
|
path: [key],
|
|
171
|
-
message: RETIRED_SOURCE_SHAPE_KEY_MESSAGES[key] ??
|
|
172
|
-
`${key} is the retired pre-cutover source shape; run \`akm-migrate apply\` to convert it to bundles`,
|
|
150
|
+
message: RETIRED_SOURCE_SHAPE_KEY_MESSAGES[key] ?? `${key} is not supported; configure the current bundles shape`,
|
|
173
151
|
});
|
|
174
152
|
}
|
|
175
153
|
}
|
|
@@ -295,7 +273,7 @@ export const AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) =>
|
|
|
295
273
|
}
|
|
296
274
|
}
|
|
297
275
|
const judgmentEngine = processConfig.judgment?.engine;
|
|
298
|
-
if (judgmentEngine) {
|
|
276
|
+
if (processConfig.judgment?.enabled === true && judgmentEngine) {
|
|
299
277
|
const engine = config.engines?.[judgmentEngine];
|
|
300
278
|
if (!engine) {
|
|
301
279
|
ctx.addIssue({
|
|
@@ -2,9 +2,8 @@
|
|
|
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
|
-
* Runtime helpers that derive {@link ConfiguredSource}
|
|
6
|
-
*
|
|
7
|
-
* in an {@link AkmConfig}.
|
|
5
|
+
* Runtime helpers that derive provider-ready and {@link ConfiguredSource}
|
|
6
|
+
* values from the current bundle map in an {@link AkmConfig}.
|
|
8
7
|
*/
|
|
9
8
|
import { createHash } from "node:crypto";
|
|
10
9
|
import path from "node:path";
|
|
@@ -20,15 +19,9 @@ export function bundleComponentConfig(bundle) {
|
|
|
20
19
|
return components[0];
|
|
21
20
|
}
|
|
22
21
|
/**
|
|
23
|
-
* Convert
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* insertion order (preserving today's installation-priority semantics, on which
|
|
27
|
-
* D-R4 short-ref resolution depends). Each entry's `name` IS its bundle key, so
|
|
28
|
-
* `deriveInstallations` re-derives the exact same installation id (D-R5 rule 1).
|
|
29
|
-
*
|
|
30
|
-
* Returns `undefined` for an old-shape config (no `bundles`), so callers fall
|
|
31
|
-
* back to the pre-cutover `stashDir`/`sources[]`/`installed[]` resolution.
|
|
22
|
+
* Convert the current `bundles` map into its ordered provider projection:
|
|
23
|
+
* `defaultBundle` first, then map insertion order. Each entry's `name` is its
|
|
24
|
+
* bundle key. Returns `undefined` when no bundles map is configured.
|
|
32
25
|
*/
|
|
33
26
|
/**
|
|
34
27
|
* The resolved primary stash path — the `defaultBundle`'s filesystem `path`
|
|
@@ -83,9 +76,7 @@ export function bundleEntryToSourceEntry(key, bundle, isPrimary = false) {
|
|
|
83
76
|
return { type: "git", url: normalizeInstalledGitRef("", bundle.git), ...base };
|
|
84
77
|
}
|
|
85
78
|
if (bundle.website && typeof bundle.website.url === "string") {
|
|
86
|
-
// All non-`url` website-descriptor keys
|
|
87
|
-
// passthrough provider options) round-trip back to the runtime entry's
|
|
88
|
-
// `options` bag, mirroring the pre-cutover `sources[].options` shape.
|
|
79
|
+
// All non-`url` website-descriptor keys become provider options.
|
|
89
80
|
const { url, ...rest } = bundle.website;
|
|
90
81
|
return {
|
|
91
82
|
type: "website",
|
|
@@ -144,9 +135,9 @@ function normalizeInstalledGitRef(source, ref) {
|
|
|
144
135
|
return requestedRef ? `${cloneUrl}/tree/${requestedRef}` : cloneUrl;
|
|
145
136
|
}
|
|
146
137
|
/**
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
138
|
+
* Produce a stable internal identifier for a provider projection. Current
|
|
139
|
+
* bundle-derived entries always carry `name`; the hash protects manually
|
|
140
|
+
* constructed internal values.
|
|
150
141
|
*/
|
|
151
142
|
function deriveBundleName(entry) {
|
|
152
143
|
if (entry.name)
|
|
@@ -160,7 +151,7 @@ function deriveBundleName(entry) {
|
|
|
160
151
|
return `${entry.type}-${hash}`;
|
|
161
152
|
}
|
|
162
153
|
/**
|
|
163
|
-
* Convert a
|
|
154
|
+
* Convert a provider-ready {@link SourceConfigEntry} into the runtime
|
|
164
155
|
* {@link SourceSpec} discriminated union. Returns `undefined` when the entry
|
|
165
156
|
* is missing the fields its provider type requires (e.g. a `filesystem`
|
|
166
157
|
* entry with no `path`); callers should drop or warn for those.
|
|
@@ -189,8 +180,7 @@ export function parseSourceSpec(entry) {
|
|
|
189
180
|
* Build the full ordered list of runtime {@link ConfiguredSource} values from a
|
|
190
181
|
* loaded {@link AkmConfig}, resolved from `bundles` + `defaultBundle` (spec
|
|
191
182
|
* §10.1): the `defaultBundle` (primary) first, then map insertion order. The
|
|
192
|
-
* retired `stashDir`/`sources[]`/`installed[]` trio is
|
|
193
|
-
* pre-cutover config is normalized to bundles by the migrator before it loads.
|
|
183
|
+
* retired `stashDir`/`sources[]`/`installed[]` trio is never read or normalized.
|
|
194
184
|
*
|
|
195
185
|
* Entries with `enabled: false` are still emitted — callers decide whether to
|
|
196
186
|
* honour the flag. Entries that fail {@link parseSourceSpec} drop silently.
|
|
@@ -180,11 +180,26 @@ export function configSet(config, dotted, raw) {
|
|
|
180
180
|
if (!schema && !symbolicApiKey) {
|
|
181
181
|
throw new UsageError(`Unknown config key: ${dotted}`, "INVALID_FLAG_VALUE", unknownKeyHint(dotted));
|
|
182
182
|
}
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
const judgmentObjectPath = isTriageJudgmentPath(path);
|
|
184
|
+
const value = judgmentObjectPath && raw === "null"
|
|
185
|
+
? undefined
|
|
186
|
+
: path[0] === "engines" && path.length === 2
|
|
187
|
+
? parseObjectPatch(raw, dotted)
|
|
188
|
+
: symbolicApiKey
|
|
189
|
+
? raw
|
|
190
|
+
: coerceForSchema(schema, raw, dotted);
|
|
191
|
+
const existing = path.reduce((value, key) => {
|
|
192
|
+
if (value && typeof value === "object")
|
|
193
|
+
return value[key];
|
|
194
|
+
return undefined;
|
|
195
|
+
}, config);
|
|
196
|
+
// The judgment leaf supplies `enabled: true` when the field is omitted.
|
|
197
|
+
// Merge a JSON object patch with the existing value before that current
|
|
198
|
+
// schema transform,
|
|
199
|
+
// otherwise the synthesized default can overwrite an explicit false.
|
|
200
|
+
const candidate = judgmentObjectPath && isPlainObject(value)
|
|
201
|
+
? deepMergeConfig(isPlainObject(existing) ? existing : {}, value)
|
|
202
|
+
: value;
|
|
188
203
|
// Validate the coerced value against the leaf schema. This catches enum
|
|
189
204
|
// mismatches, out-of-range numbers, schema-level shape errors (writable
|
|
190
205
|
// npm/website sources via .superRefine, strict-mode unknown keys in nested
|
|
@@ -195,7 +210,7 @@ export function configSet(config, dotted, raw) {
|
|
|
195
210
|
? /^\$[A-Za-z_][A-Za-z0-9_]*$|^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(raw)
|
|
196
211
|
? { success: true, data: value }
|
|
197
212
|
: { success: false, error: { issues: [{ path: [], message: `apiKey must be $VAR or \${VAR}` }] } }
|
|
198
|
-
: schema.safeParse(
|
|
213
|
+
: schema.safeParse(candidate);
|
|
199
214
|
if (!parsed.success) {
|
|
200
215
|
const lines = parsed.error.issues
|
|
201
216
|
.map((i) => {
|
|
@@ -205,11 +220,6 @@ export function configSet(config, dotted, raw) {
|
|
|
205
220
|
.join("\n");
|
|
206
221
|
throw new UsageError(`Invalid value for ${dotted}:\n${lines}`, "INVALID_FLAG_VALUE");
|
|
207
222
|
}
|
|
208
|
-
const existing = path.reduce((value, key) => {
|
|
209
|
-
if (value && typeof value === "object")
|
|
210
|
-
return value[key];
|
|
211
|
-
return undefined;
|
|
212
|
-
}, config);
|
|
213
223
|
const next = setPath(config, path, isPlainObject(existing) && isPlainObject(parsed.data) ? deepMergeConfig(existing, parsed.data) : parsed.data);
|
|
214
224
|
// Targeted invariant: defaultWriteTarget must point at a configured bundle
|
|
215
225
|
// (#464.a). Whole-config validation happens at save time; this check fires
|
|
@@ -223,6 +233,14 @@ export function configSet(config, dotted, raw) {
|
|
|
223
233
|
}
|
|
224
234
|
return next;
|
|
225
235
|
}
|
|
236
|
+
function isTriageJudgmentPath(path) {
|
|
237
|
+
return (path.length === 6 &&
|
|
238
|
+
path[0] === "improve" &&
|
|
239
|
+
path[1] === "strategies" &&
|
|
240
|
+
path[3] === "processes" &&
|
|
241
|
+
path[4] === "triage" &&
|
|
242
|
+
path[5] === "judgment");
|
|
243
|
+
}
|
|
226
244
|
/**
|
|
227
245
|
* Unset the value at the dotted path. Removes the leaf key (and prunes empty
|
|
228
246
|
* parent objects if they become empty). Returns a new config object.
|
|
@@ -411,8 +429,8 @@ function unsetPath(config, path) {
|
|
|
411
429
|
*/
|
|
412
430
|
const RETIRED_KEY_HINTS = {
|
|
413
431
|
stashDir: "stashDir was removed in 0.9; get the stash path from `akm config path --all` or `akm info`.",
|
|
414
|
-
sources: "sources
|
|
415
|
-
installed: "installed
|
|
432
|
+
sources: "sources is not supported; configure `bundles` instead.",
|
|
433
|
+
installed: "installed is not supported; configure `bundles` instead.",
|
|
416
434
|
wikiName: "the wiki subsystem was removed in 0.9; wikis are ordinary knowledge assets now — see `akm import`.",
|
|
417
435
|
wiki: "the wiki subsystem was removed in 0.9; wikis are ordinary knowledge assets now — see `akm import`.",
|
|
418
436
|
llm: "llm was replaced by named engines configuration in 0.9; configure `engines` instead.",
|
|
@@ -4,19 +4,11 @@
|
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { ConfigError } from "../errors.js";
|
|
7
|
-
import { assertNoPendingMigrationOperation } from "../migration-operation.js";
|
|
8
7
|
import { acquireConfigLock, backupExistingConfig, parseConfigText, readConfigText, withConfigLock, writeConfigAtomic, } from "./config-io.js";
|
|
9
8
|
import { AkmConfigSchema, CURRENT_CONFIG_VERSION } from "./config-schema.js";
|
|
10
9
|
import { bundlesToSourceEntries } from "./config-sources.js";
|
|
11
10
|
import { deepMergeConfig } from "./deep-merge.js";
|
|
12
11
|
export { stripJsonComments } from "./config-io.js";
|
|
13
|
-
// requireLlmConfig / getDefaultLlmConfig moved to
|
|
14
|
-
// integrations/agent/engine-resolution.ts (WI-9.8 KILL 3, D.3 edge A) — they
|
|
15
|
-
// called that module's materializeLlmConnection/resolveLlmEngineUse, and that
|
|
16
|
-
// module imported LlmConnectionConfig back from this file, closing a 2-file
|
|
17
|
-
// cycle that also fused config.ts into the harness/agent-runtime SCC. This
|
|
18
|
-
// file can no longer re-export them (a re-export is still a graph edge to
|
|
19
|
-
// engine-resolution.ts) — import them from there directly.
|
|
20
12
|
import { getConfigPath } from "../paths.js";
|
|
21
13
|
import { warn } from "../warn.js";
|
|
22
14
|
// Canonical harness-id source of truth (#565) — runtime value re-export.
|
|
@@ -74,7 +66,6 @@ export function resetConfigCache() {
|
|
|
74
66
|
cachedConfig = undefined;
|
|
75
67
|
}
|
|
76
68
|
export function loadUserConfig() {
|
|
77
|
-
assertNoPendingMigrationOperation();
|
|
78
69
|
const configPath = getConfigPath();
|
|
79
70
|
let stat;
|
|
80
71
|
try {
|
|
@@ -124,6 +115,24 @@ export function loadUserConfig() {
|
|
|
124
115
|
};
|
|
125
116
|
return finalConfig;
|
|
126
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Acquire the existing config-write sentinel and read a fresh validated
|
|
120
|
+
* generation while keeping the sentinel held. Source update uses this to
|
|
121
|
+
* fence an audited bundle descriptor through publication: a cooperating
|
|
122
|
+
* config writer can commit either before this snapshot or after the update,
|
|
123
|
+
* never between the final generation check and index commit.
|
|
124
|
+
*/
|
|
125
|
+
export function acquireConfigReadFence() {
|
|
126
|
+
const release = acquireConfigLock();
|
|
127
|
+
try {
|
|
128
|
+
cachedConfig = undefined;
|
|
129
|
+
return { config: loadUserConfig(), release };
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
release();
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
127
136
|
/**
|
|
128
137
|
* Parse raw config text and validate via Zod.
|
|
129
138
|
* ({@link AkmConfigSchema}). Returns the merged-with-defaults AkmConfig.
|
|
@@ -153,11 +162,9 @@ export function parseAndValidateConfigText(text, sourcePath) {
|
|
|
153
162
|
/**
|
|
154
163
|
* The configured stash sources as an ordered {@link SourceConfigEntry} list.
|
|
155
164
|
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* that iterated `sources[]` keep working over the new shape. Returns `[]` when
|
|
160
|
-
* no bundles are configured.
|
|
165
|
+
* Every source is a `bundles.<slug>` entry. This derives the provider-ready
|
|
166
|
+
* source list from `bundles` (defaultBundle first, then map order). Returns
|
|
167
|
+
* `[]` when no bundles are configured.
|
|
161
168
|
*/
|
|
162
169
|
export function getSources(config) {
|
|
163
170
|
return bundlesToSourceEntries(config) ?? [];
|
|
@@ -181,13 +188,11 @@ export function saveConfig(config) {
|
|
|
181
188
|
saveConfigReal(currentConfig);
|
|
182
189
|
}
|
|
183
190
|
function saveConfigReal(config) {
|
|
184
|
-
assertNoPendingMigrationOperation();
|
|
185
191
|
cachedConfig = undefined;
|
|
186
192
|
const configPath = getConfigPath();
|
|
187
193
|
const dir = path.dirname(configPath);
|
|
188
194
|
fs.mkdirSync(dir, { recursive: true });
|
|
189
195
|
withConfigLock(() => {
|
|
190
|
-
assertNoPendingMigrationOperation();
|
|
191
196
|
const validated = validateCompleteConfig(config);
|
|
192
197
|
backupExistingConfig(configPath);
|
|
193
198
|
writeConfigAtomic(configPath, sanitizeConfigForWrite(validated));
|
|
@@ -206,11 +211,9 @@ export function validateCompleteConfig(config) {
|
|
|
206
211
|
* ordinary backup, and atomic write.
|
|
207
212
|
*/
|
|
208
213
|
export function mutateConfig(mutate, options) {
|
|
209
|
-
assertNoPendingMigrationOperation();
|
|
210
214
|
cachedConfig = undefined;
|
|
211
215
|
const configPath = getConfigPath();
|
|
212
216
|
return withConfigLock(() => {
|
|
213
|
-
assertNoPendingMigrationOperation();
|
|
214
217
|
const text = readConfigText(configPath);
|
|
215
218
|
if (text === undefined && options?.absentNoop) {
|
|
216
219
|
return { config: { ...DEFAULT_CONFIG }, written: false };
|
|
@@ -233,12 +236,10 @@ export function mutateConfig(mutate, options) {
|
|
|
233
236
|
* its stash, while preventing another config writer from racing the final save.
|
|
234
237
|
*/
|
|
235
238
|
export async function mutateConfigWithPrecommit(mutate, precommit) {
|
|
236
|
-
assertNoPendingMigrationOperation();
|
|
237
239
|
cachedConfig = undefined;
|
|
238
240
|
const configPath = getConfigPath();
|
|
239
241
|
const release = acquireConfigLock();
|
|
240
242
|
try {
|
|
241
|
-
assertNoPendingMigrationOperation();
|
|
242
243
|
const text = readConfigText(configPath);
|
|
243
244
|
const current = text === undefined ? { ...DEFAULT_CONFIG } : parseAndValidateConfigText(text, configPath);
|
|
244
245
|
const mutated = mutate(current);
|
|
@@ -346,12 +347,8 @@ export function resolveSecret(value) {
|
|
|
346
347
|
* filtering out the reserved feature-section keys so callers don't mistake
|
|
347
348
|
* `metadataEnhance` for a pass.
|
|
348
349
|
*/
|
|
349
|
-
/**
|
|
350
|
-
|
|
351
|
-
* `indexBodyOpening` (stash-conventions SPEC-8) is a boolean feature flag, not
|
|
352
|
-
* a pass section.
|
|
353
|
-
*/
|
|
354
|
-
const INDEX_RESERVED_KEYS = new Set(["metadataEnhance", "indexBodyOpening"]);
|
|
350
|
+
/** Reserved well-known keys on IndexConfig that are NOT per-pass entries. */
|
|
351
|
+
const INDEX_RESERVED_KEYS = new Set(["metadataEnhance"]);
|
|
355
352
|
export function getIndexPassConfig(config, passName) {
|
|
356
353
|
if (!config)
|
|
357
354
|
return undefined;
|
|
@@ -15,7 +15,7 @@ import { z } from "zod";
|
|
|
15
15
|
// a config-schema ↔ config-types type cycle that collapses inference.
|
|
16
16
|
import { HARNESS_AGENT_DISPATCH_IDS, VALID_HARNESS_IDS } from "../../../integrations/harnesses/ids.js";
|
|
17
17
|
import { WORKFLOW_MAX_TIMEOUT_MS } from "../../../workflows/resource-limits.js";
|
|
18
|
-
import { chatCompletionsEndpoint, ENV_REFERENCE_PATTERN, ExtraParamsSchema, engineName, LlmCapabilitiesSchema,
|
|
18
|
+
import { chatCompletionsEndpoint, ENV_REFERENCE_PATTERN, ExtraParamsSchema, engineName, LlmCapabilitiesSchema, nonEmptyString, positiveInt, } from "./primitives.js";
|
|
19
19
|
/**
|
|
20
20
|
* Engine-config timeouts share the workflow ceiling.
|
|
21
21
|
*
|
|
@@ -29,11 +29,9 @@ const timeoutMsField = z.union([positiveInt.max(WORKFLOW_MAX_TIMEOUT_MS), z.null
|
|
|
29
29
|
// ── Connection configs (LLM) ────────────────────────────────────────────────
|
|
30
30
|
/**
|
|
31
31
|
* OpenAI-compatible connection fields shared by named LLM engines and bounded
|
|
32
|
-
* internal call helpers. `model` is required at schema level
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* pre-Zod migrator hook, so this strict shape gates CLI writes without
|
|
36
|
-
* breaking legacy load-time partial configs.
|
|
32
|
+
* internal call helpers. `model` is required at schema level: current loads and
|
|
33
|
+
* CLI writes reject a partial named engine rather than normalizing it through a
|
|
34
|
+
* pre-schema compatibility transform.
|
|
37
35
|
*/
|
|
38
36
|
export const LlmConnectionConfigSchema = z
|
|
39
37
|
.object({
|
|
@@ -49,6 +47,7 @@ export const LlmConnectionConfigSchema = z
|
|
|
49
47
|
extraParams: ExtraParamsSchema.optional(),
|
|
50
48
|
contextLength: positiveInt.optional(),
|
|
51
49
|
enableThinking: z.boolean().optional(),
|
|
50
|
+
reasoningEffort: nonEmptyString.optional(),
|
|
52
51
|
})
|
|
53
52
|
.passthrough();
|
|
54
53
|
export const LlmProfileConfigSchema = LlmConnectionConfigSchema.extend({
|
|
@@ -73,6 +72,7 @@ const LlmEngineSchema = z
|
|
|
73
72
|
extraParams: ExtraParamsSchema.optional(),
|
|
74
73
|
contextLength: positiveInt.optional(),
|
|
75
74
|
enableThinking: z.boolean().optional(),
|
|
75
|
+
reasoningEffort: nonEmptyString.optional(),
|
|
76
76
|
})
|
|
77
77
|
.passthrough()
|
|
78
78
|
.superRefine((value, ctx) => {
|
|
@@ -92,7 +92,6 @@ const AgentEngineSchema = z
|
|
|
92
92
|
workspace: nonEmptyString.optional(),
|
|
93
93
|
model: nonEmptyString.optional(),
|
|
94
94
|
timeoutMs: timeoutMsField,
|
|
95
|
-
modelAliases: ModelAliasMapSchema.optional(),
|
|
96
95
|
llmEngine: engineName.optional(),
|
|
97
96
|
})
|
|
98
97
|
.passthrough()
|
|
@@ -108,6 +107,8 @@ const AgentEngineSchema = z
|
|
|
108
107
|
"extraParams",
|
|
109
108
|
"contextLength",
|
|
110
109
|
"enableThinking",
|
|
110
|
+
"reasoningEffort",
|
|
111
|
+
"modelAliases",
|
|
111
112
|
]) {
|
|
112
113
|
if (key in value)
|
|
113
114
|
ctx.addIssue({ code: z.ZodIssueCode.custom, path: [key], message: `${key} is not valid on an agent engine` });
|
|
@@ -100,15 +100,32 @@ const extractTriageGateField = z
|
|
|
100
100
|
})
|
|
101
101
|
.passthrough()
|
|
102
102
|
.optional();
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
const triageJudgmentErrorMap = (issue, ctx) => {
|
|
104
|
+
if (issue.code === z.ZodIssueCode.unrecognized_keys) {
|
|
105
|
+
const retired = issue.keys.find((key) => key === "mode" || key === "profile");
|
|
106
|
+
if (retired)
|
|
107
|
+
return { message: `${retired} is retired; use engine` };
|
|
108
|
+
}
|
|
109
|
+
return { message: ctx.defaultError };
|
|
110
|
+
};
|
|
111
|
+
// Judgment is an explicit opt-in surface, so invocation typos must fail closed.
|
|
112
|
+
// Keep the shared override schema lenient for ordinary cross-version config
|
|
113
|
+
// compatibility, while making this nested surface strict. `extraParams`
|
|
114
|
+
// remains the intentional arbitrary provider-parameter escape hatch.
|
|
115
|
+
const triageJudgmentLlmOverridesField = LlmInvocationOverridesSchema.strict();
|
|
116
|
+
const triageJudgmentObjectField = z
|
|
105
117
|
.object({
|
|
118
|
+
enabled: z.boolean().optional(),
|
|
106
119
|
engine: engineName.optional(),
|
|
107
120
|
model: nonEmptyString.optional(),
|
|
108
121
|
timeoutMs: z.union([positiveInt, z.null()]).optional(),
|
|
109
|
-
llm:
|
|
110
|
-
})
|
|
111
|
-
.
|
|
122
|
+
llm: triageJudgmentLlmOverridesField.optional(),
|
|
123
|
+
}, { errorMap: triageJudgmentErrorMap })
|
|
124
|
+
.strict();
|
|
125
|
+
/** Triage process: explicit LLM-as-judge enablement and execution overrides. */
|
|
126
|
+
const triageJudgmentField = z
|
|
127
|
+
.union([z.boolean(), triageJudgmentObjectField])
|
|
128
|
+
.transform((value) => typeof value === "boolean" ? { enabled: value } : { ...value, enabled: value.enabled ?? true })
|
|
112
129
|
.optional();
|
|
113
130
|
/**
|
|
114
131
|
* WS-3b: Anti-collapse guards (step 8). Prevents the consolidation pipeline
|
|
@@ -256,6 +273,13 @@ function checkRetiredProcessKeys(value, ctx) {
|
|
|
256
273
|
ctx.addIssue({ code: z.ZodIssueCode.custom, path: [key], message: `${key} is retired; use engine` });
|
|
257
274
|
}
|
|
258
275
|
}
|
|
276
|
+
if ("judgement" in value) {
|
|
277
|
+
ctx.addIssue({
|
|
278
|
+
code: z.ZodIssueCode.custom,
|
|
279
|
+
path: ["judgement"],
|
|
280
|
+
message: "judgement is not a valid key; use judgment",
|
|
281
|
+
});
|
|
282
|
+
}
|
|
259
283
|
const judgment = value.judgment;
|
|
260
284
|
if (judgment) {
|
|
261
285
|
for (const key of ["mode", "profile"]) {
|
|
@@ -99,14 +99,6 @@ const IndexDefaultsSchema = z
|
|
|
99
99
|
* Index config is a union of reserved feature sections and per-pass entries.
|
|
100
100
|
* Passthrough so per-pass entries (keyed by arbitrary pass names like `graph`,
|
|
101
101
|
* `enrichment`) can live next to the reserved keys.
|
|
102
|
-
*
|
|
103
|
-
* Reserved scalar key `indexBodyOpening` (stash-conventions SPEC-8, default
|
|
104
|
-
* false): when true, the metadata pass captures the first prose paragraph of
|
|
105
|
-
* each markdown asset body into `entry.bodyOpening`, which folds into the
|
|
106
|
-
* lowest-weight `content` FTS column and the embedding text. It is a boolean,
|
|
107
|
-
* not a per-pass object — the preprocess below exempts it from the
|
|
108
|
-
* object-shape check so it never routes into the per-pass catchall.
|
|
109
|
-
*
|
|
110
102
|
* The outer preprocess emits the legacy parser's actionable error messages
|
|
111
103
|
* for the two most common type-shape mistakes:
|
|
112
104
|
* - An array at the `index` block.
|
|
@@ -136,17 +128,6 @@ const IndexConfigRuntimeSchema = z.preprocess((raw, ctx) => {
|
|
|
136
128
|
});
|
|
137
129
|
return raw;
|
|
138
130
|
}
|
|
139
|
-
if (passName === "indexBodyOpening") {
|
|
140
|
-
if (typeof value !== "boolean") {
|
|
141
|
-
ctx.addIssue({
|
|
142
|
-
code: z.ZodIssueCode.custom,
|
|
143
|
-
message: "Invalid `index.indexBodyOpening`: expected a boolean (true to index the first body paragraph " +
|
|
144
|
-
`of markdown assets into search). Got ${Array.isArray(value) ? "array" : typeof value}.`,
|
|
145
|
-
});
|
|
146
|
-
return raw;
|
|
147
|
-
}
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
131
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
151
132
|
ctx.addIssue({
|
|
152
133
|
code: z.ZodIssueCode.custom,
|
|
@@ -160,14 +141,6 @@ const IndexConfigRuntimeSchema = z.preprocess((raw, ctx) => {
|
|
|
160
141
|
.object({
|
|
161
142
|
defaults: IndexDefaultsSchema.optional(),
|
|
162
143
|
metadataEnhance: MetadataEnhanceSchema.optional(),
|
|
163
|
-
indexBodyOpening: z
|
|
164
|
-
.boolean()
|
|
165
|
-
.optional()
|
|
166
|
-
.describe("Index the first prose paragraph of each markdown asset body (capped at 280 chars) into the " +
|
|
167
|
-
"lowest-weight `content` search column and the embedding text (default false). Secret/env files " +
|
|
168
|
-
"and session-kind memories are never captured. Toggling the flag changes indexed text: run " +
|
|
169
|
-
"`akm index --full` afterwards to re-extract every entry and regenerate embeddings, and re-mint " +
|
|
170
|
-
"collapse-detector canary baselines via `bun scripts/refresh-canary-set.ts --refresh`."),
|
|
171
144
|
})
|
|
172
145
|
.catchall(IndexPassConfigSchema));
|
|
173
146
|
// The runtime catchall correctly validates arbitrary pass objects, but its
|
|
@@ -53,29 +53,6 @@ export const ExtraParamsSchema = z.record(z.unknown()).superRefine((value, ctx)
|
|
|
53
53
|
ctx.addIssue({ code: z.ZodIssueCode.custom, path: issue.path, message: issue.message });
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
|
-
function normalizeAliasKeys(raw, ctx) {
|
|
57
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
58
|
-
return raw;
|
|
59
|
-
const normalized = {};
|
|
60
|
-
const originalByKey = new Map();
|
|
61
|
-
for (const [key, value] of Object.entries(raw)) {
|
|
62
|
-
const lower = key.toLowerCase();
|
|
63
|
-
const previous = originalByKey.get(lower);
|
|
64
|
-
if (previous !== undefined) {
|
|
65
|
-
ctx.addIssue({
|
|
66
|
-
code: z.ZodIssueCode.custom,
|
|
67
|
-
path: [key],
|
|
68
|
-
message: `alias collides case-insensitively with ${previous}`,
|
|
69
|
-
});
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
originalByKey.set(lower, key);
|
|
73
|
-
normalized[lower] = value;
|
|
74
|
-
}
|
|
75
|
-
return normalized;
|
|
76
|
-
}
|
|
77
|
-
export const ModelAliasMapSchema = z.preprocess((raw, ctx) => normalizeAliasKeys(raw, ctx), z.record(z.string().min(1), z.string().min(1)));
|
|
78
|
-
export const GlobalModelAliasesSchema = z.preprocess((raw, ctx) => normalizeAliasKeys(raw, ctx), z.record(z.string().min(1), z.record(z.string().min(1), z.string().min(1))));
|
|
79
56
|
// ── Shared connection/invocation building blocks ────────────────────────────
|
|
80
57
|
export const LlmCapabilitiesSchema = z
|
|
81
58
|
.object({
|
|
@@ -90,5 +67,6 @@ export const LlmInvocationOverridesSchema = z
|
|
|
90
67
|
extraParams: ExtraParamsSchema.optional(),
|
|
91
68
|
contextLength: positiveInt.optional(),
|
|
92
69
|
enableThinking: z.boolean().optional(),
|
|
70
|
+
reasoningEffort: nonEmptyString.optional(),
|
|
93
71
|
})
|
|
94
72
|
.passthrough();
|