@geminixiang/mikan 1.0.0-beta.2 → 1.0.0-beta.20

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 (412) hide show
  1. package/CHANGELOG.md +354 -0
  2. package/README.md +42 -16
  3. package/dist/adapter.d.ts +1 -1
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js.map +1 -1
  6. package/dist/adapters/discord/bot.d.ts +1 -0
  7. package/dist/adapters/discord/bot.d.ts.map +1 -1
  8. package/dist/adapters/discord/bot.js +36 -67
  9. package/dist/adapters/discord/bot.js.map +1 -1
  10. package/dist/adapters/discord/context.d.ts.map +1 -1
  11. package/dist/adapters/discord/context.js +17 -42
  12. package/dist/adapters/discord/context.js.map +1 -1
  13. package/dist/adapters/github/bot.d.ts +148 -0
  14. package/dist/adapters/github/bot.d.ts.map +1 -0
  15. package/dist/adapters/github/bot.js +1031 -0
  16. package/dist/adapters/github/bot.js.map +1 -0
  17. package/dist/adapters/github/client.d.ts +118 -0
  18. package/dist/adapters/github/client.d.ts.map +1 -0
  19. package/dist/adapters/github/client.js +309 -0
  20. package/dist/adapters/github/client.js.map +1 -0
  21. package/dist/adapters/github/cloudbuild.d.ts +24 -0
  22. package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
  23. package/dist/adapters/github/cloudbuild.js +71 -0
  24. package/dist/adapters/github/cloudbuild.js.map +1 -0
  25. package/dist/adapters/github/context.d.ts +9 -0
  26. package/dist/adapters/github/context.d.ts.map +1 -0
  27. package/dist/adapters/github/context.js +175 -0
  28. package/dist/adapters/github/context.js.map +1 -0
  29. package/dist/adapters/github/gcp-auth.d.ts +31 -0
  30. package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
  31. package/dist/adapters/github/gcp-auth.js +196 -0
  32. package/dist/adapters/github/gcp-auth.js.map +1 -0
  33. package/dist/adapters/github/ids.d.ts +34 -0
  34. package/dist/adapters/github/ids.d.ts.map +1 -0
  35. package/dist/adapters/github/ids.js +53 -0
  36. package/dist/adapters/github/ids.js.map +1 -0
  37. package/dist/adapters/github/repo.d.ts +30 -0
  38. package/dist/adapters/github/repo.d.ts.map +1 -0
  39. package/dist/adapters/github/repo.js +136 -0
  40. package/dist/adapters/github/repo.js.map +1 -0
  41. package/dist/adapters/github/tool-pack.d.ts +14 -0
  42. package/dist/adapters/github/tool-pack.d.ts.map +1 -0
  43. package/dist/adapters/github/tool-pack.js +56 -0
  44. package/dist/adapters/github/tool-pack.js.map +1 -0
  45. package/dist/adapters/github/tools/checks.d.ts +24 -0
  46. package/dist/adapters/github/tools/checks.d.ts.map +1 -0
  47. package/dist/adapters/github/tools/checks.js +116 -0
  48. package/dist/adapters/github/tools/checks.js.map +1 -0
  49. package/dist/adapters/github/tools/issue.d.ts +22 -0
  50. package/dist/adapters/github/tools/issue.d.ts.map +1 -0
  51. package/dist/adapters/github/tools/issue.js +59 -0
  52. package/dist/adapters/github/tools/issue.js.map +1 -0
  53. package/dist/adapters/github/tools/pr.d.ts +22 -0
  54. package/dist/adapters/github/tools/pr.d.ts.map +1 -0
  55. package/dist/adapters/github/tools/pr.js +59 -0
  56. package/dist/adapters/github/tools/pr.js.map +1 -0
  57. package/dist/adapters/github/tools/read.d.ts +22 -0
  58. package/dist/adapters/github/tools/read.d.ts.map +1 -0
  59. package/dist/adapters/github/tools/read.js +152 -0
  60. package/dist/adapters/github/tools/read.js.map +1 -0
  61. package/dist/adapters/github/tools/review-reply.d.ts +19 -0
  62. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
  63. package/dist/adapters/github/tools/review-reply.js +49 -0
  64. package/dist/adapters/github/tools/review-reply.js.map +1 -0
  65. package/dist/adapters/github/tools/sync.d.ts +17 -0
  66. package/dist/adapters/github/tools/sync.d.ts.map +1 -0
  67. package/dist/adapters/github/tools/sync.js +45 -0
  68. package/dist/adapters/github/tools/sync.js.map +1 -0
  69. package/dist/adapters/github/types.d.ts +350 -0
  70. package/dist/adapters/github/types.d.ts.map +1 -0
  71. package/dist/adapters/github/types.js +2 -0
  72. package/dist/adapters/github/types.js.map +1 -0
  73. package/dist/adapters/intake.d.ts +16 -5
  74. package/dist/adapters/intake.d.ts.map +1 -1
  75. package/dist/adapters/intake.js +79 -22
  76. package/dist/adapters/intake.js.map +1 -1
  77. package/dist/adapters/slack/bot.d.ts +8 -6
  78. package/dist/adapters/slack/bot.d.ts.map +1 -1
  79. package/dist/adapters/slack/bot.js +81 -133
  80. package/dist/adapters/slack/bot.js.map +1 -1
  81. package/dist/adapters/slack/context.d.ts.map +1 -1
  82. package/dist/adapters/slack/context.js +3 -14
  83. package/dist/adapters/slack/context.js.map +1 -1
  84. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  85. package/dist/adapters/slack/response-lifecycle.js +14 -17
  86. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  87. package/dist/adapters/slack/session.d.ts.map +1 -1
  88. package/dist/adapters/slack/session.js +5 -8
  89. package/dist/adapters/slack/session.js.map +1 -1
  90. package/dist/adapters/streaming.d.ts +4 -0
  91. package/dist/adapters/streaming.d.ts.map +1 -1
  92. package/dist/adapters/streaming.js +11 -0
  93. package/dist/adapters/streaming.js.map +1 -1
  94. package/dist/adapters/telegram/bot.d.ts +1 -2
  95. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  96. package/dist/adapters/telegram/bot.js +27 -62
  97. package/dist/adapters/telegram/bot.js.map +1 -1
  98. package/dist/adapters/telegram/context.d.ts.map +1 -1
  99. package/dist/adapters/telegram/context.js +8 -27
  100. package/dist/adapters/telegram/context.js.map +1 -1
  101. package/dist/adapters/types.d.ts +28 -2
  102. package/dist/adapters/types.d.ts.map +1 -1
  103. package/dist/adapters/types.js.map +1 -1
  104. package/dist/agent.d.ts +38 -14
  105. package/dist/agent.d.ts.map +1 -1
  106. package/dist/agent.js +358 -224
  107. package/dist/agent.js.map +1 -1
  108. package/dist/cli/download.d.ts.map +1 -0
  109. package/dist/cli/download.js.map +1 -0
  110. package/dist/cli/ext-git.d.ts +22 -0
  111. package/dist/cli/ext-git.d.ts.map +1 -0
  112. package/dist/cli/ext-git.js +76 -0
  113. package/dist/cli/ext-git.js.map +1 -0
  114. package/dist/cli/ext.d.ts +2 -0
  115. package/dist/cli/ext.d.ts.map +1 -0
  116. package/dist/cli/ext.js +217 -0
  117. package/dist/cli/ext.js.map +1 -0
  118. package/dist/commands/admin.d.ts.map +1 -1
  119. package/dist/commands/admin.js +2 -1
  120. package/dist/commands/admin.js.map +1 -1
  121. package/dist/commands/auto-reply.d.ts.map +1 -1
  122. package/dist/commands/auto-reply.js +2 -6
  123. package/dist/commands/auto-reply.js.map +1 -1
  124. package/dist/commands/extensions.d.ts.map +1 -1
  125. package/dist/commands/extensions.js +16 -6
  126. package/dist/commands/extensions.js.map +1 -1
  127. package/dist/commands/login.d.ts +2 -1
  128. package/dist/commands/login.d.ts.map +1 -1
  129. package/dist/commands/login.js +30 -1
  130. package/dist/commands/login.js.map +1 -1
  131. package/dist/commands/manifest.d.ts +72 -0
  132. package/dist/commands/manifest.d.ts.map +1 -0
  133. package/dist/commands/manifest.js +121 -0
  134. package/dist/commands/manifest.js.map +1 -0
  135. package/dist/commands/model.d.ts.map +1 -1
  136. package/dist/commands/model.js +3 -1
  137. package/dist/commands/model.js.map +1 -1
  138. package/dist/commands/new.d.ts.map +1 -1
  139. package/dist/commands/new.js +2 -1
  140. package/dist/commands/new.js.map +1 -1
  141. package/dist/commands/sandbox.d.ts.map +1 -1
  142. package/dist/commands/sandbox.js +16 -12
  143. package/dist/commands/sandbox.js.map +1 -1
  144. package/dist/commands/text.d.ts +2 -0
  145. package/dist/commands/text.d.ts.map +1 -0
  146. package/dist/commands/text.js +16 -0
  147. package/dist/commands/text.js.map +1 -0
  148. package/dist/commands/types.d.ts +14 -1
  149. package/dist/commands/types.d.ts.map +1 -1
  150. package/dist/commands/types.js.map +1 -1
  151. package/dist/config.d.ts +1 -1
  152. package/dist/config.d.ts.map +1 -1
  153. package/dist/config.js +90 -54
  154. package/dist/config.js.map +1 -1
  155. package/dist/events.d.ts +10 -0
  156. package/dist/events.d.ts.map +1 -1
  157. package/dist/events.js +14 -5
  158. package/dist/events.js.map +1 -1
  159. package/dist/execution-resolver.d.ts +3 -2
  160. package/dist/execution-resolver.d.ts.map +1 -1
  161. package/dist/execution-resolver.js +28 -12
  162. package/dist/execution-resolver.js.map +1 -1
  163. package/dist/harness/extensions/loader.d.ts +39 -9
  164. package/dist/harness/extensions/loader.d.ts.map +1 -1
  165. package/dist/harness/extensions/loader.js +258 -54
  166. package/dist/harness/extensions/loader.js.map +1 -1
  167. package/dist/harness/extensions/registry.d.ts +48 -1
  168. package/dist/harness/extensions/registry.d.ts.map +1 -1
  169. package/dist/harness/extensions/registry.js +146 -0
  170. package/dist/harness/extensions/registry.js.map +1 -1
  171. package/dist/harness/extensions/types.d.ts +161 -14
  172. package/dist/harness/extensions/types.d.ts.map +1 -1
  173. package/dist/harness/extensions/types.js.map +1 -1
  174. package/dist/harness/index.d.ts +5 -5
  175. package/dist/harness/index.d.ts.map +1 -1
  176. package/dist/harness/index.js +2 -2
  177. package/dist/harness/index.js.map +1 -1
  178. package/dist/harness/models.d.ts +5 -0
  179. package/dist/harness/models.d.ts.map +1 -1
  180. package/dist/harness/models.js +10 -0
  181. package/dist/harness/models.js.map +1 -1
  182. package/dist/harness/runner.d.ts +21 -2
  183. package/dist/harness/runner.d.ts.map +1 -1
  184. package/dist/harness/runner.js +80 -22
  185. package/dist/harness/runner.js.map +1 -1
  186. package/dist/harness/session-store.d.ts +4 -1
  187. package/dist/harness/session-store.d.ts.map +1 -1
  188. package/dist/harness/session-store.js +11 -2
  189. package/dist/harness/session-store.js.map +1 -1
  190. package/dist/harness/subagent-runner.d.ts +17 -0
  191. package/dist/harness/subagent-runner.d.ts.map +1 -0
  192. package/dist/harness/subagent-runner.js +307 -0
  193. package/dist/harness/subagent-runner.js.map +1 -0
  194. package/dist/harness/types.d.ts +53 -0
  195. package/dist/harness/types.d.ts.map +1 -1
  196. package/dist/harness/types.js.map +1 -1
  197. package/dist/index.d.ts +1 -1
  198. package/dist/index.d.ts.map +1 -1
  199. package/dist/index.js.map +1 -1
  200. package/dist/main.js +232 -29
  201. package/dist/main.js.map +1 -1
  202. package/dist/provisioner.d.ts.map +1 -1
  203. package/dist/provisioner.js +2 -5
  204. package/dist/provisioner.js.map +1 -1
  205. package/dist/runtime/conversation-runtime.d.ts +1 -1
  206. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  207. package/dist/runtime/conversation-runtime.js +264 -41
  208. package/dist/runtime/conversation-runtime.js.map +1 -1
  209. package/dist/runtime/types.d.ts +32 -5
  210. package/dist/runtime/types.d.ts.map +1 -1
  211. package/dist/runtime/types.js.map +1 -1
  212. package/dist/sandbox/cloudflare.d.ts +2 -0
  213. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  214. package/dist/sandbox/cloudflare.js +7 -0
  215. package/dist/sandbox/cloudflare.js.map +1 -1
  216. package/dist/sandbox/container.d.ts +3 -0
  217. package/dist/sandbox/container.d.ts.map +1 -1
  218. package/dist/sandbox/container.js +8 -2
  219. package/dist/sandbox/container.js.map +1 -1
  220. package/dist/sandbox/firecracker.d.ts +2 -0
  221. package/dist/sandbox/firecracker.d.ts.map +1 -1
  222. package/dist/sandbox/firecracker.js +7 -1
  223. package/dist/sandbox/firecracker.js.map +1 -1
  224. package/dist/sandbox/gondolin-fleet.d.ts +104 -0
  225. package/dist/sandbox/gondolin-fleet.d.ts.map +1 -0
  226. package/dist/sandbox/gondolin-fleet.js +330 -0
  227. package/dist/sandbox/gondolin-fleet.js.map +1 -0
  228. package/dist/sandbox/gondolin-gateway.d.ts +85 -0
  229. package/dist/sandbox/gondolin-gateway.d.ts.map +1 -0
  230. package/dist/sandbox/gondolin-gateway.js +400 -0
  231. package/dist/sandbox/gondolin-gateway.js.map +1 -0
  232. package/dist/sandbox/gondolin-inventory.d.ts +89 -0
  233. package/dist/sandbox/gondolin-inventory.d.ts.map +1 -0
  234. package/dist/sandbox/gondolin-inventory.js +267 -0
  235. package/dist/sandbox/gondolin-inventory.js.map +1 -0
  236. package/dist/sandbox/gondolin-join.d.ts +62 -0
  237. package/dist/sandbox/gondolin-join.d.ts.map +1 -0
  238. package/dist/sandbox/gondolin-join.js +261 -0
  239. package/dist/sandbox/gondolin-join.js.map +1 -0
  240. package/dist/sandbox/gondolin-nfs-advisory.d.ts +15 -0
  241. package/dist/sandbox/gondolin-nfs-advisory.d.ts.map +1 -0
  242. package/dist/sandbox/gondolin-nfs-advisory.js +60 -0
  243. package/dist/sandbox/gondolin-nfs-advisory.js.map +1 -0
  244. package/dist/sandbox/gondolin-placement.d.ts +32 -0
  245. package/dist/sandbox/gondolin-placement.d.ts.map +1 -0
  246. package/dist/sandbox/gondolin-placement.js +83 -0
  247. package/dist/sandbox/gondolin-placement.js.map +1 -0
  248. package/dist/sandbox/gondolin-remote.d.ts +73 -0
  249. package/dist/sandbox/gondolin-remote.d.ts.map +1 -0
  250. package/dist/sandbox/gondolin-remote.js +352 -0
  251. package/dist/sandbox/gondolin-remote.js.map +1 -0
  252. package/dist/sandbox/gondolin-worker-client.d.ts +139 -0
  253. package/dist/sandbox/gondolin-worker-client.d.ts.map +1 -0
  254. package/dist/sandbox/gondolin-worker-client.js +325 -0
  255. package/dist/sandbox/gondolin-worker-client.js.map +1 -0
  256. package/dist/sandbox/gondolin-worker-main.d.ts +2 -0
  257. package/dist/sandbox/gondolin-worker-main.d.ts.map +1 -0
  258. package/dist/sandbox/gondolin-worker-main.js +22 -0
  259. package/dist/sandbox/gondolin-worker-main.js.map +1 -0
  260. package/dist/sandbox/gondolin-worker.d.ts +55 -0
  261. package/dist/sandbox/gondolin-worker.d.ts.map +1 -0
  262. package/dist/sandbox/gondolin-worker.js +201 -0
  263. package/dist/sandbox/gondolin-worker.js.map +1 -0
  264. package/dist/sandbox/gondolin.d.ts +52 -0
  265. package/dist/sandbox/gondolin.d.ts.map +1 -0
  266. package/dist/sandbox/gondolin.js +425 -0
  267. package/dist/sandbox/gondolin.js.map +1 -0
  268. package/dist/sandbox/host.d.ts +2 -0
  269. package/dist/sandbox/host.d.ts.map +1 -1
  270. package/dist/sandbox/host.js +11 -0
  271. package/dist/sandbox/host.js.map +1 -1
  272. package/dist/sandbox/identity.d.ts +21 -0
  273. package/dist/sandbox/identity.d.ts.map +1 -0
  274. package/dist/sandbox/identity.js +36 -0
  275. package/dist/sandbox/identity.js.map +1 -0
  276. package/dist/sandbox/index.d.ts +4 -3
  277. package/dist/sandbox/index.d.ts.map +1 -1
  278. package/dist/sandbox/index.js +5 -3
  279. package/dist/sandbox/index.js.map +1 -1
  280. package/dist/sandbox/types.d.ts +26 -1
  281. package/dist/sandbox/types.d.ts.map +1 -1
  282. package/dist/sandbox/types.js.map +1 -1
  283. package/dist/sandbox/utils.d.ts +11 -0
  284. package/dist/sandbox/utils.d.ts.map +1 -1
  285. package/dist/sandbox/utils.js +35 -0
  286. package/dist/sandbox/utils.js.map +1 -1
  287. package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -1
  288. package/dist/sessions/agent-memory-file-manager.js +16 -30
  289. package/dist/sessions/agent-memory-file-manager.js.map +1 -1
  290. package/dist/sessions/history-line.d.ts +20 -0
  291. package/dist/sessions/history-line.d.ts.map +1 -0
  292. package/dist/sessions/history-line.js +24 -0
  293. package/dist/sessions/history-line.js.map +1 -0
  294. package/dist/sessions/policy.d.ts.map +1 -1
  295. package/dist/sessions/policy.js +5 -3
  296. package/dist/sessions/policy.js.map +1 -1
  297. package/dist/sessions/session-key.d.ts +31 -0
  298. package/dist/sessions/session-key.d.ts.map +1 -0
  299. package/dist/sessions/session-key.js +44 -0
  300. package/dist/sessions/session-key.js.map +1 -0
  301. package/dist/sessions/store.d.ts.map +1 -1
  302. package/dist/sessions/store.js +2 -2
  303. package/dist/sessions/store.js.map +1 -1
  304. package/dist/tools/bash.d.ts +3 -1
  305. package/dist/tools/bash.d.ts.map +1 -1
  306. package/dist/tools/bash.js +24 -17
  307. package/dist/tools/bash.js.map +1 -1
  308. package/dist/tools/edit.d.ts.map +1 -1
  309. package/dist/tools/edit.js +9 -12
  310. package/dist/tools/edit.js.map +1 -1
  311. package/dist/tools/event.d.ts +1 -1
  312. package/dist/tools/event.d.ts.map +1 -1
  313. package/dist/tools/event.js +33 -4
  314. package/dist/tools/event.js.map +1 -1
  315. package/dist/tools/generate-image.d.ts +17 -0
  316. package/dist/tools/generate-image.d.ts.map +1 -0
  317. package/dist/tools/generate-image.js +63 -0
  318. package/dist/tools/generate-image.js.map +1 -0
  319. package/dist/tools/index.d.ts +16 -2
  320. package/dist/tools/index.d.ts.map +1 -1
  321. package/dist/tools/index.js +27 -3
  322. package/dist/tools/index.js.map +1 -1
  323. package/dist/tools/react.d.ts +15 -0
  324. package/dist/tools/react.d.ts.map +1 -0
  325. package/dist/tools/react.js +40 -0
  326. package/dist/tools/react.js.map +1 -0
  327. package/dist/tools/sandbox.d.ts +2 -2
  328. package/dist/tools/sandbox.d.ts.map +1 -1
  329. package/dist/tools/sandbox.js +8 -7
  330. package/dist/tools/sandbox.js.map +1 -1
  331. package/dist/tools/subagent.d.ts +69 -0
  332. package/dist/tools/subagent.d.ts.map +1 -0
  333. package/dist/tools/subagent.js +286 -0
  334. package/dist/tools/subagent.js.map +1 -0
  335. package/dist/tools/types.d.ts +34 -1
  336. package/dist/tools/types.d.ts.map +1 -1
  337. package/dist/tools/types.js.map +1 -1
  338. package/dist/tools/write.d.ts.map +1 -1
  339. package/dist/tools/write.js +1 -8
  340. package/dist/tools/write.js.map +1 -1
  341. package/dist/trigger.d.ts.map +1 -1
  342. package/dist/trigger.js +1 -2
  343. package/dist/trigger.js.map +1 -1
  344. package/dist/types.d.ts +139 -7
  345. package/dist/types.d.ts.map +1 -1
  346. package/dist/types.js.map +1 -1
  347. package/dist/vault/disabled.d.ts +9 -0
  348. package/dist/vault/disabled.d.ts.map +1 -0
  349. package/dist/vault/disabled.js +23 -0
  350. package/dist/vault/disabled.js.map +1 -0
  351. package/dist/vault/index.d.ts.map +1 -1
  352. package/dist/vault/index.js +3 -24
  353. package/dist/vault/index.js.map +1 -1
  354. package/dist/vault/policy.d.ts +20 -0
  355. package/dist/vault/policy.d.ts.map +1 -0
  356. package/dist/vault/policy.js +20 -0
  357. package/dist/vault/policy.js.map +1 -0
  358. package/dist/vault/routing.d.ts +1 -0
  359. package/dist/vault/routing.d.ts.map +1 -1
  360. package/dist/vault/routing.js +3 -10
  361. package/dist/vault/routing.js.map +1 -1
  362. package/dist/web/admin/portal.d.ts +27 -0
  363. package/dist/web/admin/portal.d.ts.map +1 -1
  364. package/dist/web/admin/portal.js +91 -130
  365. package/dist/web/admin/portal.js.map +1 -1
  366. package/dist/web/admin/types.d.ts +3 -0
  367. package/dist/web/admin/types.d.ts.map +1 -1
  368. package/dist/web/admin/types.js.map +1 -1
  369. package/dist/web/login/oauth.d.ts +2 -3
  370. package/dist/web/login/oauth.d.ts.map +1 -1
  371. package/dist/web/login/oauth.js +0 -31
  372. package/dist/web/login/oauth.js.map +1 -1
  373. package/dist/web/login/portal.js +1 -1
  374. package/dist/web/login/portal.js.map +1 -1
  375. package/dist/web/login/types.d.ts +0 -11
  376. package/dist/web/login/types.d.ts.map +1 -1
  377. package/dist/web/login/types.js.map +1 -1
  378. package/dist/web/portal-shell.d.ts +4 -0
  379. package/dist/web/portal-shell.d.ts.map +1 -0
  380. package/dist/{portal-shell.js → web/portal-shell.js} +2 -2
  381. package/dist/web/portal-shell.js.map +1 -0
  382. package/dist/web/server.d.ts.map +1 -1
  383. package/dist/web/server.js +7 -0
  384. package/dist/web/server.js.map +1 -1
  385. package/dist/web/session-view/command.d.ts.map +1 -1
  386. package/dist/web/session-view/command.js +4 -1
  387. package/dist/web/session-view/command.js.map +1 -1
  388. package/dist/web/session-view/portal.d.ts.map +1 -1
  389. package/dist/web/session-view/portal.js +4 -3
  390. package/dist/web/session-view/portal.js.map +1 -1
  391. package/dist/web/session-view/service.d.ts.map +1 -1
  392. package/dist/web/session-view/service.js +2 -1
  393. package/dist/web/session-view/service.js.map +1 -1
  394. package/dist/web/session-view/types.d.ts +2 -1
  395. package/dist/web/session-view/types.d.ts.map +1 -1
  396. package/dist/web/session-view/types.js.map +1 -1
  397. package/package.json +7 -4
  398. package/dist/download.d.ts.map +0 -1
  399. package/dist/download.js.map +0 -1
  400. package/dist/model-registry.d.ts +0 -4
  401. package/dist/model-registry.d.ts.map +0 -1
  402. package/dist/model-registry.js +0 -7
  403. package/dist/model-registry.js.map +0 -1
  404. package/dist/portal-shell.d.ts +0 -4
  405. package/dist/portal-shell.d.ts.map +0 -1
  406. package/dist/portal-shell.js.map +0 -1
  407. package/dist/runtime/agent-run-controller.d.ts +0 -31
  408. package/dist/runtime/agent-run-controller.d.ts.map +0 -1
  409. package/dist/runtime/agent-run-controller.js +0 -195
  410. package/dist/runtime/agent-run-controller.js.map +0 -1
  411. /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
  412. /package/dist/{download.js → cli/download.js} +0 -0
package/dist/agent.js CHANGED
@@ -1,24 +1,43 @@
1
- import { DEFAULT_EVENT_BUDGET, defaultExtensionDirs, formatSkillsForPrompt, loadExtensions, loadSkillsFromDir, MikanAgentSession, MikanModels, } from "./harness/index.js";
1
+ /**
2
+ * Agent runner: prompt construction, path translation, run lifecycle, and createRunner.
3
+ * Single module — do not split helpers that only this file uses.
4
+ */
5
+ import { DEFAULT_EVENT_BUDGET, defaultExtensionDirs, formatSkillsForPrompt, loadExtensions, loadSkillsFromDir, MikanAgentSession, MikanModels, parseCommandInput, } from "./harness/index.js";
6
+ import { runSubagent } from "./harness/subagent-runner.js";
2
7
  import { createHash } from "crypto";
3
8
  import { existsSync, readFileSync } from "fs";
4
- import { mkdir, readFile, writeFile } from "fs/promises";
9
+ import { mkdir, readFile } from "fs/promises";
5
10
  import { join, posix } from "path";
6
11
  import { resolveConversationSettings } from "./config.js";
7
12
  import { readEnv } from "./utils/env.js";
8
13
  import { ActorExecutionResolver } from "./execution-resolver.js";
9
14
  import * as log from "./log.js";
10
- import { reportUserFacingError } from "./observability/sentry.js";
11
15
  import { createExecutor, } from "./sandbox/index.js";
12
16
  import { createMountedRuntimePathContext } from "./sandbox/path-context.js";
13
- import { addLifecycleBreadcrumb, metricAttributes, updateActiveSpanAttribution, } from "./observability/sentry.js";
17
+ import { addLifecycleBreadcrumb, metricAttributes, reportUserFacingError, updateActiveSpanAttribution, } from "./observability/sentry.js";
14
18
  import { AgentMemoryFileManager } from "./sessions/agent-memory-file-manager.js";
19
+ import { formatHistoryLine } from "./sessions/history-line.js";
20
+ import { conversationIdOf, isThreadSessionKey } from "./sessions/session-key.js";
15
21
  import { extractSessionUuid, openManagedSession, } from "./sessions/store.js";
16
22
  import { HostEventStore } from "./tools/event.js";
17
- import { createMikanTools } from "./tools/index.js";
23
+ import { createMikanTools, createSubagentTool } from "./tools/index.js";
18
24
  import * as Sentry from "@sentry/node";
19
- import { formatLocalTimestamp } from "./utils/date.js";
20
- import { resolveConfiguredModel } from "./model-registry.js";
21
25
  import { emitAgentEvent } from "./agent-events.js";
26
+ export function getUnresolvedSandboxPathContext(sandboxConfig, hostWorkspaceRoot) {
27
+ if (sandboxConfig.type === "image") {
28
+ return createMountedRuntimePathContext(hostWorkspaceRoot, "/workspace");
29
+ }
30
+ return createExecutor(sandboxConfig).getPathContext(hostWorkspaceRoot);
31
+ }
32
+ export function translateRuntimePathToHost(runtimePath, pathContext) {
33
+ return pathContext.runtimeToHostPath?.(runtimePath) ?? runtimePath;
34
+ }
35
+ export function translateAttachPathToHost(filePath, pathContext) {
36
+ const runtimePath = posix.isAbsolute(filePath)
37
+ ? filePath
38
+ : posix.join(pathContext.runtimeWorkspaceRoot, filePath);
39
+ return translateRuntimePathToHost(runtimePath, pathContext);
40
+ }
22
41
  const IMAGE_MIME_TYPES = {
23
42
  jpg: "image/jpeg",
24
43
  jpeg: "image/jpeg",
@@ -29,12 +48,46 @@ const IMAGE_MIME_TYPES = {
29
48
  function getImageMimeType(filename) {
30
49
  return IMAGE_MIME_TYPES[filename.toLowerCase().split(".").pop() || ""];
31
50
  }
32
- function buildThreadSessionName(message) {
33
- const text = message?.text?.trim();
34
- if (!text)
35
- return undefined;
36
- const userLabel = message?.userName || message?.user || "unknown";
37
- return `[${userLabel}]: ${text}`;
51
+ function formatTimestampedUserMessage(message) {
52
+ return formatHistoryLine({
53
+ date: new Date(),
54
+ userName: message.userName,
55
+ threadTs: message.threadTs,
56
+ text: message.text,
57
+ });
58
+ }
59
+ function collectMessageAttachments(message, workspacePath, pathContext) {
60
+ const imageAttachments = [];
61
+ const nonImagePaths = [];
62
+ for (const attachment of message.attachments || []) {
63
+ const runtimePath = `${workspacePath}/${attachment.localPath}`;
64
+ const hostPath = pathContext?.runtimeToHostPath?.(runtimePath) ?? runtimePath;
65
+ const mimeType = getImageMimeType(attachment.localPath);
66
+ if (mimeType && existsSync(hostPath)) {
67
+ try {
68
+ imageAttachments.push({
69
+ type: "image",
70
+ mimeType,
71
+ data: readFileSync(hostPath).toString("base64"),
72
+ });
73
+ }
74
+ catch {
75
+ nonImagePaths.push(runtimePath);
76
+ }
77
+ }
78
+ else {
79
+ nonImagePaths.push(runtimePath);
80
+ }
81
+ }
82
+ return { imageAttachments, nonImagePaths };
83
+ }
84
+ export function buildPromptPayload(message, workspacePath, pathContext) {
85
+ let userMessage = formatTimestampedUserMessage(message);
86
+ const { imageAttachments, nonImagePaths } = collectMessageAttachments(message, workspacePath, pathContext);
87
+ if (nonImagePaths.length > 0) {
88
+ userMessage += `\n\n<slack_attachments>\n${nonImagePaths.join("\n")}\n</slack_attachments>`;
89
+ }
90
+ return { userMessage, imageAttachments };
38
91
  }
39
92
  async function getMemory(conversationDir) {
40
93
  const parts = [];
@@ -329,81 +382,21 @@ Do not add this to \`[SILENT]\` responses.`);
329
382
  }
330
383
  return parts.join("\n\n");
331
384
  }
332
- export function getUnresolvedSandboxPathContext(sandboxConfig, hostWorkspaceRoot) {
333
- if (sandboxConfig.type === "image") {
334
- return createMountedRuntimePathContext(hostWorkspaceRoot, "/workspace");
335
- }
336
- return createExecutor(sandboxConfig).getPathContext(hostWorkspaceRoot);
337
- }
338
- function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspaceDir, hostWorkspacePath) {
339
- const executionResolver = vaultManager && sandboxConfig.type !== "host"
340
- ? new ActorExecutionResolver(sandboxConfig, vaultManager, provisioner, workspaceDir)
341
- : undefined;
342
- // activeExecutor is replaced at the start of each run() call when executionResolver
343
- // is present, so the stable `executor` wrapper always delegates to the latest resolved value.
344
- let activeExecutor = executionResolver !== undefined
345
- ? createExecutor({ type: "host" })
346
- : createExecutor(sandboxConfig);
347
- const executor = {
348
- exec(command, options) {
349
- return activeExecutor.exec(command, options);
350
- },
351
- getWorkspacePath(hostPath) {
352
- return activeExecutor.getWorkspacePath(hostPath);
353
- },
354
- getSandboxConfig() {
355
- return activeExecutor.getSandboxConfig();
356
- },
357
- getPathContext(hostWorkspaceRoot) {
358
- return activeExecutor.getPathContext(hostWorkspaceRoot);
359
- },
360
- };
361
- return {
362
- executionResolver,
363
- executor,
364
- getPathContext: () => executor.getPathContext(hostWorkspacePath),
365
- async resolveExecutorForRun(context) {
366
- if (!executionResolver)
367
- return;
368
- activeExecutor = await executionResolver.resolve(context);
369
- },
370
- };
371
- }
372
- /**
373
- * Extension host services over mikan's runtime infrastructure: schedules
374
- * become event files under `<workspaceDir>/events` (picked up live by
375
- * EventsWatcher), secrets come from `vaults/extensions/<slug>/env`, and
376
- * notify posts through the platform bots when main.ts provides a notifier.
377
- */
378
- function buildExtensionHostServices(params) {
379
- const { workspaceDir, vaultManager, platformNotifier } = params;
380
- const eventStore = HostEventStore.fromWorkspaceDir(workspaceDir);
381
- return {
382
- stateDir: readEnv("STATE_DIR"),
383
- scheduleStore: {
384
- write: async (filename, payload) => {
385
- // Event files tolerate a missing platform (single-platform default),
386
- // so the harness payload is a valid event payload as written.
387
- await eventStore.write(filename, payload);
388
- },
389
- delete: async (filename) => (await eventStore.delete(filename)).deleted,
390
- list: async () => (await eventStore.list()).map((entry) => ({
391
- filename: entry.filename,
392
- payload: entry.payload,
393
- })),
394
- },
395
- ...(platformNotifier ? { postMessage: platformNotifier } : {}),
396
- ...(vaultManager
397
- ? {
398
- resolveSecrets: (slug) => vaultManager.resolve(`extensions/${slug}`)?.env ?? {},
399
- }
400
- : {}),
401
- };
385
+ export function appendTriggerAttribution(text, triggerAttribution, sessionLink) {
386
+ if (!triggerAttribution)
387
+ return text;
388
+ const trimmed = text.trimEnd();
389
+ const legacySuffix = `_Triggered by ${triggerAttribution}_`;
390
+ // Slack mrkdwn italics cannot span a URL — a `_..._` wrapping a link renders
391
+ // the underscores literally. Keep the session link outside the italic span.
392
+ const suffix = sessionLink ? `${legacySuffix} · session: ${sessionLink}` : legacySuffix;
393
+ if (trimmed.endsWith(suffix))
394
+ return text;
395
+ const body = trimmed.endsWith(legacySuffix)
396
+ ? trimmed.slice(0, -legacySuffix.length).trimEnd()
397
+ : trimmed;
398
+ return `${body}\n\n${suffix}`;
402
399
  }
403
- /**
404
- * Local (workspace/conversation) skills override extension skills on name
405
- * collision: an admin's on-disk skill always beats an extension's.
406
- */
407
400
  function mergeExtensionSkills(local, extension) {
408
401
  if (extension.length === 0)
409
402
  return local;
@@ -414,37 +407,6 @@ function mergeExtensionSkills(local, extension) {
414
407
  byName.set(skill.name, skill);
415
408
  return [...byName.values()];
416
409
  }
417
- async function createConfiguredAgentSession(params) {
418
- const { conversationId, workspaceDir, systemPrompt, model, thinkingLevel, tools, sessionStore, models, vaultManager, platformNotifier, } = params;
419
- // Host-only dirs under the state dir: extension code runs in the mikan
420
- // process, so it must never load from workspace paths — those are mounted
421
- // into sandbox containers and agent-writable (sandbox escape otherwise).
422
- const extensionsResult = await loadExtensions({
423
- dirs: defaultExtensionDirs(conversationId, readEnv("STATE_DIR")),
424
- context: { conversationId, workspaceDir, model, thinkingLevel },
425
- services: buildExtensionHostServices({ workspaceDir, vaultManager, platformNotifier }),
426
- });
427
- for (const err of extensionsResult.errors) {
428
- log.logWarning(`[${conversationId}] Extension load error: ${err.path}`, err.error);
429
- }
430
- if (extensionsResult.extensions.length > 0) {
431
- log.logInfo(`[${conversationId}] Loaded ${extensionsResult.extensions.length} extension(s): ${extensionsResult.extensions.map((extension) => extension.name).join(", ")}`);
432
- }
433
- const session = new MikanAgentSession({
434
- systemPrompt,
435
- model,
436
- thinkingLevel,
437
- tools,
438
- models,
439
- sessionStore,
440
- extensions: extensionsResult.registry,
441
- });
442
- const reloaded = session.reloadFromSession();
443
- if (reloaded > 0) {
444
- log.logInfo(`[${conversationId}] Reloaded ${reloaded} messages from session context`);
445
- }
446
- return { session, extensionSkills: extensionsResult.skills };
447
- }
448
410
  function createEmptyUsageTotals() {
449
411
  return {
450
412
  input: 0,
@@ -461,6 +423,7 @@ function createRunState() {
461
423
  queue: null,
462
424
  pendingTools: new Map(),
463
425
  toolProgress: new Map(),
426
+ toolProgressTimer: undefined,
464
427
  totalUsage: createEmptyUsageTotals(),
465
428
  llmCallCount: 0,
466
429
  stopReason: "stop",
@@ -480,6 +443,9 @@ function resetRunState(runState, responder, sessionConversation, userName, sessi
480
443
  };
481
444
  runState.pendingTools.clear();
482
445
  runState.toolProgress.clear();
446
+ if (runState.toolProgressTimer)
447
+ clearTimeout(runState.toolProgressTimer);
448
+ runState.toolProgressTimer = undefined;
483
449
  runState.totalUsage = createEmptyUsageTotals();
484
450
  runState.llmCallCount = 0;
485
451
  runState.stopReason = "stop";
@@ -515,53 +481,6 @@ function createRunQueue(responder, runState) {
515
481
  wait: () => queueChain,
516
482
  };
517
483
  }
518
- function formatTimestampedUserMessage(message) {
519
- const timestamp = formatLocalTimestamp(new Date());
520
- const threadContext = message.threadTs ? ` [in-thread:${message.threadTs}]` : "";
521
- return `[${timestamp}] [${message.userName || "unknown"}]${threadContext}: ${message.text}`;
522
- }
523
- function collectMessageAttachments(message, workspacePath, pathContext) {
524
- const imageAttachments = [];
525
- const nonImagePaths = [];
526
- for (const attachment of message.attachments || []) {
527
- const runtimePath = `${workspacePath}/${attachment.localPath}`;
528
- const hostPath = pathContext?.runtimeToHostPath?.(runtimePath) ?? runtimePath;
529
- const mimeType = getImageMimeType(attachment.localPath);
530
- if (mimeType && existsSync(hostPath)) {
531
- try {
532
- imageAttachments.push({
533
- type: "image",
534
- mimeType,
535
- data: readFileSync(hostPath).toString("base64"),
536
- });
537
- }
538
- catch {
539
- nonImagePaths.push(runtimePath);
540
- }
541
- }
542
- else {
543
- nonImagePaths.push(runtimePath);
544
- }
545
- }
546
- return { imageAttachments, nonImagePaths };
547
- }
548
- export function buildPromptPayload(message, workspacePath, pathContext) {
549
- let userMessage = formatTimestampedUserMessage(message);
550
- const { imageAttachments, nonImagePaths } = collectMessageAttachments(message, workspacePath, pathContext);
551
- if (nonImagePaths.length > 0) {
552
- userMessage += `\n\n<slack_attachments>\n${nonImagePaths.join("\n")}\n</slack_attachments>`;
553
- }
554
- return { userMessage, imageAttachments };
555
- }
556
- async function writePromptDebugContext(conversationDir, systemPrompt, session, userMessage, imageAttachmentCount) {
557
- const debugContext = {
558
- systemPrompt,
559
- messages: session.messages,
560
- newUserMessage: userMessage,
561
- imageAttachmentCount,
562
- };
563
- await writeFile(join(conversationDir, "last_prompt.jsonl"), JSON.stringify(debugContext, null, 2));
564
- }
565
484
  function getFinalAssistantText(session) {
566
485
  const lastAssistant = session.messages.findLast((message) => message.role === "assistant");
567
486
  return (lastAssistant?.content
@@ -569,21 +488,6 @@ function getFinalAssistantText(session) {
569
488
  .map((content) => content.text)
570
489
  .join("\n") || "");
571
490
  }
572
- export function appendTriggerAttribution(text, triggerAttribution, sessionLink) {
573
- if (!triggerAttribution)
574
- return text;
575
- const trimmed = text.trimEnd();
576
- const legacySuffix = `_Triggered by ${triggerAttribution}_`;
577
- const suffix = sessionLink
578
- ? `_Triggered by ${triggerAttribution} · session: ${sessionLink}_`
579
- : legacySuffix;
580
- if (trimmed.endsWith(suffix))
581
- return text;
582
- const body = trimmed.endsWith(legacySuffix)
583
- ? trimmed.slice(0, -legacySuffix.length).trimEnd()
584
- : trimmed;
585
- return `${body}\n\n${suffix}`;
586
- }
587
491
  function isEventTriggerAttribution(triggerAttribution) {
588
492
  return triggerAttribution?.startsWith("[event:") === true;
589
493
  }
@@ -609,6 +513,31 @@ async function replaceResponseWithToolProgress(responder, runState) {
609
513
  if (progress)
610
514
  await responder.replaceResponse(progress);
611
515
  }
516
+ const TOOL_PROGRESS_DEBOUNCE_MS = 500;
517
+ function scheduleToolProgressUpdate(responder, runState) {
518
+ if (runState.toolProgressTimer)
519
+ return;
520
+ runState.toolProgressTimer = setTimeout(() => {
521
+ runState.toolProgressTimer = undefined;
522
+ runState.queue?.enqueue(() => replaceResponseWithToolProgress(responder, runState), "tool progress update");
523
+ }, TOOL_PROGRESS_DEBOUNCE_MS);
524
+ runState.toolProgressTimer.unref();
525
+ }
526
+ function flushToolProgressUpdate(responder, runState) {
527
+ if (runState.toolProgressTimer)
528
+ clearTimeout(runState.toolProgressTimer);
529
+ runState.toolProgressTimer = undefined;
530
+ runState.queue?.enqueue(() => replaceResponseWithToolProgress(responder, runState), "tool progress update");
531
+ }
532
+ function extractToolProgressLabel(partialResult) {
533
+ if (!partialResult || typeof partialResult !== "object")
534
+ return undefined;
535
+ const details = partialResult.details;
536
+ if (!details || typeof details !== "object")
537
+ return undefined;
538
+ const label = details.progressLabel;
539
+ return typeof label === "string" && label.trim() ? label.trim().slice(0, 1000) : undefined;
540
+ }
612
541
  async function finalizeRunResponse(responder, session, runState, options) {
613
542
  if (runState.stopReason === "error" && runState.errorMessage) {
614
543
  if (!runState.reportedLlmError) {
@@ -739,6 +668,170 @@ async function reportUsageSummary(ctx) {
739
668
  await waitForQueue();
740
669
  }
741
670
  }
671
+ function extractToolResultText(result) {
672
+ if (typeof result === "string") {
673
+ return result;
674
+ }
675
+ if (result &&
676
+ typeof result === "object" &&
677
+ "content" in result &&
678
+ Array.isArray(result.content)) {
679
+ const content = result.content;
680
+ const textParts = [];
681
+ for (const part of content) {
682
+ if (part.type === "text" && part.text) {
683
+ textParts.push(part.text);
684
+ }
685
+ }
686
+ if (textParts.length > 0) {
687
+ return textParts.join("\n");
688
+ }
689
+ }
690
+ return JSON.stringify(result);
691
+ }
692
+ function buildThreadSessionName(message) {
693
+ const text = message?.text?.trim();
694
+ if (!text)
695
+ return undefined;
696
+ const userLabel = message?.userName || message?.user || "unknown";
697
+ return `[${userLabel}]: ${text}`;
698
+ }
699
+ function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspaceDir, hostWorkspacePath) {
700
+ const executionResolver = vaultManager && sandboxConfig.type !== "host"
701
+ ? new ActorExecutionResolver(sandboxConfig, vaultManager, provisioner, workspaceDir, hostWorkspacePath)
702
+ : undefined;
703
+ // activeExecutor is replaced at the start of each run() call when executionResolver
704
+ // is present, so the stable `executor` wrapper always delegates to the latest resolved value.
705
+ let activeExecutor = executionResolver !== undefined
706
+ ? createExecutor({ type: "host" })
707
+ : createExecutor(sandboxConfig);
708
+ const executor = {
709
+ exec(command, options) {
710
+ return activeExecutor.exec(command, options);
711
+ },
712
+ readFile(path, options) {
713
+ return activeExecutor.readFile(path, options);
714
+ },
715
+ writeFile(path, content, options) {
716
+ return activeExecutor.writeFile(path, content, options);
717
+ },
718
+ getWorkspacePath(hostPath) {
719
+ return activeExecutor.getWorkspacePath(hostPath);
720
+ },
721
+ getSandboxConfig() {
722
+ return activeExecutor.getSandboxConfig();
723
+ },
724
+ getPathContext(hostWorkspaceRoot) {
725
+ return activeExecutor.getPathContext(hostWorkspaceRoot);
726
+ },
727
+ };
728
+ return {
729
+ executionResolver,
730
+ executor,
731
+ getPathContext: () => executor.getPathContext(hostWorkspacePath),
732
+ async resolveExecutorForRun(context) {
733
+ if (!executionResolver)
734
+ return;
735
+ activeExecutor = await executionResolver.resolve(context);
736
+ },
737
+ };
738
+ }
739
+ /**
740
+ * Extension host services over mikan's runtime infrastructure: schedules
741
+ * become event files under `<workspaceDir>/events` (picked up live by
742
+ * EventsWatcher), secrets come from `vaults/extensions/<slug>/env`, and
743
+ * notify posts through the platform bots when main.ts provides a notifier.
744
+ */
745
+ function buildExtensionHostServices(params) {
746
+ const { workspaceDir, vaultManager, platformNotifier, platformReactor, platformUploader, runSubagentService, } = params;
747
+ const eventStore = HostEventStore.fromWorkspaceDir(workspaceDir);
748
+ return {
749
+ stateDir: readEnv("STATE_DIR"),
750
+ scheduleStore: {
751
+ write: async (filename, payload) => {
752
+ // Event files tolerate a missing platform (single-platform default),
753
+ // so the harness payload is a valid event payload as written.
754
+ await eventStore.write(filename, payload);
755
+ },
756
+ delete: async (filename) => (await eventStore.delete(filename)).deleted,
757
+ list: async () => (await eventStore.list())
758
+ .filter((entry) => entry.payload !== null)
759
+ .map((entry) => ({
760
+ filename: entry.filename,
761
+ payload: entry.payload,
762
+ })),
763
+ },
764
+ ...(platformNotifier ? { postMessage: platformNotifier } : {}),
765
+ ...(platformReactor ? { addReaction: platformReactor } : {}),
766
+ ...(platformUploader ? { uploadFile: platformUploader } : {}),
767
+ ...(runSubagentService ? { runSubagent: runSubagentService } : {}),
768
+ ...(vaultManager
769
+ ? {
770
+ resolveSecrets: (slug) => vaultManager.resolve(`extensions/${slug}`)?.env ?? {},
771
+ }
772
+ : {}),
773
+ };
774
+ }
775
+ async function createConfiguredAgentSession(params) {
776
+ const { conversationId, workspaceDir, systemPrompt, model, thinkingLevel, tools, sessionStore, models, vaultManager, platformNotifier, platformReactor, platformUploader, } = params;
777
+ // Host-only dirs under the state dir: extension code runs in the mikan
778
+ // process, so it must never load from workspace paths — those are mounted
779
+ // into sandbox containers and agent-writable (sandbox escape otherwise).
780
+ let contributedTools = [];
781
+ const subagentTool = createSubagentTool((request) => runSubagent({
782
+ request,
783
+ defaultModel: model,
784
+ thinkingLevel,
785
+ models,
786
+ workspaceDir,
787
+ availableTools: [...tools, ...contributedTools],
788
+ }));
789
+ const extensionsResult = await loadExtensions({
790
+ dirs: defaultExtensionDirs(conversationId, readEnv("STATE_DIR")),
791
+ context: { conversationId, workspaceDir, model, thinkingLevel },
792
+ services: buildExtensionHostServices({
793
+ workspaceDir,
794
+ vaultManager,
795
+ platformNotifier,
796
+ platformReactor,
797
+ platformUploader,
798
+ runSubagentService: (request, extensionTools) => runSubagent({
799
+ request,
800
+ defaultModel: model,
801
+ thinkingLevel,
802
+ models,
803
+ workspaceDir,
804
+ availableTools: [...tools, ...extensionTools],
805
+ }),
806
+ }),
807
+ });
808
+ contributedTools = extensionsResult.registry.getContributedTools();
809
+ for (const err of extensionsResult.errors) {
810
+ log.logWarning(`[${conversationId}] Extension load error: ${err.path}`, err.error);
811
+ }
812
+ if (extensionsResult.extensions.length > 0) {
813
+ log.logInfo(`[${conversationId}] Loaded ${extensionsResult.extensions.length} extension(s): ${extensionsResult.extensions.map((extension) => extension.name).join(", ")}`);
814
+ }
815
+ const session = new MikanAgentSession({
816
+ systemPrompt,
817
+ model,
818
+ thinkingLevel,
819
+ tools: [...tools, subagentTool],
820
+ models,
821
+ sessionStore,
822
+ extensions: extensionsResult.registry,
823
+ });
824
+ const reloaded = session.reloadFromSession();
825
+ if (reloaded > 0) {
826
+ log.logInfo(`[${conversationId}] Reloaded ${reloaded} messages from session context`);
827
+ }
828
+ return {
829
+ session,
830
+ extensionSkills: extensionsResult.skills,
831
+ extensionRegistry: extensionsResult.registry,
832
+ disposeExtensions: extensionsResult.dispose,
833
+ };
834
+ }
742
835
  function reloadSessionMessages(session, conversationId) {
743
836
  const reloaded = session.reloadFromSession();
744
837
  if (reloaded > 0) {
@@ -746,15 +839,16 @@ function reloadSessionMessages(session, conversationId) {
746
839
  }
747
840
  }
748
841
  async function prepareRunContext(params) {
749
- const { message, responder, platform, conversationId, conversationDir, sessionUuid, runState, executor, executionResolver, resolveExecutorForRun, getPathContext, session, setEventContext, setSandboxContext, setUploadFunction, } = params;
842
+ const { message, responder, platform, conversationId, conversationDir, sessionUuid, runState, executor, executionResolver, resolveExecutorForRun, getPathContext, session, setEventContext, setSandboxContext, setUploadFunction, setReactFunction, bindPlatformToolPacks, } = params;
750
843
  let pathContext = params.pathContext;
751
- const sessionConversation = message.sessionKey.split(":")[0];
844
+ const sessionConversation = conversationIdOf(message.sessionKey);
752
845
  await mkdir(join(conversationDir, "scratch"), { recursive: true });
753
846
  if (executionResolver) {
754
847
  await resolveExecutorForRun({
755
848
  platform: platform.name,
756
849
  userId: message.userId,
757
850
  conversationId,
851
+ trustModel: platform.trustModel,
758
852
  });
759
853
  pathContext = getPathContext();
760
854
  }
@@ -768,9 +862,11 @@ async function prepareRunContext(params) {
768
862
  // provider prompt caching. If this hash changes between turns of one
769
863
  // conversation, something turn-varying leaked into the prompt; if it is
770
864
  // stable and cacheRead stays 0, the miss is provider-side (e.g. OpenRouter
771
- // routing the model across upstream hosts).
865
+ // routing the model across upstream hosts). This is the base prompt mikan
866
+ // builds; a `before_agent_start` extension may still rewrite it per turn
867
+ // (logged separately by the runner).
772
868
  const promptHash = createHash("sha256").update(systemPrompt).digest("hex").slice(0, 8);
773
- log.logInfo(`[${conversationId}] System prompt: ${systemPrompt.length} chars, sha ${promptHash}`);
869
+ log.logInfo(`[${conversationId}] System prompt (base): ${systemPrompt.length} chars, sha ${promptHash}`);
774
870
  setEventContext({
775
871
  platform: platform.name,
776
872
  conversationId,
@@ -782,6 +878,13 @@ async function prepareRunContext(params) {
782
878
  const hostPath = translateAttachPathToHost(filePath, pathContext);
783
879
  await responder.uploadFile(hostPath, title);
784
880
  });
881
+ // The react tool is available only when the responder supports reactions
882
+ // (interactive turns on platforms with reaction support); otherwise unset
883
+ // so the tool reports it is unavailable rather than silently no-op'ing.
884
+ setReactFunction(responder.react ? async (emoji) => responder.react(emoji) : null);
885
+ // Platform capability packs (e.g. GitHub PR/CI) enable themselves per run;
886
+ // core does not branch on platform name here.
887
+ bindPlatformToolPacks({ conversationId, platformName: platform.name });
785
888
  resetRunState(runState, responder, sessionConversation, message.userName, sessionUuid, triggerAttribution);
786
889
  const runQueue = createRunQueue(responder, runState);
787
890
  runState.queue = runQueue.queue;
@@ -790,7 +893,6 @@ async function prepareRunContext(params) {
790
893
  const { userMessage, imageAttachments } = buildPromptPayload(message, pathContext.runtimeWorkspaceRoot, pathContext);
791
894
  const turnInstructions = buildTurnInstructions(message.id.startsWith("event:"), triggerAttribution, platform.name);
792
895
  const finalUserMessage = turnInstructions ? `${turnInstructions}\n\n${userMessage}` : userMessage;
793
- await writePromptDebugContext(conversationDir, systemPrompt, session, finalUserMessage, imageAttachments.length);
794
896
  return {
795
897
  sessionConversation,
796
898
  runQueue,
@@ -845,6 +947,15 @@ function attachSessionEventHandlers(params) {
845
947
  log.logToolStart(logCtx, event.toolName, label, event.args);
846
948
  return;
847
949
  }
950
+ if (event.type === "tool_execution_update") {
951
+ const label = extractToolProgressLabel(event.partialResult);
952
+ const progress = runState.toolProgress.get(event.toolCallId);
953
+ if (label && progress) {
954
+ progress.label = label;
955
+ scheduleToolProgressUpdate(responder, runState);
956
+ }
957
+ return;
958
+ }
848
959
  if (event.type === "tool_execution_end") {
849
960
  const resultStr = extractToolResultText(event.result);
850
961
  const pending = pendingTools.get(event.toolCallId);
@@ -856,7 +967,7 @@ function attachSessionEventHandlers(params) {
856
967
  const progress = runState.toolProgress.get(event.toolCallId);
857
968
  if (progress)
858
969
  progress.status = event.isError ? "error" : "done";
859
- queue.enqueue(() => replaceResponseWithToolProgress(responder, runState), "tool progress update");
970
+ flushToolProgressUpdate(responder, runState);
860
971
  pendingTools.delete(event.toolCallId);
861
972
  const durationMs = pending ? Date.now() - pending.startTime : 0;
862
973
  Sentry.metrics.count("agent.tool.calls", 1, {
@@ -1069,27 +1180,6 @@ function attachSessionEventHandlers(params) {
1069
1180
  }
1070
1181
  });
1071
1182
  }
1072
- function extractToolResultText(result) {
1073
- if (typeof result === "string") {
1074
- return result;
1075
- }
1076
- if (result &&
1077
- typeof result === "object" &&
1078
- "content" in result &&
1079
- Array.isArray(result.content)) {
1080
- const content = result.content;
1081
- const textParts = [];
1082
- for (const part of content) {
1083
- if (part.type === "text" && part.text) {
1084
- textParts.push(part.text);
1085
- }
1086
- }
1087
- if (textParts.length > 0) {
1088
- return textParts.join("\n");
1089
- }
1090
- }
1091
- return JSON.stringify(result);
1092
- }
1093
1183
  /**
1094
1184
  * Create a new PiAgentWrapper for a channel.
1095
1185
  * Sets up the session and subscribes to events once.
@@ -1097,18 +1187,22 @@ function extractToolResultText(result) {
1097
1187
  * Runner caching is handled by the caller (channelStates in main.ts).
1098
1188
  * This is a stateless factory function.
1099
1189
  */
1100
- export async function createRunner(sandboxConfig, sessionKey, conversationId, conversationDir, workspaceDir, sessionScope, vaultManager, provisioner, sessionView, platformNotifier) {
1190
+ export async function createRunner(options) {
1191
+ const { sandboxConfig, sessionKey, conversationId, conversationDir, workspaceDir, sessionScope, vaultManager, provisioner, resourceController, sessionView, platformNotifier, platformReactor, platformUploader, platformToolPackFactories, } = options;
1101
1192
  const agentConfig = resolveConversationSettings(conversationDir);
1102
1193
  const workspaceBase = join(conversationDir, "..");
1103
1194
  const { executionResolver, executor, getPathContext, resolveExecutorForRun } = createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspaceDir, workspaceBase);
1104
1195
  let pathContext = getUnresolvedSandboxPathContext(sandboxConfig, workspaceBase);
1105
- // Create tools (per-runner, with per-runner upload function setter)
1106
- const { tools, setUploadFunction, setEventContext, setSandboxContext } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, provisioner });
1107
- const modelRegistry = MikanModels.create();
1196
+ const modelRegistry = options.models ?? MikanModels.create();
1108
1197
  if (modelRegistry.getError()) {
1109
1198
  log.logWarning("models.json load error", modelRegistry.getError());
1110
1199
  }
1111
- const model = resolveConfiguredModel(modelRegistry, agentConfig.provider, agentConfig.model);
1200
+ const model = modelRegistry.resolve(agentConfig.provider, agentConfig.model);
1201
+ // Create tools (per-runner, with per-runner upload function setter)
1202
+ const { tools, setUploadFunction, setReactFunction, bindPlatformToolPacks, setEventContext, setSandboxContext, } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, resourceController: resourceController ?? provisioner }, platformToolPackFactories ?? [], {
1203
+ model,
1204
+ getApiKey: () => modelRegistry.getApiKeyForProvider(model.provider),
1205
+ });
1112
1206
  // Initial system prompt (will be updated each run with fresh memory/channels/users/skills)
1113
1207
  const memory = await getMemory(conversationDir);
1114
1208
  const skills = loadMikanSkills(conversationDir, pathContext.runtimeWorkspaceRoot);
@@ -1117,12 +1211,13 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1117
1211
  formattingGuide: "",
1118
1212
  channels: [],
1119
1213
  users: [],
1214
+ trustModel: "membership",
1120
1215
  };
1121
1216
  const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot, conversationId, "shared", undefined, memory, sandboxConfig, emptyPlatform, skills);
1122
1217
  // Create session manager and settings manager. Top-level/private sessions
1123
1218
  // use the conversation's current pointer; scoped sessions use fixed files.
1124
1219
  // Platform-specific scope behavior is resolved before runner creation.
1125
- const isThread = sessionKey.includes(":");
1220
+ const isThread = isThreadSessionKey(sessionKey);
1126
1221
  const { contextFile, threadRootMessage } = sessionScope;
1127
1222
  const sessionManager = openManagedSession(contextFile, pathContext.runtimeWorkspaceRoot);
1128
1223
  const threadSessionName = buildThreadSessionName(threadRootMessage);
@@ -1131,7 +1226,7 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1131
1226
  }
1132
1227
  const sessionUuid = extractSessionUuid(contextFile);
1133
1228
  const chatSessionManager = new AgentMemoryFileManager();
1134
- const { session, extensionSkills } = await createConfiguredAgentSession({
1229
+ const { session, extensionSkills, extensionRegistry, disposeExtensions } = await createConfiguredAgentSession({
1135
1230
  conversationId,
1136
1231
  workspaceDir,
1137
1232
  systemPrompt,
@@ -1142,6 +1237,8 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1142
1237
  models: modelRegistry,
1143
1238
  vaultManager,
1144
1239
  platformNotifier,
1240
+ platformReactor,
1241
+ platformUploader,
1145
1242
  });
1146
1243
  // Mutable per-run state - event handler references this
1147
1244
  const runState = createRunState();
@@ -1173,6 +1270,8 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1173
1270
  setEventContext,
1174
1271
  setSandboxContext,
1175
1272
  setUploadFunction,
1273
+ setReactFunction,
1274
+ bindPlatformToolPacks,
1176
1275
  pathContext,
1177
1276
  });
1178
1277
  pathContext = prepared.pathContext;
@@ -1201,10 +1300,39 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1201
1300
  // Autonomous (event/trigger) runs get an explicit resource ceiling since
1202
1301
  // no human is watching the loop; interactive turns stay human-gated.
1203
1302
  const isEventRun = message.id.startsWith("event:");
1204
- await session.prompt(prepared.userMessage, {
1303
+ // Event runs have no triggering platform message, so identity fields
1304
+ // stay unset and extensions must null-check them.
1305
+ const origin = isEventRun
1306
+ ? { kind: "event", platform: platform.name }
1307
+ : {
1308
+ kind: "interactive",
1309
+ platform: platform.name,
1310
+ messageTs: message.id,
1311
+ userId: message.userId,
1312
+ userName: message.userName,
1313
+ threadTs: message.threadTs,
1314
+ attachments: message.attachments,
1315
+ };
1316
+ const outcome = await session.prompt(prepared.userMessage, {
1317
+ origin,
1205
1318
  ...(prepared.imageAttachments.length > 0 ? { images: prepared.imageAttachments } : {}),
1206
1319
  ...(isEventRun ? { budget: DEFAULT_EVENT_BUDGET } : {}),
1207
1320
  });
1321
+ if (outcome?.blocked) {
1322
+ const text = outcome.reason
1323
+ ? `_Turn blocked by an extension: ${outcome.reason}_`
1324
+ : "_Turn blocked by an extension._";
1325
+ sendAgentEvent({
1326
+ sessionId: sessionUuid,
1327
+ actorName: formatAgentActorName(message.userName, prepared.sessionConversation),
1328
+ event: { kind: "diagnostic", text },
1329
+ });
1330
+ await responder.respondDiagnostic(text, { style: "muted" });
1331
+ runState.responder = null;
1332
+ runState.logCtx = null;
1333
+ runState.queue = null;
1334
+ return { stopReason: "blocked" };
1335
+ }
1208
1336
  // Wait for queued messages
1209
1337
  await prepared.runQueue.wait();
1210
1338
  const sessionViewTokenStore = sessionView?.tokenStore;
@@ -1250,6 +1378,21 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1250
1378
  abort() {
1251
1379
  session.abort();
1252
1380
  },
1381
+ async tryExtensionCommand(message, responder) {
1382
+ const parsed = parseCommandInput(message.text);
1383
+ if (!parsed)
1384
+ return false;
1385
+ return extensionRegistry.dispatchCommand(parsed.name, {
1386
+ args: parsed.args,
1387
+ conversationId,
1388
+ userId: message.userId,
1389
+ userName: message.userName,
1390
+ respond: (text) => responder.respond(text),
1391
+ });
1392
+ },
1393
+ async dispose() {
1394
+ await disposeExtensions();
1395
+ },
1253
1396
  getCurrentStep() {
1254
1397
  const pending = runState.pendingTools;
1255
1398
  if (pending.size === 0)
@@ -1265,13 +1408,4 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1265
1408
  },
1266
1409
  };
1267
1410
  }
1268
- export function translateRuntimePathToHost(runtimePath, pathContext) {
1269
- return pathContext.runtimeToHostPath?.(runtimePath) ?? runtimePath;
1270
- }
1271
- export function translateAttachPathToHost(filePath, pathContext) {
1272
- const runtimePath = posix.isAbsolute(filePath)
1273
- ? filePath
1274
- : posix.join(pathContext.runtimeWorkspaceRoot, filePath);
1275
- return translateRuntimePathToHost(runtimePath, pathContext);
1276
- }
1277
1411
  //# sourceMappingURL=agent.js.map