open-multi-agent-kit 0.96.0 → 0.96.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +34 -6
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +1 -0
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/commands/doctor-provider.d.ts.map +1 -1
  7. package/dist/commands/doctor-provider.js +15 -20
  8. package/dist/commands/doctor-provider.js.map +1 -1
  9. package/dist/commands/resource-doctor-cli.d.ts +22 -0
  10. package/dist/commands/resource-doctor-cli.d.ts.map +1 -0
  11. package/dist/commands/resource-doctor-cli.js +98 -0
  12. package/dist/commands/resource-doctor-cli.js.map +1 -0
  13. package/dist/commands/sdk-session-cli.d.ts +24 -0
  14. package/dist/commands/sdk-session-cli.d.ts.map +1 -0
  15. package/dist/commands/sdk-session-cli.js +225 -0
  16. package/dist/commands/sdk-session-cli.js.map +1 -0
  17. package/dist/core/advisory-judge-model.d.ts +18 -0
  18. package/dist/core/advisory-judge-model.d.ts.map +1 -0
  19. package/dist/core/advisory-judge-model.js +168 -0
  20. package/dist/core/advisory-judge-model.js.map +1 -0
  21. package/dist/core/advisory-judge-response.d.ts +8 -0
  22. package/dist/core/advisory-judge-response.d.ts.map +1 -0
  23. package/dist/core/advisory-judge-response.js +61 -0
  24. package/dist/core/advisory-judge-response.js.map +1 -0
  25. package/dist/core/advisory-judge-types.d.ts +53 -0
  26. package/dist/core/advisory-judge-types.d.ts.map +1 -0
  27. package/dist/core/advisory-judge-types.js +2 -0
  28. package/dist/core/advisory-judge-types.js.map +1 -0
  29. package/dist/core/advisory-judge.d.ts +8 -0
  30. package/dist/core/advisory-judge.d.ts.map +1 -0
  31. package/dist/core/advisory-judge.js +178 -0
  32. package/dist/core/advisory-judge.js.map +1 -0
  33. package/dist/core/agent-session-services.d.ts +1 -0
  34. package/dist/core/agent-session-services.d.ts.map +1 -1
  35. package/dist/core/agent-session-services.js +1 -0
  36. package/dist/core/agent-session-services.js.map +1 -1
  37. package/dist/core/agent-session.d.ts +41 -2
  38. package/dist/core/agent-session.d.ts.map +1 -1
  39. package/dist/core/agent-session.js +396 -179
  40. package/dist/core/agent-session.js.map +1 -1
  41. package/dist/core/auth-storage.d.ts.map +1 -1
  42. package/dist/core/auth-storage.js +28 -4
  43. package/dist/core/auth-storage.js.map +1 -1
  44. package/dist/core/compaction-gate.d.ts +28 -0
  45. package/dist/core/compaction-gate.d.ts.map +1 -0
  46. package/dist/core/compaction-gate.js +34 -0
  47. package/dist/core/compaction-gate.js.map +1 -0
  48. package/dist/core/completion-sound.d.ts +109 -0
  49. package/dist/core/completion-sound.d.ts.map +1 -0
  50. package/dist/core/completion-sound.js +165 -0
  51. package/dist/core/completion-sound.js.map +1 -0
  52. package/dist/core/context-budget-system-prompt-items.d.ts.map +1 -1
  53. package/dist/core/context-budget-system-prompt-items.js +5 -3
  54. package/dist/core/context-budget-system-prompt-items.js.map +1 -1
  55. package/dist/core/domain-loadouts.d.ts.map +1 -1
  56. package/dist/core/domain-loadouts.js +2 -2
  57. package/dist/core/domain-loadouts.js.map +1 -1
  58. package/dist/core/durable-goal-checkpoint.d.ts +6 -0
  59. package/dist/core/durable-goal-checkpoint.d.ts.map +1 -0
  60. package/dist/core/durable-goal-checkpoint.js +195 -0
  61. package/dist/core/durable-goal-checkpoint.js.map +1 -0
  62. package/dist/core/durable-goal-parse.d.ts +3 -0
  63. package/dist/core/durable-goal-parse.d.ts.map +1 -0
  64. package/dist/core/durable-goal-parse.js +86 -0
  65. package/dist/core/durable-goal-parse.js.map +1 -0
  66. package/dist/core/durable-goal-reducer.d.ts +3 -0
  67. package/dist/core/durable-goal-reducer.d.ts.map +1 -0
  68. package/dist/core/durable-goal-reducer.js +175 -0
  69. package/dist/core/durable-goal-reducer.js.map +1 -0
  70. package/dist/core/durable-goal-store.d.ts +19 -0
  71. package/dist/core/durable-goal-store.d.ts.map +1 -0
  72. package/dist/core/durable-goal-store.js +126 -0
  73. package/dist/core/durable-goal-store.js.map +1 -0
  74. package/dist/core/durable-goal.d.ts +92 -0
  75. package/dist/core/durable-goal.d.ts.map +1 -0
  76. package/dist/core/durable-goal.js +62 -0
  77. package/dist/core/durable-goal.js.map +1 -0
  78. package/dist/core/extensions/builtin/goal-controller.d.ts +3 -0
  79. package/dist/core/extensions/builtin/goal-controller.d.ts.map +1 -0
  80. package/dist/core/extensions/builtin/goal-controller.js +125 -0
  81. package/dist/core/extensions/builtin/goal-controller.js.map +1 -0
  82. package/dist/core/extensions/builtin/identical-loop.d.ts +3 -0
  83. package/dist/core/extensions/builtin/identical-loop.d.ts.map +1 -0
  84. package/dist/core/extensions/builtin/identical-loop.js +31 -0
  85. package/dist/core/extensions/builtin/identical-loop.js.map +1 -0
  86. package/dist/core/extensions/builtin/prompt-preset.d.ts +3 -0
  87. package/dist/core/extensions/builtin/prompt-preset.d.ts.map +1 -0
  88. package/dist/core/extensions/builtin/prompt-preset.js +13 -0
  89. package/dist/core/extensions/builtin/prompt-preset.js.map +1 -0
  90. package/dist/core/extensions/builtin/tool-pair-repair.d.ts +3 -0
  91. package/dist/core/extensions/builtin/tool-pair-repair.d.ts.map +1 -0
  92. package/dist/core/extensions/builtin/tool-pair-repair.js +12 -0
  93. package/dist/core/extensions/builtin/tool-pair-repair.js.map +1 -0
  94. package/dist/core/extensions/types.d.ts +6 -2
  95. package/dist/core/extensions/types.d.ts.map +1 -1
  96. package/dist/core/extensions/types.js.map +1 -1
  97. package/dist/core/goal-continuation.d.ts +13 -0
  98. package/dist/core/goal-continuation.d.ts.map +1 -0
  99. package/dist/core/goal-continuation.js +10 -0
  100. package/dist/core/goal-continuation.js.map +1 -0
  101. package/dist/core/grok-harness.d.ts +1 -1
  102. package/dist/core/grok-harness.d.ts.map +1 -1
  103. package/dist/core/grok-harness.js +1 -1
  104. package/dist/core/grok-harness.js.map +1 -1
  105. package/dist/core/grok-playbook.d.ts +1 -1
  106. package/dist/core/grok-playbook.d.ts.map +1 -1
  107. package/dist/core/grok-playbook.js +1 -1
  108. package/dist/core/grok-playbook.js.map +1 -1
  109. package/dist/core/host-resource-probe.d.ts +63 -0
  110. package/dist/core/host-resource-probe.d.ts.map +1 -0
  111. package/dist/core/host-resource-probe.js +126 -0
  112. package/dist/core/host-resource-probe.js.map +1 -0
  113. package/dist/core/host-resource-snapshot.d.ts +54 -0
  114. package/dist/core/host-resource-snapshot.d.ts.map +1 -0
  115. package/dist/core/host-resource-snapshot.js +139 -0
  116. package/dist/core/host-resource-snapshot.js.map +1 -0
  117. package/dist/core/identical-loop.d.ts +15 -0
  118. package/dist/core/identical-loop.d.ts.map +1 -0
  119. package/dist/core/identical-loop.js +34 -0
  120. package/dist/core/identical-loop.js.map +1 -0
  121. package/dist/core/index.d.ts +1 -1
  122. package/dist/core/index.d.ts.map +1 -1
  123. package/dist/core/index.js +1 -1
  124. package/dist/core/index.js.map +1 -1
  125. package/dist/core/model-prompt-policy.d.ts +11 -0
  126. package/dist/core/model-prompt-policy.d.ts.map +1 -0
  127. package/dist/core/model-prompt-policy.js +17 -0
  128. package/dist/core/model-prompt-policy.js.map +1 -0
  129. package/dist/core/model-registry.d.ts.map +1 -1
  130. package/dist/core/model-registry.js +16 -4
  131. package/dist/core/model-registry.js.map +1 -1
  132. package/dist/core/model-resolver.d.ts.map +1 -1
  133. package/dist/core/model-resolver.js +2 -2
  134. package/dist/core/model-resolver.js.map +1 -1
  135. package/dist/core/prompt-budget.d.ts +21 -0
  136. package/dist/core/prompt-budget.d.ts.map +1 -0
  137. package/dist/core/prompt-budget.js +51 -0
  138. package/dist/core/prompt-budget.js.map +1 -0
  139. package/dist/core/prompt-cache.d.ts +14 -0
  140. package/dist/core/prompt-cache.d.ts.map +1 -0
  141. package/dist/core/prompt-cache.js +16 -0
  142. package/dist/core/prompt-cache.js.map +1 -0
  143. package/dist/core/prompt-preset.d.ts +8 -0
  144. package/dist/core/prompt-preset.d.ts.map +1 -0
  145. package/dist/core/prompt-preset.js +56 -0
  146. package/dist/core/prompt-preset.js.map +1 -0
  147. package/dist/core/prompt-settlement.d.ts +81 -0
  148. package/dist/core/prompt-settlement.d.ts.map +1 -0
  149. package/dist/core/prompt-settlement.js +84 -0
  150. package/dist/core/prompt-settlement.js.map +1 -0
  151. package/dist/core/provider-resilience.d.ts +16 -0
  152. package/dist/core/provider-resilience.d.ts.map +1 -1
  153. package/dist/core/provider-resilience.js +24 -2
  154. package/dist/core/provider-resilience.js.map +1 -1
  155. package/dist/core/provider-retry.d.ts +36 -0
  156. package/dist/core/provider-retry.d.ts.map +1 -0
  157. package/dist/core/provider-retry.js +73 -0
  158. package/dist/core/provider-retry.js.map +1 -0
  159. package/dist/core/provider-usage.d.ts +16 -2
  160. package/dist/core/provider-usage.d.ts.map +1 -1
  161. package/dist/core/provider-usage.js +150 -8
  162. package/dist/core/provider-usage.js.map +1 -1
  163. package/dist/core/reasoning-router-resolver.d.ts.map +1 -1
  164. package/dist/core/reasoning-router-resolver.js +1 -1
  165. package/dist/core/reasoning-router-resolver.js.map +1 -1
  166. package/dist/core/resource-admission-config.d.ts +55 -0
  167. package/dist/core/resource-admission-config.d.ts.map +1 -0
  168. package/dist/core/resource-admission-config.js +97 -0
  169. package/dist/core/resource-admission-config.js.map +1 -0
  170. package/dist/core/resource-admission.d.ts +81 -0
  171. package/dist/core/resource-admission.d.ts.map +1 -0
  172. package/dist/core/resource-admission.js +128 -0
  173. package/dist/core/resource-admission.js.map +1 -0
  174. package/dist/core/resource-governor-format.d.ts +50 -0
  175. package/dist/core/resource-governor-format.d.ts.map +1 -0
  176. package/dist/core/resource-governor-format.js +113 -0
  177. package/dist/core/resource-governor-format.js.map +1 -0
  178. package/dist/core/resource-governor-settings.d.ts +56 -0
  179. package/dist/core/resource-governor-settings.d.ts.map +1 -0
  180. package/dist/core/resource-governor-settings.js +89 -0
  181. package/dist/core/resource-governor-settings.js.map +1 -0
  182. package/dist/core/resource-loader.d.ts.map +1 -1
  183. package/dist/core/resource-loader.js +32 -0
  184. package/dist/core/resource-loader.js.map +1 -1
  185. package/dist/core/resource-observation-journal.d.ts +74 -0
  186. package/dist/core/resource-observation-journal.d.ts.map +1 -0
  187. package/dist/core/resource-observation-journal.js +198 -0
  188. package/dist/core/resource-observation-journal.js.map +1 -0
  189. package/dist/core/resource-safety-gate.d.ts +54 -0
  190. package/dist/core/resource-safety-gate.d.ts.map +1 -0
  191. package/dist/core/resource-safety-gate.js +51 -0
  192. package/dist/core/resource-safety-gate.js.map +1 -0
  193. package/dist/core/run-journal.d.ts.map +1 -1
  194. package/dist/core/run-journal.js +13 -1
  195. package/dist/core/run-journal.js.map +1 -1
  196. package/dist/core/run-resource-lease.d.ts +73 -0
  197. package/dist/core/run-resource-lease.d.ts.map +1 -0
  198. package/dist/core/run-resource-lease.js +78 -0
  199. package/dist/core/run-resource-lease.js.map +1 -0
  200. package/dist/core/sandbox/backend.d.ts +12 -0
  201. package/dist/core/sandbox/backend.d.ts.map +1 -1
  202. package/dist/core/sandbox/backend.js +52 -42
  203. package/dist/core/sandbox/backend.js.map +1 -1
  204. package/dist/core/sandbox/policy.d.ts +2 -0
  205. package/dist/core/sandbox/policy.d.ts.map +1 -1
  206. package/dist/core/sandbox/policy.js +2 -1
  207. package/dist/core/sandbox/policy.js.map +1 -1
  208. package/dist/core/sdk.d.ts +2 -0
  209. package/dist/core/sdk.d.ts.map +1 -1
  210. package/dist/core/sdk.js +1 -0
  211. package/dist/core/sdk.js.map +1 -1
  212. package/dist/core/session-bash-service.d.ts +12 -0
  213. package/dist/core/session-bash-service.d.ts.map +1 -1
  214. package/dist/core/session-bash-service.js +14 -0
  215. package/dist/core/session-bash-service.js.map +1 -1
  216. package/dist/core/session-system-prompt.d.ts +30 -0
  217. package/dist/core/session-system-prompt.d.ts.map +1 -0
  218. package/dist/core/session-system-prompt.js +39 -0
  219. package/dist/core/session-system-prompt.js.map +1 -0
  220. package/dist/core/session-termination.d.ts +7 -2
  221. package/dist/core/session-termination.d.ts.map +1 -1
  222. package/dist/core/session-termination.js +29 -1
  223. package/dist/core/session-termination.js.map +1 -1
  224. package/dist/core/settings-manager.d.ts +12 -0
  225. package/dist/core/settings-manager.d.ts.map +1 -1
  226. package/dist/core/settings-manager.js +36 -0
  227. package/dist/core/settings-manager.js.map +1 -1
  228. package/dist/core/slash-commands.d.ts.map +1 -1
  229. package/dist/core/slash-commands.js +1 -0
  230. package/dist/core/slash-commands.js.map +1 -1
  231. package/dist/core/strict-record.d.ts +2 -0
  232. package/dist/core/strict-record.d.ts.map +1 -0
  233. package/dist/core/strict-record.js +9 -0
  234. package/dist/core/strict-record.js.map +1 -0
  235. package/dist/core/subagent-lane-launcher.d.ts +64 -0
  236. package/dist/core/subagent-lane-launcher.d.ts.map +1 -0
  237. package/dist/core/subagent-lane-launcher.js +107 -0
  238. package/dist/core/subagent-lane-launcher.js.map +1 -0
  239. package/dist/core/system-cpu-sampler.d.ts +45 -0
  240. package/dist/core/system-cpu-sampler.d.ts.map +1 -0
  241. package/dist/core/system-cpu-sampler.js +95 -0
  242. package/dist/core/system-cpu-sampler.js.map +1 -0
  243. package/dist/core/system-prompt.d.ts.map +1 -1
  244. package/dist/core/system-prompt.js +5 -8
  245. package/dist/core/system-prompt.js.map +1 -1
  246. package/dist/core/tool-pair-repair.d.ts +11 -0
  247. package/dist/core/tool-pair-repair.d.ts.map +1 -0
  248. package/dist/core/tool-pair-repair.js +38 -0
  249. package/dist/core/tool-pair-repair.js.map +1 -0
  250. package/dist/core/tools/artifact-spill.d.ts +13 -0
  251. package/dist/core/tools/artifact-spill.d.ts.map +1 -0
  252. package/dist/core/tools/artifact-spill.js +26 -0
  253. package/dist/core/tools/artifact-spill.js.map +1 -0
  254. package/dist/core/tools/bash.d.ts +7 -4
  255. package/dist/core/tools/bash.d.ts.map +1 -1
  256. package/dist/core/tools/bash.js +8 -7
  257. package/dist/core/tools/bash.js.map +1 -1
  258. package/dist/core/tools/index.d.ts +1 -1
  259. package/dist/core/tools/index.d.ts.map +1 -1
  260. package/dist/core/tools/index.js.map +1 -1
  261. package/dist/core/tools/read.d.ts +1 -0
  262. package/dist/core/tools/read.d.ts.map +1 -1
  263. package/dist/core/tools/read.js +10 -1
  264. package/dist/core/tools/read.js.map +1 -1
  265. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  266. package/dist/core/tools/tool-definition-wrapper.js +2 -0
  267. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  268. package/dist/core/workload-classifier.d.ts +32 -0
  269. package/dist/core/workload-classifier.d.ts.map +1 -0
  270. package/dist/core/workload-classifier.js +66 -0
  271. package/dist/core/workload-classifier.js.map +1 -0
  272. package/dist/core/workload-family-matcher.d.ts +3 -0
  273. package/dist/core/workload-family-matcher.d.ts.map +1 -0
  274. package/dist/core/workload-family-matcher.js +126 -0
  275. package/dist/core/workload-family-matcher.js.map +1 -0
  276. package/dist/core/workload-permit-pool.d.ts +78 -0
  277. package/dist/core/workload-permit-pool.d.ts.map +1 -0
  278. package/dist/core/workload-permit-pool.js +138 -0
  279. package/dist/core/workload-permit-pool.js.map +1 -0
  280. package/dist/core/workload-shard-executor.d.ts +68 -0
  281. package/dist/core/workload-shard-executor.d.ts.map +1 -0
  282. package/dist/core/workload-shard-executor.js +156 -0
  283. package/dist/core/workload-shard-executor.js.map +1 -0
  284. package/dist/core/workload-shard-plan.d.ts +81 -0
  285. package/dist/core/workload-shard-plan.d.ts.map +1 -0
  286. package/dist/core/workload-shard-plan.js +183 -0
  287. package/dist/core/workload-shard-plan.js.map +1 -0
  288. package/dist/core/workload-shard-runner.d.ts +11 -0
  289. package/dist/core/workload-shard-runner.d.ts.map +1 -0
  290. package/dist/core/workload-shard-runner.js +98 -0
  291. package/dist/core/workload-shard-runner.js.map +1 -0
  292. package/dist/core/workload-shard-store.d.ts +44 -0
  293. package/dist/core/workload-shard-store.d.ts.map +1 -0
  294. package/dist/core/workload-shard-store.js +189 -0
  295. package/dist/core/workload-shard-store.js.map +1 -0
  296. package/dist/core/workload-sharders.d.ts +47 -0
  297. package/dist/core/workload-sharders.d.ts.map +1 -0
  298. package/dist/core/workload-sharders.js +162 -0
  299. package/dist/core/workload-sharders.js.map +1 -0
  300. package/dist/core/workload-shell-scan.d.ts +12 -0
  301. package/dist/core/workload-shell-scan.d.ts.map +1 -0
  302. package/dist/core/workload-shell-scan.js +79 -0
  303. package/dist/core/workload-shell-scan.js.map +1 -0
  304. package/dist/index.d.ts +18 -1
  305. package/dist/index.d.ts.map +1 -1
  306. package/dist/index.js +18 -0
  307. package/dist/index.js.map +1 -1
  308. package/dist/main.d.ts.map +1 -1
  309. package/dist/main.js +14 -0
  310. package/dist/main.js.map +1 -1
  311. package/dist/modes/interactive/interactive-mode.d.ts +4 -0
  312. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  313. package/dist/modes/interactive/interactive-mode.js +81 -0
  314. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  315. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  316. package/dist/modes/interactive/theme/theme.js +14 -3
  317. package/dist/modes/interactive/theme/theme.js.map +1 -1
  318. package/docs/adaptorch-preview-spec.md +1 -1
  319. package/docs/adaptorch-preview.md +2 -2
  320. package/docs/book-to-skill.md +1 -1
  321. package/docs/containerization.md +9 -0
  322. package/docs/docs.json +11 -3
  323. package/docs/environment-variables.md +11 -4
  324. package/docs/extensions.md +14 -1
  325. package/docs/grok-harness.md +35 -12
  326. package/docs/index.md +7 -6
  327. package/docs/loadout-domains/grok-harness.md +2 -2
  328. package/docs/models.md +10 -9
  329. package/docs/provider-resilience.md +9 -3
  330. package/docs/providers.md +9 -4
  331. package/docs/run-protocol.md +32 -0
  332. package/docs/sdk.md +100 -3
  333. package/docs/security.md +22 -32
  334. package/docs/sessions.md +14 -0
  335. package/docs/settings.md +64 -2
  336. package/docs/skills.md +16 -0
  337. package/docs/usage.md +37 -15
  338. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  339. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  340. package/examples/extensions/custom-provider-gitlab-duo/index.ts +6 -1
  341. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  342. package/examples/extensions/gondolin/package-lock.json +2 -2
  343. package/examples/extensions/gondolin/package.json +1 -1
  344. package/examples/extensions/sandbox/package-lock.json +2 -2
  345. package/examples/extensions/sandbox/package.json +1 -1
  346. package/examples/extensions/subagent/agent-capability-router.test.ts +7 -0
  347. package/examples/extensions/subagent/domain-profiles.ts +0 -1
  348. package/examples/extensions/with-deps/package-lock.json +2 -2
  349. package/examples/extensions/with-deps/package.json +1 -1
  350. package/npm-shrinkwrap.json +18 -18
  351. package/package.json +7 -9
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tAgent,\n\ttype AgentMessage,\n\tinspectTranscriptIntegrity,\n\trepairTranscriptIntegrity,\n\ttype ThinkingLevel,\n} from \"omk-agent-core\";\nimport { createNodeResourceKeyResolver } from \"omk-agent-core/node\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple, type ToolResultMessage } from \"omk-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { ReplayLedgerManager } from \"../guardrails/evidence-system.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type SessionTranscriptRepair } from \"./agent-session.ts\";\nimport { resolveAgentToolSettings } from \"./agent-tool-settings.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createDomainDispatchRuntimeSession, isDomainRoutingEnabled, tryDomainDispatch } from \"./domain-dispatch.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { tryGrokHarnessDispatch } from \"./grok-harness-dispatch.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport { recordClaudePassiveUsage, recordCodexPassiveUsage } from \"./provider-usage.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { classifySessionTermination, SessionTerminationError } from \"./session-termination.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { BashSandboxPreflight } from \"./tools/bash.ts\";\nimport {\n\tallToolNames,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.omk/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, OMK enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/**\n\t * Optional prompt hint used only for opt-in domain routing (`OMK_DOMAIN_ROUTING=1`).\n\t * This text only selects a loadout policy and is never sent to the model.\n\t */\n\tdomainRoutingPrompt?: string;\n\t/** Optional loadout enforcement policy for SDK-created sessions. */\n\tloadoutAccessPolicy?: LoadoutAccessPolicy;\n\t/** Trusted sandbox preflight used for built-in local bash execution. */\n\tbashSandboxPreflight?: BashSandboxPreflight;\n\t/** Optional replay ledger shared with VerifiedEvidenceExecutor freshness checks. */\n\treplayLedger?: ReplayLedgerManager;\n\t/** Goal binding for AgentSession replay events; defaults to replayLedger.goalId. */\n\treplayGoalId?: string;\n\t/** Optional lane binding for AgentSession replay events. */\n\treplayLaneId?: string;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\ninterface SessionTranscriptRecovery {\n\tmessages: AgentMessage[];\n\trepair?: SessionTranscriptRepair;\n}\n\n/**\n * ALG001-A: inspect the restored transcript on every live session open/resume.\n *\n * - A clean transcript passes through untouched.\n * - Unambiguous missing-only tail results are auto-repaired: synthetic\n * terminal results (tool-result/v2 envelope) are persisted to the session\n * so the repair is durable and idempotent, together with a durable\n * `transcript_repaired` audit entry.\n * - Any duplicate/orphan/duplicate-call/interleaved corruption marks the\n * session (`session_corrupt` entry, once) and fails closed.\n */\nfunction recoverSessionTranscriptOnOpen(\n\tsessionManager: SessionManager,\n\tmessages: AgentMessage[],\n): SessionTranscriptRecovery {\n\tconst report = inspectTranscriptIntegrity(messages);\n\tif (report.ok) {\n\t\treturn { messages };\n\t}\n\n\tlet repaired: AgentMessage[];\n\ttry {\n\t\trepaired = repairTranscriptIntegrity(messages, \"Tool result missing; synthesized during session resume recovery\");\n\t} catch {\n\t\tconst alreadyMarked = sessionManager\n\t\t\t.getBranch()\n\t\t\t.some((entry) => entry.type === \"custom\" && entry.customType === \"session_corrupt\");\n\t\tif (!alreadyMarked) {\n\t\t\tsessionManager.appendCustomEntry(\"session_corrupt\", {\n\t\t\t\tissues: report.issues.map((issue) => ({\n\t\t\t\t\tkind: issue.kind,\n\t\t\t\t\ttoolCallId: issue.toolCallId,\n\t\t\t\t\t...(issue.toolName === undefined ? {} : { toolName: issue.toolName }),\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst summary = report.issues.map((issue) => `${issue.kind}:${issue.toolCallId}`).join(\", \");\n\t\tconst firstIssue = report.issues[0]?.kind ?? \"missing_result\";\n\t\tconst termination = classifySessionTermination({\n\t\t\tsessionId: sessionManager.getSessionId(),\n\t\t\trunId: `resume-${randomUUID()}`,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsource: \"inferred_on_resume\",\n\t\t\tmessage: \"Session transcript has ambiguous tool-result corruption.\",\n\t\t\tcause: { area: \"transcript\", code: firstIssue },\n\t\t\tsideEffects: \"possible\",\n\t\t});\n\t\tthrow new SessionTerminationError(\n\t\t\t`Cannot open session: corrupt tool transcript (${summary}). ` +\n\t\t\t\t\"The session has been marked corrupt; repair it explicitly before resuming.\",\n\t\t\ttermination,\n\t\t);\n\t}\n\n\tconst inserted = repaired.slice(messages.length) as ToolResultMessage[];\n\tif (inserted.length === 0) {\n\t\treturn { messages: repaired };\n\t}\n\tfor (const message of inserted) {\n\t\tsessionManager.appendMessage(message);\n\t}\n\tconst insertedToolCallIds = inserted.map((message) => message.toolCallId);\n\tsessionManager.appendCustomEntry(\"transcript_repaired\", { insertedToolCallIds, reason: \"resume\" });\n\treturn { messages: repaired, repair: { insertedToolCallIds, reason: \"resume\" } };\n}\n\nfunction getDomainDispatchBaseToolNames(options: CreateAgentSessionOptions): string[] {\n\tif (!options.tools && (options.noTools === \"all\" || options.noTools === \"builtin\")) {\n\t\treturn [];\n\t}\n\treturn [...allToolNames];\n}\n\nfunction getAllowedToolNamesForDomainDispatch(options: CreateAgentSessionOptions): string[] | undefined {\n\treturn options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n}\n\nfunction createEffectiveLoadoutAccessPolicy(\n\toptions: CreateAgentSessionOptions,\n\tresourceLoader: ResourceLoader,\n\tcwd: string,\n\tagentDir: string,\n\tprovider?: string,\n): LoadoutAccessPolicy | undefined {\n\tif (options.loadoutAccessPolicy) {\n\t\treturn options.loadoutAccessPolicy;\n\t}\n\n\tconst session = createDomainDispatchRuntimeSession({\n\t\tbaseToolNames: getDomainDispatchBaseToolNames(options),\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tallowedToolNames: getAllowedToolNamesForDomainDispatch(options),\n\t\texcludedToolNames: options.excludeTools,\n\t});\n\n\t// Grok OAuth: apply grok-harness domain loadout without requiring OMK_DOMAIN_ROUTING=1.\n\tif (provider) {\n\t\ttry {\n\t\t\tconst grokDispatch = tryGrokHarnessDispatch({\n\t\t\t\tprovider,\n\t\t\t\tsession,\n\t\t\t\tresourceLoader,\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tenv: process.env,\n\t\t\t});\n\t\t\tif (grokDispatch.loadoutAccessPolicy) {\n\t\t\t\treturn grokDispatch.loadoutAccessPolicy;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to opt-in domain routing.\n\t\t}\n\t}\n\n\tconst domainRoutingPrompt = options.domainRoutingPrompt?.trim();\n\tif (!domainRoutingPrompt || !isDomainRoutingEnabled(process.env)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst dispatch = tryDomainDispatch({\n\t\t\trole: \"coder\",\n\t\t\tinitialPrompt: domainRoutingPrompt,\n\t\t\tsession,\n\t\t\tresourceLoader,\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tenv: process.env,\n\t\t});\n\t\treturn dispatch.loadoutAccessPolicy;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from 'omk-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst agentToolSettings = resolveAgentToolSettings(settingsManager);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\tlet replayLedger = options.replayLedger;\n\tlet replayGoalId = options.replayGoalId;\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!replayLedger && sessionManager.isPersisted() && sessionFile) {\n\t\treplayGoalId ??=\n\t\t\tsessionManager\n\t\t\t\t.getSessionId()\n\t\t\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t\t\t.replace(/^[._-]+|[._-]+$/g, \"\") || \"session\";\n\t\treplayLedger = new ReplayLedgerManager(replayGoalId, `${sessionFile}.replay.jsonl`);\n\t}\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore. Live open/resume always\n\t// inspects the transcript and either auto-repairs missing-only tail results\n\t// or fails closed on ambiguous corruption (ALG001-A).\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst transcriptRecovery = recoverSessionTranscriptOnOpen(sessionManager, existingSession.messages);\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\t// Loadout policy after model resolution so Grok OAuth can auto-apply grok-harness.\n\tconst effectiveLoadoutAccessPolicy = createEffectiveLoadoutAccessPolicy(\n\t\toptions,\n\t\tresourceLoader,\n\t\tcwd,\n\t\tagentDir,\n\t\tmodel?.provider,\n\t);\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\", \"diagnostics\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames: string[] = (\n\t\toptions.tools ? [...options.tools] : options.noTools ? [] : defaultActiveToolNames\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\t\t\tif (!auth.ok) {\n\t\t\t\tthrow new Error(auth.error);\n\t\t\t}\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\t\t// SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n\t\t\t// Use max int32 to effectively disable the timeout.\n\t\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\t\tconst timeoutMs = options?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n\t\t\tconst websocketConnectTimeoutMs =\n\t\t\t\toptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n\t\t\treturn streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\ttimeoutMs,\n\t\t\t\twebsocketConnectTimeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\tonRateLimit: async (snapshot, responseModel) => {\n\t\t\t\t\tif (auth.apiKey && /^openai-codex(?:-|$)/.test(responseModel.provider)) {\n\t\t\t\t\t\trecordCodexPassiveUsage(auth.apiKey, snapshot);\n\t\t\t\t\t} else if (auth.apiKey && responseModel.provider === \"anthropic\") {\n\t\t\t\t\t\trecordClaudePassiveUsage(auth.apiKey, snapshot);\n\t\t\t\t\t}\n\t\t\t\t\tawait options?.onRateLimit?.(snapshot, responseModel);\n\t\t\t\t},\n\t\t\t\theaders: mergeProviderAttributionHeaders(\n\t\t\t\t\tmodel,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\toptions?.sessionId,\n\t\t\t\t\tauth.headers,\n\t\t\t\t\toptions?.headers,\n\t\t\t\t),\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\ttoolTimeoutMs: agentToolSettings.toolTimeoutMs,\n\t\ttoolTimeouts: agentToolSettings.toolTimeouts,\n\t\ttoolScheduler: agentToolSettings.toolScheduler,\n\t\tmaxToolConcurrency: agentToolSettings.maxToolConcurrency,\n\t\tstrictExtensionClaims: agentToolSettings.strictExtensionClaims,\n\t\tcwd,\n\t\t// §5.5 Node identity resolver: symlink/hardlink/drive/UNC path aliases\n\t\t// conflict in the dag-v2 scheduler instead of racing (ALG002-A).\n\t\tresourceKeyResolver: createNodeResourceKeyResolver(),\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = transcriptRecovery.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tloadoutAccessPolicy: effectiveLoadoutAccessPolicy,\n\t\tbashSandboxPreflight: options.bashSandboxPreflight,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\ttranscriptRepair: transcriptRecovery.repair,\n\t\treplayLedger,\n\t\treplayGoalId,\n\t\treplayLaneId: options.replayLaneId,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tAgent,\n\ttype AgentMessage,\n\tinspectTranscriptIntegrity,\n\trepairTranscriptIntegrity,\n\ttype ThinkingLevel,\n} from \"omk-agent-core\";\nimport { createNodeResourceKeyResolver } from \"omk-agent-core/node\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple, type ToolResultMessage } from \"omk-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { ReplayLedgerManager } from \"../guardrails/evidence-system.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type SessionTranscriptRepair } from \"./agent-session.ts\";\nimport { resolveAgentToolSettings } from \"./agent-tool-settings.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createDomainDispatchRuntimeSession, isDomainRoutingEnabled, tryDomainDispatch } from \"./domain-dispatch.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { tryGrokHarnessDispatch } from \"./grok-harness-dispatch.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport { recordClaudePassiveUsage, recordCodexPassiveUsage } from \"./provider-usage.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { classifySessionTermination, SessionTerminationError } from \"./session-termination.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { BashSandboxPreflight } from \"./tools/bash.ts\";\nimport {\n\tallToolNames,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.omk/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\t/** True when the user pinned `--model` / `--provider` for this process. */\n\tmodelPinned?: boolean;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, OMK enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/**\n\t * Optional prompt hint used only for opt-in domain routing (`OMK_DOMAIN_ROUTING=1`).\n\t * This text only selects a loadout policy and is never sent to the model.\n\t */\n\tdomainRoutingPrompt?: string;\n\t/** Optional loadout enforcement policy for SDK-created sessions. */\n\tloadoutAccessPolicy?: LoadoutAccessPolicy;\n\t/** Trusted sandbox preflight used for built-in local bash execution. */\n\tbashSandboxPreflight?: BashSandboxPreflight;\n\t/** Optional replay ledger shared with VerifiedEvidenceExecutor freshness checks. */\n\treplayLedger?: ReplayLedgerManager;\n\t/** Goal binding for AgentSession replay events; defaults to replayLedger.goalId. */\n\treplayGoalId?: string;\n\t/** Optional lane binding for AgentSession replay events. */\n\treplayLaneId?: string;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\ninterface SessionTranscriptRecovery {\n\tmessages: AgentMessage[];\n\trepair?: SessionTranscriptRepair;\n}\n\n/**\n * ALG001-A: inspect the restored transcript on every live session open/resume.\n *\n * - A clean transcript passes through untouched.\n * - Unambiguous missing-only tail results are auto-repaired: synthetic\n * terminal results (tool-result/v2 envelope) are persisted to the session\n * so the repair is durable and idempotent, together with a durable\n * `transcript_repaired` audit entry.\n * - Any duplicate/orphan/duplicate-call/interleaved corruption marks the\n * session (`session_corrupt` entry, once) and fails closed.\n */\nfunction recoverSessionTranscriptOnOpen(\n\tsessionManager: SessionManager,\n\tmessages: AgentMessage[],\n): SessionTranscriptRecovery {\n\tconst report = inspectTranscriptIntegrity(messages);\n\tif (report.ok) {\n\t\treturn { messages };\n\t}\n\n\tlet repaired: AgentMessage[];\n\ttry {\n\t\trepaired = repairTranscriptIntegrity(messages, \"Tool result missing; synthesized during session resume recovery\");\n\t} catch {\n\t\tconst alreadyMarked = sessionManager\n\t\t\t.getBranch()\n\t\t\t.some((entry) => entry.type === \"custom\" && entry.customType === \"session_corrupt\");\n\t\tif (!alreadyMarked) {\n\t\t\tsessionManager.appendCustomEntry(\"session_corrupt\", {\n\t\t\t\tissues: report.issues.map((issue) => ({\n\t\t\t\t\tkind: issue.kind,\n\t\t\t\t\ttoolCallId: issue.toolCallId,\n\t\t\t\t\t...(issue.toolName === undefined ? {} : { toolName: issue.toolName }),\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst summary = report.issues.map((issue) => `${issue.kind}:${issue.toolCallId}`).join(\", \");\n\t\tconst firstIssue = report.issues[0]?.kind ?? \"missing_result\";\n\t\tconst termination = classifySessionTermination({\n\t\t\tsessionId: sessionManager.getSessionId(),\n\t\t\trunId: `resume-${randomUUID()}`,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsource: \"inferred_on_resume\",\n\t\t\tmessage: \"Session transcript has ambiguous tool-result corruption.\",\n\t\t\tcause: { area: \"transcript\", code: firstIssue },\n\t\t\tsideEffects: \"possible\",\n\t\t});\n\t\tthrow new SessionTerminationError(\n\t\t\t`Cannot open session: corrupt tool transcript (${summary}). ` +\n\t\t\t\t\"The session has been marked corrupt; repair it explicitly before resuming.\",\n\t\t\ttermination,\n\t\t);\n\t}\n\n\tconst inserted = repaired.slice(messages.length) as ToolResultMessage[];\n\tif (inserted.length === 0) {\n\t\treturn { messages: repaired };\n\t}\n\tfor (const message of inserted) {\n\t\tsessionManager.appendMessage(message);\n\t}\n\tconst insertedToolCallIds = inserted.map((message) => message.toolCallId);\n\tsessionManager.appendCustomEntry(\"transcript_repaired\", { insertedToolCallIds, reason: \"resume\" });\n\treturn { messages: repaired, repair: { insertedToolCallIds, reason: \"resume\" } };\n}\n\nfunction getDomainDispatchBaseToolNames(options: CreateAgentSessionOptions): string[] {\n\tif (!options.tools && (options.noTools === \"all\" || options.noTools === \"builtin\")) {\n\t\treturn [];\n\t}\n\treturn [...allToolNames];\n}\n\nfunction getAllowedToolNamesForDomainDispatch(options: CreateAgentSessionOptions): string[] | undefined {\n\treturn options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n}\n\nfunction createEffectiveLoadoutAccessPolicy(\n\toptions: CreateAgentSessionOptions,\n\tresourceLoader: ResourceLoader,\n\tcwd: string,\n\tagentDir: string,\n\tprovider?: string,\n): LoadoutAccessPolicy | undefined {\n\tif (options.loadoutAccessPolicy) {\n\t\treturn options.loadoutAccessPolicy;\n\t}\n\n\tconst session = createDomainDispatchRuntimeSession({\n\t\tbaseToolNames: getDomainDispatchBaseToolNames(options),\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tallowedToolNames: getAllowedToolNamesForDomainDispatch(options),\n\t\texcludedToolNames: options.excludeTools,\n\t});\n\n\t// Grok OAuth: apply grok-harness domain loadout without requiring OMK_DOMAIN_ROUTING=1.\n\tif (provider) {\n\t\ttry {\n\t\t\tconst grokDispatch = tryGrokHarnessDispatch({\n\t\t\t\tprovider,\n\t\t\t\tsession,\n\t\t\t\tresourceLoader,\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tenv: process.env,\n\t\t\t});\n\t\t\tif (grokDispatch.loadoutAccessPolicy) {\n\t\t\t\treturn grokDispatch.loadoutAccessPolicy;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to opt-in domain routing.\n\t\t}\n\t}\n\n\tconst domainRoutingPrompt = options.domainRoutingPrompt?.trim();\n\tif (!domainRoutingPrompt || !isDomainRoutingEnabled(process.env)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst dispatch = tryDomainDispatch({\n\t\t\trole: \"coder\",\n\t\t\tinitialPrompt: domainRoutingPrompt,\n\t\t\tsession,\n\t\t\tresourceLoader,\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tenv: process.env,\n\t\t});\n\t\treturn dispatch.loadoutAccessPolicy;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from 'omk-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst agentToolSettings = resolveAgentToolSettings(settingsManager);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\tlet replayLedger = options.replayLedger;\n\tlet replayGoalId = options.replayGoalId;\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!replayLedger && sessionManager.isPersisted() && sessionFile) {\n\t\treplayGoalId ??=\n\t\t\tsessionManager\n\t\t\t\t.getSessionId()\n\t\t\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t\t\t.replace(/^[._-]+|[._-]+$/g, \"\") || \"session\";\n\t\treplayLedger = new ReplayLedgerManager(replayGoalId, `${sessionFile}.replay.jsonl`);\n\t}\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore. Live open/resume always\n\t// inspects the transcript and either auto-repairs missing-only tail results\n\t// or fails closed on ambiguous corruption (ALG001-A).\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst transcriptRecovery = recoverSessionTranscriptOnOpen(sessionManager, existingSession.messages);\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\t// Loadout policy after model resolution so Grok OAuth can auto-apply grok-harness.\n\tconst effectiveLoadoutAccessPolicy = createEffectiveLoadoutAccessPolicy(\n\t\toptions,\n\t\tresourceLoader,\n\t\tcwd,\n\t\tagentDir,\n\t\tmodel?.provider,\n\t);\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\", \"diagnostics\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames: string[] = (\n\t\toptions.tools ? [...options.tools] : options.noTools ? [] : defaultActiveToolNames\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\t\t\tif (!auth.ok) {\n\t\t\t\tthrow new Error(auth.error);\n\t\t\t}\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\t\t// SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n\t\t\t// Use max int32 to effectively disable the timeout.\n\t\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\t\tconst timeoutMs = options?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n\t\t\tconst websocketConnectTimeoutMs =\n\t\t\t\toptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n\t\t\treturn streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\ttimeoutMs,\n\t\t\t\twebsocketConnectTimeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\tonRateLimit: async (snapshot, responseModel) => {\n\t\t\t\t\tif (auth.apiKey && /^openai-codex(?:-|$)/.test(responseModel.provider)) {\n\t\t\t\t\t\trecordCodexPassiveUsage(auth.apiKey, snapshot);\n\t\t\t\t\t} else if (auth.apiKey && responseModel.provider === \"anthropic\") {\n\t\t\t\t\t\trecordClaudePassiveUsage(auth.apiKey, snapshot);\n\t\t\t\t\t}\n\t\t\t\t\tawait options?.onRateLimit?.(snapshot, responseModel);\n\t\t\t\t},\n\t\t\t\theaders: mergeProviderAttributionHeaders(\n\t\t\t\t\tmodel,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\toptions?.sessionId,\n\t\t\t\t\tauth.headers,\n\t\t\t\t\toptions?.headers,\n\t\t\t\t),\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\ttoolTimeoutMs: agentToolSettings.toolTimeoutMs,\n\t\ttoolTimeouts: agentToolSettings.toolTimeouts,\n\t\ttoolScheduler: agentToolSettings.toolScheduler,\n\t\tmaxToolConcurrency: agentToolSettings.maxToolConcurrency,\n\t\tstrictExtensionClaims: agentToolSettings.strictExtensionClaims,\n\t\tcwd,\n\t\t// §5.5 Node identity resolver: symlink/hardlink/drive/UNC path aliases\n\t\t// conflict in the dag-v2 scheduler instead of racing (ALG002-A).\n\t\tresourceKeyResolver: createNodeResourceKeyResolver(),\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = transcriptRecovery.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tloadoutAccessPolicy: effectiveLoadoutAccessPolicy,\n\t\tbashSandboxPreflight: options.bashSandboxPreflight,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tmodelPinned: options.modelPinned,\n\t\ttranscriptRepair: transcriptRecovery.repair,\n\t\treplayLedger,\n\t\treplayGoalId,\n\t\treplayLaneId: options.replayLaneId,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
package/dist/core/sdk.js CHANGED
@@ -416,6 +416,7 @@ export async function createAgentSession(options = {}) {
416
416
  loadoutAccessPolicy: effectiveLoadoutAccessPolicy,
417
417
  bashSandboxPreflight: options.bashSandboxPreflight,
418
418
  sessionStartEvent: options.sessionStartEvent,
419
+ modelPinned: options.modelPinned,
419
420
  transcriptRepair: transcriptRecovery.repair,
420
421
  replayLedger,
421
422
  replayGoalId,
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tAgent,\n\ttype AgentMessage,\n\tinspectTranscriptIntegrity,\n\trepairTranscriptIntegrity,\n\ttype ThinkingLevel,\n} from \"omk-agent-core\";\nimport { createNodeResourceKeyResolver } from \"omk-agent-core/node\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple, type ToolResultMessage } from \"omk-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { ReplayLedgerManager } from \"../guardrails/evidence-system.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type SessionTranscriptRepair } from \"./agent-session.ts\";\nimport { resolveAgentToolSettings } from \"./agent-tool-settings.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createDomainDispatchRuntimeSession, isDomainRoutingEnabled, tryDomainDispatch } from \"./domain-dispatch.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { tryGrokHarnessDispatch } from \"./grok-harness-dispatch.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport { recordClaudePassiveUsage, recordCodexPassiveUsage } from \"./provider-usage.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { classifySessionTermination, SessionTerminationError } from \"./session-termination.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { BashSandboxPreflight } from \"./tools/bash.ts\";\nimport {\n\tallToolNames,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.omk/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, OMK enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/**\n\t * Optional prompt hint used only for opt-in domain routing (`OMK_DOMAIN_ROUTING=1`).\n\t * This text only selects a loadout policy and is never sent to the model.\n\t */\n\tdomainRoutingPrompt?: string;\n\t/** Optional loadout enforcement policy for SDK-created sessions. */\n\tloadoutAccessPolicy?: LoadoutAccessPolicy;\n\t/** Trusted sandbox preflight used for built-in local bash execution. */\n\tbashSandboxPreflight?: BashSandboxPreflight;\n\t/** Optional replay ledger shared with VerifiedEvidenceExecutor freshness checks. */\n\treplayLedger?: ReplayLedgerManager;\n\t/** Goal binding for AgentSession replay events; defaults to replayLedger.goalId. */\n\treplayGoalId?: string;\n\t/** Optional lane binding for AgentSession replay events. */\n\treplayLaneId?: string;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\ninterface SessionTranscriptRecovery {\n\tmessages: AgentMessage[];\n\trepair?: SessionTranscriptRepair;\n}\n\n/**\n * ALG001-A: inspect the restored transcript on every live session open/resume.\n *\n * - A clean transcript passes through untouched.\n * - Unambiguous missing-only tail results are auto-repaired: synthetic\n * terminal results (tool-result/v2 envelope) are persisted to the session\n * so the repair is durable and idempotent, together with a durable\n * `transcript_repaired` audit entry.\n * - Any duplicate/orphan/duplicate-call/interleaved corruption marks the\n * session (`session_corrupt` entry, once) and fails closed.\n */\nfunction recoverSessionTranscriptOnOpen(\n\tsessionManager: SessionManager,\n\tmessages: AgentMessage[],\n): SessionTranscriptRecovery {\n\tconst report = inspectTranscriptIntegrity(messages);\n\tif (report.ok) {\n\t\treturn { messages };\n\t}\n\n\tlet repaired: AgentMessage[];\n\ttry {\n\t\trepaired = repairTranscriptIntegrity(messages, \"Tool result missing; synthesized during session resume recovery\");\n\t} catch {\n\t\tconst alreadyMarked = sessionManager\n\t\t\t.getBranch()\n\t\t\t.some((entry) => entry.type === \"custom\" && entry.customType === \"session_corrupt\");\n\t\tif (!alreadyMarked) {\n\t\t\tsessionManager.appendCustomEntry(\"session_corrupt\", {\n\t\t\t\tissues: report.issues.map((issue) => ({\n\t\t\t\t\tkind: issue.kind,\n\t\t\t\t\ttoolCallId: issue.toolCallId,\n\t\t\t\t\t...(issue.toolName === undefined ? {} : { toolName: issue.toolName }),\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst summary = report.issues.map((issue) => `${issue.kind}:${issue.toolCallId}`).join(\", \");\n\t\tconst firstIssue = report.issues[0]?.kind ?? \"missing_result\";\n\t\tconst termination = classifySessionTermination({\n\t\t\tsessionId: sessionManager.getSessionId(),\n\t\t\trunId: `resume-${randomUUID()}`,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsource: \"inferred_on_resume\",\n\t\t\tmessage: \"Session transcript has ambiguous tool-result corruption.\",\n\t\t\tcause: { area: \"transcript\", code: firstIssue },\n\t\t\tsideEffects: \"possible\",\n\t\t});\n\t\tthrow new SessionTerminationError(\n\t\t\t`Cannot open session: corrupt tool transcript (${summary}). ` +\n\t\t\t\t\"The session has been marked corrupt; repair it explicitly before resuming.\",\n\t\t\ttermination,\n\t\t);\n\t}\n\n\tconst inserted = repaired.slice(messages.length) as ToolResultMessage[];\n\tif (inserted.length === 0) {\n\t\treturn { messages: repaired };\n\t}\n\tfor (const message of inserted) {\n\t\tsessionManager.appendMessage(message);\n\t}\n\tconst insertedToolCallIds = inserted.map((message) => message.toolCallId);\n\tsessionManager.appendCustomEntry(\"transcript_repaired\", { insertedToolCallIds, reason: \"resume\" });\n\treturn { messages: repaired, repair: { insertedToolCallIds, reason: \"resume\" } };\n}\n\nfunction getDomainDispatchBaseToolNames(options: CreateAgentSessionOptions): string[] {\n\tif (!options.tools && (options.noTools === \"all\" || options.noTools === \"builtin\")) {\n\t\treturn [];\n\t}\n\treturn [...allToolNames];\n}\n\nfunction getAllowedToolNamesForDomainDispatch(options: CreateAgentSessionOptions): string[] | undefined {\n\treturn options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n}\n\nfunction createEffectiveLoadoutAccessPolicy(\n\toptions: CreateAgentSessionOptions,\n\tresourceLoader: ResourceLoader,\n\tcwd: string,\n\tagentDir: string,\n\tprovider?: string,\n): LoadoutAccessPolicy | undefined {\n\tif (options.loadoutAccessPolicy) {\n\t\treturn options.loadoutAccessPolicy;\n\t}\n\n\tconst session = createDomainDispatchRuntimeSession({\n\t\tbaseToolNames: getDomainDispatchBaseToolNames(options),\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tallowedToolNames: getAllowedToolNamesForDomainDispatch(options),\n\t\texcludedToolNames: options.excludeTools,\n\t});\n\n\t// Grok OAuth: apply grok-harness domain loadout without requiring OMK_DOMAIN_ROUTING=1.\n\tif (provider) {\n\t\ttry {\n\t\t\tconst grokDispatch = tryGrokHarnessDispatch({\n\t\t\t\tprovider,\n\t\t\t\tsession,\n\t\t\t\tresourceLoader,\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tenv: process.env,\n\t\t\t});\n\t\t\tif (grokDispatch.loadoutAccessPolicy) {\n\t\t\t\treturn grokDispatch.loadoutAccessPolicy;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to opt-in domain routing.\n\t\t}\n\t}\n\n\tconst domainRoutingPrompt = options.domainRoutingPrompt?.trim();\n\tif (!domainRoutingPrompt || !isDomainRoutingEnabled(process.env)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst dispatch = tryDomainDispatch({\n\t\t\trole: \"coder\",\n\t\t\tinitialPrompt: domainRoutingPrompt,\n\t\t\tsession,\n\t\t\tresourceLoader,\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tenv: process.env,\n\t\t});\n\t\treturn dispatch.loadoutAccessPolicy;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from 'omk-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst agentToolSettings = resolveAgentToolSettings(settingsManager);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\tlet replayLedger = options.replayLedger;\n\tlet replayGoalId = options.replayGoalId;\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!replayLedger && sessionManager.isPersisted() && sessionFile) {\n\t\treplayGoalId ??=\n\t\t\tsessionManager\n\t\t\t\t.getSessionId()\n\t\t\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t\t\t.replace(/^[._-]+|[._-]+$/g, \"\") || \"session\";\n\t\treplayLedger = new ReplayLedgerManager(replayGoalId, `${sessionFile}.replay.jsonl`);\n\t}\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore. Live open/resume always\n\t// inspects the transcript and either auto-repairs missing-only tail results\n\t// or fails closed on ambiguous corruption (ALG001-A).\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst transcriptRecovery = recoverSessionTranscriptOnOpen(sessionManager, existingSession.messages);\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\t// Loadout policy after model resolution so Grok OAuth can auto-apply grok-harness.\n\tconst effectiveLoadoutAccessPolicy = createEffectiveLoadoutAccessPolicy(\n\t\toptions,\n\t\tresourceLoader,\n\t\tcwd,\n\t\tagentDir,\n\t\tmodel?.provider,\n\t);\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\", \"diagnostics\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames: string[] = (\n\t\toptions.tools ? [...options.tools] : options.noTools ? [] : defaultActiveToolNames\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\t\t\tif (!auth.ok) {\n\t\t\t\tthrow new Error(auth.error);\n\t\t\t}\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\t\t// SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n\t\t\t// Use max int32 to effectively disable the timeout.\n\t\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\t\tconst timeoutMs = options?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n\t\t\tconst websocketConnectTimeoutMs =\n\t\t\t\toptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n\t\t\treturn streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\ttimeoutMs,\n\t\t\t\twebsocketConnectTimeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\tonRateLimit: async (snapshot, responseModel) => {\n\t\t\t\t\tif (auth.apiKey && /^openai-codex(?:-|$)/.test(responseModel.provider)) {\n\t\t\t\t\t\trecordCodexPassiveUsage(auth.apiKey, snapshot);\n\t\t\t\t\t} else if (auth.apiKey && responseModel.provider === \"anthropic\") {\n\t\t\t\t\t\trecordClaudePassiveUsage(auth.apiKey, snapshot);\n\t\t\t\t\t}\n\t\t\t\t\tawait options?.onRateLimit?.(snapshot, responseModel);\n\t\t\t\t},\n\t\t\t\theaders: mergeProviderAttributionHeaders(\n\t\t\t\t\tmodel,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\toptions?.sessionId,\n\t\t\t\t\tauth.headers,\n\t\t\t\t\toptions?.headers,\n\t\t\t\t),\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\ttoolTimeoutMs: agentToolSettings.toolTimeoutMs,\n\t\ttoolTimeouts: agentToolSettings.toolTimeouts,\n\t\ttoolScheduler: agentToolSettings.toolScheduler,\n\t\tmaxToolConcurrency: agentToolSettings.maxToolConcurrency,\n\t\tstrictExtensionClaims: agentToolSettings.strictExtensionClaims,\n\t\tcwd,\n\t\t// §5.5 Node identity resolver: symlink/hardlink/drive/UNC path aliases\n\t\t// conflict in the dag-v2 scheduler instead of racing (ALG002-A).\n\t\tresourceKeyResolver: createNodeResourceKeyResolver(),\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = transcriptRecovery.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tloadoutAccessPolicy: effectiveLoadoutAccessPolicy,\n\t\tbashSandboxPreflight: options.bashSandboxPreflight,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\ttranscriptRepair: transcriptRecovery.repair,\n\t\treplayLedger,\n\t\treplayGoalId,\n\t\treplayLaneId: options.replayLaneId,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
1
+ {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tAgent,\n\ttype AgentMessage,\n\tinspectTranscriptIntegrity,\n\trepairTranscriptIntegrity,\n\ttype ThinkingLevel,\n} from \"omk-agent-core\";\nimport { createNodeResourceKeyResolver } from \"omk-agent-core/node\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple, type ToolResultMessage } from \"omk-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { ReplayLedgerManager } from \"../guardrails/evidence-system.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type SessionTranscriptRepair } from \"./agent-session.ts\";\nimport { resolveAgentToolSettings } from \"./agent-tool-settings.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createDomainDispatchRuntimeSession, isDomainRoutingEnabled, tryDomainDispatch } from \"./domain-dispatch.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { tryGrokHarnessDispatch } from \"./grok-harness-dispatch.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport { recordClaudePassiveUsage, recordCodexPassiveUsage } from \"./provider-usage.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { classifySessionTermination, SessionTerminationError } from \"./session-termination.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { BashSandboxPreflight } from \"./tools/bash.ts\";\nimport {\n\tallToolNames,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.omk/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\t/** True when the user pinned `--model` / `--provider` for this process. */\n\tmodelPinned?: boolean;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, OMK enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/**\n\t * Optional prompt hint used only for opt-in domain routing (`OMK_DOMAIN_ROUTING=1`).\n\t * This text only selects a loadout policy and is never sent to the model.\n\t */\n\tdomainRoutingPrompt?: string;\n\t/** Optional loadout enforcement policy for SDK-created sessions. */\n\tloadoutAccessPolicy?: LoadoutAccessPolicy;\n\t/** Trusted sandbox preflight used for built-in local bash execution. */\n\tbashSandboxPreflight?: BashSandboxPreflight;\n\t/** Optional replay ledger shared with VerifiedEvidenceExecutor freshness checks. */\n\treplayLedger?: ReplayLedgerManager;\n\t/** Goal binding for AgentSession replay events; defaults to replayLedger.goalId. */\n\treplayGoalId?: string;\n\t/** Optional lane binding for AgentSession replay events. */\n\treplayLaneId?: string;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\ninterface SessionTranscriptRecovery {\n\tmessages: AgentMessage[];\n\trepair?: SessionTranscriptRepair;\n}\n\n/**\n * ALG001-A: inspect the restored transcript on every live session open/resume.\n *\n * - A clean transcript passes through untouched.\n * - Unambiguous missing-only tail results are auto-repaired: synthetic\n * terminal results (tool-result/v2 envelope) are persisted to the session\n * so the repair is durable and idempotent, together with a durable\n * `transcript_repaired` audit entry.\n * - Any duplicate/orphan/duplicate-call/interleaved corruption marks the\n * session (`session_corrupt` entry, once) and fails closed.\n */\nfunction recoverSessionTranscriptOnOpen(\n\tsessionManager: SessionManager,\n\tmessages: AgentMessage[],\n): SessionTranscriptRecovery {\n\tconst report = inspectTranscriptIntegrity(messages);\n\tif (report.ok) {\n\t\treturn { messages };\n\t}\n\n\tlet repaired: AgentMessage[];\n\ttry {\n\t\trepaired = repairTranscriptIntegrity(messages, \"Tool result missing; synthesized during session resume recovery\");\n\t} catch {\n\t\tconst alreadyMarked = sessionManager\n\t\t\t.getBranch()\n\t\t\t.some((entry) => entry.type === \"custom\" && entry.customType === \"session_corrupt\");\n\t\tif (!alreadyMarked) {\n\t\t\tsessionManager.appendCustomEntry(\"session_corrupt\", {\n\t\t\t\tissues: report.issues.map((issue) => ({\n\t\t\t\t\tkind: issue.kind,\n\t\t\t\t\ttoolCallId: issue.toolCallId,\n\t\t\t\t\t...(issue.toolName === undefined ? {} : { toolName: issue.toolName }),\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst summary = report.issues.map((issue) => `${issue.kind}:${issue.toolCallId}`).join(\", \");\n\t\tconst firstIssue = report.issues[0]?.kind ?? \"missing_result\";\n\t\tconst termination = classifySessionTermination({\n\t\t\tsessionId: sessionManager.getSessionId(),\n\t\t\trunId: `resume-${randomUUID()}`,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsource: \"inferred_on_resume\",\n\t\t\tmessage: \"Session transcript has ambiguous tool-result corruption.\",\n\t\t\tcause: { area: \"transcript\", code: firstIssue },\n\t\t\tsideEffects: \"possible\",\n\t\t});\n\t\tthrow new SessionTerminationError(\n\t\t\t`Cannot open session: corrupt tool transcript (${summary}). ` +\n\t\t\t\t\"The session has been marked corrupt; repair it explicitly before resuming.\",\n\t\t\ttermination,\n\t\t);\n\t}\n\n\tconst inserted = repaired.slice(messages.length) as ToolResultMessage[];\n\tif (inserted.length === 0) {\n\t\treturn { messages: repaired };\n\t}\n\tfor (const message of inserted) {\n\t\tsessionManager.appendMessage(message);\n\t}\n\tconst insertedToolCallIds = inserted.map((message) => message.toolCallId);\n\tsessionManager.appendCustomEntry(\"transcript_repaired\", { insertedToolCallIds, reason: \"resume\" });\n\treturn { messages: repaired, repair: { insertedToolCallIds, reason: \"resume\" } };\n}\n\nfunction getDomainDispatchBaseToolNames(options: CreateAgentSessionOptions): string[] {\n\tif (!options.tools && (options.noTools === \"all\" || options.noTools === \"builtin\")) {\n\t\treturn [];\n\t}\n\treturn [...allToolNames];\n}\n\nfunction getAllowedToolNamesForDomainDispatch(options: CreateAgentSessionOptions): string[] | undefined {\n\treturn options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n}\n\nfunction createEffectiveLoadoutAccessPolicy(\n\toptions: CreateAgentSessionOptions,\n\tresourceLoader: ResourceLoader,\n\tcwd: string,\n\tagentDir: string,\n\tprovider?: string,\n): LoadoutAccessPolicy | undefined {\n\tif (options.loadoutAccessPolicy) {\n\t\treturn options.loadoutAccessPolicy;\n\t}\n\n\tconst session = createDomainDispatchRuntimeSession({\n\t\tbaseToolNames: getDomainDispatchBaseToolNames(options),\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tallowedToolNames: getAllowedToolNamesForDomainDispatch(options),\n\t\texcludedToolNames: options.excludeTools,\n\t});\n\n\t// Grok OAuth: apply grok-harness domain loadout without requiring OMK_DOMAIN_ROUTING=1.\n\tif (provider) {\n\t\ttry {\n\t\t\tconst grokDispatch = tryGrokHarnessDispatch({\n\t\t\t\tprovider,\n\t\t\t\tsession,\n\t\t\t\tresourceLoader,\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tenv: process.env,\n\t\t\t});\n\t\t\tif (grokDispatch.loadoutAccessPolicy) {\n\t\t\t\treturn grokDispatch.loadoutAccessPolicy;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to opt-in domain routing.\n\t\t}\n\t}\n\n\tconst domainRoutingPrompt = options.domainRoutingPrompt?.trim();\n\tif (!domainRoutingPrompt || !isDomainRoutingEnabled(process.env)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst dispatch = tryDomainDispatch({\n\t\t\trole: \"coder\",\n\t\t\tinitialPrompt: domainRoutingPrompt,\n\t\t\tsession,\n\t\t\tresourceLoader,\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tenv: process.env,\n\t\t});\n\t\treturn dispatch.loadoutAccessPolicy;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from 'omk-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst agentToolSettings = resolveAgentToolSettings(settingsManager);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\tlet replayLedger = options.replayLedger;\n\tlet replayGoalId = options.replayGoalId;\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!replayLedger && sessionManager.isPersisted() && sessionFile) {\n\t\treplayGoalId ??=\n\t\t\tsessionManager\n\t\t\t\t.getSessionId()\n\t\t\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t\t\t.replace(/^[._-]+|[._-]+$/g, \"\") || \"session\";\n\t\treplayLedger = new ReplayLedgerManager(replayGoalId, `${sessionFile}.replay.jsonl`);\n\t}\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore. Live open/resume always\n\t// inspects the transcript and either auto-repairs missing-only tail results\n\t// or fails closed on ambiguous corruption (ALG001-A).\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst transcriptRecovery = recoverSessionTranscriptOnOpen(sessionManager, existingSession.messages);\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\t// Loadout policy after model resolution so Grok OAuth can auto-apply grok-harness.\n\tconst effectiveLoadoutAccessPolicy = createEffectiveLoadoutAccessPolicy(\n\t\toptions,\n\t\tresourceLoader,\n\t\tcwd,\n\t\tagentDir,\n\t\tmodel?.provider,\n\t);\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\", \"diagnostics\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames: string[] = (\n\t\toptions.tools ? [...options.tools] : options.noTools ? [] : defaultActiveToolNames\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\t\t\tif (!auth.ok) {\n\t\t\t\tthrow new Error(auth.error);\n\t\t\t}\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\t\t// SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n\t\t\t// Use max int32 to effectively disable the timeout.\n\t\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\t\tconst timeoutMs = options?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n\t\t\tconst websocketConnectTimeoutMs =\n\t\t\t\toptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n\t\t\treturn streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\ttimeoutMs,\n\t\t\t\twebsocketConnectTimeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\tonRateLimit: async (snapshot, responseModel) => {\n\t\t\t\t\tif (auth.apiKey && /^openai-codex(?:-|$)/.test(responseModel.provider)) {\n\t\t\t\t\t\trecordCodexPassiveUsage(auth.apiKey, snapshot);\n\t\t\t\t\t} else if (auth.apiKey && responseModel.provider === \"anthropic\") {\n\t\t\t\t\t\trecordClaudePassiveUsage(auth.apiKey, snapshot);\n\t\t\t\t\t}\n\t\t\t\t\tawait options?.onRateLimit?.(snapshot, responseModel);\n\t\t\t\t},\n\t\t\t\theaders: mergeProviderAttributionHeaders(\n\t\t\t\t\tmodel,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\toptions?.sessionId,\n\t\t\t\t\tauth.headers,\n\t\t\t\t\toptions?.headers,\n\t\t\t\t),\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\ttoolTimeoutMs: agentToolSettings.toolTimeoutMs,\n\t\ttoolTimeouts: agentToolSettings.toolTimeouts,\n\t\ttoolScheduler: agentToolSettings.toolScheduler,\n\t\tmaxToolConcurrency: agentToolSettings.maxToolConcurrency,\n\t\tstrictExtensionClaims: agentToolSettings.strictExtensionClaims,\n\t\tcwd,\n\t\t// §5.5 Node identity resolver: symlink/hardlink/drive/UNC path aliases\n\t\t// conflict in the dag-v2 scheduler instead of racing (ALG002-A).\n\t\tresourceKeyResolver: createNodeResourceKeyResolver(),\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = transcriptRecovery.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tloadoutAccessPolicy: effectiveLoadoutAccessPolicy,\n\t\tbashSandboxPreflight: options.bashSandboxPreflight,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tmodelPinned: options.modelPinned,\n\t\ttranscriptRepair: transcriptRecovery.repair,\n\t\treplayLedger,\n\t\treplayGoalId,\n\t\treplayLaneId: options.replayLaneId,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
@@ -24,6 +24,12 @@ export interface ExecuteBashOptions {
24
24
  /** Trusted internal/test override for local bash sandboxing. */
25
25
  sandboxPolicy?: BashSandboxPreflight;
26
26
  }
27
+ /** Resource gate grant (roadmap §11/M3): §11.3 blocked payload, permit release, or ungated. */
28
+ export interface BashResourcePermitGrant {
29
+ /** §11.3 structured block JSON; when set the command must not spawn. */
30
+ readonly blocked?: string;
31
+ readonly release?: () => void;
32
+ }
27
33
  export interface SessionBashServiceDeps {
28
34
  readonly settings: SettingsManager;
29
35
  readonly runtime: SessionBashRuntime;
@@ -37,6 +43,12 @@ export interface SessionBashServiceDeps {
37
43
  readonly isStreaming: () => boolean;
38
44
  readonly pushMessage: (message: BashExecutionMessage) => void;
39
45
  readonly appendMessage: (message: BashExecutionMessage) => void;
46
+ /**
47
+ * Optional resource governor gate, invoked AFTER command safety (§9.4
48
+ * order) and before any shell spawns. The abort signal cancels a queued
49
+ * permit wait. Implementations must never throw.
50
+ */
51
+ readonly acquireResourcePermit?: (command: string, signal: AbortSignal) => Promise<BashResourcePermitGrant>;
40
52
  }
41
53
  export declare class SessionBashService {
42
54
  private abortController;
@@ -1 +1 @@
1
- {"version":3,"file":"session-bash-service.d.ts","sourceRoot":"","sources":["../../src/core/session-bash-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,UAAU,EAA6B,MAAM,oBAAoB,CAAC;AAOhF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,oBAAoB,EAA6B,MAAM,iBAAiB,CAAC;AAE5G,MAAM,WAAW,kBAAkB;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,8FAA8F;IAC9F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,gEAAgE;IAChE,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,uBAAuB,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9F,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC9D,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAChE;AAUD,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyB;IAE9C,YAAY,IAAI,EAAE,sBAAsB,EAEvC;IAEK,WAAW,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,OAAO,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAoFrB;IAED;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAoBtG;IAED,mCAAmC;IACnC,SAAS,IAAI,IAAI,CAEhB;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,IAAI,sBAAsB,IAAI,OAAO,CAEpC;IAED,+EAA+E;IAC/E,YAAY,IAAI,IAAI,CAOnB;CACD","sourcesContent":["/**\n * Session bash service: command execution, result recording, abort, and the\n * streaming-deferral queue. Extracted from AgentSession so the session class\n * coordinates lifecycle while this owns the bash surface end-to-end.\n *\n * Ordering contract (preserved from the session implementation):\n * - results recorded while the agent is streaming are queued and flushed on\n * turn end (`flushPending`) so tool_use/tool_result ordering never breaks;\n * - `recordBashResult` is idempotent-safe to call from executeBash and from\n * extensions that run bash themselves.\n */\nimport { type BashResult, executeBashWithOperations } from \"./bash-executor.ts\";\nimport { classifyShellCommand } from \"./command-safety.ts\";\nimport {\n\tbuildBlockedBashResult,\n\tevaluateCommandGate,\n\tisCommandSafetyAssumeYesEnabled,\n} from \"./extensions/builtin/command-safety-gate.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { assertLoadoutAccess, decideLoadoutAccess } from \"./loadout-access-policy.ts\";\nimport type { BashExecutionMessage } from \"./messages.ts\";\nimport type { SessionBashRuntime } from \"./session-bash-runtime.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\nimport { type BashOperations, type BashSandboxPreflight, createLocalBashOperations } from \"./tools/bash.ts\";\n\nexport interface ExecuteBashOptions {\n\texcludeFromContext?: boolean;\n\t/** Optional identifier echoed in `bash_execution_update` events (RPC request correlation). */\n\tid?: string;\n\toperations?: BashOperations;\n\tsafetyGate?: \"headless\";\n\t/** Trusted internal/test override for local bash sandboxing. */\n\tsandboxPolicy?: BashSandboxPreflight;\n}\n\nexport interface SessionBashServiceDeps {\n\treadonly settings: SettingsManager;\n\treadonly runtime: SessionBashRuntime;\n\treadonly loadoutPolicy: LoadoutAccessPolicy | undefined;\n\treadonly getCwd: () => string;\n\treadonly emit: (event: { type: \"bash_execution_update\"; id?: string; delta: string }) => void;\n\treadonly isStreaming: () => boolean;\n\treadonly pushMessage: (message: BashExecutionMessage) => void;\n\treadonly appendMessage: (message: BashExecutionMessage) => void;\n}\n\nfunction isSandboxDeniedError(error: unknown): error is Error {\n\treturn error instanceof Error && error.message.startsWith(\"sandbox: shell denied\");\n}\n\nfunction buildSandboxDeniedBashResult(reason: string): BashResult {\n\treturn { output: reason, exitCode: 1, cancelled: false, truncated: false };\n}\n\nexport class SessionBashService {\n\tprivate abortController: AbortController | undefined;\n\tprivate pendingBashMessages: BashExecutionMessage[] = [];\n\tprivate readonly deps: SessionBashServiceDeps;\n\n\tconstructor(deps: SessionBashServiceDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tasync executeBash(\n\t\tcommand: string,\n\t\tonChunk?: (chunk: string) => void,\n\t\toptions?: ExecuteBashOptions,\n\t): Promise<BashResult> {\n\t\tconst { settings, runtime, loadoutPolicy } = this.deps;\n\t\tconst prefix = settings.getShellCommandPrefix();\n\t\tconst shellPath = settings.getShellPath();\n\t\tconst resolvedCommand = prefix ? `${prefix}\\n${command}` : command;\n\t\tif (loadoutPolicy) {\n\t\t\tassertLoadoutAccess((request) => decideLoadoutAccess(loadoutPolicy, request), {\n\t\t\t\toperation: \"execute\",\n\t\t\t\ttoolName: \"bash\",\n\t\t\t\tcommand: resolvedCommand,\n\t\t\t});\n\t\t}\n\n\t\t// Non-negotiable safety floor for headless callers (RPC bash): hard-deny\n\t\t// block-tier commands before any shell is spawned.\n\t\tif (options?.safetyGate === \"headless\") {\n\t\t\tconst floorVerdict = classifyShellCommand(command);\n\t\t\tif (floorVerdict.risk === \"block\") {\n\t\t\t\tthrow new Error(`OMK §0.1 safety floor blocked bash: [${floorVerdict.rule}] ${floorVerdict.reason}`);\n\t\t\t}\n\t\t}\n\n\t\t// Command-safety parity for non-interactive callers (RPC bash). Interactive\n\t\t// `!`/`!!` bash is gated earlier through the user_bash extension event, which\n\t\t// keeps its prompt-based approval semantics, so it does not pass safetyGate and\n\t\t// is never double-prompted here. confirm/block-tier verdicts deny headlessly;\n\t\t// the EFFECTIVE command (after the shell command prefix) is classified.\n\t\tif (options?.safetyGate === \"headless\") {\n\t\t\tconst decision = await evaluateCommandGate(resolvedCommand, {\n\t\t\t\thasUI: false,\n\t\t\t\theadlessConfirmPolicy: isCommandSafetyAssumeYesEnabled() ? \"allow\" : \"deny\",\n\t\t\t});\n\t\t\tif (decision?.deny) {\n\t\t\t\tconst blocked = buildBlockedBashResult(decision.reason);\n\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\treturn blocked;\n\t\t\t}\n\t\t}\n\n\t\tthis.abortController = new AbortController();\n\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tconst operations =\n\t\t\t\t\toptions?.operations ??\n\t\t\t\t\tcreateLocalBashOperations({\n\t\t\t\t\t\tshellPath,\n\t\t\t\t\t\tsandboxPolicy: runtime.sandboxPreflight(options?.sandboxPolicy),\n\t\t\t\t\t});\n\t\t\t\tconst cwd = this.deps.getCwd();\n\t\t\t\tconst onChunkWrapped = (delta: string) => {\n\t\t\t\t\tonChunk?.(delta);\n\t\t\t\t\tthis.deps.emit({ type: \"bash_execution_update\", id: options?.id, delta });\n\t\t\t\t};\n\n\t\t\t\t// Default-on verified path when a session ledger exists; OMK_VERIFIED_BASH=0 rolls back.\n\t\t\t\tconst verified = await runtime.executeVerified({\n\t\t\t\t\tresolvedCommand,\n\t\t\t\t\tcwd,\n\t\t\t\t\tshellPath,\n\t\t\t\t\toperations,\n\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\tonChunk: onChunkWrapped,\n\t\t\t\t});\n\t\t\t\tconst result: BashResult =\n\t\t\t\t\tverified ??\n\t\t\t\t\t(await executeBashWithOperations(resolvedCommand, cwd, operations, {\n\t\t\t\t\t\tonChunk: onChunkWrapped,\n\t\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\t}));\n\n\t\t\t\tthis.recordBashResult(command, result, options);\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tif (!isSandboxDeniedError(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst blocked = buildSandboxDeniedBashResult(error.message);\n\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\treturn blocked;\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.abortController = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Record a bash execution result in session history.\n\t * Used by executeBash and by extensions that handle bash execution themselves.\n\t */\n\trecordBashResult(command: string, result: BashResult, options?: { excludeFromContext?: boolean }): void {\n\t\tconst bashMessage: BashExecutionMessage = {\n\t\t\trole: \"bashExecution\",\n\t\t\tcommand,\n\t\t\toutput: result.output,\n\t\t\texitCode: result.exitCode,\n\t\t\tcancelled: result.cancelled,\n\t\t\ttruncated: result.truncated,\n\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\ttimestamp: Date.now(),\n\t\t\texcludeFromContext: options?.excludeFromContext,\n\t\t};\n\n\t\t// If agent is streaming, defer adding to avoid breaking tool_use/tool_result ordering\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthis.pendingBashMessages.push(bashMessage);\n\t\t} else {\n\t\t\tthis.deps.pushMessage(bashMessage);\n\t\t\tthis.deps.appendMessage(bashMessage);\n\t\t}\n\t}\n\n\t/** Cancel running bash command. */\n\tabortBash(): void {\n\t\tthis.abortController?.abort();\n\t}\n\n\tget isBashRunning(): boolean {\n\t\treturn this.abortController !== undefined;\n\t}\n\n\tget hasPendingBashMessages(): boolean {\n\t\treturn this.pendingBashMessages.length > 0;\n\t}\n\n\t/** Flush queued results after the agent turn completes (ordering contract). */\n\tflushPending(): void {\n\t\tif (this.pendingBashMessages.length === 0) return;\n\t\tfor (const bashMessage of this.pendingBashMessages) {\n\t\t\tthis.deps.pushMessage(bashMessage);\n\t\t\tthis.deps.appendMessage(bashMessage);\n\t\t}\n\t\tthis.pendingBashMessages = [];\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-bash-service.d.ts","sourceRoot":"","sources":["../../src/core/session-bash-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,UAAU,EAA6B,MAAM,oBAAoB,CAAC;AAOhF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,oBAAoB,EAA6B,MAAM,iBAAiB,CAAC;AAE5G,MAAM,WAAW,kBAAkB;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,8FAA8F;IAC9F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,gEAAgE;IAChE,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACrC;AAED,iGAA+F;AAC/F,MAAM,WAAW,uBAAuB;IACvC,yEAAwE;IACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,uBAAuB,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9F,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC9D,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAChE;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC5G;AAUD,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyB;IAE9C,YAAY,IAAI,EAAE,sBAAsB,EAEvC;IAEK,WAAW,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,OAAO,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAkGrB;IAED;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAoBtG;IAED,mCAAmC;IACnC,SAAS,IAAI,IAAI,CAEhB;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,IAAI,sBAAsB,IAAI,OAAO,CAEpC;IAED,+EAA+E;IAC/E,YAAY,IAAI,IAAI,CAOnB;CACD","sourcesContent":["/**\n * Session bash service: command execution, result recording, abort, and the\n * streaming-deferral queue. Extracted from AgentSession so the session class\n * coordinates lifecycle while this owns the bash surface end-to-end.\n *\n * Ordering contract (preserved from the session implementation):\n * - results recorded while the agent is streaming are queued and flushed on\n * turn end (`flushPending`) so tool_use/tool_result ordering never breaks;\n * - `recordBashResult` is idempotent-safe to call from executeBash and from\n * extensions that run bash themselves.\n */\nimport { type BashResult, executeBashWithOperations } from \"./bash-executor.ts\";\nimport { classifyShellCommand } from \"./command-safety.ts\";\nimport {\n\tbuildBlockedBashResult,\n\tevaluateCommandGate,\n\tisCommandSafetyAssumeYesEnabled,\n} from \"./extensions/builtin/command-safety-gate.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { assertLoadoutAccess, decideLoadoutAccess } from \"./loadout-access-policy.ts\";\nimport type { BashExecutionMessage } from \"./messages.ts\";\nimport type { SessionBashRuntime } from \"./session-bash-runtime.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\nimport { type BashOperations, type BashSandboxPreflight, createLocalBashOperations } from \"./tools/bash.ts\";\n\nexport interface ExecuteBashOptions {\n\texcludeFromContext?: boolean;\n\t/** Optional identifier echoed in `bash_execution_update` events (RPC request correlation). */\n\tid?: string;\n\toperations?: BashOperations;\n\tsafetyGate?: \"headless\";\n\t/** Trusted internal/test override for local bash sandboxing. */\n\tsandboxPolicy?: BashSandboxPreflight;\n}\n\n/** Resource gate grant (roadmap §11/M3): §11.3 blocked payload, permit release, or ungated. */\nexport interface BashResourcePermitGrant {\n\t/** §11.3 structured block JSON; when set the command must not spawn. */\n\treadonly blocked?: string;\n\treadonly release?: () => void;\n}\n\nexport interface SessionBashServiceDeps {\n\treadonly settings: SettingsManager;\n\treadonly runtime: SessionBashRuntime;\n\treadonly loadoutPolicy: LoadoutAccessPolicy | undefined;\n\treadonly getCwd: () => string;\n\treadonly emit: (event: { type: \"bash_execution_update\"; id?: string; delta: string }) => void;\n\treadonly isStreaming: () => boolean;\n\treadonly pushMessage: (message: BashExecutionMessage) => void;\n\treadonly appendMessage: (message: BashExecutionMessage) => void;\n\t/**\n\t * Optional resource governor gate, invoked AFTER command safety (§9.4\n\t * order) and before any shell spawns. The abort signal cancels a queued\n\t * permit wait. Implementations must never throw.\n\t */\n\treadonly acquireResourcePermit?: (command: string, signal: AbortSignal) => Promise<BashResourcePermitGrant>;\n}\n\nfunction isSandboxDeniedError(error: unknown): error is Error {\n\treturn error instanceof Error && error.message.startsWith(\"sandbox: shell denied\");\n}\n\nfunction buildSandboxDeniedBashResult(reason: string): BashResult {\n\treturn { output: reason, exitCode: 1, cancelled: false, truncated: false };\n}\n\nexport class SessionBashService {\n\tprivate abortController: AbortController | undefined;\n\tprivate pendingBashMessages: BashExecutionMessage[] = [];\n\tprivate readonly deps: SessionBashServiceDeps;\n\n\tconstructor(deps: SessionBashServiceDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tasync executeBash(\n\t\tcommand: string,\n\t\tonChunk?: (chunk: string) => void,\n\t\toptions?: ExecuteBashOptions,\n\t): Promise<BashResult> {\n\t\tconst { settings, runtime, loadoutPolicy } = this.deps;\n\t\tconst prefix = settings.getShellCommandPrefix();\n\t\tconst shellPath = settings.getShellPath();\n\t\tconst resolvedCommand = prefix ? `${prefix}\\n${command}` : command;\n\t\tif (loadoutPolicy) {\n\t\t\tassertLoadoutAccess((request) => decideLoadoutAccess(loadoutPolicy, request), {\n\t\t\t\toperation: \"execute\",\n\t\t\t\ttoolName: \"bash\",\n\t\t\t\tcommand: resolvedCommand,\n\t\t\t});\n\t\t}\n\n\t\t// Non-negotiable safety floor for headless callers (RPC bash): hard-deny\n\t\t// block-tier commands before any shell is spawned.\n\t\tif (options?.safetyGate === \"headless\") {\n\t\t\tconst floorVerdict = classifyShellCommand(command);\n\t\t\tif (floorVerdict.risk === \"block\") {\n\t\t\t\tthrow new Error(`OMK §0.1 safety floor blocked bash: [${floorVerdict.rule}] ${floorVerdict.reason}`);\n\t\t\t}\n\t\t}\n\n\t\t// Command-safety parity for non-interactive callers (RPC bash). Interactive\n\t\t// `!`/`!!` bash is gated earlier through the user_bash extension event, which\n\t\t// keeps its prompt-based approval semantics, so it does not pass safetyGate and\n\t\t// is never double-prompted here. confirm/block-tier verdicts deny headlessly;\n\t\t// the EFFECTIVE command (after the shell command prefix) is classified.\n\t\tif (options?.safetyGate === \"headless\") {\n\t\t\tconst decision = await evaluateCommandGate(resolvedCommand, {\n\t\t\t\thasUI: false,\n\t\t\t\theadlessConfirmPolicy: isCommandSafetyAssumeYesEnabled() ? \"allow\" : \"deny\",\n\t\t\t});\n\t\t\tif (decision?.deny) {\n\t\t\t\tconst blocked = buildBlockedBashResult(decision.reason);\n\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\treturn blocked;\n\t\t\t}\n\t\t}\n\n\t\tthis.abortController = new AbortController();\n\t\tlet releaseResourcePermit: (() => void) | undefined;\n\n\t\ttry {\n\t\t\t// Resource safety gate (§9.4: command safety above stays authoritative;\n\t\t\t// pressure can only throttle or defer an already-allowed command).\n\t\t\tif (this.deps.acquireResourcePermit) {\n\t\t\t\tconst grant = await this.deps.acquireResourcePermit(resolvedCommand, this.abortController.signal);\n\t\t\t\tif (grant.blocked !== undefined) {\n\t\t\t\t\tconst blocked = buildBlockedBashResult(grant.blocked);\n\t\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\t\treturn blocked;\n\t\t\t\t}\n\t\t\t\treleaseResourcePermit = grant.release;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst operations =\n\t\t\t\t\toptions?.operations ??\n\t\t\t\t\tcreateLocalBashOperations({\n\t\t\t\t\t\tshellPath,\n\t\t\t\t\t\tsandboxPolicy: runtime.sandboxPreflight(options?.sandboxPolicy),\n\t\t\t\t\t});\n\t\t\t\tconst cwd = this.deps.getCwd();\n\t\t\t\tconst onChunkWrapped = (delta: string) => {\n\t\t\t\t\tonChunk?.(delta);\n\t\t\t\t\tthis.deps.emit({ type: \"bash_execution_update\", id: options?.id, delta });\n\t\t\t\t};\n\n\t\t\t\t// Default-on verified path when a session ledger exists; OMK_VERIFIED_BASH=0 rolls back.\n\t\t\t\tconst verified = await runtime.executeVerified({\n\t\t\t\t\tresolvedCommand,\n\t\t\t\t\tcwd,\n\t\t\t\t\tshellPath,\n\t\t\t\t\toperations,\n\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\tonChunk: onChunkWrapped,\n\t\t\t\t});\n\t\t\t\tconst result: BashResult =\n\t\t\t\t\tverified ??\n\t\t\t\t\t(await executeBashWithOperations(resolvedCommand, cwd, operations, {\n\t\t\t\t\t\tonChunk: onChunkWrapped,\n\t\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\t}));\n\n\t\t\t\tthis.recordBashResult(command, result, options);\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tif (!isSandboxDeniedError(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst blocked = buildSandboxDeniedBashResult(error.message);\n\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\treturn blocked;\n\t\t\t}\n\t\t} finally {\n\t\t\t// §10.3 exactly-once: the pool treats a repeated release as a no-op.\n\t\t\treleaseResourcePermit?.();\n\t\t\tthis.abortController = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Record a bash execution result in session history.\n\t * Used by executeBash and by extensions that handle bash execution themselves.\n\t */\n\trecordBashResult(command: string, result: BashResult, options?: { excludeFromContext?: boolean }): void {\n\t\tconst bashMessage: BashExecutionMessage = {\n\t\t\trole: \"bashExecution\",\n\t\t\tcommand,\n\t\t\toutput: result.output,\n\t\t\texitCode: result.exitCode,\n\t\t\tcancelled: result.cancelled,\n\t\t\ttruncated: result.truncated,\n\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\ttimestamp: Date.now(),\n\t\t\texcludeFromContext: options?.excludeFromContext,\n\t\t};\n\n\t\t// If agent is streaming, defer adding to avoid breaking tool_use/tool_result ordering\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthis.pendingBashMessages.push(bashMessage);\n\t\t} else {\n\t\t\tthis.deps.pushMessage(bashMessage);\n\t\t\tthis.deps.appendMessage(bashMessage);\n\t\t}\n\t}\n\n\t/** Cancel running bash command. */\n\tabortBash(): void {\n\t\tthis.abortController?.abort();\n\t}\n\n\tget isBashRunning(): boolean {\n\t\treturn this.abortController !== undefined;\n\t}\n\n\tget hasPendingBashMessages(): boolean {\n\t\treturn this.pendingBashMessages.length > 0;\n\t}\n\n\t/** Flush queued results after the agent turn completes (ordering contract). */\n\tflushPending(): void {\n\t\tif (this.pendingBashMessages.length === 0) return;\n\t\tfor (const bashMessage of this.pendingBashMessages) {\n\t\t\tthis.deps.pushMessage(bashMessage);\n\t\t\tthis.deps.appendMessage(bashMessage);\n\t\t}\n\t\tthis.pendingBashMessages = [];\n\t}\n}\n"]}
@@ -64,7 +64,19 @@ export class SessionBashService {
64
64
  }
65
65
  }
66
66
  this.abortController = new AbortController();
67
+ let releaseResourcePermit;
67
68
  try {
69
+ // Resource safety gate (§9.4: command safety above stays authoritative;
70
+ // pressure can only throttle or defer an already-allowed command).
71
+ if (this.deps.acquireResourcePermit) {
72
+ const grant = await this.deps.acquireResourcePermit(resolvedCommand, this.abortController.signal);
73
+ if (grant.blocked !== undefined) {
74
+ const blocked = buildBlockedBashResult(grant.blocked);
75
+ this.recordBashResult(command, blocked, options);
76
+ return blocked;
77
+ }
78
+ releaseResourcePermit = grant.release;
79
+ }
68
80
  try {
69
81
  const operations = options?.operations ??
70
82
  createLocalBashOperations({
@@ -103,6 +115,8 @@ export class SessionBashService {
103
115
  }
104
116
  }
105
117
  finally {
118
+ // §10.3 exactly-once: the pool treats a repeated release as a no-op.
119
+ releaseResourcePermit?.();
106
120
  this.abortController = undefined;
107
121
  }
108
122
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session-bash-service.js","sourceRoot":"","sources":["../../src/core/session-bash-service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Session bash service: command execution, result recording, abort, and the\n * streaming-deferral queue. Extracted from AgentSession so the session class\n * coordinates lifecycle while this owns the bash surface end-to-end.\n *\n * Ordering contract (preserved from the session implementation):\n * - results recorded while the agent is streaming are queued and flushed on\n * turn end (`flushPending`) so tool_use/tool_result ordering never breaks;\n * - `recordBashResult` is idempotent-safe to call from executeBash and from\n * extensions that run bash themselves.\n */\nimport { type BashResult, executeBashWithOperations } from \"./bash-executor.ts\";\nimport { classifyShellCommand } from \"./command-safety.ts\";\nimport {\n\tbuildBlockedBashResult,\n\tevaluateCommandGate,\n\tisCommandSafetyAssumeYesEnabled,\n} from \"./extensions/builtin/command-safety-gate.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { assertLoadoutAccess, decideLoadoutAccess } from \"./loadout-access-policy.ts\";\nimport type { BashExecutionMessage } from \"./messages.ts\";\nimport type { SessionBashRuntime } from \"./session-bash-runtime.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\nimport { type BashOperations, type BashSandboxPreflight, createLocalBashOperations } from \"./tools/bash.ts\";\n\nexport interface ExecuteBashOptions {\n\texcludeFromContext?: boolean;\n\t/** Optional identifier echoed in `bash_execution_update` events (RPC request correlation). */\n\tid?: string;\n\toperations?: BashOperations;\n\tsafetyGate?: \"headless\";\n\t/** Trusted internal/test override for local bash sandboxing. */\n\tsandboxPolicy?: BashSandboxPreflight;\n}\n\nexport interface SessionBashServiceDeps {\n\treadonly settings: SettingsManager;\n\treadonly runtime: SessionBashRuntime;\n\treadonly loadoutPolicy: LoadoutAccessPolicy | undefined;\n\treadonly getCwd: () => string;\n\treadonly emit: (event: { type: \"bash_execution_update\"; id?: string; delta: string }) => void;\n\treadonly isStreaming: () => boolean;\n\treadonly pushMessage: (message: BashExecutionMessage) => void;\n\treadonly appendMessage: (message: BashExecutionMessage) => void;\n}\n\nfunction isSandboxDeniedError(error: unknown): error is Error {\n\treturn error instanceof Error && error.message.startsWith(\"sandbox: shell denied\");\n}\n\nfunction buildSandboxDeniedBashResult(reason: string): BashResult {\n\treturn { output: reason, exitCode: 1, cancelled: false, truncated: false };\n}\n\nexport class SessionBashService {\n\tprivate abortController: AbortController | undefined;\n\tprivate pendingBashMessages: BashExecutionMessage[] = [];\n\tprivate readonly deps: SessionBashServiceDeps;\n\n\tconstructor(deps: SessionBashServiceDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tasync executeBash(\n\t\tcommand: string,\n\t\tonChunk?: (chunk: string) => void,\n\t\toptions?: ExecuteBashOptions,\n\t): Promise<BashResult> {\n\t\tconst { settings, runtime, loadoutPolicy } = this.deps;\n\t\tconst prefix = settings.getShellCommandPrefix();\n\t\tconst shellPath = settings.getShellPath();\n\t\tconst resolvedCommand = prefix ? `${prefix}\\n${command}` : command;\n\t\tif (loadoutPolicy) {\n\t\t\tassertLoadoutAccess((request) => decideLoadoutAccess(loadoutPolicy, request), {\n\t\t\t\toperation: \"execute\",\n\t\t\t\ttoolName: \"bash\",\n\t\t\t\tcommand: resolvedCommand,\n\t\t\t});\n\t\t}\n\n\t\t// Non-negotiable safety floor for headless callers (RPC bash): hard-deny\n\t\t// block-tier commands before any shell is spawned.\n\t\tif (options?.safetyGate === \"headless\") {\n\t\t\tconst floorVerdict = classifyShellCommand(command);\n\t\t\tif (floorVerdict.risk === \"block\") {\n\t\t\t\tthrow new Error(`OMK §0.1 safety floor blocked bash: [${floorVerdict.rule}] ${floorVerdict.reason}`);\n\t\t\t}\n\t\t}\n\n\t\t// Command-safety parity for non-interactive callers (RPC bash). Interactive\n\t\t// `!`/`!!` bash is gated earlier through the user_bash extension event, which\n\t\t// keeps its prompt-based approval semantics, so it does not pass safetyGate and\n\t\t// is never double-prompted here. confirm/block-tier verdicts deny headlessly;\n\t\t// the EFFECTIVE command (after the shell command prefix) is classified.\n\t\tif (options?.safetyGate === \"headless\") {\n\t\t\tconst decision = await evaluateCommandGate(resolvedCommand, {\n\t\t\t\thasUI: false,\n\t\t\t\theadlessConfirmPolicy: isCommandSafetyAssumeYesEnabled() ? \"allow\" : \"deny\",\n\t\t\t});\n\t\t\tif (decision?.deny) {\n\t\t\t\tconst blocked = buildBlockedBashResult(decision.reason);\n\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\treturn blocked;\n\t\t\t}\n\t\t}\n\n\t\tthis.abortController = new AbortController();\n\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tconst operations =\n\t\t\t\t\toptions?.operations ??\n\t\t\t\t\tcreateLocalBashOperations({\n\t\t\t\t\t\tshellPath,\n\t\t\t\t\t\tsandboxPolicy: runtime.sandboxPreflight(options?.sandboxPolicy),\n\t\t\t\t\t});\n\t\t\t\tconst cwd = this.deps.getCwd();\n\t\t\t\tconst onChunkWrapped = (delta: string) => {\n\t\t\t\t\tonChunk?.(delta);\n\t\t\t\t\tthis.deps.emit({ type: \"bash_execution_update\", id: options?.id, delta });\n\t\t\t\t};\n\n\t\t\t\t// Default-on verified path when a session ledger exists; OMK_VERIFIED_BASH=0 rolls back.\n\t\t\t\tconst verified = await runtime.executeVerified({\n\t\t\t\t\tresolvedCommand,\n\t\t\t\t\tcwd,\n\t\t\t\t\tshellPath,\n\t\t\t\t\toperations,\n\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\tonChunk: onChunkWrapped,\n\t\t\t\t});\n\t\t\t\tconst result: BashResult =\n\t\t\t\t\tverified ??\n\t\t\t\t\t(await executeBashWithOperations(resolvedCommand, cwd, operations, {\n\t\t\t\t\t\tonChunk: onChunkWrapped,\n\t\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\t}));\n\n\t\t\t\tthis.recordBashResult(command, result, options);\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tif (!isSandboxDeniedError(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst blocked = buildSandboxDeniedBashResult(error.message);\n\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\treturn blocked;\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.abortController = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Record a bash execution result in session history.\n\t * Used by executeBash and by extensions that handle bash execution themselves.\n\t */\n\trecordBashResult(command: string, result: BashResult, options?: { excludeFromContext?: boolean }): void {\n\t\tconst bashMessage: BashExecutionMessage = {\n\t\t\trole: \"bashExecution\",\n\t\t\tcommand,\n\t\t\toutput: result.output,\n\t\t\texitCode: result.exitCode,\n\t\t\tcancelled: result.cancelled,\n\t\t\ttruncated: result.truncated,\n\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\ttimestamp: Date.now(),\n\t\t\texcludeFromContext: options?.excludeFromContext,\n\t\t};\n\n\t\t// If agent is streaming, defer adding to avoid breaking tool_use/tool_result ordering\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthis.pendingBashMessages.push(bashMessage);\n\t\t} else {\n\t\t\tthis.deps.pushMessage(bashMessage);\n\t\t\tthis.deps.appendMessage(bashMessage);\n\t\t}\n\t}\n\n\t/** Cancel running bash command. */\n\tabortBash(): void {\n\t\tthis.abortController?.abort();\n\t}\n\n\tget isBashRunning(): boolean {\n\t\treturn this.abortController !== undefined;\n\t}\n\n\tget hasPendingBashMessages(): boolean {\n\t\treturn this.pendingBashMessages.length > 0;\n\t}\n\n\t/** Flush queued results after the agent turn completes (ordering contract). */\n\tflushPending(): void {\n\t\tif (this.pendingBashMessages.length === 0) return;\n\t\tfor (const bashMessage of this.pendingBashMessages) {\n\t\t\tthis.deps.pushMessage(bashMessage);\n\t\t\tthis.deps.appendMessage(bashMessage);\n\t\t}\n\t\tthis.pendingBashMessages = [];\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-bash-service.js","sourceRoot":"","sources":["../../src/core/session-bash-service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Session bash service: command execution, result recording, abort, and the\n * streaming-deferral queue. Extracted from AgentSession so the session class\n * coordinates lifecycle while this owns the bash surface end-to-end.\n *\n * Ordering contract (preserved from the session implementation):\n * - results recorded while the agent is streaming are queued and flushed on\n * turn end (`flushPending`) so tool_use/tool_result ordering never breaks;\n * - `recordBashResult` is idempotent-safe to call from executeBash and from\n * extensions that run bash themselves.\n */\nimport { type BashResult, executeBashWithOperations } from \"./bash-executor.ts\";\nimport { classifyShellCommand } from \"./command-safety.ts\";\nimport {\n\tbuildBlockedBashResult,\n\tevaluateCommandGate,\n\tisCommandSafetyAssumeYesEnabled,\n} from \"./extensions/builtin/command-safety-gate.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { assertLoadoutAccess, decideLoadoutAccess } from \"./loadout-access-policy.ts\";\nimport type { BashExecutionMessage } from \"./messages.ts\";\nimport type { SessionBashRuntime } from \"./session-bash-runtime.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\nimport { type BashOperations, type BashSandboxPreflight, createLocalBashOperations } from \"./tools/bash.ts\";\n\nexport interface ExecuteBashOptions {\n\texcludeFromContext?: boolean;\n\t/** Optional identifier echoed in `bash_execution_update` events (RPC request correlation). */\n\tid?: string;\n\toperations?: BashOperations;\n\tsafetyGate?: \"headless\";\n\t/** Trusted internal/test override for local bash sandboxing. */\n\tsandboxPolicy?: BashSandboxPreflight;\n}\n\n/** Resource gate grant (roadmap §11/M3): §11.3 blocked payload, permit release, or ungated. */\nexport interface BashResourcePermitGrant {\n\t/** §11.3 structured block JSON; when set the command must not spawn. */\n\treadonly blocked?: string;\n\treadonly release?: () => void;\n}\n\nexport interface SessionBashServiceDeps {\n\treadonly settings: SettingsManager;\n\treadonly runtime: SessionBashRuntime;\n\treadonly loadoutPolicy: LoadoutAccessPolicy | undefined;\n\treadonly getCwd: () => string;\n\treadonly emit: (event: { type: \"bash_execution_update\"; id?: string; delta: string }) => void;\n\treadonly isStreaming: () => boolean;\n\treadonly pushMessage: (message: BashExecutionMessage) => void;\n\treadonly appendMessage: (message: BashExecutionMessage) => void;\n\t/**\n\t * Optional resource governor gate, invoked AFTER command safety (§9.4\n\t * order) and before any shell spawns. The abort signal cancels a queued\n\t * permit wait. Implementations must never throw.\n\t */\n\treadonly acquireResourcePermit?: (command: string, signal: AbortSignal) => Promise<BashResourcePermitGrant>;\n}\n\nfunction isSandboxDeniedError(error: unknown): error is Error {\n\treturn error instanceof Error && error.message.startsWith(\"sandbox: shell denied\");\n}\n\nfunction buildSandboxDeniedBashResult(reason: string): BashResult {\n\treturn { output: reason, exitCode: 1, cancelled: false, truncated: false };\n}\n\nexport class SessionBashService {\n\tprivate abortController: AbortController | undefined;\n\tprivate pendingBashMessages: BashExecutionMessage[] = [];\n\tprivate readonly deps: SessionBashServiceDeps;\n\n\tconstructor(deps: SessionBashServiceDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tasync executeBash(\n\t\tcommand: string,\n\t\tonChunk?: (chunk: string) => void,\n\t\toptions?: ExecuteBashOptions,\n\t): Promise<BashResult> {\n\t\tconst { settings, runtime, loadoutPolicy } = this.deps;\n\t\tconst prefix = settings.getShellCommandPrefix();\n\t\tconst shellPath = settings.getShellPath();\n\t\tconst resolvedCommand = prefix ? `${prefix}\\n${command}` : command;\n\t\tif (loadoutPolicy) {\n\t\t\tassertLoadoutAccess((request) => decideLoadoutAccess(loadoutPolicy, request), {\n\t\t\t\toperation: \"execute\",\n\t\t\t\ttoolName: \"bash\",\n\t\t\t\tcommand: resolvedCommand,\n\t\t\t});\n\t\t}\n\n\t\t// Non-negotiable safety floor for headless callers (RPC bash): hard-deny\n\t\t// block-tier commands before any shell is spawned.\n\t\tif (options?.safetyGate === \"headless\") {\n\t\t\tconst floorVerdict = classifyShellCommand(command);\n\t\t\tif (floorVerdict.risk === \"block\") {\n\t\t\t\tthrow new Error(`OMK §0.1 safety floor blocked bash: [${floorVerdict.rule}] ${floorVerdict.reason}`);\n\t\t\t}\n\t\t}\n\n\t\t// Command-safety parity for non-interactive callers (RPC bash). Interactive\n\t\t// `!`/`!!` bash is gated earlier through the user_bash extension event, which\n\t\t// keeps its prompt-based approval semantics, so it does not pass safetyGate and\n\t\t// is never double-prompted here. confirm/block-tier verdicts deny headlessly;\n\t\t// the EFFECTIVE command (after the shell command prefix) is classified.\n\t\tif (options?.safetyGate === \"headless\") {\n\t\t\tconst decision = await evaluateCommandGate(resolvedCommand, {\n\t\t\t\thasUI: false,\n\t\t\t\theadlessConfirmPolicy: isCommandSafetyAssumeYesEnabled() ? \"allow\" : \"deny\",\n\t\t\t});\n\t\t\tif (decision?.deny) {\n\t\t\t\tconst blocked = buildBlockedBashResult(decision.reason);\n\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\treturn blocked;\n\t\t\t}\n\t\t}\n\n\t\tthis.abortController = new AbortController();\n\t\tlet releaseResourcePermit: (() => void) | undefined;\n\n\t\ttry {\n\t\t\t// Resource safety gate (§9.4: command safety above stays authoritative;\n\t\t\t// pressure can only throttle or defer an already-allowed command).\n\t\t\tif (this.deps.acquireResourcePermit) {\n\t\t\t\tconst grant = await this.deps.acquireResourcePermit(resolvedCommand, this.abortController.signal);\n\t\t\t\tif (grant.blocked !== undefined) {\n\t\t\t\t\tconst blocked = buildBlockedBashResult(grant.blocked);\n\t\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\t\treturn blocked;\n\t\t\t\t}\n\t\t\t\treleaseResourcePermit = grant.release;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst operations =\n\t\t\t\t\toptions?.operations ??\n\t\t\t\t\tcreateLocalBashOperations({\n\t\t\t\t\t\tshellPath,\n\t\t\t\t\t\tsandboxPolicy: runtime.sandboxPreflight(options?.sandboxPolicy),\n\t\t\t\t\t});\n\t\t\t\tconst cwd = this.deps.getCwd();\n\t\t\t\tconst onChunkWrapped = (delta: string) => {\n\t\t\t\t\tonChunk?.(delta);\n\t\t\t\t\tthis.deps.emit({ type: \"bash_execution_update\", id: options?.id, delta });\n\t\t\t\t};\n\n\t\t\t\t// Default-on verified path when a session ledger exists; OMK_VERIFIED_BASH=0 rolls back.\n\t\t\t\tconst verified = await runtime.executeVerified({\n\t\t\t\t\tresolvedCommand,\n\t\t\t\t\tcwd,\n\t\t\t\t\tshellPath,\n\t\t\t\t\toperations,\n\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\tonChunk: onChunkWrapped,\n\t\t\t\t});\n\t\t\t\tconst result: BashResult =\n\t\t\t\t\tverified ??\n\t\t\t\t\t(await executeBashWithOperations(resolvedCommand, cwd, operations, {\n\t\t\t\t\t\tonChunk: onChunkWrapped,\n\t\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\t}));\n\n\t\t\t\tthis.recordBashResult(command, result, options);\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tif (!isSandboxDeniedError(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst blocked = buildSandboxDeniedBashResult(error.message);\n\t\t\t\tthis.recordBashResult(command, blocked, options);\n\t\t\t\treturn blocked;\n\t\t\t}\n\t\t} finally {\n\t\t\t// §10.3 exactly-once: the pool treats a repeated release as a no-op.\n\t\t\treleaseResourcePermit?.();\n\t\t\tthis.abortController = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Record a bash execution result in session history.\n\t * Used by executeBash and by extensions that handle bash execution themselves.\n\t */\n\trecordBashResult(command: string, result: BashResult, options?: { excludeFromContext?: boolean }): void {\n\t\tconst bashMessage: BashExecutionMessage = {\n\t\t\trole: \"bashExecution\",\n\t\t\tcommand,\n\t\t\toutput: result.output,\n\t\t\texitCode: result.exitCode,\n\t\t\tcancelled: result.cancelled,\n\t\t\ttruncated: result.truncated,\n\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\ttimestamp: Date.now(),\n\t\t\texcludeFromContext: options?.excludeFromContext,\n\t\t};\n\n\t\t// If agent is streaming, defer adding to avoid breaking tool_use/tool_result ordering\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthis.pendingBashMessages.push(bashMessage);\n\t\t} else {\n\t\t\tthis.deps.pushMessage(bashMessage);\n\t\t\tthis.deps.appendMessage(bashMessage);\n\t\t}\n\t}\n\n\t/** Cancel running bash command. */\n\tabortBash(): void {\n\t\tthis.abortController?.abort();\n\t}\n\n\tget isBashRunning(): boolean {\n\t\treturn this.abortController !== undefined;\n\t}\n\n\tget hasPendingBashMessages(): boolean {\n\t\treturn this.pendingBashMessages.length > 0;\n\t}\n\n\t/** Flush queued results after the agent turn completes (ordering contract). */\n\tflushPending(): void {\n\t\tif (this.pendingBashMessages.length === 0) return;\n\t\tfor (const bashMessage of this.pendingBashMessages) {\n\t\t\tthis.deps.pushMessage(bashMessage);\n\t\t\tthis.deps.appendMessage(bashMessage);\n\t\t}\n\t\tthis.pendingBashMessages = [];\n\t}\n}\n"]}
@@ -0,0 +1,30 @@
1
+ import type { ContextFile } from "./resource-loader.ts";
2
+ import type { Skill } from "./skills.ts";
3
+ import { type BuildSystemPromptOptions } from "./system-prompt.ts";
4
+ export interface SessionSystemPromptInput {
5
+ readonly cwd: string;
6
+ readonly toolNames: readonly string[];
7
+ readonly hasTool: (name: string) => boolean;
8
+ readonly toolPromptSnippets: ReadonlyMap<string, string>;
9
+ readonly toolPromptGuidelines: ReadonlyMap<string, readonly string[]>;
10
+ readonly customPrompt?: string;
11
+ readonly appendSystemPrompt?: readonly string[];
12
+ readonly providerAppend?: string;
13
+ readonly skills: readonly Skill[];
14
+ readonly activeSkillNames?: readonly string[];
15
+ readonly activeSkillSource?: string;
16
+ readonly contextFiles: readonly ContextFile[];
17
+ readonly contextBudget?: BuildSystemPromptOptions["contextBudget"];
18
+ }
19
+ export interface SessionSystemPromptAssembly {
20
+ readonly options: BuildSystemPromptOptions;
21
+ readonly prompt: string;
22
+ readonly cacheBoundary: number;
23
+ }
24
+ /**
25
+ * Pure assembly of the session system-prompt plan: tool filtering, snippet and
26
+ * guideline collection, and append-section joining. Callers resolve side effects
27
+ * (resource loader reads, provider playbook files) and pass them in.
28
+ */
29
+ export declare function assembleSessionSystemPrompt(input: SessionSystemPromptInput): SessionSystemPromptAssembly;
30
+ //# sourceMappingURL=session-system-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/session-system-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,wBAAwB,EAAiD,MAAM,oBAAoB,CAAC;AAElH,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,QAAQ,CAAC,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzD,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IACtE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9C,QAAQ,CAAC,aAAa,CAAC,EAAE,wBAAwB,CAAC,eAAe,CAAC,CAAC;CACnE;AAED,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,OAAO,EAAE,wBAAwB,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,wBAAwB,GAAG,2BAA2B,CA8BxG","sourcesContent":["import type { ContextFile } from \"./resource-loader.ts\";\nimport type { Skill } from \"./skills.ts\";\nimport { type BuildSystemPromptOptions, type BuiltSystemPrompt, buildSystemPromptPlan } from \"./system-prompt.ts\";\n\nexport interface SessionSystemPromptInput {\n\treadonly cwd: string;\n\treadonly toolNames: readonly string[];\n\treadonly hasTool: (name: string) => boolean;\n\treadonly toolPromptSnippets: ReadonlyMap<string, string>;\n\treadonly toolPromptGuidelines: ReadonlyMap<string, readonly string[]>;\n\treadonly customPrompt?: string;\n\treadonly appendSystemPrompt?: readonly string[];\n\treadonly providerAppend?: string;\n\treadonly skills: readonly Skill[];\n\treadonly activeSkillNames?: readonly string[];\n\treadonly activeSkillSource?: string;\n\treadonly contextFiles: readonly ContextFile[];\n\treadonly contextBudget?: BuildSystemPromptOptions[\"contextBudget\"];\n}\n\nexport interface SessionSystemPromptAssembly {\n\treadonly options: BuildSystemPromptOptions;\n\treadonly prompt: string;\n\treadonly cacheBoundary: number;\n}\n\n/**\n * Pure assembly of the session system-prompt plan: tool filtering, snippet and\n * guideline collection, and append-section joining. Callers resolve side effects\n * (resource loader reads, provider playbook files) and pass them in.\n */\nexport function assembleSessionSystemPrompt(input: SessionSystemPromptInput): SessionSystemPromptAssembly {\n\tconst validToolNames = input.toolNames.filter((name) => input.hasTool(name));\n\tconst toolSnippets: Record<string, string> = {};\n\tconst promptGuidelines: string[] = [];\n\tfor (const name of validToolNames) {\n\t\tconst snippet = input.toolPromptSnippets.get(name);\n\t\tif (snippet) toolSnippets[name] = snippet;\n\t\tconst toolGuidelines = input.toolPromptGuidelines.get(name);\n\t\tif (toolGuidelines) promptGuidelines.push(...toolGuidelines);\n\t}\n\n\tconst appendParts = [...(input.appendSystemPrompt ?? [])];\n\tif (input.providerAppend) appendParts.push(input.providerAppend);\n\tconst appendSystemPrompt = appendParts.length > 0 ? appendParts.join(\"\\n\\n\") : undefined;\n\n\tconst options: BuildSystemPromptOptions = {\n\t\tcwd: input.cwd,\n\t\tskills: [...input.skills],\n\t\tactiveSkillNames: input.activeSkillNames ? [...input.activeSkillNames] : undefined,\n\t\tactiveSkillSource: input.activeSkillSource,\n\t\tcontextFiles: [...input.contextFiles],\n\t\tcustomPrompt: input.customPrompt,\n\t\tappendSystemPrompt,\n\t\tselectedTools: validToolNames,\n\t\ttoolSnippets,\n\t\tpromptGuidelines,\n\t\tcontextBudget: input.contextBudget,\n\t};\n\tconst built: BuiltSystemPrompt = buildSystemPromptPlan(options);\n\treturn { options, prompt: built.prompt, cacheBoundary: built.cacheBoundary };\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import { buildSystemPromptPlan } from "./system-prompt.js";
2
+ /**
3
+ * Pure assembly of the session system-prompt plan: tool filtering, snippet and
4
+ * guideline collection, and append-section joining. Callers resolve side effects
5
+ * (resource loader reads, provider playbook files) and pass them in.
6
+ */
7
+ export function assembleSessionSystemPrompt(input) {
8
+ const validToolNames = input.toolNames.filter((name) => input.hasTool(name));
9
+ const toolSnippets = {};
10
+ const promptGuidelines = [];
11
+ for (const name of validToolNames) {
12
+ const snippet = input.toolPromptSnippets.get(name);
13
+ if (snippet)
14
+ toolSnippets[name] = snippet;
15
+ const toolGuidelines = input.toolPromptGuidelines.get(name);
16
+ if (toolGuidelines)
17
+ promptGuidelines.push(...toolGuidelines);
18
+ }
19
+ const appendParts = [...(input.appendSystemPrompt ?? [])];
20
+ if (input.providerAppend)
21
+ appendParts.push(input.providerAppend);
22
+ const appendSystemPrompt = appendParts.length > 0 ? appendParts.join("\n\n") : undefined;
23
+ const options = {
24
+ cwd: input.cwd,
25
+ skills: [...input.skills],
26
+ activeSkillNames: input.activeSkillNames ? [...input.activeSkillNames] : undefined,
27
+ activeSkillSource: input.activeSkillSource,
28
+ contextFiles: [...input.contextFiles],
29
+ customPrompt: input.customPrompt,
30
+ appendSystemPrompt,
31
+ selectedTools: validToolNames,
32
+ toolSnippets,
33
+ promptGuidelines,
34
+ contextBudget: input.contextBudget,
35
+ };
36
+ const built = buildSystemPromptPlan(options);
37
+ return { options, prompt: built.prompt, cacheBoundary: built.cacheBoundary };
38
+ }
39
+ //# sourceMappingURL=session-system-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-system-prompt.js","sourceRoot":"","sources":["../../src/core/session-system-prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyD,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAwBlH;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAA+B,EAA+B;IACzG,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,MAAM,gBAAgB,GAAa,EAAE,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,OAAO;YAAE,YAAY,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;QAC1C,MAAM,cAAc,GAAG,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5D,IAAI,cAAc;YAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1D,IAAI,KAAK,CAAC,cAAc;QAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACjE,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEzF,MAAM,OAAO,GAA6B;QACzC,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;QACzB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS;QAClF,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,YAAY,EAAE,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC;QACrC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,kBAAkB;QAClB,aAAa,EAAE,cAAc;QAC7B,YAAY;QACZ,gBAAgB;QAChB,aAAa,EAAE,KAAK,CAAC,aAAa;KAClC,CAAC;IACF,MAAM,KAAK,GAAsB,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAChE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC;AAAA,CAC7E","sourcesContent":["import type { ContextFile } from \"./resource-loader.ts\";\nimport type { Skill } from \"./skills.ts\";\nimport { type BuildSystemPromptOptions, type BuiltSystemPrompt, buildSystemPromptPlan } from \"./system-prompt.ts\";\n\nexport interface SessionSystemPromptInput {\n\treadonly cwd: string;\n\treadonly toolNames: readonly string[];\n\treadonly hasTool: (name: string) => boolean;\n\treadonly toolPromptSnippets: ReadonlyMap<string, string>;\n\treadonly toolPromptGuidelines: ReadonlyMap<string, readonly string[]>;\n\treadonly customPrompt?: string;\n\treadonly appendSystemPrompt?: readonly string[];\n\treadonly providerAppend?: string;\n\treadonly skills: readonly Skill[];\n\treadonly activeSkillNames?: readonly string[];\n\treadonly activeSkillSource?: string;\n\treadonly contextFiles: readonly ContextFile[];\n\treadonly contextBudget?: BuildSystemPromptOptions[\"contextBudget\"];\n}\n\nexport interface SessionSystemPromptAssembly {\n\treadonly options: BuildSystemPromptOptions;\n\treadonly prompt: string;\n\treadonly cacheBoundary: number;\n}\n\n/**\n * Pure assembly of the session system-prompt plan: tool filtering, snippet and\n * guideline collection, and append-section joining. Callers resolve side effects\n * (resource loader reads, provider playbook files) and pass them in.\n */\nexport function assembleSessionSystemPrompt(input: SessionSystemPromptInput): SessionSystemPromptAssembly {\n\tconst validToolNames = input.toolNames.filter((name) => input.hasTool(name));\n\tconst toolSnippets: Record<string, string> = {};\n\tconst promptGuidelines: string[] = [];\n\tfor (const name of validToolNames) {\n\t\tconst snippet = input.toolPromptSnippets.get(name);\n\t\tif (snippet) toolSnippets[name] = snippet;\n\t\tconst toolGuidelines = input.toolPromptGuidelines.get(name);\n\t\tif (toolGuidelines) promptGuidelines.push(...toolGuidelines);\n\t}\n\n\tconst appendParts = [...(input.appendSystemPrompt ?? [])];\n\tif (input.providerAppend) appendParts.push(input.providerAppend);\n\tconst appendSystemPrompt = appendParts.length > 0 ? appendParts.join(\"\\n\\n\") : undefined;\n\n\tconst options: BuildSystemPromptOptions = {\n\t\tcwd: input.cwd,\n\t\tskills: [...input.skills],\n\t\tactiveSkillNames: input.activeSkillNames ? [...input.activeSkillNames] : undefined,\n\t\tactiveSkillSource: input.activeSkillSource,\n\t\tcontextFiles: [...input.contextFiles],\n\t\tcustomPrompt: input.customPrompt,\n\t\tappendSystemPrompt,\n\t\tselectedTools: validToolNames,\n\t\ttoolSnippets,\n\t\tpromptGuidelines,\n\t\tcontextBudget: input.contextBudget,\n\t};\n\tconst built: BuiltSystemPrompt = buildSystemPromptPlan(options);\n\treturn { options, prompt: built.prompt, cacheBoundary: built.cacheBoundary };\n}\n"]}