akm-cli 0.9.17-alpha.3 → 0.9.17-alpha.5

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.
Files changed (346) hide show
  1. package/CHANGELOG.md +760 -0
  2. package/dist/akm +94 -196
  3. package/dist/cli/shared.js +6 -2
  4. package/dist/cli.js +22 -9
  5. package/dist/commands/agent/agent-dispatch.js +1 -1
  6. package/dist/commands/command/command-execution.js +24 -62
  7. package/dist/commands/feedback-cli.js +0 -1
  8. package/dist/commands/health/accept-rate.js +2 -2
  9. package/dist/commands/health/checks.js +30 -75
  10. package/dist/commands/health/config-skew.js +38 -0
  11. package/dist/commands/health/egress.js +54 -0
  12. package/dist/commands/health/html-report.js +0 -38
  13. package/dist/commands/health/improve-metrics.js +123 -562
  14. package/dist/commands/health/plugin-staleness.js +53 -3
  15. package/dist/commands/health/renderers.js +12 -4
  16. package/dist/commands/health/report-view-model.js +11 -106
  17. package/dist/commands/health/types-improve.js +4 -19
  18. package/dist/commands/health/windows.js +64 -73
  19. package/dist/commands/health.js +122 -143
  20. package/dist/commands/improve/consolidate/chunking.js +25 -100
  21. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  22. package/dist/commands/improve/consolidate.js +538 -1075
  23. package/dist/commands/improve/content-hash.js +16 -24
  24. package/dist/commands/improve/distill/content-repair.js +18 -100
  25. package/dist/commands/improve/distill-guards.js +20 -81
  26. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  27. package/dist/commands/improve/distill.js +608 -1075
  28. package/dist/commands/improve/eligibility.js +126 -400
  29. package/dist/commands/improve/execution.js +3 -5
  30. package/dist/commands/improve/extract.js +487 -1046
  31. package/dist/commands/improve/feedback-valence.js +0 -25
  32. package/dist/commands/improve/improve-cli.js +29 -166
  33. package/dist/commands/improve/improve-result-file.js +10 -66
  34. package/dist/commands/improve/improve-strategies.js +12 -7
  35. package/dist/commands/improve/improve-usage-report.js +18 -64
  36. package/dist/commands/improve/improve.js +443 -1063
  37. package/dist/commands/improve/ledger.js +114 -0
  38. package/dist/commands/improve/locks.js +2 -8
  39. package/dist/commands/improve/loop-stages.js +459 -1172
  40. package/dist/commands/improve/memory/derived-ref.js +12 -77
  41. package/dist/commands/improve/memory/memory-belief.js +14 -118
  42. package/dist/commands/improve/memory/memory-improve.js +4 -3
  43. package/dist/commands/improve/outcome-loop.js +28 -156
  44. package/dist/commands/improve/planner.js +5 -10
  45. package/dist/commands/improve/preparation.js +851 -2339
  46. package/dist/commands/improve/proactive-maintenance.js +34 -101
  47. package/dist/commands/improve/reflect-noise.js +104 -280
  48. package/dist/commands/improve/reflect.js +621 -1367
  49. package/dist/commands/improve/salience.js +46 -232
  50. package/dist/commands/improve/session-asset.js +19 -100
  51. package/dist/commands/improve/stage.js +323 -0
  52. package/dist/commands/lint/base-linter.js +19 -5
  53. package/dist/commands/proposal/drain.js +251 -644
  54. package/dist/commands/proposal/proposal-cli.js +3 -18
  55. package/dist/commands/proposal/proposal-types.js +20 -41
  56. package/dist/commands/proposal/proposal.js +1 -2
  57. package/dist/commands/proposal/propose.js +134 -160
  58. package/dist/commands/proposal/repository.js +502 -1487
  59. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  60. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  61. package/dist/commands/proposal/validators/proposals.js +13 -89
  62. package/dist/commands/read/curate.js +63 -413
  63. package/dist/commands/read/search-cli.js +16 -33
  64. package/dist/commands/read/search.js +17 -23
  65. package/dist/commands/read/show.js +2 -13
  66. package/dist/commands/sources/bundle-cli.js +25 -2
  67. package/dist/commands/sources/bundle-config-ops.js +4 -0
  68. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  69. package/dist/commands/sources/info.js +2 -11
  70. package/dist/commands/sources/installed-stashes.js +197 -746
  71. package/dist/commands/sources/schema-repair.js +98 -129
  72. package/dist/commands/sources/source-add.js +62 -12
  73. package/dist/commands/sources/source-manage.js +9 -2
  74. package/dist/commands/sources/stash-cli.js +1 -1
  75. package/dist/commands/tasks/explain.js +10 -13
  76. package/dist/commands/tasks/tasks-cli.js +9 -8
  77. package/dist/commands/tasks/tasks.js +326 -930
  78. package/dist/commands/tasks/validate.js +42 -21
  79. package/dist/commands/workflow/plan.js +22 -29
  80. package/dist/commands/workflow-cli.js +4 -4
  81. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  82. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  83. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  84. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  85. package/dist/core/adapter/execution-source.js +17 -29
  86. package/dist/core/asset/asset-placement.js +4 -13
  87. package/dist/core/asset/resolve-ref.js +1 -1
  88. package/dist/core/bundle-id.js +42 -5
  89. package/dist/core/bundle-rename.js +291 -0
  90. package/dist/core/config/config-io.js +1 -2
  91. package/dist/core/config/config-schema.js +1 -33
  92. package/dist/core/config/config-walker.js +1 -1
  93. package/dist/core/config/config.js +163 -68
  94. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  95. package/dist/core/config/schema/embedding.js +20 -5
  96. package/dist/core/config/schema/engines.js +5 -0
  97. package/dist/core/config/schema/execution.js +1 -1
  98. package/dist/core/config/schema/experimental.js +1 -1
  99. package/dist/core/config/schema/improve-processes.js +21 -95
  100. package/dist/core/config/schema/improve.js +4 -42
  101. package/dist/core/config/schema/scheduler.js +12 -12
  102. package/dist/core/config/schema/search.js +6 -22
  103. package/dist/core/env-secret-ref.js +0 -1
  104. package/dist/core/errors.js +8 -9
  105. package/dist/core/file-lock.js +76 -173
  106. package/dist/core/logs-db.js +2 -2
  107. package/dist/core/paths.js +0 -27
  108. package/dist/core/redaction.js +109 -2
  109. package/dist/core/run-lock.js +2 -5
  110. package/dist/core/spawn-env.js +1 -1
  111. package/dist/core/state/migrations.js +108 -61
  112. package/dist/core/state-db-scope.js +2 -4
  113. package/dist/core/state-db.js +126 -692
  114. package/dist/core/type-presentation.js +1 -9
  115. package/dist/core/write-source.js +293 -1012
  116. package/dist/execution/input-contract.js +1 -1
  117. package/dist/execution/resolved-request.js +135 -689
  118. package/dist/execution/source.js +63 -257
  119. package/dist/execution/target-ref.js +1 -1
  120. package/dist/indexer/bundle-identity-guard.js +2 -2
  121. package/dist/indexer/db/graph-db.js +106 -46
  122. package/dist/indexer/ensure-index.js +44 -85
  123. package/dist/indexer/graph/graph-extraction.js +340 -562
  124. package/dist/indexer/graph/graph-related.js +130 -0
  125. package/dist/indexer/index-rebuild-lock.js +3 -11
  126. package/dist/indexer/index-writer-lock.js +8 -17
  127. package/dist/indexer/index-written-assets.js +139 -151
  128. package/dist/indexer/indexer.js +524 -846
  129. package/dist/indexer/materialize-embeddings.js +60 -397
  130. package/dist/indexer/passes/memory-inference.js +81 -90
  131. package/dist/indexer/passes/metadata.js +132 -200
  132. package/dist/indexer/read-preflight.js +0 -7
  133. package/dist/indexer/scan/doc-to-entry.js +1 -3
  134. package/dist/indexer/scan/drain-dir.js +1 -1
  135. package/dist/indexer/search/db-search.js +181 -590
  136. package/dist/indexer/search/fts-query.js +30 -41
  137. package/dist/indexer/search/ranking.js +28 -154
  138. package/dist/indexer/search/search-attribution.js +12 -32
  139. package/dist/indexer/search/search-fields.js +11 -15
  140. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  141. package/dist/indexer/search/search-source.js +1 -4
  142. package/dist/indexer/usage/usage-events.js +2 -7
  143. package/dist/integrations/agent/engine-fallback.js +23 -40
  144. package/dist/integrations/agent/engine-resolution.js +93 -183
  145. package/dist/integrations/agent/execution.js +507 -0
  146. package/dist/integrations/agent/model-map.js +28 -156
  147. package/dist/integrations/agent/request-lowering.js +66 -141
  148. package/dist/integrations/agent/runner-dispatch.js +143 -321
  149. package/dist/integrations/agent/runner.js +54 -14
  150. package/dist/integrations/lockfile.js +53 -101
  151. package/dist/llm/embedders/deterministic.js +2 -3
  152. package/dist/llm/embedders/profile.js +71 -0
  153. package/dist/llm/embedders/remote.js +10 -15
  154. package/dist/llm/graph-extract.js +3 -12
  155. package/dist/llm/index-passes.js +3 -5
  156. package/dist/llm/memory-infer.js +1 -2
  157. package/dist/llm/metadata-enhance.js +1 -2
  158. package/dist/llm/structured-call.js +5 -24
  159. package/dist/output/generic-render.js +23 -11
  160. package/dist/output/html-render.js +13 -10
  161. package/dist/output/render-registry.js +3 -32
  162. package/dist/output/shapes/helpers.js +2 -34
  163. package/dist/output/shapes/passthrough.js +1 -9
  164. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  165. package/dist/output/text/command-format.js +60 -23
  166. package/dist/output/text/helpers.js +1 -1
  167. package/dist/output/text/migrate.js +5 -14
  168. package/dist/output/text/proposal-format.js +1 -2
  169. package/dist/output/text/workflow-format.js +0 -32
  170. package/dist/output/text.js +2 -0
  171. package/dist/registry/factory.js +4 -19
  172. package/dist/registry/network.js +66 -220
  173. package/dist/registry/providers/index.js +0 -2
  174. package/dist/registry/providers/skills-sh.js +3 -14
  175. package/dist/registry/providers/static-index.js +24 -26
  176. package/dist/registry/resolve.js +55 -131
  177. package/dist/scripts/akm-migrate-node.js +43940 -93320
  178. package/dist/scripts/akm-migrate.js +43700 -93078
  179. package/dist/setup/registry-stash-loader.js +4 -13
  180. package/dist/setup/semantic-assets.js +3 -44
  181. package/dist/setup/setup.js +1 -1
  182. package/dist/setup/steps/tasks.js +25 -15
  183. package/dist/sources/provider-factory.js +17 -18
  184. package/dist/sources/providers/filesystem.js +2 -3
  185. package/dist/sources/providers/git-install.js +7 -1
  186. package/dist/sources/providers/git-provider.js +0 -3
  187. package/dist/sources/providers/git-stash.js +0 -17
  188. package/dist/sources/providers/npm.js +2 -4
  189. package/dist/sources/providers/provider-utils.js +5 -10
  190. package/dist/sources/providers/website.js +0 -2
  191. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  192. package/dist/sources/website-url.js +2 -2
  193. package/dist/storage/database.js +9 -35
  194. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  195. package/dist/storage/repositories/index-connection.js +34 -70
  196. package/dist/storage/repositories/index-entries-repository.js +69 -111
  197. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  198. package/dist/storage/repositories/index-entry-schema.js +83 -269
  199. package/dist/storage/repositories/index-fts-repository.js +86 -256
  200. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  201. package/dist/storage/repositories/index-meta-repository.js +6 -4
  202. package/dist/storage/repositories/index-schema.js +192 -220
  203. package/dist/storage/repositories/index-utility-repository.js +8 -29
  204. package/dist/storage/repositories/index-vec-repository.js +133 -414
  205. package/dist/storage/repositories/outcome-repository.js +2 -1
  206. package/dist/storage/repositories/proposals-repository.js +35 -0
  207. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  208. package/dist/storage/repositories/task-history-repository.js +26 -4
  209. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  210. package/dist/storage/sqlite-migrations.js +136 -0
  211. package/dist/storage/sqlite-pragmas.js +11 -9
  212. package/dist/storage/sqlite-transaction.js +170 -0
  213. package/dist/storage/state-db-integrity.js +34 -27
  214. package/dist/tasks/activation-config.js +134 -62
  215. package/dist/tasks/backends/cron.js +129 -277
  216. package/dist/tasks/backends/exec-utils.js +2 -5
  217. package/dist/tasks/backends/launchd.js +125 -745
  218. package/dist/tasks/backends/schtasks.js +101 -620
  219. package/dist/tasks/prepare/prepare-support.js +5 -15
  220. package/dist/tasks/prepare/prepare.js +0 -2
  221. package/dist/tasks/resolve-akm-bin.js +20 -79
  222. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  223. package/dist/tasks/scheduler-binding.js +18 -238
  224. package/dist/tasks/scheduler-invocation.js +52 -52
  225. package/dist/tasks/scheduler-lock.js +53 -0
  226. package/dist/tasks/scheduler-sync.js +361 -751
  227. package/dist/tasks/source/parse-task-source.js +160 -10
  228. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  229. package/dist/tasks/source/task-to-v4.js +2 -2
  230. package/dist/workflows/authoring/authoring.js +3 -12
  231. package/dist/workflows/compile.js +211 -0
  232. package/dist/workflows/concurrency-policy.js +13 -74
  233. package/dist/workflows/exec/child-invocation.js +3 -17
  234. package/dist/workflows/exec/child-workflow.js +32 -141
  235. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  236. package/dist/workflows/exec/environment.js +98 -0
  237. package/dist/workflows/exec/exec-unit.js +33 -140
  238. package/dist/workflows/exec/frozen-judge.js +7 -59
  239. package/dist/workflows/exec/native-executor.js +82 -341
  240. package/dist/workflows/exec/param-secrets.js +29 -47
  241. package/dist/workflows/exec/run-workflow.js +154 -387
  242. package/dist/workflows/exec/scheduler.js +9 -36
  243. package/dist/workflows/exec/step-work.js +127 -430
  244. package/dist/workflows/exec/unit-dispatch.js +11 -63
  245. package/dist/workflows/exec/unit-writer.js +8 -52
  246. package/dist/workflows/exec/worktree.js +39 -273
  247. package/dist/workflows/freeze/child-output-references.js +4 -15
  248. package/dist/workflows/freeze/environment.js +99 -92
  249. package/dist/workflows/freeze/freeze.js +172 -0
  250. package/dist/workflows/freeze/step-values.js +19 -21
  251. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  252. package/dist/workflows/freeze/targets/command.js +10 -33
  253. package/dist/workflows/freeze/targets/script.js +5 -12
  254. package/dist/workflows/freeze/targets/shell.js +3 -6
  255. package/dist/workflows/freeze/targets/task.js +25 -80
  256. package/dist/workflows/freeze/task-bindings.js +20 -67
  257. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  258. package/dist/workflows/ir/params.js +6 -51
  259. package/dist/workflows/ir/plan-hash.js +2 -34
  260. package/dist/workflows/parser.js +140 -43
  261. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  262. package/dist/workflows/renderer.js +36 -69
  263. package/dist/workflows/resource-limits.js +12 -120
  264. package/dist/workflows/runtime/agent-identity.js +8 -40
  265. package/dist/workflows/runtime/run-outputs.js +3 -6
  266. package/dist/workflows/runtime/run-plan.js +316 -0
  267. package/dist/workflows/runtime/runs.js +48 -200
  268. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  269. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  270. package/dist/workflows/validate-summary.js +2 -7
  271. package/docs/integration/bundling-akm.md +49 -42
  272. package/docs/migration/README.md +1 -0
  273. package/docs/migration/release-notes/0.9.17.md +41 -0
  274. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  275. package/docs/reference/cli.md +182 -125
  276. package/docs/reference/configuration.md +49 -56
  277. package/docs/reference/data-and-telemetry.md +19 -20
  278. package/docs/reference/tasks.md +86 -38
  279. package/docs/reference/workflow-schema.md +14 -18
  280. package/docs/reference/workflows.md +6 -9
  281. package/package.json +1 -1
  282. package/schemas/akm-config.json +87 -406
  283. package/dist/commands/health/advisories.js +0 -150
  284. package/dist/commands/health/metrics.js +0 -329
  285. package/dist/commands/health/surfaces.js +0 -102
  286. package/dist/commands/improve/anti-collapse.js +0 -83
  287. package/dist/commands/improve/collapse-detector.js +0 -432
  288. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  289. package/dist/commands/improve/consolidate/merge.js +0 -146
  290. package/dist/commands/improve/distill/promote-memory.js +0 -329
  291. package/dist/commands/improve/distill/quality-gate.js +0 -500
  292. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  293. package/dist/commands/improve/proposal-envelope.js +0 -31
  294. package/dist/commands/improve/run-context.js +0 -123
  295. package/dist/commands/improve/shared.js +0 -21
  296. package/dist/commands/improve/source-identity.js +0 -28
  297. package/dist/commands/improve/triage.js +0 -96
  298. package/dist/commands/proposal/drain-policies.js +0 -151
  299. package/dist/commands/sources/update-transaction.js +0 -220
  300. package/dist/core/action-contributors.js +0 -28
  301. package/dist/core/config/config-version-shim.js +0 -101
  302. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  303. package/dist/core/fs-txn.js +0 -405
  304. package/dist/core/lexical-score.js +0 -25
  305. package/dist/core/maintenance-barrier.js +0 -167
  306. package/dist/execution/executable-identity.js +0 -105
  307. package/dist/execution/guarded-source.js +0 -441
  308. package/dist/indexer/graph/graph-boost.js +0 -427
  309. package/dist/indexer/graph/graph-dedup.js +0 -95
  310. package/dist/indexer/search/name-match.js +0 -35
  311. package/dist/indexer/search/ranking-contributors.js +0 -515
  312. package/dist/indexer/walk/project-context.js +0 -192
  313. package/dist/integrations/agent/execution-cascade.js +0 -566
  314. package/dist/integrations/agent/execution-definitions.js +0 -202
  315. package/dist/integrations/agent/execution-lowering.js +0 -841
  316. package/dist/integrations/agent/execution-preparation.js +0 -98
  317. package/dist/integrations/agent/inline-execution.js +0 -74
  318. package/dist/registry/create-provider-registry.js +0 -29
  319. package/dist/registry/pinned-request-helper.js +0 -247
  320. package/dist/registry/pinned-transport.js +0 -717
  321. package/dist/sources/providers/index.js +0 -14
  322. package/dist/storage/engines/sqlite-migrations.js +0 -271
  323. package/dist/storage/repositories/canaries-repository.js +0 -107
  324. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  325. package/dist/storage/repositories/registry-cache.js +0 -113
  326. package/dist/tasks/scheduler-sync-preview.js +0 -52
  327. package/dist/workflows/freeze/resolve-steps.js +0 -86
  328. package/dist/workflows/freeze/source-freeze.js +0 -64
  329. package/dist/workflows/ir/compile.js +0 -321
  330. package/dist/workflows/ir/environment-v4.js +0 -330
  331. package/dist/workflows/ir/freeze-v4.js +0 -153
  332. package/dist/workflows/ir/schema-v4.js +0 -745
  333. package/dist/workflows/ir/schema.js +0 -354
  334. package/dist/workflows/program/schema.js +0 -78
  335. package/dist/workflows/runtime/checkin.js +0 -57
  336. package/dist/workflows/runtime/plan-classifier.js +0 -196
  337. package/dist/workflows/runtime/unit-checkin.js +0 -45
  338. package/dist/workflows/runtime/unit-phases.js +0 -20
  339. package/dist/workflows/schema.js +0 -4
  340. package/dist/workflows/source-ir/compile.js +0 -200
  341. package/dist/workflows/source-ir/program.js +0 -50
  342. package/dist/workflows/source-ir/result.js +0 -26
  343. package/dist/workflows/source-ir/schema.js +0 -786
  344. package/dist/workflows/source-ir/triggers.js +0 -79
  345. package/dist/workflows/source-ir/uses.js +0 -40
  346. package/dist/workflows/validator.js +0 -60
@@ -0,0 +1,507 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ import { deepMergeConfig } from "../../core/config/deep-merge.js";
5
+ import { ConfigError } from "../../core/errors.js";
6
+ import { DURATION_UNITS, parseDuration } from "../../core/time.js";
7
+ import { EXECUTION_MAX_TIMEOUT_MS } from "../../execution/limits.js";
8
+ import { createInlineResolvedCommand, createResolvedExecutionRequest, decodeResolvedExecutionRequest, } from "../../execution/resolved-request.js";
9
+ import { cloneToolSelection, isPortableExecutionAgentSelector, } from "../../execution/source.js";
10
+ import { getHarness } from "../harnesses/index.js";
11
+ import { DEFAULT_AGENT_TIMEOUT_MS, DEFAULT_LLM_TIMEOUT_MS } from "./config.js";
12
+ import { FALLBACK_ENGINE_NAME, fallbackEngineConfig, NO_ENGINE_MESSAGE_SUFFIX, NO_ENGINE_REMEDY, } from "./engine-fallback.js";
13
+ import { configuredEngine, resolveEngine } from "./engine-resolution.js";
14
+ import { engineModelAndInference, loadModelMap, resolveModelMapAlias } from "./model-map.js";
15
+ import { extensionFields, hasToolSelection, untranslated } from "./request-lowering.js";
16
+ import { decodeFrozenRunnerSpec } from "./runner.js";
17
+ const LLM_INFERENCE_FIELDS = [
18
+ "temperature",
19
+ "maxTokens",
20
+ "supportsJsonSchema",
21
+ "extraParams",
22
+ "contextLength",
23
+ "enableThinking",
24
+ "reasoningEffort",
25
+ ];
26
+ function has(values, key) {
27
+ return (values !== null &&
28
+ values !== undefined &&
29
+ Object.hasOwn(values, key) &&
30
+ values[key] !== undefined);
31
+ }
32
+ function nearest(layers, key) {
33
+ for (let index = layers.length - 1; index >= 0; index -= 1) {
34
+ const layer = layers[index];
35
+ if (layer && has(layer.values, key))
36
+ return layer;
37
+ }
38
+ return undefined;
39
+ }
40
+ function explicit(layer, via = "explicit") {
41
+ return { layer: layer.id, kind: layer.kind, via };
42
+ }
43
+ function inferenceOf(source) {
44
+ const out = {};
45
+ for (const key of LLM_INFERENCE_FIELDS)
46
+ if (source[key] !== undefined)
47
+ out[key] = source[key];
48
+ return Object.keys(out).length > 0 ? out : undefined;
49
+ }
50
+ /** A configured engine's model, inference, timeout and workspace, and where its aliases resolve. */
51
+ function engineDefaults(name, engine, config) {
52
+ const own = engineModelAndInference(engine);
53
+ const values = {
54
+ ...(own.model !== undefined ? { model: own.model } : {}),
55
+ ...(own.inference !== undefined ? { inference: own.inference } : {}),
56
+ ...(Object.hasOwn(engine, "timeoutMs") ? { timeout: engine.timeoutMs ?? null } : {}),
57
+ };
58
+ if (engine.kind === "llm")
59
+ return { kind: "llm", platform: engine.provider ?? name, modelMapKey: name, values };
60
+ if (engine.workspace !== undefined)
61
+ values.workspace = engine.workspace;
62
+ if (engine.platform !== "opencode-sdk") {
63
+ return { kind: "agent", platform: engine.platform, modelMapKey: engine.platform, values };
64
+ }
65
+ // An SDK engine runs its LLM fallback's model/inference/timeout unless it sets its own.
66
+ const fallbackName = engine.llmEngine ?? config.defaults?.llmEngine;
67
+ const fallback = fallbackName && config.engines && Object.hasOwn(config.engines, fallbackName)
68
+ ? config.engines[fallbackName]
69
+ : undefined;
70
+ if (fallback?.kind !== "llm" || !fallbackName) {
71
+ return {
72
+ kind: "sdk",
73
+ platform: "opencode-sdk",
74
+ modelMapKey: "opencode-sdk",
75
+ values: {
76
+ ...values,
77
+ timeout: has(values, "timeout") ? values.timeout : DEFAULT_AGENT_TIMEOUT_MS,
78
+ },
79
+ };
80
+ }
81
+ const inherited = engineModelAndInference(fallback);
82
+ return {
83
+ kind: "sdk",
84
+ platform: "opencode-sdk",
85
+ modelMapKey: own.model === undefined ? fallbackName : "opencode-sdk",
86
+ values: {
87
+ ...(inherited.model !== undefined ? { model: inherited.model } : {}),
88
+ ...(inherited.inference !== undefined ? { inference: inherited.inference } : {}),
89
+ ...values,
90
+ timeout: Object.hasOwn(engine, "timeoutMs")
91
+ ? (engine.timeoutMs ?? null)
92
+ : Object.hasOwn(fallback, "timeoutMs")
93
+ ? (fallback.timeoutMs ?? null)
94
+ : DEFAULT_LLM_TIMEOUT_MS,
95
+ },
96
+ };
97
+ }
98
+ /** The same defaults read back from an already-resolved runner. */
99
+ function runnerDefaults(runner) {
100
+ const timeout = Object.hasOwn(runner, "timeoutMs") ? { timeout: runner.timeoutMs ?? null } : {};
101
+ if (runner.kind === "llm") {
102
+ const inference = inferenceOf(runner.connection);
103
+ return {
104
+ kind: "llm",
105
+ platform: runner.connection.provider ?? runner.engine,
106
+ modelMapKey: runner.engine,
107
+ values: {
108
+ ...(runner.connection.model !== undefined ? { model: runner.connection.model } : {}),
109
+ ...(inference ? { inference } : {}),
110
+ ...timeout,
111
+ },
112
+ };
113
+ }
114
+ const platform = runner.profile.platform ?? runner.profile.name;
115
+ const fallback = runner.kind === "sdk" ? runner.fallbackConnection : undefined;
116
+ const model = runner.profile.model ?? fallback?.model;
117
+ const inference = fallback ? inferenceOf(fallback) : undefined;
118
+ return {
119
+ kind: runner.kind,
120
+ platform,
121
+ modelMapKey: platform,
122
+ values: {
123
+ ...(model !== undefined ? { model } : {}),
124
+ ...(inference ? { inference } : {}),
125
+ ...timeout,
126
+ ...(runner.profile.workspace !== undefined ? { workspace: runner.profile.workspace } : {}),
127
+ },
128
+ };
129
+ }
130
+ /**
131
+ * The engine, from an ordered list: the nearest layer that names one, then
132
+ * `defaults.engine`, then the implicit opencode-sdk fallback when its binary
133
+ * is present. A named engine that is not configured is an error, never rescued.
134
+ */
135
+ function selectEngine(config, layers) {
136
+ for (let index = layers.length - 1; index >= 0; index -= 1) {
137
+ const layer = layers[index];
138
+ const name = layer?.values.engine;
139
+ if (layer && typeof name === "string" && name.length > 0) {
140
+ return { name, engine: configuredEngine(name, config), provenance: explicit(layer), fallback: false };
141
+ }
142
+ }
143
+ const installed = config.defaults?.engine;
144
+ if (installed) {
145
+ return {
146
+ name: installed,
147
+ engine: configuredEngine(installed, config),
148
+ provenance: { layer: "installation-defaults", kind: "installation", via: "explicit" },
149
+ fallback: false,
150
+ };
151
+ }
152
+ const fallback = fallbackEngineConfig(config);
153
+ if (fallback) {
154
+ return {
155
+ name: FALLBACK_ENGINE_NAME,
156
+ engine: fallback,
157
+ provenance: { layer: FALLBACK_ENGINE_NAME, kind: "fallback", via: "fallback" },
158
+ fallback: true,
159
+ };
160
+ }
161
+ throw new ConfigError(`Execution ${NO_ENGINE_MESSAGE_SUFFIX}`, "INVALID_CONFIG_FILE", NO_ENGINE_REMEDY);
162
+ }
163
+ function parseTimeout(value) {
164
+ if (value === null)
165
+ return null;
166
+ const milliseconds = typeof value === "string" ? parseDuration(value, DURATION_UNITS) : value;
167
+ if (typeof milliseconds !== "number" ||
168
+ !Number.isInteger(milliseconds) ||
169
+ milliseconds < 0 ||
170
+ milliseconds > EXECUTION_MAX_TIMEOUT_MS) {
171
+ throw new ConfigError("Execution timeout must be null, a whole number of milliseconds, or a duration such as 20m.", "INVALID_CONFIG_FILE");
172
+ }
173
+ return milliseconds;
174
+ }
175
+ /** Tool names a selection asks for; `undefined` when a structured policy cannot be reduced to names. */
176
+ function requestedToolNames(tools) {
177
+ if (typeof tools === "string") {
178
+ return tools
179
+ .split(",")
180
+ .map((tool) => tool.trim())
181
+ .filter(Boolean);
182
+ }
183
+ if (Array.isArray(tools))
184
+ return tools.map((tool) => tool.trim()).filter(Boolean);
185
+ const policy = tools;
186
+ if (Object.values(policy).some((value) => typeof value !== "boolean"))
187
+ return undefined;
188
+ return Object.keys(policy).filter((tool) => policy[tool] === true);
189
+ }
190
+ /** Assets may only narrow the host's `execution.allowedTools`; without a config nothing is allowed. */
191
+ function authorizeTools(tools, config) {
192
+ if (!hasToolSelection(tools))
193
+ return { status: "not-required" };
194
+ if (!config) {
195
+ return {
196
+ status: "denied",
197
+ reason: "Selected tools require an explicit machine/user authorization policy.",
198
+ policy: { id: "unconfigured" },
199
+ };
200
+ }
201
+ const allowed = new Set(config.execution?.allowedTools ?? []);
202
+ const names = requestedToolNames(tools);
203
+ const permitted = allowed.has("*") || names?.every((tool) => allowed.has(tool)) === true;
204
+ return permitted
205
+ ? {
206
+ status: "allowed",
207
+ reason: "Selected tools were authorized by operator policy.",
208
+ policy: { id: "config-execution-allowed-tools" },
209
+ }
210
+ : {
211
+ status: "denied",
212
+ reason: "Selected tools are not authorized by operator policy.",
213
+ policy: { id: "config-execution-allowed-tools" },
214
+ };
215
+ }
216
+ function withInference(connection, inference) {
217
+ const out = { ...connection };
218
+ for (const key of LLM_INFERENCE_FIELDS)
219
+ delete out[key];
220
+ if (inference)
221
+ for (const key of LLM_INFERENCE_FIELDS)
222
+ if (inference[key] !== undefined)
223
+ out[key] = inference[key];
224
+ return out;
225
+ }
226
+ /** Apply a request's model, inference, timeout and workspace to its runner. Idempotent. */
227
+ function applyRequest(base, request) {
228
+ const timeout = Object.hasOwn(request.runtime, "timeoutMs")
229
+ ? { timeoutMs: request.runtime.timeoutMs ?? null }
230
+ : Object.hasOwn(base, "timeoutMs")
231
+ ? { timeoutMs: base.timeoutMs }
232
+ : {};
233
+ const model = request.model?.resolved;
234
+ if (base.kind === "llm") {
235
+ const { model: _model, ...connection } = base.connection;
236
+ return {
237
+ ...base,
238
+ connection: withInference({ ...connection, ...(model !== undefined ? { model } : {}) }, request.inference),
239
+ ...timeout,
240
+ };
241
+ }
242
+ const { model: _model, workspace: _workspace, ...profile } = base.profile;
243
+ const workspace = request.runtime.workspace;
244
+ const next = {
245
+ ...base,
246
+ profile: {
247
+ ...profile,
248
+ ...(model !== undefined ? { model } : {}),
249
+ ...(typeof workspace === "string" ? { workspace } : {}),
250
+ },
251
+ ...timeout,
252
+ };
253
+ if (next.kind === "sdk" && next.fallbackConnection) {
254
+ let fallback = { ...next.fallbackConnection };
255
+ if (request.model === null)
256
+ delete fallback.model;
257
+ if (Object.hasOwn(request, "inference"))
258
+ fallback = withInference(fallback, request.inference);
259
+ next.fallbackConnection = fallback;
260
+ }
261
+ return next;
262
+ }
263
+ function mergeInference(current, next, source, provenance) {
264
+ provenance["/inference"] = source;
265
+ if (next === null) {
266
+ for (const key of Object.keys(provenance))
267
+ if (key.startsWith("/inference/"))
268
+ delete provenance[key];
269
+ return null;
270
+ }
271
+ for (const key of Object.keys(next)) {
272
+ provenance[`/inference/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`] = source;
273
+ }
274
+ return deepMergeConfig(current ?? {}, next);
275
+ }
276
+ /**
277
+ * Resolve one execution: select the engine, merge its defaults with the
278
+ * caller's layers (nearest wins), expand a model alias, authorize tools, and
279
+ * apply the result to the engine's runner.
280
+ */
281
+ export function resolveExecution(input) {
282
+ const command = input.command ??
283
+ createInlineResolvedCommand({
284
+ template: input.content ?? "",
285
+ ...(input.argumentInput !== undefined ? { argumentInput: input.argumentInput } : {}),
286
+ content: input.content ?? "",
287
+ });
288
+ const callerLayers = [
289
+ ...(input.agentLayer ? [{ ...input.agentLayer, kind: "agent" }] : []),
290
+ {
291
+ id: input.commandLayer?.id ?? "inline-command",
292
+ kind: "command",
293
+ values: input.commandLayer?.values ?? {},
294
+ },
295
+ ...(input.invocationDefaults
296
+ ? [{ id: "invocation-defaults", kind: "invocation-defaults", values: input.invocationDefaults }]
297
+ : []),
298
+ ...(input.current ? [{ id: "current-invocation", kind: "current", values: input.current }] : []),
299
+ ];
300
+ const provenance = {};
301
+ let name;
302
+ let defaults;
303
+ let base;
304
+ let fallback = false;
305
+ if (input.runner) {
306
+ name = input.runner.engine;
307
+ defaults = runnerDefaults(input.runner);
308
+ base = input.runner;
309
+ provenance.engine = { layer: "installation-defaults", kind: "installation", via: "explicit" };
310
+ }
311
+ else {
312
+ if (!input.config)
313
+ throw new TypeError("resolveExecution needs a config or a runner");
314
+ const selected = selectEngine(input.config, callerLayers);
315
+ name = selected.name;
316
+ fallback = selected.fallback;
317
+ defaults = engineDefaults(name, selected.engine, input.config);
318
+ base = resolveEngine(name, input.config, selected.engine);
319
+ provenance.engine = selected.provenance;
320
+ }
321
+ const layers = [{ id: name, kind: "engine", values: defaults.values }, ...callerLayers];
322
+ provenance.command = { layer: command.source?.ref ?? "inline", kind: "command", via: "source" };
323
+ let persona = input.persona;
324
+ const agentLayer = nearest(layers, "agent");
325
+ const agent = agentLayer?.values.agent;
326
+ if (agentLayer) {
327
+ provenance.agent = explicit(agentLayer);
328
+ // A native selector (or an explicit null) replaces any persona.
329
+ if (typeof agent !== "string" || !isPortableExecutionAgentSelector(agent))
330
+ persona = null;
331
+ }
332
+ if (persona)
333
+ provenance.persona = { layer: persona.source.ref, kind: "agent", via: "source" };
334
+ const modelLayer = nearest(layers, "model");
335
+ let model;
336
+ let aliasInference;
337
+ if (modelLayer) {
338
+ provenance.model = explicit(modelLayer);
339
+ const value = modelLayer.values.model;
340
+ if (value === null)
341
+ model = null;
342
+ else if (typeof value === "string" && value.length > 0) {
343
+ const map = input.modelMap ?? (input.config ? loadModelMap({ engines: input.config.engines }).map : undefined);
344
+ const selection = map
345
+ ? resolveModelMapAlias(value, defaults.modelMapKey, map)
346
+ : { input: value, interpretation: "exact", model: value };
347
+ model = { input: selection.input, interpretation: selection.interpretation, resolved: selection.model };
348
+ if ("inference" in selection && selection.inference !== undefined)
349
+ aliasInference = selection.inference;
350
+ }
351
+ else {
352
+ throw new ConfigError("Resolved model must be null or a non-empty string.", "INVALID_CONFIG_FILE");
353
+ }
354
+ }
355
+ // An alias's inference applies at the layer that chose the alias, under that layer's own inference.
356
+ let inference;
357
+ for (const layer of layers) {
358
+ if (layer === modelLayer && aliasInference !== undefined) {
359
+ inference = mergeInference(inference, aliasInference, explicit(layer, "model-alias"), provenance);
360
+ }
361
+ if (has(layer.values, "inference")) {
362
+ inference = mergeInference(inference, layer.values.inference ?? null, explicit(layer), provenance);
363
+ }
364
+ }
365
+ const select = (key, field) => {
366
+ const layer = nearest(layers, key);
367
+ if (layer)
368
+ provenance[field] = explicit(layer);
369
+ return layer;
370
+ };
371
+ const schemaLayer = select("outputSchema", "outputSchema");
372
+ const toolsLayer = select("tools", "tools");
373
+ const timeoutLayer = select("timeout", "runtime.timeoutMs");
374
+ const workspaceLayer = select("workspace", "runtime.workspace");
375
+ const environmentLayer = select("environment", "runtime.environment");
376
+ const settingsLayer = select("runtime", "runtime.settings");
377
+ const tools = toolsLayer ? cloneToolSelection(toolsLayer.values.tools ?? null, "tools") : undefined;
378
+ const authorization = authorizeTools(tools, input.runner ? undefined : input.config);
379
+ provenance.authorization = {
380
+ layer: typeof authorization.policy?.id === "string" ? authorization.policy.id : "not-required",
381
+ kind: "authorization",
382
+ via: "policy",
383
+ };
384
+ const request = createResolvedExecutionRequest({
385
+ command,
386
+ ...(input.conversation !== undefined ? { conversation: input.conversation } : {}),
387
+ ...(agentLayer ? { agent: agent } : {}),
388
+ ...(persona !== undefined ? { persona } : {}),
389
+ engine: { name, kind: defaults.kind, platform: defaults.platform },
390
+ ...(modelLayer ? { model: model ?? null } : {}),
391
+ ...(inference !== undefined ? { inference } : {}),
392
+ ...(schemaLayer ? { outputSchema: schemaLayer.values.outputSchema ?? null } : {}),
393
+ ...(toolsLayer ? { tools } : {}),
394
+ authorization,
395
+ runtime: {
396
+ ...(timeoutLayer ? { timeoutMs: parseTimeout(timeoutLayer.values.timeout ?? null) } : {}),
397
+ ...(workspaceLayer ? { workspace: workspaceLayer.values.workspace ?? null } : {}),
398
+ ...(environmentLayer ? { environment: environmentLayer.values.environment ?? null } : {}),
399
+ ...(settingsLayer ? { settings: settingsLayer.values.runtime ?? null } : {}),
400
+ },
401
+ notices: [],
402
+ });
403
+ const sorted = Object.fromEntries(Object.entries(provenance).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));
404
+ return {
405
+ request,
406
+ runner: applyRequest(base, request),
407
+ provenance: sorted,
408
+ ...(fallback ? { fallbackEngineName: name } : {}),
409
+ };
410
+ }
411
+ function nonEmpty(value) {
412
+ return value !== null && value !== undefined && Object.keys(value).length > 0;
413
+ }
414
+ function buildLlm(request, runner, options) {
415
+ if (typeof request.agent === "string" && request.persona === null) {
416
+ throw new ConfigError(`The direct LLM transport cannot consume native agent selector ${JSON.stringify(request.agent)}.`, "INVALID_CONFIG_FILE");
417
+ }
418
+ if (hasToolSelection(request.tools)) {
419
+ throw new ConfigError("The direct LLM transport cannot enforce the resolved tool policy.", "INVALID_CONFIG_FILE");
420
+ }
421
+ const notices = [...request.notices];
422
+ const skip = (field) => {
423
+ notices.push(untranslated("llm", field));
424
+ };
425
+ for (const key of Object.keys(request.inference ?? {}).sort()) {
426
+ if (!LLM_INFERENCE_FIELDS.includes(key))
427
+ skip(`inference.${key}`);
428
+ }
429
+ const chatOptions = {};
430
+ if (request.outputSchema) {
431
+ if (runner.connection.supportsJsonSchema === true)
432
+ chatOptions.responseSchema = request.outputSchema;
433
+ else
434
+ skip("outputSchema");
435
+ }
436
+ if (request.runtime.workspace)
437
+ skip("runtime.workspace");
438
+ if (nonEmpty(request.runtime.environment))
439
+ skip("runtime.environment");
440
+ if (nonEmpty(request.runtime.settings))
441
+ skip("runtime.settings");
442
+ for (const field of extensionFields(request))
443
+ skip(field);
444
+ const messages = [
445
+ ...(request.persona ? [{ role: "system", content: request.persona.content }] : []),
446
+ ...(request.conversation ?? []).map((message) => ({ role: message.role, content: message.content })),
447
+ { role: "user", content: request.command.content },
448
+ ];
449
+ return { request, runner, prompt: request.command.content, options, messages, chatOptions, notices };
450
+ }
451
+ /**
452
+ * Build a request for its runner's transport: the harness's own builder for
453
+ * agent/SDK engines, chat messages for a direct LLM. A request whose tools
454
+ * were denied by `execution.allowedTools` stops here.
455
+ */
456
+ export function buildExecution(request, runner) {
457
+ if (request.authorization.status === "denied") {
458
+ throw new ConfigError(request.authorization.reason ?? "Resolved execution is not authorized by operator policy.", "EXECUTION_NOT_AUTHORIZED");
459
+ }
460
+ const applied = applyRequest(runner, request);
461
+ const environment = request.runtime.environment;
462
+ const options = {
463
+ stdio: "captured",
464
+ parseOutput: "text",
465
+ ...(applied.timeoutMs !== undefined ? { timeoutMs: applied.timeoutMs } : {}),
466
+ ...(applied.kind !== "llm" && applied.profile.workspace ? { cwd: applied.profile.workspace } : {}),
467
+ ...(environment ? { env: { ...environment } } : {}),
468
+ };
469
+ if (applied.kind === "llm")
470
+ return buildLlm(request, applied, options);
471
+ const platform = applied.profile.platform ?? applied.profile.name;
472
+ const harness = getHarness(platform);
473
+ const lower = harness?.agentBuilder?.lower ?? harness?.executionLowerer?.lower;
474
+ if (!lower) {
475
+ throw new ConfigError(`Agent platform ${JSON.stringify(platform)} has no registered request builder.`, "INVALID_CONFIG_FILE");
476
+ }
477
+ const built = lower(applied.profile, request);
478
+ return {
479
+ request,
480
+ runner: applied,
481
+ prompt: built.prompt,
482
+ options: { ...options, dispatch: built.dispatch },
483
+ notices: [...request.notices, ...built.notices],
484
+ };
485
+ }
486
+ /**
487
+ * Resume: build a journaled `{ request, runner }` exactly as frozen. Never
488
+ * reads config, models.json or credentials, so a config edit after the freeze
489
+ * cannot change what a resumed unit runs.
490
+ */
491
+ export function buildExecutionFromWire(wire) {
492
+ return buildExecution(decodeResolvedExecutionRequest(wire.request), decodeFrozenRunnerSpec(wire.runner));
493
+ }
494
+ /** Each configured engine's own model selection and models.json column, for `akm health`. */
495
+ export function executionEngineDefinitionsFromConfig(config) {
496
+ return Object.fromEntries(Object.entries(config.engines ?? {}).map(([name, engine]) => {
497
+ const defaults = engineDefaults(name, engine, config);
498
+ return [
499
+ name,
500
+ {
501
+ selection: { name, kind: defaults.kind, platform: defaults.platform },
502
+ defaults: defaults.values,
503
+ modelMapKey: defaults.modelMapKey,
504
+ },
505
+ ];
506
+ }));
507
+ }