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
@@ -1,841 +0,0 @@
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 { ConfigError, UsageError } from "../../core/errors.js";
5
- import { cloneExecutionJsonObject } from "../../execution/json.js";
6
- import { EXECUTION_MAX_TIMEOUT_MS } from "../../execution/limits.js";
7
- import { assertSnapshotKeys, snapshotStrictRecord } from "../../execution/record.js";
8
- import { canonicalResolvedExecutionRequest, } from "../../execution/resolved-request.js";
9
- import { chatCompletion, LlmCallError, } from "../../llm/client.js";
10
- import { HARNESS_REGISTRY } from "../harnesses/index.js";
11
- import { resolveEngine } from "./engine-resolution.js";
12
- import { SDK_FALLBACK_MODEL_FROM_REQUEST_SETTING } from "./execution-definitions.js";
13
- import { acquireRunnerDispatchLease, assertRunnerDispatchLease, disposeRunnerDispatchLease, executeRunner, redactWithRunnerDispatchLease, } from "./runner-dispatch.js";
14
- export const EXECUTION_LOWERING_SCHEMA_VERSION = 1;
15
- const loweredExecutionInstances = new WeakSet();
16
- function registerLoweredExecution(value) {
17
- const frozen = Object.freeze(value);
18
- loweredExecutionInstances.add(frozen);
19
- return frozen;
20
- }
21
- function own(value, key) {
22
- return Object.hasOwn(value, key);
23
- }
24
- function sterileRecord(value) {
25
- return Object.assign(Object.create(null), value);
26
- }
27
- function sortedUnique(values) {
28
- return Object.freeze([...new Set(values)].sort());
29
- }
30
- function freezeNotices(values) {
31
- return Object.freeze([...values]);
32
- }
33
- const SAFE_ENGINE_FALLBACK_NOTICE = Object.freeze({
34
- code: "engine-fallback",
35
- severity: "info",
36
- adapter: "akm",
37
- field: "engine",
38
- message: "No engine was selected; using the fixed opencode-sdk fallback.",
39
- });
40
- const UNRECOGNIZED_REQUEST_NOTICE = Object.freeze({
41
- code: "unrecognized-request-notice",
42
- severity: "warning",
43
- adapter: "akm",
44
- message: "An unrecognized durable execution notice was omitted at the engine lowering boundary.",
45
- });
46
- /** Reconstruct durable/untrusted notices without forwarding message/details bytes. */
47
- function safeRequestNotices(request) {
48
- let fallback = false;
49
- let unknown = false;
50
- for (const notice of request.notices) {
51
- if (notice.code === "engine-fallback")
52
- fallback = true;
53
- else
54
- unknown = true;
55
- }
56
- return Object.freeze([
57
- ...(fallback ? [SAFE_ENGINE_FALLBACK_NOTICE] : []),
58
- ...(unknown ? [UNRECOGNIZED_REQUEST_NOTICE] : []),
59
- ]);
60
- }
61
- function untranslatedNotice(adapter, field) {
62
- return Object.freeze({
63
- code: "untranslated-field",
64
- severity: "warning",
65
- adapter,
66
- field,
67
- message: `The ${adapter} lowerer does not translate resolved field ${field}; dispatch will continue optimistically.`,
68
- });
69
- }
70
- function requireAuthorizedRequest(request) {
71
- // The canonical round trip is the public brand/prototype/accessor guard. It
72
- // deliberately happens before config or registry access.
73
- canonicalResolvedExecutionRequest(request);
74
- if (request.authorization.status === "denied") {
75
- throw new ConfigError(request.authorization.reason ?? "Resolved execution is not authorized by operator policy.", "EXECUTION_NOT_AUTHORIZED");
76
- }
77
- return request;
78
- }
79
- function snapshotConfig(config) {
80
- return cloneExecutionJsonObject(config, "execution lowering config");
81
- }
82
- function assertKeys(value, allowed, path) {
83
- const allowedKeys = new Set(allowed);
84
- for (const key of Object.keys(value)) {
85
- if (!allowedKeys.has(key))
86
- throw new TypeError(`${path} contains unsupported field: ${key}`);
87
- }
88
- }
89
- function requireStringField(value, key, path) {
90
- const field = value[key];
91
- if (typeof field !== "string")
92
- throw new TypeError(`${path}.${key} must be a string`);
93
- return field;
94
- }
95
- function validateOptionalString(value, key, path) {
96
- if (own(value, key) && typeof value[key] !== "string")
97
- throw new TypeError(`${path}.${key} must be a string`);
98
- }
99
- function validateTimeout(value, path) {
100
- if (value !== null &&
101
- (typeof value !== "number" || !Number.isInteger(value) || value < 0 || value > EXECUTION_MAX_TIMEOUT_MS)) {
102
- throw new TypeError(`${path} must be null or an integer from 0 through ${EXECUTION_MAX_TIMEOUT_MS}`);
103
- }
104
- }
105
- function validateStringArray(value, path, allowEmpty = true) {
106
- if (!Array.isArray(value) ||
107
- (!allowEmpty && value.length === 0) ||
108
- value.some((entry) => typeof entry !== "string")) {
109
- throw new TypeError(`${path} must be ${allowEmpty ? "an" : "a non-empty"} array of strings`);
110
- }
111
- }
112
- function validateCredential(value, path) {
113
- if (value === null || typeof value !== "object" || Array.isArray(value))
114
- throw new TypeError(`${path} must be an object`);
115
- const record = value;
116
- assertKeys(record, ["names", "required"], path);
117
- validateStringArray(record.names, `${path}.names`, false);
118
- if (typeof record.required !== "boolean")
119
- throw new TypeError(`${path}.required must be a boolean`);
120
- }
121
- function validateConnection(value, path, requireModel = true) {
122
- if (value === null || typeof value !== "object" || Array.isArray(value))
123
- throw new TypeError(`${path} must be an object`);
124
- const record = value;
125
- requireStringField(record, "endpoint", path);
126
- if (requireModel || own(record, "model"))
127
- requireStringField(record, "model", path);
128
- if (own(record, "apiKey")) {
129
- throw new TypeError(`${path}.apiKey must remain a symbolic credential and cannot be frozen as secret material`);
130
- }
131
- }
132
- function validateProfile(value, path) {
133
- if (value === null || typeof value !== "object" || Array.isArray(value))
134
- throw new TypeError(`${path} must be an object`);
135
- const record = value;
136
- assertKeys(record, [
137
- "name",
138
- "platform",
139
- "personaChannel",
140
- "workspace",
141
- "bin",
142
- "args",
143
- "stdio",
144
- "env",
145
- "envPassthrough",
146
- "parseOutput",
147
- "model",
148
- ], path);
149
- requireStringField(record, "name", path);
150
- requireStringField(record, "bin", path);
151
- validateOptionalString(record, "platform", path);
152
- validateOptionalString(record, "workspace", path);
153
- validateOptionalString(record, "model", path);
154
- validateStringArray(record.args, `${path}.args`);
155
- validateStringArray(record.envPassthrough, `${path}.envPassthrough`);
156
- if (record.stdio !== "captured" && record.stdio !== "interactive") {
157
- throw new TypeError(`${path}.stdio is invalid`);
158
- }
159
- if (record.parseOutput !== "text" && record.parseOutput !== "json") {
160
- throw new TypeError(`${path}.parseOutput is invalid`);
161
- }
162
- if (own(record, "personaChannel") && record.personaChannel !== "native" && record.personaChannel !== "prompt") {
163
- throw new TypeError(`${path}.personaChannel is invalid`);
164
- }
165
- if (own(record, "env")) {
166
- const env = record.env;
167
- if (env === null ||
168
- typeof env !== "object" ||
169
- Array.isArray(env) ||
170
- Object.values(env).some((entry) => typeof entry !== "string")) {
171
- throw new TypeError(`${path}.env must be an object of strings`);
172
- }
173
- }
174
- }
175
- /** Durable runner material may contain ordinary literals, never credential-shaped bytes. */
176
- function runnerEnvironmentValueLooksSecret(name, value) {
177
- const key = name.toLowerCase();
178
- if ([
179
- "secret",
180
- "token",
181
- "password",
182
- "passwd",
183
- "apikey",
184
- "api_key",
185
- "api-key",
186
- "accesskey",
187
- "access_key",
188
- "privatekey",
189
- "private_key",
190
- "credential",
191
- "bearer",
192
- "client_secret",
193
- ].some((hint) => key.includes(hint))) {
194
- return true;
195
- }
196
- const candidate = value.trim();
197
- if (candidate.length < 20 || /\s/.test(candidate))
198
- return false;
199
- if (/^(?:sk-|rk-|ghp_|gho_|ghu_|ghs_|ghr_|github_pat_|xox[baprs]-|AKIA|ASIA|AIza|ya29\.|-----BEGIN)/.test(candidate)) {
200
- return true;
201
- }
202
- const classes = [/[a-z]/, /[A-Z]/, /[0-9]/, /[^A-Za-z0-9]/].filter((pattern) => pattern.test(candidate)).length;
203
- return (candidate.length >= 24 && classes >= 3) || (candidate.length >= 32 && /^[A-Za-z0-9+/=_-]+$/.test(candidate));
204
- }
205
- /** Strictly detach and deep-freeze non-secret runner material before lowering. */
206
- function snapshotRunnerSpec(input, options = {}) {
207
- const cloned = cloneExecutionJsonObject(input, "execution runner material");
208
- const kind = cloned.kind;
209
- validateOptionalString(cloned, "engine", "execution runner material");
210
- if (own(cloned, "timeoutMs"))
211
- validateTimeout(cloned.timeoutMs, "execution runner material.timeoutMs");
212
- if (kind === "llm") {
213
- assertKeys(cloned, ["kind", "engine", "connection", "credential", "apiKeyFile", "apiKeySecretRef", "timeoutMs"], "execution runner material");
214
- validateConnection(cloned.connection, "execution runner material.connection", !options.allowMissingLlmModel);
215
- if (own(cloned, "credential"))
216
- validateCredential(cloned.credential, "execution runner material.credential");
217
- // #905: a path, not the secret itself — as safe to freeze as `credential`'s
218
- // env-var name.
219
- validateOptionalString(cloned, "apiKeyFile", "execution runner material");
220
- // #953: a `secret://<name>` reference, not the secret itself — same
221
- // freeze-safety rationale as apiKeyFile above.
222
- validateOptionalString(cloned, "apiKeySecretRef", "execution runner material");
223
- }
224
- else if (kind === "agent") {
225
- assertKeys(cloned, ["kind", "engine", "profile", "timeoutMs"], "execution runner material");
226
- validateProfile(cloned.profile, "execution runner material.profile");
227
- }
228
- else if (kind === "sdk") {
229
- assertKeys(cloned, [
230
- "kind",
231
- "engine",
232
- "profile",
233
- "fallbackConnection",
234
- "fallbackCredential",
235
- "fallbackApiKeyFile",
236
- "fallbackApiKeySecretRef",
237
- "fallbackTimeoutMs",
238
- "timeoutMs",
239
- ], "execution runner material");
240
- validateProfile(cloned.profile, "execution runner material.profile");
241
- if (own(cloned, "fallbackConnection")) {
242
- validateConnection(cloned.fallbackConnection, "execution runner material.fallbackConnection", !options.allowMissingSdkFallbackModel);
243
- }
244
- if (own(cloned, "fallbackCredential")) {
245
- validateCredential(cloned.fallbackCredential, "execution runner material.fallbackCredential");
246
- }
247
- validateOptionalString(cloned, "fallbackApiKeyFile", "execution runner material");
248
- validateOptionalString(cloned, "fallbackApiKeySecretRef", "execution runner material");
249
- if (own(cloned, "fallbackTimeoutMs")) {
250
- validateTimeout(cloned.fallbackTimeoutMs, "execution runner material.fallbackTimeoutMs");
251
- }
252
- }
253
- else {
254
- throw new TypeError("execution runner material.kind must be llm, agent, or sdk");
255
- }
256
- return cloned;
257
- }
258
- /** Strict public decoder for persisted, non-secret runner/transport material. */
259
- export function decodeFrozenRunnerSpec(input) {
260
- const runner = snapshotRunnerSpec(input);
261
- if (runner.kind !== "llm") {
262
- for (const [name, value] of Object.entries(runner.profile.env ?? {})) {
263
- if (runnerEnvironmentValueLooksSecret(name, value)) {
264
- throw new TypeError("execution runner material.profile.env contains a secret-shaped literal; freeze only symbolic environment names");
265
- }
266
- }
267
- }
268
- return runner;
269
- }
270
- function lowererEntries() {
271
- return HARNESS_REGISTRY.map((harness) => {
272
- const lowerer = harness.agentBuilder?.lower !== undefined
273
- ? {
274
- platform: harness.agentBuilder.platform,
275
- personaChannel: harness.agentBuilder.personaChannel,
276
- lower: harness.agentBuilder.lower,
277
- }
278
- : harness.executionLowerer;
279
- if (!lowerer) {
280
- throw new Error(`dispatch harness ${harness.id} has no registered resolved-request lowerer`);
281
- }
282
- if (lowerer.platform !== harness.id) {
283
- throw new Error(`dispatch harness ${harness.id} registered mismatched lowerer ${lowerer.platform}`);
284
- }
285
- return [harness.id, lowerer];
286
- });
287
- }
288
- const AGENT_LOWERERS = new Map(lowererEntries());
289
- function requireRunnerShape(request, runner) {
290
- if (!own(runner, "engine") || runner.engine !== request.engine.name) {
291
- throw new ConfigError(`Resolved engine ${JSON.stringify(request.engine.name)} changed engine identity before lowering.`, "INVALID_CONFIG_FILE");
292
- }
293
- if (request.engine.kind !== runner.kind) {
294
- throw new ConfigError(`Resolved engine ${JSON.stringify(request.engine.name)} changed transport kind before lowering.`, "INVALID_CONFIG_FILE");
295
- }
296
- const platform = own(request.engine, "platform") ? request.engine.platform : undefined;
297
- const runnerPlatform = runner.kind === "llm"
298
- ? (runner.connection.provider ?? runner.engine)
299
- : (runner.profile.platform ?? runner.profile.name);
300
- // A selected platform is an identity binding rather than a capability hint.
301
- if (typeof platform === "string" && platform !== runnerPlatform) {
302
- throw new ConfigError(`Resolved engine ${JSON.stringify(request.engine.name)} changed provider/harness platform before lowering.`, "INVALID_CONFIG_FILE");
303
- }
304
- }
305
- const LLM_CALL_ERROR_CODES = new Set([
306
- "aborted",
307
- "timeout",
308
- "rate_limited",
309
- "parse_error",
310
- "provider_html_error",
311
- "network_error",
312
- "provider_error",
313
- ]);
314
- function safeLlmCallErrorCode(error) {
315
- if (!(error instanceof LlmCallError))
316
- return undefined;
317
- const descriptor = Reflect.getOwnPropertyDescriptor(error, "code");
318
- if (!descriptor || !("value" in descriptor) || !LLM_CALL_ERROR_CODES.has(descriptor.value)) {
319
- return undefined;
320
- }
321
- return descriptor.value;
322
- }
323
- function directLlmFailure(error) {
324
- const code = safeLlmCallErrorCode(error);
325
- if (!code)
326
- return { reason: "spawn_failed" };
327
- switch (code) {
328
- case "aborted":
329
- return { reason: "aborted", code };
330
- case "timeout":
331
- return { reason: "timeout", code };
332
- case "rate_limited":
333
- return { reason: "llm_rate_limit", code };
334
- case "parse_error":
335
- case "provider_html_error":
336
- return { reason: "parse_error", code };
337
- case "network_error":
338
- case "provider_error":
339
- return { reason: "spawn_failed", code };
340
- }
341
- }
342
- function safeCaughtErrorMessage(error) {
343
- if (typeof error === "string")
344
- return error;
345
- if (error instanceof Error) {
346
- const descriptor = Reflect.getOwnPropertyDescriptor(error, "message");
347
- if (descriptor && "value" in descriptor && typeof descriptor.value === "string")
348
- return descriptor.value;
349
- }
350
- if (error === null || error === undefined || typeof error === "number" || typeof error === "boolean") {
351
- return String(error);
352
- }
353
- return "LLM transport failed.";
354
- }
355
- function requestRuntimeOptions(request) {
356
- const options = sterileRecord({ stdio: "captured", parseOutput: "text" });
357
- if (own(request.runtime, "timeoutMs"))
358
- options.timeoutMs = request.runtime.timeoutMs;
359
- if (own(request.runtime, "workspace") && typeof request.runtime.workspace === "string") {
360
- options.cwd = request.runtime.workspace;
361
- }
362
- if (own(request.runtime, "environment") && request.runtime.environment !== null) {
363
- options.env = request.runtime.environment;
364
- }
365
- return Object.freeze(options);
366
- }
367
- function projectAgentRunner(base, request) {
368
- const settings = own(request.engine, "settings") ? request.engine.settings : undefined;
369
- const profile = sterileRecord({ ...base.profile });
370
- delete profile.model;
371
- delete profile.workspace;
372
- if (own(request, "model") && request.model) {
373
- profile.model = request.model.resolved;
374
- }
375
- if (own(request.runtime, "workspace") && typeof request.runtime.workspace === "string") {
376
- profile.workspace = request.runtime.workspace;
377
- }
378
- if (settings) {
379
- if (own(settings, "bin") && typeof settings.bin === "string")
380
- profile.bin = settings.bin;
381
- if (own(settings, "args") &&
382
- Array.isArray(settings.args) &&
383
- settings.args.every((entry) => typeof entry === "string")) {
384
- profile.args = Object.freeze([...settings.args]);
385
- }
386
- }
387
- const common = {
388
- ...base,
389
- profile: Object.freeze(profile),
390
- };
391
- const sdkFallbackModelFromRequest = base.kind === "sdk" &&
392
- settings !== null &&
393
- settings !== undefined &&
394
- own(settings, SDK_FALLBACK_MODEL_FROM_REQUEST_SETTING);
395
- const clearsSdkFallbackModel = base.kind === "sdk" && base.fallbackConnection !== undefined && request.model === null;
396
- if (sdkFallbackModelFromRequest && settings?.[SDK_FALLBACK_MODEL_FROM_REQUEST_SETTING] !== true) {
397
- throw new ConfigError("Resolved SDK fallback model marker is invalid.", "INVALID_CONFIG_FILE");
398
- }
399
- if (sdkFallbackModelFromRequest && (!base.fallbackConnection || !own(request, "model"))) {
400
- throw new ConfigError("Resolved SDK fallback model material is incomplete.", "INVALID_CONFIG_FILE");
401
- }
402
- if (base.kind === "sdk" && base.fallbackConnection) {
403
- const fallbackConnection = sterileRecord({ ...base.fallbackConnection });
404
- if (sdkFallbackModelFromRequest || clearsSdkFallbackModel) {
405
- delete fallbackConnection.model;
406
- if (sdkFallbackModelFromRequest && request.model)
407
- fallbackConnection.model = request.model.resolved;
408
- }
409
- if (own(request, "inference")) {
410
- for (const key of LLM_INFERENCE_CONNECTION_FIELDS)
411
- delete fallbackConnection[key];
412
- if (request.inference) {
413
- for (const key of LLM_INFERENCE_CONNECTION_FIELDS) {
414
- if (own(request.inference, key))
415
- fallbackConnection[key] = request.inference[key];
416
- }
417
- }
418
- }
419
- common.fallbackConnection = Object.freeze(fallbackConnection);
420
- }
421
- delete common.timeoutMs;
422
- if (own(request.runtime, "timeoutMs"))
423
- common.timeoutMs = request.runtime.timeoutMs;
424
- else if (own(base, "timeoutMs"))
425
- common.timeoutMs = base.timeoutMs;
426
- return snapshotRunnerSpec(common, {
427
- allowMissingSdkFallbackModel: clearsSdkFallbackModel,
428
- });
429
- }
430
- function selectedExtensionPaths(request) {
431
- const out = [];
432
- if (own(request, "extensions"))
433
- out.push("extensions");
434
- if (own(request.command, "extensions"))
435
- out.push("command.extensions");
436
- const persona = own(request, "persona") ? request.persona : undefined;
437
- if (persona && own(persona, "extensions"))
438
- out.push("persona.extensions");
439
- if (own(request.engine, "extensions"))
440
- out.push("engine.extensions");
441
- if (own(request.runtime, "extensions"))
442
- out.push("runtime.extensions");
443
- return out;
444
- }
445
- const LLM_INFERENCE_CONNECTION_FIELDS = new Set([
446
- "temperature",
447
- "maxTokens",
448
- "supportsJsonSchema",
449
- "extraParams",
450
- "contextLength",
451
- "enableThinking",
452
- "reasoningEffort",
453
- ]);
454
- function projectLlmRunner(base, request) {
455
- const connection = sterileRecord({ ...base.connection });
456
- for (const key of [
457
- "model",
458
- "temperature",
459
- "maxTokens",
460
- "supportsJsonSchema",
461
- "extraParams",
462
- "contextLength",
463
- "enableThinking",
464
- "reasoningEffort",
465
- ]) {
466
- delete connection[key];
467
- }
468
- const settings = own(request.engine, "settings") ? request.engine.settings : undefined;
469
- if (settings) {
470
- if (own(settings, "endpoint") && typeof settings.endpoint === "string")
471
- connection.endpoint = settings.endpoint;
472
- if (own(settings, "provider") && typeof settings.provider === "string")
473
- connection.provider = settings.provider;
474
- }
475
- if (own(request, "model") && request.model)
476
- connection.model = request.model.resolved;
477
- const inference = own(request, "inference") ? request.inference : undefined;
478
- if (inference) {
479
- for (const key of LLM_INFERENCE_CONNECTION_FIELDS) {
480
- if (own(inference, key))
481
- connection[key] = inference[key];
482
- }
483
- }
484
- const projected = {
485
- ...base,
486
- connection: Object.freeze(connection),
487
- };
488
- delete projected.timeoutMs;
489
- if (own(request.runtime, "timeoutMs"))
490
- projected.timeoutMs = request.runtime.timeoutMs;
491
- else if (own(base, "timeoutMs"))
492
- projected.timeoutMs = base.timeoutMs;
493
- return snapshotRunnerSpec(projected, { allowMissingLlmModel: true });
494
- }
495
- function lowerAgent(request, base) {
496
- const platform = own(request.engine, "platform") ? request.engine.platform : undefined;
497
- if (typeof platform !== "string") {
498
- throw new ConfigError(`Resolved agent engine ${JSON.stringify(request.engine.name)} has no platform.`, "INVALID_CONFIG_FILE");
499
- }
500
- const lowerer = AGENT_LOWERERS.get(platform);
501
- if (!lowerer) {
502
- throw new ConfigError(`Agent platform ${JSON.stringify(platform)} has no registered lowerer.`, "INVALID_CONFIG_FILE");
503
- }
504
- const runner = projectAgentRunner(base, request);
505
- const lowered = lowerer.lower(runner.profile, request);
506
- const options = Object.freeze(sterileRecord({ ...requestRuntimeOptions(request), dispatch: lowered.dispatch }));
507
- return registerLoweredExecution({
508
- schemaVersion: EXECUTION_LOWERING_SCHEMA_VERSION,
509
- request,
510
- adapter: platform,
511
- runner,
512
- prompt: lowered.prompt,
513
- dispatch: lowered.dispatch,
514
- options,
515
- translatedFields: sortedUnique([
516
- ...lowered.translatedFields,
517
- ...(own(request.engine, "settings") ? ["engine.settings"] : []),
518
- ]),
519
- untranslatedFields: lowered.untranslatedFields,
520
- notices: freezeNotices([...safeRequestNotices(request), ...lowered.notices]),
521
- });
522
- }
523
- function lowerLlm(request, base) {
524
- const runner = projectLlmRunner(base, request);
525
- const translated = new Set(["command.content", "engine"]);
526
- const untranslated = new Set();
527
- const notices = [...safeRequestNotices(request)];
528
- const reject = (field) => {
529
- untranslated.add(field);
530
- notices.push(untranslatedNotice("llm", field));
531
- };
532
- if (own(request.engine, "settings"))
533
- translated.add("engine.settings");
534
- if (own(request, "model"))
535
- translated.add("model");
536
- if (own(request, "persona"))
537
- translated.add("persona");
538
- if (own(request, "agent")) {
539
- if (typeof request.agent === "string" && request.persona === null) {
540
- throw new ConfigError(`The direct LLM transport cannot consume native agent selector ${JSON.stringify(request.agent)}.`, "INVALID_CONFIG_FILE");
541
- }
542
- translated.add("agent");
543
- }
544
- if (own(request, "conversation"))
545
- translated.add("conversation");
546
- if (own(request, "inference")) {
547
- const inference = request.inference;
548
- if (inference && Object.keys(inference).length > 0) {
549
- for (const key of Object.keys(inference).sort()) {
550
- const field = `inference.${key}`;
551
- if (LLM_INFERENCE_CONNECTION_FIELDS.has(key))
552
- translated.add(field);
553
- else
554
- reject(field);
555
- }
556
- }
557
- else {
558
- translated.add("inference");
559
- }
560
- }
561
- const chatOptions = sterileRecord({});
562
- if (own(request.runtime, "timeoutMs")) {
563
- translated.add("runtime.timeoutMs");
564
- chatOptions.timeoutMs = request.runtime.timeoutMs;
565
- }
566
- if (own(request, "outputSchema")) {
567
- if (request.outputSchema === null)
568
- translated.add("outputSchema");
569
- else if (runner.connection.supportsJsonSchema === true) {
570
- translated.add("outputSchema");
571
- chatOptions.responseSchema = request.outputSchema;
572
- }
573
- else
574
- reject("outputSchema");
575
- }
576
- if (own(request, "tools")) {
577
- const tools = request.tools;
578
- const empty = tools === null ||
579
- tools === "" ||
580
- (Array.isArray(tools) && tools.length === 0) ||
581
- (typeof tools === "object" && tools !== null && !Array.isArray(tools) && Object.keys(tools).length === 0);
582
- if (empty)
583
- translated.add("tools");
584
- else {
585
- throw new ConfigError("The direct LLM transport cannot enforce the resolved tool policy.", "INVALID_CONFIG_FILE");
586
- }
587
- }
588
- if (own(request.runtime, "workspace")) {
589
- if (request.runtime.workspace === null || request.runtime.workspace === "")
590
- translated.add("runtime.workspace");
591
- else
592
- reject("runtime.workspace");
593
- }
594
- if (own(request.runtime, "environment")) {
595
- const environment = request.runtime.environment;
596
- if (environment === null || environment === undefined || Object.keys(environment).length === 0) {
597
- translated.add("runtime.environment");
598
- }
599
- else
600
- reject("runtime.environment");
601
- }
602
- if (own(request.runtime, "settings")) {
603
- const settings = request.runtime.settings;
604
- if (settings === null || settings === undefined || Object.keys(settings).length === 0) {
605
- translated.add("runtime.settings");
606
- }
607
- else
608
- reject("runtime.settings");
609
- }
610
- for (const field of selectedExtensionPaths(request))
611
- reject(field);
612
- const messages = Object.freeze([
613
- ...(own(request, "persona") && request.persona
614
- ? [{ role: "system", content: request.persona.content }]
615
- : []),
616
- ...(request.conversation ?? []),
617
- { role: "user", content: request.command.content },
618
- ].map((message) => Object.freeze({ role: message.role, content: message.content })));
619
- return registerLoweredExecution({
620
- schemaVersion: EXECUTION_LOWERING_SCHEMA_VERSION,
621
- request,
622
- adapter: "llm",
623
- runner,
624
- prompt: request.command.content,
625
- messages,
626
- chatOptions: Object.freeze(chatOptions),
627
- options: requestRuntimeOptions(request),
628
- translatedFields: sortedUnique(translated),
629
- untranslatedFields: sortedUnique(untranslated),
630
- notices: freezeNotices(notices),
631
- });
632
- }
633
- /** The sole live-config engine resolver used by every current execution mode. */
634
- function resolveSnapshotRunner(engine, config) {
635
- return snapshotRunnerSpec(resolveEngine(engine, config));
636
- }
637
- /**
638
- * Lower one payload-free interactive launch. The input vocabulary is closed:
639
- * there is deliberately no command, prompt, model, tool, or arbitrary env.
640
- */
641
- function lowerInteractiveAgentExecution(input) {
642
- if (typeof input.engine !== "string" || input.engine.length === 0) {
643
- throw new TypeError("interactive agent execution input.engine must be a non-empty string");
644
- }
645
- if (input.timeoutMs !== undefined) {
646
- validateTimeout(input.timeoutMs, "interactive agent execution input.timeoutMs");
647
- }
648
- if (input.cwd !== undefined && typeof input.cwd !== "string") {
649
- throw new TypeError("interactive agent execution input.cwd must be a string");
650
- }
651
- const runner = resolveSnapshotRunner(input.engine, snapshotConfig(input.config));
652
- if (runner.kind === "llm") {
653
- throw new UsageError(`Engine "${input.engine}" is an LLM engine; akm agent requires an agent engine.`, "INVALID_FLAG_VALUE");
654
- }
655
- const options = Object.freeze(sterileRecord({
656
- stdio: runner.kind === "sdk" ? runner.profile.stdio : "interactive",
657
- parseOutput: "text",
658
- ...(input.timeoutMs !== undefined ? { timeoutMs: input.timeoutMs } : {}),
659
- ...(input.cwd ? { cwd: input.cwd } : {}),
660
- }));
661
- return Object.freeze({
662
- engine: input.engine,
663
- runner,
664
- options,
665
- });
666
- }
667
- /**
668
- * The one optimistic lowering boundary. Authorization and request-brand
669
- * validation precede config, registry, credential, and transport work.
670
- */
671
- export function lowerResolvedExecutionRequest(input, config) {
672
- const request = requireAuthorizedRequest(input);
673
- const frozenConfig = snapshotConfig(config);
674
- const base = resolveSnapshotRunner(request.engine.name, frozenConfig);
675
- requireRunnerShape(request, base);
676
- return base.kind === "llm" ? lowerLlm(request, base) : lowerAgent(request, base);
677
- }
678
- /**
679
- * Lower from already-frozen, symbolic runner material. Workflow resume uses
680
- * this entry point so no live config, alias, environment, or credential lookup
681
- * can alter a journaled request before dispatch.
682
- */
683
- export function lowerResolvedExecutionRequestWithRunner(input, runner) {
684
- const request = requireAuthorizedRequest(input);
685
- const base = snapshotRunnerSpec(runner);
686
- requireRunnerShape(request, base);
687
- return base.kind === "llm" ? lowerLlm(request, base) : lowerAgent(request, base);
688
- }
689
- function requireLoweredExecutionProvenance(lowered) {
690
- if (typeof lowered !== "object" ||
691
- lowered === null ||
692
- !loweredExecutionInstances.has(lowered) ||
693
- !Object.isFrozen(lowered)) {
694
- throw new TypeError("lowered execution request must be produced by the engine lowerer registry");
695
- }
696
- canonicalResolvedExecutionRequest(lowered.request);
697
- }
698
- /**
699
- * Acquire an opaque operation capability only after genuine lowered-request
700
- * provenance and canonical authorization have been revalidated.
701
- */
702
- export function acquireLoweredExecutionDispatchLease(lowered, options = {}) {
703
- requireLoweredExecutionProvenance(lowered);
704
- const optionSnapshot = snapshotStrictRecord(options, "dispatch lease acquisition options");
705
- assertSnapshotKeys(optionSnapshot, ["envSource"], "dispatch lease acquisition options");
706
- const strictOptions = optionSnapshot;
707
- return acquireRunnerDispatchLease(lowered.runner, strictOptions.envSource ?? process.env);
708
- }
709
- /** Idempotently scrub and invalidate a genuine operation dispatch lease. */
710
- export function disposeLoweredExecutionDispatchLease(lease) {
711
- disposeRunnerDispatchLease(lease);
712
- }
713
- /** Redact text with a lease's private credential inventory without exposing it. */
714
- export function redactWithLoweredExecutionDispatchLease(lease, value) {
715
- return redactWithRunnerDispatchLease(lease, value);
716
- }
717
- /** One raw runner symbol reference for every shared execution dispatch mode. */
718
- function runnerDispatcher(candidate) {
719
- return candidate ?? executeRunner;
720
- }
721
- async function dispatchLoweredInteractiveAgentExecution(lowered, seams) {
722
- const lease = acquireRunnerDispatchLease(lowered.runner, process.env);
723
- try {
724
- return await runnerDispatcher()(lowered.runner, "", lowered.options, {
725
- ...(seams.runAgent ? { runAgent: seams.runAgent } : {}),
726
- ...(seams.runSdk ? { runSdk: seams.runSdk } : {}),
727
- }, lease);
728
- }
729
- finally {
730
- disposeRunnerDispatchLease(lease);
731
- }
732
- }
733
- /** Resolve, lower, and dispatch one native interactive agent invocation. */
734
- export async function executeInteractiveAgentInvocation(input, seams = {}) {
735
- const lowered = lowerInteractiveAgentExecution(input);
736
- return {
737
- engine: lowered.engine,
738
- result: await dispatchLoweredInteractiveAgentExecution(lowered, seams),
739
- };
740
- }
741
- /** Dispatch a previously lowered request without re-resolving any model, ref, or persona. */
742
- export async function dispatchLoweredExecutionRequest(lowered, options = {}) {
743
- requireLoweredExecutionProvenance(lowered);
744
- const optionSnapshot = snapshotStrictRecord(options, "lowered execution dispatch options");
745
- assertSnapshotKeys(optionSnapshot, ["executeRunner", "chat", "onRetryAttempt", "runAgent", "runSdk", "lease", "runOptions", "eventSource"], "lowered execution dispatch options");
746
- const strictOptions = optionSnapshot;
747
- if (strictOptions.onRetryAttempt !== undefined && typeof strictOptions.onRetryAttempt !== "function") {
748
- throw new TypeError("lowered execution dispatch options.onRetryAttempt must be a function");
749
- }
750
- if (strictOptions.eventSource !== undefined && typeof strictOptions.eventSource !== "string") {
751
- throw new TypeError("lowered execution dispatch options.eventSource must be a string");
752
- }
753
- const usesDefaultRunner = strictOptions.executeRunner === undefined;
754
- const run = runnerDispatcher(strictOptions.executeRunner);
755
- const operationalSnapshot = snapshotStrictRecord(strictOptions.runOptions ?? {}, "lowered execution operational options");
756
- assertSnapshotKeys(operationalSnapshot, [
757
- "stdio",
758
- "timeoutMs",
759
- "parseOutput",
760
- "env",
761
- "cwd",
762
- "args",
763
- "stdin",
764
- "signal",
765
- "envSource",
766
- "spawn",
767
- "setTimeoutFn",
768
- "clearTimeoutFn",
769
- "onEvent",
770
- "dispatch",
771
- "builderRegistry",
772
- ], "lowered execution operational options");
773
- const operational = operationalSnapshot;
774
- const runOptions = sterileRecord({
775
- ...lowered.options,
776
- ...(operational.stdio !== undefined ? { stdio: operational.stdio } : {}),
777
- ...(operational.parseOutput !== undefined ? { parseOutput: operational.parseOutput } : {}),
778
- ...(operational.signal !== undefined ? { signal: operational.signal } : {}),
779
- ...(operational.envSource !== undefined ? { envSource: operational.envSource } : {}),
780
- ...(operational.spawn !== undefined ? { spawn: operational.spawn } : {}),
781
- ...(operational.setTimeoutFn !== undefined ? { setTimeoutFn: operational.setTimeoutFn } : {}),
782
- ...(operational.clearTimeoutFn !== undefined ? { clearTimeoutFn: operational.clearTimeoutFn } : {}),
783
- ...(operational.onEvent !== undefined ? { onEvent: operational.onEvent } : {}),
784
- // F-1 (spec docs/plans/specs/p1b-model-extraction.md §5.2 point 3): the
785
- // ONE narrowly-scoped exception to "resolved content cannot be
786
- // overridden" — sets exactly the one named key, never a caller-supplied
787
- // env bag (runOptions.env stays unhonored, same as before P1b; see
788
- // DispatchLoweredExecutionOptions.eventSource's doc).
789
- ...(strictOptions.eventSource !== undefined
790
- ? { env: { ...lowered.options.env, AKM_EVENT_SOURCE: strictOptions.eventSource } }
791
- : {}),
792
- });
793
- const ownedLease = strictOptions.lease === undefined && usesDefaultRunner;
794
- const lease = strictOptions.lease ??
795
- (ownedLease ? acquireRunnerDispatchLease(lowered.runner, runOptions.envSource ?? process.env) : undefined);
796
- if (lease)
797
- assertRunnerDispatchLease(lease, lowered.runner);
798
- try {
799
- return await run(lowered.runner, lowered.prompt, runOptions, {
800
- ...(strictOptions.runAgent ? { runAgent: strictOptions.runAgent } : {}),
801
- ...(strictOptions.runSdk ? { runSdk: strictOptions.runSdk } : {}),
802
- ...("messages" in lowered
803
- ? {
804
- llm: async (spec, _prompt, runOptions) => {
805
- const started = Date.now();
806
- try {
807
- const stdout = await (strictOptions.chat ?? chatCompletion)(spec.connection, [...lowered.messages], {
808
- ...lowered.chatOptions,
809
- ...(!own(lowered.chatOptions, "timeoutMs") && own(runOptions, "timeoutMs")
810
- ? { timeoutMs: runOptions.timeoutMs }
811
- : {}),
812
- ...(runOptions.signal ? { signal: runOptions.signal } : {}),
813
- ...(strictOptions.onRetryAttempt ? { onRetryAttempt: strictOptions.onRetryAttempt } : {}),
814
- });
815
- return { ok: true, exitCode: 0, stdout, stderr: "", durationMs: Date.now() - started };
816
- }
817
- catch (error) {
818
- // Return through executeRunner so its credential-aware redactor
819
- // handles provider bodies before any caller can persist them.
820
- const failure = directLlmFailure(error);
821
- return {
822
- ok: false,
823
- exitCode: null,
824
- stdout: "",
825
- stderr: "",
826
- durationMs: Date.now() - started,
827
- error: safeCaughtErrorMessage(error),
828
- reason: failure.reason,
829
- ...(failure.code ? { llmErrorCode: failure.code } : {}),
830
- };
831
- }
832
- },
833
- }
834
- : {}),
835
- }, lease);
836
- }
837
- finally {
838
- if (ownedLease && lease)
839
- disposeRunnerDispatchLease(lease);
840
- }
841
- }