@jungjaehoon/mama-os 0.32.0 → 0.32.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 (327) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +15 -13
  3. package/dist/agent/agent-loop.d.ts +10 -1
  4. package/dist/agent/agent-loop.d.ts.map +1 -1
  5. package/dist/agent/agent-loop.js +221 -103
  6. package/dist/agent/agent-loop.js.map +1 -1
  7. package/dist/agent/backend-model-policy.d.ts +9 -0
  8. package/dist/agent/backend-model-policy.d.ts.map +1 -0
  9. package/dist/agent/backend-model-policy.js +21 -0
  10. package/dist/agent/backend-model-policy.js.map +1 -0
  11. package/dist/agent/backend-model-runner-factory.d.ts +27 -0
  12. package/dist/agent/backend-model-runner-factory.d.ts.map +1 -0
  13. package/dist/agent/backend-model-runner-factory.js +85 -0
  14. package/dist/agent/backend-model-runner-factory.js.map +1 -0
  15. package/dist/agent/cline-cli-adapter.d.ts +124 -0
  16. package/dist/agent/cline-cli-adapter.d.ts.map +1 -0
  17. package/dist/agent/cline-cli-adapter.js +1040 -0
  18. package/dist/agent/cline-cli-adapter.js.map +1 -0
  19. package/dist/agent/cline-native-tool-policy.d.ts +3 -0
  20. package/dist/agent/cline-native-tool-policy.d.ts.map +1 -0
  21. package/dist/agent/cline-native-tool-policy.js +50 -0
  22. package/dist/agent/cline-native-tool-policy.js.map +1 -0
  23. package/dist/agent/code-act/constants.d.ts +1 -1
  24. package/dist/agent/code-act/constants.d.ts.map +1 -1
  25. package/dist/agent/code-act/constants.js +13 -1
  26. package/dist/agent/code-act/constants.js.map +1 -1
  27. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  28. package/dist/agent/code-act/host-bridge.js +35 -74
  29. package/dist/agent/code-act/host-bridge.js.map +1 -1
  30. package/dist/agent/codex-app-server-process.d.ts +5 -0
  31. package/dist/agent/codex-app-server-process.d.ts.map +1 -1
  32. package/dist/agent/codex-app-server-process.js +30 -0
  33. package/dist/agent/codex-app-server-process.js.map +1 -1
  34. package/dist/agent/codex-auxiliary-tools.d.ts +17 -0
  35. package/dist/agent/codex-auxiliary-tools.d.ts.map +1 -0
  36. package/dist/agent/codex-auxiliary-tools.js +267 -0
  37. package/dist/agent/codex-auxiliary-tools.js.map +1 -0
  38. package/dist/agent/codex-home.d.ts.map +1 -1
  39. package/dist/agent/codex-home.js +1 -0
  40. package/dist/agent/codex-home.js.map +1 -1
  41. package/dist/agent/gateway-tool-catalog.d.ts +14 -0
  42. package/dist/agent/gateway-tool-catalog.d.ts.map +1 -0
  43. package/dist/agent/gateway-tool-catalog.js +41 -0
  44. package/dist/agent/gateway-tool-catalog.js.map +1 -0
  45. package/dist/agent/gateway-tool-executor.d.ts +12 -1
  46. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  47. package/dist/agent/gateway-tool-executor.js +149 -15
  48. package/dist/agent/gateway-tool-executor.js.map +1 -1
  49. package/dist/agent/gateway-tools.md +5 -7
  50. package/dist/agent/managed-agent-runtime-sync.d.ts.map +1 -1
  51. package/dist/agent/managed-agent-runtime-sync.js +17 -3
  52. package/dist/agent/managed-agent-runtime-sync.js.map +1 -1
  53. package/dist/agent/managed-agent-validation.js +1 -1
  54. package/dist/agent/managed-agent-validation.js.map +1 -1
  55. package/dist/agent/model-runner.d.ts +11 -1
  56. package/dist/agent/model-runner.d.ts.map +1 -1
  57. package/dist/agent/model-runner.js +12 -1
  58. package/dist/agent/model-runner.js.map +1 -1
  59. package/dist/agent/session-pool.d.ts +10 -9
  60. package/dist/agent/session-pool.d.ts.map +1 -1
  61. package/dist/agent/session-pool.js +12 -47
  62. package/dist/agent/session-pool.js.map +1 -1
  63. package/dist/agent/tool-registry.d.ts +6 -4
  64. package/dist/agent/tool-registry.d.ts.map +1 -1
  65. package/dist/agent/tool-registry.js +62 -30
  66. package/dist/agent/tool-registry.js.map +1 -1
  67. package/dist/agent/types.d.ts +36 -4
  68. package/dist/agent/types.d.ts.map +1 -1
  69. package/dist/agent/types.js.map +1 -1
  70. package/dist/api/graph-api.d.ts.map +1 -1
  71. package/dist/api/graph-api.js +15 -5
  72. package/dist/api/graph-api.js.map +1 -1
  73. package/dist/api/index.d.ts +10 -0
  74. package/dist/api/index.d.ts.map +1 -1
  75. package/dist/api/index.js +7 -16
  76. package/dist/api/index.js.map +1 -1
  77. package/dist/cli/commands/connector.d.ts +6 -1
  78. package/dist/cli/commands/connector.d.ts.map +1 -1
  79. package/dist/cli/commands/connector.js +61 -45
  80. package/dist/cli/commands/connector.js.map +1 -1
  81. package/dist/cli/commands/init.d.ts +1 -1
  82. package/dist/cli/commands/init.d.ts.map +1 -1
  83. package/dist/cli/commands/init.js +43 -10
  84. package/dist/cli/commands/init.js.map +1 -1
  85. package/dist/cli/commands/run.d.ts.map +1 -1
  86. package/dist/cli/commands/run.js +12 -0
  87. package/dist/cli/commands/run.js.map +1 -1
  88. package/dist/cli/commands/setup.d.ts +22 -0
  89. package/dist/cli/commands/setup.d.ts.map +1 -1
  90. package/dist/cli/commands/setup.js +79 -28
  91. package/dist/cli/commands/setup.js.map +1 -1
  92. package/dist/cli/commands/start.d.ts +13 -9
  93. package/dist/cli/commands/start.d.ts.map +1 -1
  94. package/dist/cli/commands/start.js +190 -97
  95. package/dist/cli/commands/start.js.map +1 -1
  96. package/dist/cli/commands/status.d.ts.map +1 -1
  97. package/dist/cli/commands/status.js +4 -0
  98. package/dist/cli/commands/status.js.map +1 -1
  99. package/dist/cli/config/config-manager.d.ts.map +1 -1
  100. package/dist/cli/config/config-manager.js +63 -14
  101. package/dist/cli/config/config-manager.js.map +1 -1
  102. package/dist/cli/config/types.d.ts +12 -5
  103. package/dist/cli/config/types.d.ts.map +1 -1
  104. package/dist/cli/config/types.js +3 -4
  105. package/dist/cli/config/types.js.map +1 -1
  106. package/dist/cli/index.js +6 -4
  107. package/dist/cli/index.js.map +1 -1
  108. package/dist/cli/runtime/agent-loop-init.d.ts +1 -1
  109. package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
  110. package/dist/cli/runtime/agent-loop-init.js +8 -3
  111. package/dist/cli/runtime/agent-loop-init.js.map +1 -1
  112. package/dist/cli/runtime/api-routes-init.d.ts +38 -1
  113. package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
  114. package/dist/cli/runtime/api-routes-init.js +150 -30
  115. package/dist/cli/runtime/api-routes-init.js.map +1 -1
  116. package/dist/cli/runtime/api-server-init.d.ts +4 -0
  117. package/dist/cli/runtime/api-server-init.d.ts.map +1 -1
  118. package/dist/cli/runtime/api-server-init.js +3 -1
  119. package/dist/cli/runtime/api-server-init.js.map +1 -1
  120. package/dist/cli/runtime/connector-bootstrap.d.ts +8 -0
  121. package/dist/cli/runtime/connector-bootstrap.d.ts.map +1 -0
  122. package/dist/cli/runtime/connector-bootstrap.js +14 -0
  123. package/dist/cli/runtime/connector-bootstrap.js.map +1 -0
  124. package/dist/cli/runtime/connector-init.d.ts +4 -1
  125. package/dist/cli/runtime/connector-init.d.ts.map +1 -1
  126. package/dist/cli/runtime/connector-init.js +2 -8
  127. package/dist/cli/runtime/connector-init.js.map +1 -1
  128. package/dist/cli/runtime/envelope-bootstrap.d.ts +2 -1
  129. package/dist/cli/runtime/envelope-bootstrap.d.ts.map +1 -1
  130. package/dist/cli/runtime/envelope-bootstrap.js +7 -15
  131. package/dist/cli/runtime/envelope-bootstrap.js.map +1 -1
  132. package/dist/cli/runtime/gateway-init.d.ts +1 -1
  133. package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
  134. package/dist/cli/runtime/gateway-init.js.map +1 -1
  135. package/dist/cli/runtime/mama-core-init.d.ts +10 -2
  136. package/dist/cli/runtime/mama-core-init.d.ts.map +1 -1
  137. package/dist/cli/runtime/mama-core-init.js +52 -68
  138. package/dist/cli/runtime/mama-core-init.js.map +1 -1
  139. package/dist/cli/runtime/memory-agent-init.d.ts.map +1 -1
  140. package/dist/cli/runtime/memory-agent-init.js +18 -5
  141. package/dist/cli/runtime/memory-agent-init.js.map +1 -1
  142. package/dist/cli/runtime/scheduler-init.d.ts +4 -0
  143. package/dist/cli/runtime/scheduler-init.d.ts.map +1 -1
  144. package/dist/cli/runtime/scheduler-init.js +24 -3
  145. package/dist/cli/runtime/scheduler-init.js.map +1 -1
  146. package/dist/cli/runtime/shutdown.d.ts +4 -0
  147. package/dist/cli/runtime/shutdown.d.ts.map +1 -1
  148. package/dist/cli/runtime/shutdown.js +30 -6
  149. package/dist/cli/runtime/shutdown.js.map +1 -1
  150. package/dist/cli/runtime/utilities.d.ts +2 -0
  151. package/dist/cli/runtime/utilities.d.ts.map +1 -1
  152. package/dist/cli/runtime/utilities.js +33 -0
  153. package/dist/cli/runtime/utilities.js.map +1 -1
  154. package/dist/connectors/index.d.ts +4 -1
  155. package/dist/connectors/index.d.ts.map +1 -1
  156. package/dist/connectors/index.js +3 -2
  157. package/dist/connectors/index.js.map +1 -1
  158. package/dist/connectors/private-connector-policy.d.ts +150 -0
  159. package/dist/connectors/private-connector-policy.d.ts.map +1 -0
  160. package/dist/connectors/private-connector-policy.js +289 -0
  161. package/dist/connectors/private-connector-policy.js.map +1 -0
  162. package/dist/connectors/private-prompt-overlay.d.ts +17 -0
  163. package/dist/connectors/private-prompt-overlay.d.ts.map +1 -0
  164. package/dist/connectors/private-prompt-overlay.js +156 -0
  165. package/dist/connectors/private-prompt-overlay.js.map +1 -0
  166. package/dist/db/migrations/operator-task-external-lifecycle.d.ts +8 -0
  167. package/dist/db/migrations/operator-task-external-lifecycle.d.ts.map +1 -0
  168. package/dist/db/migrations/operator-task-external-lifecycle.js +169 -0
  169. package/dist/db/migrations/operator-task-external-lifecycle.js.map +1 -0
  170. package/dist/envelope/enforcer.js +8 -7
  171. package/dist/envelope/enforcer.js.map +1 -1
  172. package/dist/envelope/reactive-config.d.ts.map +1 -1
  173. package/dist/envelope/reactive-config.js +2 -1
  174. package/dist/envelope/reactive-config.js.map +1 -1
  175. package/dist/envelope/tool-connector-scope.d.ts.map +1 -1
  176. package/dist/envelope/tool-connector-scope.js +4 -0
  177. package/dist/envelope/tool-connector-scope.js.map +1 -1
  178. package/dist/gateways/discord.d.ts.map +1 -1
  179. package/dist/gateways/discord.js +11 -6
  180. package/dist/gateways/discord.js.map +1 -1
  181. package/dist/gateways/image-analyzer.d.ts +5 -0
  182. package/dist/gateways/image-analyzer.d.ts.map +1 -1
  183. package/dist/gateways/image-analyzer.js +8 -0
  184. package/dist/gateways/image-analyzer.js.map +1 -1
  185. package/dist/gateways/message-router.d.ts +11 -1
  186. package/dist/gateways/message-router.d.ts.map +1 -1
  187. package/dist/gateways/message-router.js +146 -52
  188. package/dist/gateways/message-router.js.map +1 -1
  189. package/dist/gateways/slack.d.ts.map +1 -1
  190. package/dist/gateways/slack.js +6 -2
  191. package/dist/gateways/slack.js.map +1 -1
  192. package/dist/gateways/telegram-message-ledger.d.ts +8 -1
  193. package/dist/gateways/telegram-message-ledger.d.ts.map +1 -1
  194. package/dist/gateways/telegram-message-ledger.js +141 -24
  195. package/dist/gateways/telegram-message-ledger.js.map +1 -1
  196. package/dist/gateways/telegram.d.ts +2 -0
  197. package/dist/gateways/telegram.d.ts.map +1 -1
  198. package/dist/gateways/telegram.js +19 -12
  199. package/dist/gateways/telegram.js.map +1 -1
  200. package/dist/gateways/types.d.ts +1 -1
  201. package/dist/gateways/types.d.ts.map +1 -1
  202. package/dist/index.d.ts +1 -1
  203. package/dist/index.js +1 -1
  204. package/dist/multi-agent/agent-process-manager.d.ts +14 -4
  205. package/dist/multi-agent/agent-process-manager.d.ts.map +1 -1
  206. package/dist/multi-agent/agent-process-manager.js +144 -47
  207. package/dist/multi-agent/agent-process-manager.js.map +1 -1
  208. package/dist/multi-agent/dashboard-agent-persona.d.ts +3 -3
  209. package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
  210. package/dist/multi-agent/dashboard-agent-persona.js +10 -13
  211. package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
  212. package/dist/multi-agent/memory-agent-persona.d.ts +1 -1
  213. package/dist/multi-agent/memory-agent-persona.d.ts.map +1 -1
  214. package/dist/multi-agent/memory-agent-persona.js +1 -1
  215. package/dist/multi-agent/runtime-process.d.ts +3 -0
  216. package/dist/multi-agent/runtime-process.d.ts.map +1 -1
  217. package/dist/multi-agent/runtime-process.js +10 -2
  218. package/dist/multi-agent/runtime-process.js.map +1 -1
  219. package/dist/multi-agent/types.d.ts +12 -2
  220. package/dist/multi-agent/types.d.ts.map +1 -1
  221. package/dist/multi-agent/types.js.map +1 -1
  222. package/dist/multi-agent/wiki-agent-persona.d.ts +2 -2
  223. package/dist/multi-agent/wiki-agent-persona.js +2 -2
  224. package/dist/multi-agent/workflow-types.d.ts +1 -1
  225. package/dist/multi-agent/workflow-types.d.ts.map +1 -1
  226. package/dist/onboarding/complete-autonomous-prompt.d.ts +1 -1
  227. package/dist/onboarding/complete-autonomous-prompt.d.ts.map +1 -1
  228. package/dist/onboarding/complete-autonomous-prompt.js +9 -9
  229. package/dist/operator/board-slot-instructions.d.ts +1 -1
  230. package/dist/operator/board-slot-instructions.js +2 -2
  231. package/dist/operator/board-slot-instructions.js.map +1 -1
  232. package/dist/operator/briefs.d.ts +3 -0
  233. package/dist/operator/briefs.d.ts.map +1 -1
  234. package/dist/operator/briefs.js +64 -3
  235. package/dist/operator/briefs.js.map +1 -1
  236. package/dist/operator/console-brief.d.ts +6 -3
  237. package/dist/operator/console-brief.d.ts.map +1 -1
  238. package/dist/operator/console-brief.js +39 -9
  239. package/dist/operator/console-brief.js.map +1 -1
  240. package/dist/operator/external-lifecycle-candidates.d.ts +56 -0
  241. package/dist/operator/external-lifecycle-candidates.d.ts.map +1 -0
  242. package/dist/operator/external-lifecycle-candidates.js +415 -0
  243. package/dist/operator/external-lifecycle-candidates.js.map +1 -0
  244. package/dist/operator/external-lifecycle.d.ts +82 -0
  245. package/dist/operator/external-lifecycle.d.ts.map +1 -0
  246. package/dist/operator/external-lifecycle.js +27 -0
  247. package/dist/operator/external-lifecycle.js.map +1 -0
  248. package/dist/operator/file-coordination.d.ts +7 -0
  249. package/dist/operator/file-coordination.d.ts.map +1 -0
  250. package/dist/operator/file-coordination.js +84 -0
  251. package/dist/operator/file-coordination.js.map +1 -0
  252. package/dist/operator/operator-trigger-loop.d.ts +19 -4
  253. package/dist/operator/operator-trigger-loop.d.ts.map +1 -1
  254. package/dist/operator/operator-trigger-loop.js +151 -23
  255. package/dist/operator/operator-trigger-loop.js.map +1 -1
  256. package/dist/operator/pending-report-store.d.ts +62 -3
  257. package/dist/operator/pending-report-store.d.ts.map +1 -1
  258. package/dist/operator/pending-report-store.js +297 -40
  259. package/dist/operator/pending-report-store.js.map +1 -1
  260. package/dist/operator/report-carry-delivery.d.ts +35 -0
  261. package/dist/operator/report-carry-delivery.d.ts.map +1 -0
  262. package/dist/operator/report-carry-delivery.js +55 -0
  263. package/dist/operator/report-carry-delivery.js.map +1 -0
  264. package/dist/operator/report-carry.d.ts +50 -30
  265. package/dist/operator/report-carry.d.ts.map +1 -1
  266. package/dist/operator/report-carry.js +323 -71
  267. package/dist/operator/report-carry.js.map +1 -1
  268. package/dist/operator/situation-report.d.ts +30 -11
  269. package/dist/operator/situation-report.d.ts.map +1 -1
  270. package/dist/operator/situation-report.js +79 -35
  271. package/dist/operator/situation-report.js.map +1 -1
  272. package/dist/operator/task-ledger.d.ts +101 -0
  273. package/dist/operator/task-ledger.d.ts.map +1 -1
  274. package/dist/operator/task-ledger.js +599 -124
  275. package/dist/operator/task-ledger.js.map +1 -1
  276. package/dist/operator/temporal-runtime.d.ts.map +1 -1
  277. package/dist/operator/temporal-runtime.js +3 -1
  278. package/dist/operator/temporal-runtime.js.map +1 -1
  279. package/dist/operator/temporal-worker.js +1 -1
  280. package/dist/operator/trigger-author.d.ts +13 -1
  281. package/dist/operator/trigger-author.d.ts.map +1 -1
  282. package/dist/operator/trigger-author.js +35 -0
  283. package/dist/operator/trigger-author.js.map +1 -1
  284. package/dist/operator/worker-run.d.ts +1 -1
  285. package/dist/operator/worker-run.d.ts.map +1 -1
  286. package/dist/operator/worker-run.js +27 -9
  287. package/dist/operator/worker-run.js.map +1 -1
  288. package/dist/operator/workorder-consumer.d.ts +12 -1
  289. package/dist/operator/workorder-consumer.d.ts.map +1 -1
  290. package/dist/operator/workorder-consumer.js +125 -6
  291. package/dist/operator/workorder-consumer.js.map +1 -1
  292. package/dist/operator/workorder-hooks.d.ts +7 -2
  293. package/dist/operator/workorder-hooks.d.ts.map +1 -1
  294. package/dist/operator/workorder-hooks.js +22 -0
  295. package/dist/operator/workorder-hooks.js.map +1 -1
  296. package/dist/operator/workorder-publishers.d.ts +9 -2
  297. package/dist/operator/workorder-publishers.d.ts.map +1 -1
  298. package/dist/operator/workorder-publishers.js +167 -5
  299. package/dist/operator/workorder-publishers.js.map +1 -1
  300. package/dist/scheduler/cron-worker.d.ts +8 -4
  301. package/dist/scheduler/cron-worker.d.ts.map +1 -1
  302. package/dist/scheduler/cron-worker.js +56 -39
  303. package/dist/scheduler/cron-worker.js.map +1 -1
  304. package/dist/setup/setup-actions.d.ts +26 -0
  305. package/dist/setup/setup-actions.d.ts.map +1 -0
  306. package/dist/setup/setup-actions.js +371 -0
  307. package/dist/setup/setup-actions.js.map +1 -0
  308. package/dist/setup/setup-prompt.d.ts +1 -1
  309. package/dist/setup/setup-prompt.d.ts.map +1 -1
  310. package/dist/setup/setup-prompt.js +28 -33
  311. package/dist/setup/setup-prompt.js.map +1 -1
  312. package/dist/setup/setup-server.d.ts +6 -1
  313. package/dist/setup/setup-server.d.ts.map +1 -1
  314. package/dist/setup/setup-server.js +55 -9
  315. package/dist/setup/setup-server.js.map +1 -1
  316. package/dist/setup/setup-websocket.d.ts +14 -2
  317. package/dist/setup/setup-websocket.d.ts.map +1 -1
  318. package/dist/setup/setup-websocket.js +121 -37
  319. package/dist/setup/setup-websocket.js.map +1 -1
  320. package/package.json +2 -2
  321. package/public/setup.html +9 -6
  322. package/public/viewer/js/modules/agents.js +5 -4
  323. package/public/viewer/js/modules/settings.js +34 -10
  324. package/public/viewer/src/modules/agents.ts +5 -4
  325. package/public/viewer/src/modules/settings.ts +49 -11
  326. package/public/viewer/src/utils/api.ts +3 -2
  327. package/scripts/generate-gateway-tools.ts +13 -3
@@ -54,11 +54,15 @@ const fs_1 = require("fs");
54
54
  const prompt_size_monitor_js_1 = require("./prompt-size-monitor.js");
55
55
  const skill_loader_js_1 = require("./skill-loader.js");
56
56
  const persistent_cli_adapter_js_1 = require("./persistent-cli-adapter.js");
57
+ const cline_cli_adapter_js_1 = require("./cline-cli-adapter.js");
58
+ const cline_native_tool_policy_js_1 = require("./cline-native-tool-policy.js");
57
59
  const runtime_process_js_1 = require("../multi-agent/runtime-process.js");
58
60
  const model_runner_js_1 = require("./model-runner.js");
59
61
  const gateway_tool_executor_js_1 = require("./gateway-tool-executor.js");
60
62
  const run_guard_js_1 = require("../envelope/run-guard.js");
61
63
  const tool_registry_js_1 = require("./tool-registry.js");
64
+ const gateway_tool_catalog_js_1 = require("./gateway-tool-catalog.js");
65
+ const private_connector_policy_js_1 = require("../connectors/private-connector-policy.js");
62
66
  const index_js_1 = require("./code-act/index.js");
63
67
  const index_js_2 = require("../concurrency/index.js");
64
68
  const session_pool_js_1 = require("./session-pool.js");
@@ -73,6 +77,14 @@ const pre_compact_handler_js_1 = require("./pre-compact-handler.js");
73
77
  const debugLogger = __importStar(require("@jungjaehoon/mama-core/debug-logger"));
74
78
  const { DebugLogger } = debugLogger;
75
79
  const logger = new DebugLogger('AgentLoop');
80
+ const MODEL_RUNNER_AGENT_ERROR_CODES = {
81
+ timeout: 'NETWORK_ERROR',
82
+ crash: 'CLI_ERROR',
83
+ context_overflow: 'MAX_TOKENS',
84
+ auth_failure: 'AUTH_ERROR',
85
+ rate_limit: 'RATE_LIMIT',
86
+ unknown: 'CLI_ERROR',
87
+ };
76
88
  /**
77
89
  * Default configuration
78
90
  */
@@ -85,6 +97,11 @@ const DEFAULT_TOOLS_CONFIG = {
85
97
  mcp: [],
86
98
  mcp_config: '~/.mama/mama-mcp-config.json',
87
99
  };
100
+ const DEFAULT_PRIVATE_CONNECTOR_POLICY = (0, private_connector_policy_js_1.resolvePrivateConnectorPolicy)({
101
+ ok: true,
102
+ config: {},
103
+ enabledNames: [],
104
+ });
88
105
  // Exported so the conductor test can PIN that 'conductor' is absent: the
89
106
  // conductor must run on its own session:operator:conductor lane, never the
90
107
  // global operator lane where Stage-2 workers serialize (deadlock topology).
@@ -309,33 +326,23 @@ function loadComposedSystemPrompt(verbose = false, context) {
309
326
  * Load Gateway Tools prompt from MD file
310
327
  * These tools are executed by GatewayToolExecutor, NOT MCP
311
328
  */
312
- // Cache gateway-tools.md content (static at runtime, no need to re-read)
313
- let _gatewayToolsCache = null;
314
- // Cache filtered versions keyed by sorted disallowed list
315
- const _filteredCache = new Map();
316
329
  function getGatewayToolsPrompt(disallowed) {
317
- if (!_gatewayToolsCache) {
318
- const gatewayToolsPath = (0, path_1.join)(__dirname, 'gateway-tools.md');
319
- if ((0, fs_1.existsSync)(gatewayToolsPath)) {
320
- _gatewayToolsCache = (0, fs_1.readFileSync)(gatewayToolsPath, 'utf-8');
321
- }
322
- else {
323
- logger.warn('gateway-tools.md not found, using registry fallback');
324
- _gatewayToolsCache = `# Gateway Tools\n\n${tool_registry_js_1.ToolRegistry.generateFallbackPrompt()}`;
325
- }
326
- }
327
- if (!disallowed?.length)
328
- return _gatewayToolsCache;
329
- const cacheKey = [...disallowed].sort().join(',');
330
- let filtered = _filteredCache.get(cacheKey);
331
- if (!filtered) {
332
- filtered = _gatewayToolsCache;
333
- for (const tool of disallowed) {
334
- filtered = filtered.replace(new RegExp(`^- \\*\\*${tool}\\*\\*.*$`, 'gm'), '');
335
- }
336
- _filteredCache.set(cacheKey, filtered);
337
- }
338
- return filtered;
330
+ return (0, gateway_tool_catalog_js_1.buildGatewayToolCatalog)({
331
+ surface: 'multi-agent-generic',
332
+ allowedTools: ['*'],
333
+ blockedTools: disallowed,
334
+ privateConnectorPolicy: DEFAULT_PRIVATE_CONNECTOR_POLICY,
335
+ }).prompt;
336
+ }
337
+ function getRunGatewayToolsPrompt(context, disallowed) {
338
+ return (0, gateway_tool_catalog_js_1.buildGatewayToolCatalog)({
339
+ surface: context
340
+ ? (0, private_connector_policy_js_1.resolvePrivatePrincipalSurface)({ agentContext: context })
341
+ : 'multi-agent-generic',
342
+ allowedTools: context?.role.allowedTools ?? ['*'],
343
+ blockedTools: [...(context?.role.blockedTools ?? []), ...(disallowed ?? [])],
344
+ privateConnectorPolicy: DEFAULT_PRIVATE_CONNECTOR_POLICY,
345
+ }).prompt;
339
346
  }
340
347
  const CANONICAL_CODE_ACT_HEADING = '## Code-Act: Gateway Tool Execution via Sandbox';
341
348
  const CODE_ACT_MCP_COMPAT_NAME = 'mcp__code-act__code_act';
@@ -370,26 +377,20 @@ function wrapGeneratedPromptSection(kind, content) {
370
377
  }
371
378
  function stripGenericGatewayToolsCatalog(systemPrompt) {
372
379
  const withoutMarked = stripMarkedPromptSection(systemPrompt, GENERATED_GATEWAY_TOOLS_START, GENERATED_GATEWAY_TOOLS_END);
373
- const headingPattern = /^#{1,6}\s+Gateway Tools\s*$/gm;
374
- let catalogStart = -1;
375
- let match;
376
- while ((match = headingPattern.exec(withoutMarked)) !== null) {
377
- catalogStart = match.index;
378
- }
380
+ const generatedCatalog = getGatewayToolsPrompt();
381
+ const catalogStart = withoutMarked.lastIndexOf(generatedCatalog);
379
382
  if (catalogStart < 0) {
380
383
  return withoutMarked;
381
384
  }
382
- const catalog = withoutMarked.slice(catalogStart);
383
- if (!catalog.includes('Call tools via JSON block:') || !catalog.includes('```tool_call')) {
385
+ const catalogEnd = catalogStart + generatedCatalog.length;
386
+ const startsAtLayerBoundary = catalogStart === 0 ||
387
+ /\r?\n\r?\n---[ \t]*\r?\n\r?\n$/.test(withoutMarked.slice(0, catalogStart));
388
+ const endsAtLayerBoundary = catalogEnd === withoutMarked.length ||
389
+ /^\r?\n\r?\n---[ \t]*\r?\n\r?\n/.test(withoutMarked.slice(catalogEnd));
390
+ if (!startsAtLayerBoundary || !endsAtLayerBoundary) {
384
391
  return withoutMarked;
385
392
  }
386
- const generatedCatalog = getGatewayToolsPrompt();
387
- if (withoutMarked.startsWith(generatedCatalog, catalogStart)) {
388
- return removePromptSection(withoutMarked, catalogStart, catalogStart + generatedCatalog.length);
389
- }
390
- const boundedSeparator = catalog.match(/\r?\n\r?\n---[ \t]*\r?\n\r?\n/);
391
- const sectionEnd = boundedSeparator?.index ?? catalog.length;
392
- return removePromptSection(withoutMarked, catalogStart, catalogStart + sectionEnd);
393
+ return removePromptSection(withoutMarked, catalogStart, catalogEnd);
393
394
  }
394
395
  function stripTrailingCanonicalCodeActSection(systemPrompt) {
395
396
  const withoutMarked = stripMarkedPromptSection(systemPrompt, GENERATED_CODE_ACT_START, GENERATED_CODE_ACT_END);
@@ -515,6 +516,11 @@ class AgentLoop {
515
516
  // overlapping owner chat) would steal each other's callbacks and leak tiers
516
517
  // if these were instance fields.
517
518
  disallowedTools;
519
+ clineNativeAllowedTools;
520
+ clineNativeDisallowedTools;
521
+ clineNativePolicyConfigured;
522
+ clineAllowSpawnAgent;
523
+ clineAllowAgentTeams;
518
524
  constructor(_oauthManager, options = {}, _clientOptions, executorOptions) {
519
525
  // Initialize tools config (hybrid Gateway/MCP routing)
520
526
  this.toolsConfig = {
@@ -534,7 +540,9 @@ class AgentLoop {
534
540
  const useGatewayMode = gatewayTools.includes('*') || gatewayTools.length > 0;
535
541
  const useMCPMode = mcpTools.includes('*') || mcpTools.length > 0;
536
542
  this.useCodeAct = options.useCodeAct ?? false;
537
- this.isGatewayMode = useGatewayMode || (options.backend === 'codex' && this.useCodeAct);
543
+ this.isGatewayMode =
544
+ useGatewayMode ||
545
+ ((options.backend === 'codex' || options.backend === 'cline') && this.useCodeAct);
538
546
  this.disallowedTools = this.useCodeAct
539
547
  ? options.disallowedTools
540
548
  : [
@@ -544,6 +552,13 @@ class AgentLoop {
544
552
  CODE_ACT_MCP_COMPAT_NAME,
545
553
  ]),
546
554
  ];
555
+ this.clineNativeAllowedTools = [...(options.clineNativeAllowedTools ?? [])];
556
+ this.clineNativeDisallowedTools = [...(options.clineNativeDisallowedTools ?? [])];
557
+ this.clineNativePolicyConfigured =
558
+ options.clineNativeAllowedTools !== undefined ||
559
+ options.clineNativeDisallowedTools !== undefined;
560
+ this.clineAllowSpawnAgent = options.clineAllowSpawnAgent ?? false;
561
+ this.clineAllowAgentTeams = options.clineAllowAgentTeams ?? false;
547
562
  if (useGatewayMode && useMCPMode) {
548
563
  logger.debug('🔀 Hybrid mode: Gateway + MCP tools enabled');
549
564
  }
@@ -647,7 +662,7 @@ class AgentLoop {
647
662
  promptLayers.push({ name: 'codeAct', content: codeActPrompt, priority: 2 });
648
663
  }
649
664
  else if (!this.useCodeAct && backend !== 'codex') {
650
- const gatewayToolsPrompt = getGatewayToolsPrompt(this.disallowedTools);
665
+ const gatewayToolsPrompt = getRunGatewayToolsPrompt(options.agentContext, this.disallowedTools);
651
666
  if (gatewayToolsPrompt) {
652
667
  promptLayers.push({
653
668
  name: 'gatewayTools',
@@ -700,6 +715,25 @@ class AgentLoop {
700
715
  });
701
716
  logger.debug('Codex app-server backend enabled');
702
717
  }
718
+ else if (this.backend === 'cline') {
719
+ const workspaceDir = options.clineCwd ?? (0, path_1.join)((0, os_1.homedir)(), '.mama', 'workspace');
720
+ if (!(0, fs_1.existsSync)(workspaceDir)) {
721
+ (0, fs_1.mkdirSync)(workspaceDir, { recursive: true });
722
+ }
723
+ this.agent = new cline_cli_adapter_js_1.ClineCLIAdapter({
724
+ command: options.clineCommand,
725
+ provider: options.clineProvider ?? 'cline',
726
+ model: options.model,
727
+ systemPrompt: defaultSystemPrompt,
728
+ cwd: workspaceDir,
729
+ // Cline receives MAMA CodeAct as a session-bound Hub custom tool.
730
+ // Its shared daemon owns native MCP settings independently.
731
+ dataDir: options.clineDataDir,
732
+ requestTimeout: options.timeoutMs,
733
+ sessionId,
734
+ });
735
+ logger.debug('Cline CLI backend enabled');
736
+ }
703
737
  else {
704
738
  // Claude backend: always use PersistentCLI for fast responses (~2-3s vs ~16-30s)
705
739
  this.persistentCLI = new persistent_cli_adapter_js_1.PersistentCLIAdapter({
@@ -938,6 +972,12 @@ class AgentLoop {
938
972
  if (this.stopped) {
939
973
  throw new types_js_1.AgentError('Agent loop is stopping', 'AGENT_STOPPED', undefined, false);
940
974
  }
975
+ if (options?.agentContext) {
976
+ options = {
977
+ ...options,
978
+ agentContext: this.mcpExecutor.projectPrivateAgentContext(options.agentContext),
979
+ };
980
+ }
941
981
  const runScope = {
942
982
  streamCallbacks: options?.streamCallbacks,
943
983
  tier: 1,
@@ -984,8 +1024,20 @@ class AgentLoop {
984
1024
  let ownedSession = false;
985
1025
  // Set session ID on the agent
986
1026
  // Claude PersistentCLI: process alive → CONTINUE (stdin message), process dead → NEW (spawn with --session-id)
987
- // Codex: threadId alive → CONTINUE (codex-reply), threadId null → NEW (codex tool)
1027
+ // Codex/Cline: durable runtime session alive → CONTINUE, missing → NEW.
988
1028
  const isCodex = this.backend === 'codex';
1029
+ const isCline = this.backend === 'cline';
1030
+ const isDurableRuntime = isCodex || isCline;
1031
+ const clineRole = options?.agentContext?.role;
1032
+ const clineAllowedTools = this.clineNativePolicyConfigured
1033
+ ? this.clineNativeAllowedTools
1034
+ : (0, cline_native_tool_policy_js_1.projectClineNativeTools)(clineRole?.allowedTools);
1035
+ const clineDisallowedTools = this.clineNativePolicyConfigured
1036
+ ? this.clineNativeDisallowedTools
1037
+ : (0, cline_native_tool_policy_js_1.projectClineNativeTools)(clineRole?.blockedTools);
1038
+ const clineDelegationBlocked = clineRole?.blockedTools?.includes('delegate') ?? false;
1039
+ const clineAllowSpawnAgent = this.clineAllowSpawnAgent && !clineDelegationBlocked;
1040
+ const clineAllowAgentTeams = this.clineAllowAgentTeams && !clineDelegationBlocked;
989
1041
  const codeActPolicy = this.useCodeAct
990
1042
  ? (0, index_js_1.projectCodeActToolPolicy)({
991
1043
  tier: runScope.tier,
@@ -998,12 +1050,12 @@ class AgentLoop {
998
1050
  })
999
1051
  : undefined;
1000
1052
  const outerCodeActAllowed = this.useCodeAct && roleAllowsOuterCodeAct(options?.agentContext?.role, this.disallowedTools);
1001
- const effectiveSessionPolicyFingerprint = isCodex && codeActPolicy
1053
+ const effectiveSessionPolicyFingerprint = isDurableRuntime && codeActPolicy
1002
1054
  ? combineCodeActSessionPolicyFingerprint(options?.sessionPolicyFingerprint, codeActPolicy)
1003
1055
  : options?.sessionPolicyFingerprint;
1004
1056
  let resolvedCliSessionId = options?.cliSessionId ?? null;
1005
1057
  const sessionLabel = (isNew) => {
1006
- if (isCodex) {
1058
+ if (isDurableRuntime) {
1007
1059
  return isNew ? 'NEW thread' : 'CONTINUE thread';
1008
1060
  }
1009
1061
  return isNew ? 'NEW process' : 'CONTINUE session';
@@ -1012,7 +1064,7 @@ class AgentLoop {
1012
1064
  // Session routing travels per prompt() call via resolvedCliSessionId - no
1013
1065
  // shared-adapter mutation (setSessionId re-pointed channelKey/currentProcess
1014
1066
  // across awaits, cross-wiring concurrent lanes).
1015
- console.log(`[AgentLoop] [${isCodex ? 'codex' : 'claude'}] ${channelKey} (${sessionLabel(sessionIsNew)})`);
1067
+ console.log(`[AgentLoop] [${this.backend}] ${channelKey} (${sessionLabel(sessionIsNew)})`);
1016
1068
  }
1017
1069
  else if (options?.freshSession) {
1018
1070
  // Stateless lanes (operator reports): session context is a cache, not
@@ -1023,7 +1075,7 @@ class AgentLoop {
1023
1075
  sessionIsNew = true;
1024
1076
  ownedSession = true;
1025
1077
  resolvedCliSessionId = cliSessionId;
1026
- console.log(`[AgentLoop] [${isCodex ? 'codex' : 'claude'}] ${channelKey} (FRESH session - stateless lane)`);
1078
+ console.log(`[AgentLoop] [${this.backend}] ${channelKey} (FRESH session - stateless lane)`);
1027
1079
  }
1028
1080
  else {
1029
1081
  // Fallback: get session from pool (for direct AgentLoop usage)
@@ -1036,7 +1088,7 @@ class AgentLoop {
1036
1088
  ownedSession = true;
1037
1089
  resolvedCliSessionId = cliSessionId;
1038
1090
  // Per-call routing via resolvedCliSessionId - no shared-adapter mutation.
1039
- console.log(`[AgentLoop] [${isCodex ? 'codex' : 'claude'}] ${channelKey} (${sessionLabel(isNew)})`);
1091
+ console.log(`[AgentLoop] [${this.backend}] ${channelKey} (${sessionLabel(isNew)})`);
1040
1092
  }
1041
1093
  try {
1042
1094
  if (this.shouldBeginModelRun(options)) {
@@ -1050,7 +1102,7 @@ class AgentLoop {
1050
1102
  let nativeToolCallCount = 0;
1051
1103
  let nativeConsecutiveToolCalls = 0;
1052
1104
  let nativeLastToolSignature = '';
1053
- const hostToolBridge = isCodex && this.isGatewayMode
1105
+ const hostToolBridge = isDurableRuntime && this.isGatewayMode
1054
1106
  ? {
1055
1107
  tools: this.useCodeAct
1056
1108
  ? outerCodeActAllowed
@@ -1092,13 +1144,18 @@ class AgentLoop {
1092
1144
  name: call.name,
1093
1145
  input: call.input,
1094
1146
  };
1095
- history.push({ role: 'assistant', content: [toolUse] });
1096
- runScope.onTurn?.({
1097
- turn,
1098
- role: 'assistant',
1099
- content: [toolUse],
1100
- stopReason: 'tool_use',
1101
- });
1147
+ // Codex does not return completed host exchanges, so record them
1148
+ // here. Cline reports the paired custom-tool exchange from its Hub
1149
+ // event stream and AgentLoop appends it exactly once below.
1150
+ if (isCodex) {
1151
+ history.push({ role: 'assistant', content: [toolUse] });
1152
+ runScope.onTurn?.({
1153
+ turn,
1154
+ role: 'assistant',
1155
+ content: [toolUse],
1156
+ stopReason: 'tool_use',
1157
+ });
1158
+ }
1102
1159
  const callExecutionContext = toolExecutionContext
1103
1160
  ? {
1104
1161
  ...toolExecutionContext,
@@ -1118,13 +1175,15 @@ class AgentLoop {
1118
1175
  if (!toolResult.terminalCode) {
1119
1176
  callSignal.throwIfAborted();
1120
1177
  }
1121
- const persistedToolResult = historyToolResult(toolResult);
1122
- history.push({ role: 'user', content: [persistedToolResult] });
1123
- runScope.onTurn?.({
1124
- turn,
1125
- role: 'user',
1126
- content: [persistedToolResult],
1127
- });
1178
+ if (isCodex) {
1179
+ const persistedToolResult = historyToolResult(toolResult);
1180
+ history.push({ role: 'user', content: [persistedToolResult] });
1181
+ runScope.onTurn?.({
1182
+ turn,
1183
+ role: 'user',
1184
+ content: [persistedToolResult],
1185
+ });
1186
+ }
1128
1187
  return {
1129
1188
  content: toolResult.content,
1130
1189
  isError: toolResult.is_error === true,
@@ -1144,7 +1203,7 @@ class AgentLoop {
1144
1203
  if (outerCodeActAllowed) {
1145
1204
  const policy = codeActPolicy;
1146
1205
  const typeDefs = index_js_1.TypeDefinitionGenerator.generate(policy);
1147
- gatewayToolsPrompt = wrapGeneratedPromptSection('codeAct', (0, index_js_1.getCodeActInstructions)(isCodex ? 'codex' : 'claude', policy.names) +
1206
+ gatewayToolsPrompt = wrapGeneratedPromptSection('codeAct', (0, index_js_1.getCodeActInstructions)(this.backend, policy.names) +
1148
1207
  '\n```typescript\n' +
1149
1208
  typeDefs +
1150
1209
  '\n```');
@@ -1153,12 +1212,23 @@ class AgentLoop {
1153
1212
  else if (this.isGatewayMode && !isCodex) {
1154
1213
  baseSystemPrompt = stripDisabledCodeActGuidance(baseSystemPrompt);
1155
1214
  if (!isResumingSession) {
1156
- // Non-CodeAct callers may already embed the generic gateway catalog.
1157
- const alreadyHasTools = baseSystemPrompt.includes('# Gateway Tools') ||
1158
- baseSystemPrompt.includes('# Code Execution') ||
1159
- baseSystemPrompt.includes('## Code-Act');
1160
- if (!alreadyHasTools) {
1161
- gatewayToolsPrompt = wrapGeneratedPromptSection('gatewayTools', getGatewayToolsPrompt(this.disallowedTools));
1215
+ if (options?.gatewayToolsPrompt !== undefined) {
1216
+ // A short-lived caller may carry a more specific final policy than
1217
+ // the process-wide default. Replace the host-generated constructor
1218
+ // catalog with that exact policy-keyed catalog for this run.
1219
+ baseSystemPrompt = stripGenericGatewayToolsCatalog(baseSystemPrompt);
1220
+ if (options.gatewayToolsPrompt) {
1221
+ gatewayToolsPrompt = wrapGeneratedPromptSection('gatewayTools', options.gatewayToolsPrompt);
1222
+ }
1223
+ }
1224
+ else {
1225
+ // Non-CodeAct callers may already embed the generic gateway catalog.
1226
+ const alreadyHasTools = baseSystemPrompt.includes('# Gateway Tools') ||
1227
+ baseSystemPrompt.includes('# Code Execution') ||
1228
+ baseSystemPrompt.includes('## Code-Act');
1229
+ if (!alreadyHasTools) {
1230
+ gatewayToolsPrompt = wrapGeneratedPromptSection('gatewayTools', getRunGatewayToolsPrompt(options?.agentContext, this.disallowedTools));
1231
+ }
1162
1232
  }
1163
1233
  }
1164
1234
  }
@@ -1193,22 +1263,30 @@ class AgentLoop {
1193
1263
  return effectivePrompt;
1194
1264
  };
1195
1265
  let perCallSystemPrompt;
1196
- if (options?.systemPrompt || (this.isGatewayMode && this.useCodeAct)) {
1266
+ if (isCline && this.isGatewayMode && this.useCodeAct && !sessionIsNew) {
1267
+ // TG-05: a compatible Cline Hub session ignores the per-call system prompt.
1268
+ // Keep the continuation stub cheap; missing/mismatched sessions rebuild the
1269
+ // complete policy lazily through freshSessionSystemPrompt below.
1270
+ perCallSystemPrompt = options?.systemPrompt ?? this.defaultSystemPrompt;
1271
+ }
1272
+ else if (options?.systemPrompt ||
1273
+ options?.gatewayToolsPrompt !== undefined ||
1274
+ (this.isGatewayMode && this.useCodeAct)) {
1197
1275
  perCallSystemPrompt = prepareSystemPrompt(options?.systemPrompt, options?.resumeSession === true);
1198
1276
  }
1199
1277
  else {
1200
1278
  perCallSystemPrompt = this.defaultSystemPrompt;
1201
1279
  console.log(`[AgentLoop] No systemPrompt in options - using spawn default for this call`);
1202
1280
  }
1203
- // Codex re-anchors a rehydrated durable thread through thread/resume's
1204
- // baseInstructions rather than replaying instructions as user text. A CONTINUE
1281
+ // Durable backends re-anchor a lost session with the complete current policy.
1282
+ // A CONTINUE
1205
1283
  // turn's per-call prompt is deliberately minimal (message-router
1206
1284
  // buildMinimalResumePrompt), so resuming with it would REPLACE the thread's full
1207
1285
  // policy with a stub - only freshSessionSystemPrompt rebuilds the complete one.
1208
1286
  // That rebuild costs an embedding search, so hand the backend a lazy builder it
1209
1287
  // invokes only inside the resume branch; a live thread never pays for it.
1210
1288
  const freshSystemPromptBuilder = options?.freshSessionSystemPrompt;
1211
- const resumeInstructions = isCodex && freshSystemPromptBuilder
1289
+ const resumeInstructions = isDurableRuntime && freshSystemPromptBuilder
1212
1290
  ? async () => prepareSystemPrompt(await freshSystemPromptBuilder(), false)
1213
1291
  : undefined;
1214
1292
  // Reset StopContinuation state for this channel to prevent leaking
@@ -1266,24 +1344,27 @@ class AgentLoop {
1266
1344
  };
1267
1345
  let piResult;
1268
1346
  // Claude: First turn → --session-id (inject system prompt), subsequent → --resume
1269
- // Codex: resumeSession only controls threadId reset (false=new thread, true=continue)
1270
- let shouldResume = isCodex
1347
+ // Codex/Cline: resumeSession controls durable session reset/continuation.
1348
+ let shouldResume = isDurableRuntime
1271
1349
  ? turn > 1 || (options?.freshSession === true ? false : (options?.resumeSession ?? true))
1272
1350
  : !sessionIsNew || turn > 1;
1273
1351
  let requestSystemPrompt = perCallSystemPrompt;
1274
- let provisionalCodexSessionId;
1275
- // Both Claude PersistentCLI and Codex app-server preserve context - only send new messages
1352
+ let provisionalDurableSessionId;
1353
+ // All three backends preserve context and receive only the new user message.
1276
1354
  const promptText = this.formatLastMessageOnly(history);
1277
1355
  const promptStart = Date.now();
1278
1356
  const throwFinalCliError = (error) => {
1279
1357
  const normalizedError = error instanceof Error ? error : new Error(String(error));
1358
+ const modelRunnerErrorCode = normalizedError instanceof model_runner_js_1.ModelRunnerError
1359
+ ? MODEL_RUNNER_AGENT_ERROR_CODES[normalizedError.code]
1360
+ : undefined;
1280
1361
  const errorType = normalizedError instanceof types_js_1.McpResultMissingError ||
1281
1362
  normalizedError instanceof types_js_1.McpCompletedMutationInterruptedError ||
1282
1363
  normalizedError instanceof types_js_1.ClaudeToolStreamProtocolError
1283
1364
  ? normalizedError.code
1284
1365
  : normalizedError instanceof model_runner_js_1.HostToolTerminalError
1285
1366
  ? normalizedError.terminalCode
1286
- : 'CLI_ERROR';
1367
+ : (modelRunnerErrorCode ?? 'CLI_ERROR');
1287
1368
  this.onMetric?.('prompt_error', 1, {
1288
1369
  backend: this.backend,
1289
1370
  error_type: errorType,
@@ -1297,12 +1378,15 @@ class AgentLoop {
1297
1378
  if (normalizedError instanceof model_runner_js_1.HostToolTerminalError) {
1298
1379
  throw new types_js_1.AgentError(normalizedError.message, normalizedError.terminalCode, normalizedError, false);
1299
1380
  }
1381
+ if (normalizedError instanceof model_runner_js_1.HostToolAbortError) {
1382
+ throw new types_js_1.AgentError(normalizedError.message, 'CLI_ERROR', normalizedError, false);
1383
+ }
1300
1384
  if (normalizedError instanceof types_js_1.McpResultMissingError ||
1301
1385
  normalizedError instanceof types_js_1.McpCompletedMutationInterruptedError ||
1302
1386
  normalizedError instanceof types_js_1.ClaudeToolStreamProtocolError) {
1303
1387
  throw new types_js_1.AgentError(normalizedError.message, normalizedError.code, normalizedError, false);
1304
1388
  }
1305
- throw new types_js_1.AgentError(`CLI error: ${normalizedError.message}`, 'CLI_ERROR', normalizedError, true);
1389
+ throw new types_js_1.AgentError(`CLI error: ${normalizedError.message}`, modelRunnerErrorCode ?? 'CLI_ERROR', normalizedError, normalizedError instanceof model_runner_js_1.ModelRunnerError ? normalizedError.retryable : true);
1306
1390
  };
1307
1391
  const appendCompletedToolExchanges = (exchanges) => {
1308
1392
  for (const exchange of exchanges) {
@@ -1322,7 +1406,7 @@ class AgentLoop {
1322
1406
  }
1323
1407
  };
1324
1408
  try {
1325
- const durablePolicyStatus = isCodex && turn === 1 && shouldResume
1409
+ const durablePolicyStatus = isDurableRuntime && turn === 1 && shouldResume
1326
1410
  ? this.agent.getSessionPolicyStatus?.({
1327
1411
  model: options?.model,
1328
1412
  resumeSession: true,
@@ -1332,15 +1416,23 @@ class AgentLoop {
1332
1416
  sessionId: resolvedCliSessionId ?? undefined,
1333
1417
  requestTimeout: options?.requestTimeoutMs,
1334
1418
  hostToolBridge,
1419
+ ...(isCline
1420
+ ? {
1421
+ allowedTools: clineAllowedTools,
1422
+ disallowedTools: clineDisallowedTools,
1423
+ allowSpawnAgent: clineAllowSpawnAgent,
1424
+ allowAgentTeams: clineAllowAgentTeams,
1425
+ }
1426
+ : {}),
1335
1427
  })
1336
1428
  : undefined;
1337
1429
  if (durablePolicyStatus === 'mismatch' || durablePolicyStatus === 'missing') {
1338
- console.log(`[AgentLoop] Codex durable session ${durablePolicyStatus}; ` +
1430
+ console.log(`[AgentLoop] ${this.backend} durable session ${durablePolicyStatus}; ` +
1339
1431
  'opening the full policy before model request');
1340
1432
  const newSessionId = this.sessionPool.resetSession(channelKey);
1341
1433
  options?.onCliSessionReset?.(newSessionId);
1342
1434
  resolvedCliSessionId = newSessionId;
1343
- provisionalCodexSessionId = newSessionId;
1435
+ provisionalDurableSessionId = newSessionId;
1344
1436
  try {
1345
1437
  if (options?.freshSessionSystemPrompt) {
1346
1438
  requestSystemPrompt = prepareSystemPrompt(await options.freshSessionSystemPrompt(), false);
@@ -1348,7 +1440,7 @@ class AgentLoop {
1348
1440
  }
1349
1441
  catch (rebuildError) {
1350
1442
  this.sessionPool.invalidateSession(channelKey, newSessionId);
1351
- provisionalCodexSessionId = undefined;
1443
+ provisionalDurableSessionId = undefined;
1352
1444
  attemptReportedError =
1353
1445
  rebuildError instanceof Error ? rebuildError : new Error(String(rebuildError));
1354
1446
  throw rebuildError;
@@ -1368,13 +1460,21 @@ class AgentLoop {
1368
1460
  requestTimeout: options?.requestTimeoutMs,
1369
1461
  hostToolBridge,
1370
1462
  toolExecutionContext,
1463
+ ...(isCline
1464
+ ? {
1465
+ allowedTools: clineAllowedTools,
1466
+ disallowedTools: clineDisallowedTools,
1467
+ allowSpawnAgent: clineAllowSpawnAgent,
1468
+ allowAgentTeams: clineAllowAgentTeams,
1469
+ }
1470
+ : {}),
1371
1471
  });
1372
- provisionalCodexSessionId = undefined;
1472
+ provisionalDurableSessionId = undefined;
1373
1473
  }
1374
1474
  catch (error) {
1375
- if (provisionalCodexSessionId) {
1376
- this.sessionPool.invalidateSession(channelKey, provisionalCodexSessionId);
1377
- provisionalCodexSessionId = undefined;
1475
+ if (provisionalDurableSessionId) {
1476
+ this.sessionPool.invalidateSession(channelKey, provisionalDurableSessionId);
1477
+ provisionalDurableSessionId = undefined;
1378
1478
  }
1379
1479
  const errorMessage = error instanceof Error ? error.message : String(error);
1380
1480
  console.error(`[AgentLoop] ${this.backend} CLI error:`, errorMessage);
@@ -1386,13 +1486,18 @@ class AgentLoop {
1386
1486
  appendCompletedToolExchanges(error.completedToolExchanges);
1387
1487
  throwFinalCliError(error);
1388
1488
  }
1489
+ if (error instanceof model_runner_js_1.HostToolAbortError && error.completedToolExchanges.length > 0) {
1490
+ appendCompletedToolExchanges(error.completedToolExchanges);
1491
+ throwFinalCliError(error);
1492
+ }
1389
1493
  // Check if this is a recoverable session error
1390
1494
  // 1. "No conversation found" - CLI session was lost (daemon restart, timeout)
1391
1495
  // 2. "Session ID already in use" - concurrent request conflict
1392
1496
  // 3. "Prompt is too long" - session context exceeded API limits
1393
1497
  const isSessionNotFound = errorMessage.includes('No conversation found with session ID');
1394
1498
  const isSessionInUse = errorMessage.includes('is already in use');
1395
- const isPromptTooLong = errorMessage.includes('Prompt is too long') ||
1499
+ const isPromptTooLong = (error instanceof model_runner_js_1.ModelRunnerError && error.code === 'context_overflow') ||
1500
+ errorMessage.includes('Prompt is too long') ||
1396
1501
  errorMessage.includes('prompt is too long') ||
1397
1502
  errorMessage.includes('request_too_large') ||
1398
1503
  errorMessage.includes('context window') ||
@@ -1423,16 +1528,16 @@ class AgentLoop {
1423
1528
  // Per-call routing: hand the new id to this prompt() and update the
1424
1529
  // resolved id so later turns follow it - no shared-adapter mutation.
1425
1530
  resolvedCliSessionId = newSessionId;
1426
- // A policy mismatch can occur on a resumed MessageRouter session,
1427
- // whose per-call prompt is intentionally minimal. Rebuild the full
1428
- // policy prompt before opening the replacement durable thread.
1531
+ // A recoverable durable-session error can occur on a resumed
1532
+ // MessageRouter session whose per-call prompt is intentionally minimal.
1533
+ // Rebuild the full policy before opening every replacement session.
1429
1534
  let resetSystemPrompt = perCallSystemPrompt;
1430
1535
  try {
1431
1536
  // Discard the recoverable first-attempt error before any reset
1432
1537
  // preparation. A prompt rebuild or retry failure must surface
1433
1538
  // its own final error, never the mismatch that triggered it.
1434
1539
  attemptReportedError = undefined;
1435
- if (isCodexPolicyMismatch && options?.freshSessionSystemPrompt) {
1540
+ if (options?.freshSessionSystemPrompt) {
1436
1541
  resetSystemPrompt = prepareSystemPrompt(await options.freshSessionSystemPrompt(), false);
1437
1542
  }
1438
1543
  piResult = await this.agent.prompt(promptText, callbacks, {
@@ -1446,6 +1551,14 @@ class AgentLoop {
1446
1551
  requestTimeout: options?.requestTimeoutMs,
1447
1552
  hostToolBridge,
1448
1553
  toolExecutionContext,
1554
+ ...(isCline
1555
+ ? {
1556
+ allowedTools: clineAllowedTools,
1557
+ disallowedTools: clineDisallowedTools,
1558
+ allowSpawnAgent: clineAllowSpawnAgent,
1559
+ allowAgentTeams: clineAllowAgentTeams,
1560
+ }
1561
+ : {}),
1449
1562
  });
1450
1563
  }
1451
1564
  catch (retryError) {
@@ -1483,7 +1596,7 @@ class AgentLoop {
1483
1596
  const contentBlocks = [];
1484
1597
  let parsedToolCalls = [];
1485
1598
  // Parse tool_call / code_act blocks from text response (Gateway Tools mode ONLY)
1486
- if (this.isGatewayMode && !isCodex) {
1599
+ if (this.isGatewayMode && !isDurableRuntime) {
1487
1600
  parsedToolCalls = this.parseToolCallsFromText(piResult.response || '');
1488
1601
  // Code-Act: parse ```js blocks only if enabled
1489
1602
  if (this.useCodeAct) {
@@ -1560,9 +1673,9 @@ class AgentLoop {
1560
1673
  // Ignore recording errors - never break the agent loop
1561
1674
  }
1562
1675
  }
1563
- // Track tokens in session pool for auto-reset at 80% context
1564
- const tokenBackend = this.backend === 'codex' ? 'codex' : 'claude';
1565
- const tokenStatus = this.sessionPool.updateTokens(channelKey, response.usage.input_tokens, tokenBackend);
1676
+ // Preserve the SessionPool usage-status contract. Billing telemetry is
1677
+ // recorded above; durable runtimes own model-aware compaction.
1678
+ const tokenStatus = this.sessionPool.updateTokens(channelKey, response.usage.input_tokens, this.backend);
1566
1679
  // Claude's MCP server may already have executed these tool calls while the
1567
1680
  // prompt was streaming. Preserve the observed exchange in conversation
1568
1681
  // order, but never put the completed tool_use back into executeTools().
@@ -1578,7 +1691,8 @@ class AgentLoop {
1578
1691
  if (piResult.terminalError) {
1579
1692
  throwFinalCliError(new model_runner_js_1.HostToolTerminalError(piResult.terminalError.code, piResult.terminalError.message));
1580
1693
  }
1581
- // PreCompact: inject compaction summary when approaching context limit
1694
+ // PreCompact remains available for a future authoritative occupancy
1695
+ // signal. Runtime-owned sessions do not infer one from usage telemetry.
1582
1696
  if (tokenStatus.nearThreshold && this.preCompactHandler && !runScope.preCompactInjected) {
1583
1697
  runScope.preCompactInjected = true;
1584
1698
  try {
@@ -1793,6 +1907,9 @@ class AgentLoop {
1793
1907
  ...(options?.sourceTurnId ? { sourceTurnId: options.sourceTurnId } : {}),
1794
1908
  ...(options?.sourceMessageRef ? { sourceMessageRef: options.sourceMessageRef } : {}),
1795
1909
  ...(resolvedCliSessionId ? { cliSessionId: resolvedCliSessionId } : {}),
1910
+ ...(options?.workorderAttemptId !== undefined
1911
+ ? { workorderAttemptId: options.workorderAttemptId }
1912
+ : {}),
1796
1913
  },
1797
1914
  };
1798
1915
  }
@@ -2003,6 +2120,7 @@ class AgentLoop {
2003
2120
  * Persistent CLI maintains context automatically, so we only send the new message
2004
2121
  */
2005
2122
  formatLastMessageOnly(history) {
2123
+ const imageReaderTool = this.backend === 'cline' ? 'read_files' : this.backend === 'codex' ? 'view_image' : 'Read';
2006
2124
  // Find the last user message in the history
2007
2125
  for (let i = history.length - 1; i >= 0; i--) {
2008
2126
  const msg = history[i];
@@ -2022,9 +2140,9 @@ class AgentLoop {
2022
2140
  else if (block.type === 'image' && block.localPath) {
2023
2141
  parts.push(`⚠️ CRITICAL: The user has uploaded an image file.\n` +
2024
2142
  `Image path: ${block.localPath}\n` +
2025
- `You MUST call the Read tool on "${block.localPath}" to view this image FIRST.\n` +
2143
+ `You MUST call the ${imageReaderTool} tool on "${block.localPath}" to view this image FIRST.\n` +
2026
2144
  `DO NOT describe or guess the image contents without reading it.\n` +
2027
- `DO NOT say you cannot read images - the Read tool supports image files.`);
2145
+ `DO NOT say you cannot read images - ${imageReaderTool} supports image files.`);
2028
2146
  }
2029
2147
  else if (block.type === 'image' && block.source?.data) {
2030
2148
  // Base64-encoded image — save to disk so persistent CLI can read it
@@ -2048,9 +2166,9 @@ class AgentLoop {
2048
2166
  fs.writeFileSync(imagePath, Buffer.from(block.source.data, 'base64'));
2049
2167
  parts.push(`⚠️ CRITICAL: The user has uploaded an image file.\n` +
2050
2168
  `Image path: ${imagePath}\n` +
2051
- `You MUST call the Read tool on "${imagePath}" to view this image FIRST.\n` +
2169
+ `You MUST call the ${imageReaderTool} tool on "${imagePath}" to view this image FIRST.\n` +
2052
2170
  `DO NOT describe or guess the image contents without reading it.\n` +
2053
- `DO NOT say you cannot read images - the Read tool supports image files.`);
2171
+ `DO NOT say you cannot read images - ${imageReaderTool} supports image files.`);
2054
2172
  }
2055
2173
  catch {
2056
2174
  parts.push('[Image attached but could not be processed]');