@geminixiang/mikan 1.0.0-beta.13 → 1.0.0-beta.15

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 (303) hide show
  1. package/CHANGELOG.md +58 -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.map +1 -1
  7. package/dist/adapters/discord/bot.js +26 -67
  8. package/dist/adapters/discord/bot.js.map +1 -1
  9. package/dist/adapters/discord/context.d.ts.map +1 -1
  10. package/dist/adapters/discord/context.js +17 -43
  11. package/dist/adapters/discord/context.js.map +1 -1
  12. package/dist/adapters/github/bot.d.ts +69 -1
  13. package/dist/adapters/github/bot.d.ts.map +1 -1
  14. package/dist/adapters/github/bot.js +428 -57
  15. package/dist/adapters/github/bot.js.map +1 -1
  16. package/dist/adapters/github/client.d.ts +32 -1
  17. package/dist/adapters/github/client.d.ts.map +1 -1
  18. package/dist/adapters/github/client.js +79 -0
  19. package/dist/adapters/github/client.js.map +1 -1
  20. package/dist/adapters/github/cloudbuild.d.ts +24 -0
  21. package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
  22. package/dist/adapters/github/cloudbuild.js +71 -0
  23. package/dist/adapters/github/cloudbuild.js.map +1 -0
  24. package/dist/adapters/github/context.d.ts.map +1 -1
  25. package/dist/adapters/github/context.js +34 -31
  26. package/dist/adapters/github/context.js.map +1 -1
  27. package/dist/adapters/github/gcp-auth.d.ts +31 -0
  28. package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
  29. package/dist/adapters/github/gcp-auth.js +196 -0
  30. package/dist/adapters/github/gcp-auth.js.map +1 -0
  31. package/dist/adapters/github/ids.d.ts +9 -0
  32. package/dist/adapters/github/ids.d.ts.map +1 -1
  33. package/dist/adapters/github/ids.js +14 -0
  34. package/dist/adapters/github/ids.js.map +1 -1
  35. package/dist/adapters/github/repo.d.ts +13 -2
  36. package/dist/adapters/github/repo.d.ts.map +1 -1
  37. package/dist/adapters/github/repo.js +80 -2
  38. package/dist/adapters/github/repo.js.map +1 -1
  39. package/dist/adapters/github/tool-pack.d.ts +3 -1
  40. package/dist/adapters/github/tool-pack.d.ts.map +1 -1
  41. package/dist/adapters/github/tool-pack.js +30 -4
  42. package/dist/adapters/github/tool-pack.js.map +1 -1
  43. package/dist/{tools/github-checks.d.ts → adapters/github/tools/checks.d.ts} +4 -2
  44. package/dist/adapters/github/tools/checks.d.ts.map +1 -0
  45. package/dist/{tools/github-checks.js → adapters/github/tools/checks.js} +28 -11
  46. package/dist/adapters/github/tools/checks.js.map +1 -0
  47. package/dist/adapters/github/tools/issue.d.ts +22 -0
  48. package/dist/adapters/github/tools/issue.d.ts.map +1 -0
  49. package/dist/adapters/github/tools/issue.js +59 -0
  50. package/dist/adapters/github/tools/issue.js.map +1 -0
  51. package/dist/{tools/github-pr.d.ts → adapters/github/tools/pr.d.ts} +2 -2
  52. package/dist/adapters/github/tools/pr.d.ts.map +1 -0
  53. package/dist/{tools/github-pr.js → adapters/github/tools/pr.js} +8 -4
  54. package/dist/adapters/github/tools/pr.js.map +1 -0
  55. package/dist/adapters/github/tools/read.d.ts +22 -0
  56. package/dist/adapters/github/tools/read.d.ts.map +1 -0
  57. package/dist/adapters/github/tools/read.js +152 -0
  58. package/dist/adapters/github/tools/read.js.map +1 -0
  59. package/dist/adapters/github/tools/review-reply.d.ts +19 -0
  60. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
  61. package/dist/adapters/github/tools/review-reply.js +49 -0
  62. package/dist/adapters/github/tools/review-reply.js.map +1 -0
  63. package/dist/adapters/github/tools/sync.d.ts +17 -0
  64. package/dist/adapters/github/tools/sync.d.ts.map +1 -0
  65. package/dist/adapters/github/tools/sync.js +45 -0
  66. package/dist/adapters/github/tools/sync.js.map +1 -0
  67. package/dist/adapters/github/types.d.ts +174 -1
  68. package/dist/adapters/github/types.d.ts.map +1 -1
  69. package/dist/adapters/github/types.js.map +1 -1
  70. package/dist/adapters/intake.d.ts +16 -5
  71. package/dist/adapters/intake.d.ts.map +1 -1
  72. package/dist/adapters/intake.js +79 -22
  73. package/dist/adapters/intake.js.map +1 -1
  74. package/dist/adapters/slack/bot.d.ts +7 -6
  75. package/dist/adapters/slack/bot.d.ts.map +1 -1
  76. package/dist/adapters/slack/bot.js +65 -135
  77. package/dist/adapters/slack/bot.js.map +1 -1
  78. package/dist/adapters/slack/context.d.ts.map +1 -1
  79. package/dist/adapters/slack/context.js +3 -15
  80. package/dist/adapters/slack/context.js.map +1 -1
  81. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  82. package/dist/adapters/slack/response-lifecycle.js +7 -16
  83. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  84. package/dist/adapters/slack/session.d.ts.map +1 -1
  85. package/dist/adapters/slack/session.js +5 -8
  86. package/dist/adapters/slack/session.js.map +1 -1
  87. package/dist/adapters/streaming.d.ts +4 -0
  88. package/dist/adapters/streaming.d.ts.map +1 -1
  89. package/dist/adapters/streaming.js +11 -0
  90. package/dist/adapters/streaming.js.map +1 -1
  91. package/dist/adapters/telegram/bot.d.ts +0 -2
  92. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  93. package/dist/adapters/telegram/bot.js +16 -62
  94. package/dist/adapters/telegram/bot.js.map +1 -1
  95. package/dist/adapters/telegram/context.d.ts.map +1 -1
  96. package/dist/adapters/telegram/context.js +8 -28
  97. package/dist/adapters/telegram/context.js.map +1 -1
  98. package/dist/adapters/types.d.ts +28 -2
  99. package/dist/adapters/types.d.ts.map +1 -1
  100. package/dist/adapters/types.js.map +1 -1
  101. package/dist/agent.d.ts +23 -5
  102. package/dist/agent.d.ts.map +1 -1
  103. package/dist/agent.js +86 -28
  104. package/dist/agent.js.map +1 -1
  105. package/dist/commands/admin.d.ts.map +1 -1
  106. package/dist/commands/admin.js +2 -1
  107. package/dist/commands/admin.js.map +1 -1
  108. package/dist/commands/auto-reply.d.ts.map +1 -1
  109. package/dist/commands/auto-reply.js +2 -6
  110. package/dist/commands/auto-reply.js.map +1 -1
  111. package/dist/commands/extensions.d.ts.map +1 -1
  112. package/dist/commands/extensions.js +2 -1
  113. package/dist/commands/extensions.js.map +1 -1
  114. package/dist/commands/login.d.ts +2 -1
  115. package/dist/commands/login.d.ts.map +1 -1
  116. package/dist/commands/login.js +30 -1
  117. package/dist/commands/login.js.map +1 -1
  118. package/dist/commands/manifest.d.ts +72 -0
  119. package/dist/commands/manifest.d.ts.map +1 -0
  120. package/dist/commands/manifest.js +121 -0
  121. package/dist/commands/manifest.js.map +1 -0
  122. package/dist/commands/model.d.ts.map +1 -1
  123. package/dist/commands/model.js +2 -1
  124. package/dist/commands/model.js.map +1 -1
  125. package/dist/commands/new.d.ts.map +1 -1
  126. package/dist/commands/new.js +2 -1
  127. package/dist/commands/new.js.map +1 -1
  128. package/dist/commands/sandbox.d.ts.map +1 -1
  129. package/dist/commands/sandbox.js +3 -2
  130. package/dist/commands/sandbox.js.map +1 -1
  131. package/dist/commands/text.d.ts +2 -0
  132. package/dist/commands/text.d.ts.map +1 -0
  133. package/dist/commands/text.js +16 -0
  134. package/dist/commands/text.js.map +1 -0
  135. package/dist/commands/types.d.ts +12 -1
  136. package/dist/commands/types.d.ts.map +1 -1
  137. package/dist/commands/types.js.map +1 -1
  138. package/dist/config.d.ts +1 -1
  139. package/dist/config.d.ts.map +1 -1
  140. package/dist/config.js +49 -54
  141. package/dist/config.js.map +1 -1
  142. package/dist/events.d.ts +10 -0
  143. package/dist/events.d.ts.map +1 -1
  144. package/dist/events.js +14 -5
  145. package/dist/events.js.map +1 -1
  146. package/dist/execution-resolver.d.ts.map +1 -1
  147. package/dist/execution-resolver.js +3 -3
  148. package/dist/execution-resolver.js.map +1 -1
  149. package/dist/harness/extensions/loader.d.ts +6 -0
  150. package/dist/harness/extensions/loader.d.ts.map +1 -1
  151. package/dist/harness/extensions/loader.js +24 -4
  152. package/dist/harness/extensions/loader.js.map +1 -1
  153. package/dist/harness/extensions/registry.d.ts +48 -1
  154. package/dist/harness/extensions/registry.d.ts.map +1 -1
  155. package/dist/harness/extensions/registry.js +146 -0
  156. package/dist/harness/extensions/registry.js.map +1 -1
  157. package/dist/harness/extensions/types.d.ts +123 -12
  158. package/dist/harness/extensions/types.d.ts.map +1 -1
  159. package/dist/harness/extensions/types.js.map +1 -1
  160. package/dist/harness/index.d.ts +3 -3
  161. package/dist/harness/index.d.ts.map +1 -1
  162. package/dist/harness/index.js +1 -1
  163. package/dist/harness/index.js.map +1 -1
  164. package/dist/harness/runner.d.ts +13 -2
  165. package/dist/harness/runner.d.ts.map +1 -1
  166. package/dist/harness/runner.js +59 -16
  167. package/dist/harness/runner.js.map +1 -1
  168. package/dist/index.d.ts +1 -1
  169. package/dist/index.d.ts.map +1 -1
  170. package/dist/index.js.map +1 -1
  171. package/dist/main.js +36 -13
  172. package/dist/main.js.map +1 -1
  173. package/dist/provisioner.d.ts.map +1 -1
  174. package/dist/provisioner.js +2 -5
  175. package/dist/provisioner.js.map +1 -1
  176. package/dist/runtime/conversation-runtime.d.ts +1 -1
  177. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  178. package/dist/runtime/conversation-runtime.js +262 -41
  179. package/dist/runtime/conversation-runtime.js.map +1 -1
  180. package/dist/runtime/types.d.ts +22 -5
  181. package/dist/runtime/types.d.ts.map +1 -1
  182. package/dist/runtime/types.js.map +1 -1
  183. package/dist/sandbox/cloudflare.d.ts +2 -0
  184. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  185. package/dist/sandbox/cloudflare.js +7 -0
  186. package/dist/sandbox/cloudflare.js.map +1 -1
  187. package/dist/sandbox/container.d.ts +2 -0
  188. package/dist/sandbox/container.d.ts.map +1 -1
  189. package/dist/sandbox/container.js +7 -1
  190. package/dist/sandbox/container.js.map +1 -1
  191. package/dist/sandbox/firecracker.d.ts +2 -0
  192. package/dist/sandbox/firecracker.d.ts.map +1 -1
  193. package/dist/sandbox/firecracker.js +7 -1
  194. package/dist/sandbox/firecracker.js.map +1 -1
  195. package/dist/sandbox/host.d.ts +2 -0
  196. package/dist/sandbox/host.d.ts.map +1 -1
  197. package/dist/sandbox/host.js +11 -0
  198. package/dist/sandbox/host.js.map +1 -1
  199. package/dist/sandbox/identity.d.ts +21 -0
  200. package/dist/sandbox/identity.d.ts.map +1 -0
  201. package/dist/sandbox/identity.js +35 -0
  202. package/dist/sandbox/identity.js.map +1 -0
  203. package/dist/sandbox/types.d.ts +12 -0
  204. package/dist/sandbox/types.d.ts.map +1 -1
  205. package/dist/sandbox/types.js.map +1 -1
  206. package/dist/sandbox/utils.d.ts +11 -0
  207. package/dist/sandbox/utils.d.ts.map +1 -1
  208. package/dist/sandbox/utils.js +35 -0
  209. package/dist/sandbox/utils.js.map +1 -1
  210. package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -1
  211. package/dist/sessions/agent-memory-file-manager.js +16 -30
  212. package/dist/sessions/agent-memory-file-manager.js.map +1 -1
  213. package/dist/sessions/history-line.d.ts +20 -0
  214. package/dist/sessions/history-line.d.ts.map +1 -0
  215. package/dist/sessions/history-line.js +24 -0
  216. package/dist/sessions/history-line.js.map +1 -0
  217. package/dist/sessions/policy.d.ts.map +1 -1
  218. package/dist/sessions/policy.js +4 -3
  219. package/dist/sessions/policy.js.map +1 -1
  220. package/dist/sessions/session-key.d.ts +31 -0
  221. package/dist/sessions/session-key.d.ts.map +1 -0
  222. package/dist/sessions/session-key.js +44 -0
  223. package/dist/sessions/session-key.js.map +1 -0
  224. package/dist/sessions/store.d.ts.map +1 -1
  225. package/dist/sessions/store.js +2 -2
  226. package/dist/sessions/store.js.map +1 -1
  227. package/dist/tools/bash.d.ts +3 -1
  228. package/dist/tools/bash.d.ts.map +1 -1
  229. package/dist/tools/bash.js +24 -17
  230. package/dist/tools/bash.js.map +1 -1
  231. package/dist/tools/edit.d.ts.map +1 -1
  232. package/dist/tools/edit.js +9 -12
  233. package/dist/tools/edit.js.map +1 -1
  234. package/dist/tools/event.d.ts +1 -1
  235. package/dist/tools/event.d.ts.map +1 -1
  236. package/dist/tools/event.js +33 -4
  237. package/dist/tools/event.js.map +1 -1
  238. package/dist/tools/generate-image.d.ts +17 -0
  239. package/dist/tools/generate-image.d.ts.map +1 -0
  240. package/dist/tools/generate-image.js +63 -0
  241. package/dist/tools/generate-image.js.map +1 -0
  242. package/dist/tools/index.d.ts +5 -1
  243. package/dist/tools/index.d.ts.map +1 -1
  244. package/dist/tools/index.js +11 -3
  245. package/dist/tools/index.js.map +1 -1
  246. package/dist/tools/types.d.ts +6 -1
  247. package/dist/tools/types.d.ts.map +1 -1
  248. package/dist/tools/types.js.map +1 -1
  249. package/dist/tools/write.d.ts.map +1 -1
  250. package/dist/tools/write.js +1 -8
  251. package/dist/tools/write.js.map +1 -1
  252. package/dist/types.d.ts +32 -6
  253. package/dist/types.d.ts.map +1 -1
  254. package/dist/types.js.map +1 -1
  255. package/dist/vault/disabled.d.ts +9 -0
  256. package/dist/vault/disabled.d.ts.map +1 -0
  257. package/dist/vault/disabled.js +23 -0
  258. package/dist/vault/disabled.js.map +1 -0
  259. package/dist/vault/index.d.ts.map +1 -1
  260. package/dist/vault/index.js +3 -24
  261. package/dist/vault/index.js.map +1 -1
  262. package/dist/vault/routing.d.ts +1 -0
  263. package/dist/vault/routing.d.ts.map +1 -1
  264. package/dist/vault/routing.js +3 -10
  265. package/dist/vault/routing.js.map +1 -1
  266. package/dist/web/admin/portal.d.ts +27 -0
  267. package/dist/web/admin/portal.d.ts.map +1 -1
  268. package/dist/web/admin/portal.js +87 -126
  269. package/dist/web/admin/portal.js.map +1 -1
  270. package/dist/web/admin/types.d.ts +3 -0
  271. package/dist/web/admin/types.d.ts.map +1 -1
  272. package/dist/web/admin/types.js.map +1 -1
  273. package/dist/web/login/oauth.d.ts +2 -3
  274. package/dist/web/login/oauth.d.ts.map +1 -1
  275. package/dist/web/login/oauth.js +0 -31
  276. package/dist/web/login/oauth.js.map +1 -1
  277. package/dist/web/login/types.d.ts +0 -11
  278. package/dist/web/login/types.d.ts.map +1 -1
  279. package/dist/web/login/types.js.map +1 -1
  280. package/dist/web/server.d.ts.map +1 -1
  281. package/dist/web/server.js +7 -0
  282. package/dist/web/server.js.map +1 -1
  283. package/dist/web/session-view/command.d.ts.map +1 -1
  284. package/dist/web/session-view/command.js +4 -1
  285. package/dist/web/session-view/command.js.map +1 -1
  286. package/dist/web/session-view/portal.d.ts.map +1 -1
  287. package/dist/web/session-view/portal.js +3 -2
  288. package/dist/web/session-view/portal.js.map +1 -1
  289. package/dist/web/session-view/service.d.ts.map +1 -1
  290. package/dist/web/session-view/service.js +2 -1
  291. package/dist/web/session-view/service.js.map +1 -1
  292. package/dist/web/session-view/types.d.ts +2 -1
  293. package/dist/web/session-view/types.d.ts.map +1 -1
  294. package/dist/web/session-view/types.js.map +1 -1
  295. package/package.json +1 -1
  296. package/dist/runtime/agent-run-controller.d.ts +0 -31
  297. package/dist/runtime/agent-run-controller.d.ts.map +0 -1
  298. package/dist/runtime/agent-run-controller.js +0 -195
  299. package/dist/runtime/agent-run-controller.js.map +0 -1
  300. package/dist/tools/github-checks.d.ts.map +0 -1
  301. package/dist/tools/github-checks.js.map +0 -1
  302. package/dist/tools/github-pr.d.ts.map +0 -1
  303. package/dist/tools/github-pr.js.map +0 -1
package/dist/agent.js CHANGED
@@ -2,10 +2,10 @@
2
2
  * Agent runner: prompt construction, path translation, run lifecycle, and createRunner.
3
3
  * Single module — do not split helpers that only this file uses.
4
4
  */
5
- import { DEFAULT_EVENT_BUDGET, defaultExtensionDirs, formatSkillsForPrompt, loadExtensions, loadSkillsFromDir, MikanAgentSession, MikanModels, } from "./harness/index.js";
5
+ import { DEFAULT_EVENT_BUDGET, defaultExtensionDirs, formatSkillsForPrompt, loadExtensions, loadSkillsFromDir, MikanAgentSession, MikanModels, parseCommandInput, } from "./harness/index.js";
6
6
  import { createHash } from "crypto";
7
7
  import { existsSync, readFileSync } from "fs";
8
- import { mkdir, readFile, writeFile } from "fs/promises";
8
+ import { mkdir, readFile } from "fs/promises";
9
9
  import { join, posix } from "path";
10
10
  import { resolveConversationSettings } from "./config.js";
11
11
  import { readEnv } from "./utils/env.js";
@@ -15,11 +15,12 @@ import { createExecutor, } from "./sandbox/index.js";
15
15
  import { createMountedRuntimePathContext } from "./sandbox/path-context.js";
16
16
  import { addLifecycleBreadcrumb, metricAttributes, reportUserFacingError, updateActiveSpanAttribution, } from "./observability/sentry.js";
17
17
  import { AgentMemoryFileManager } from "./sessions/agent-memory-file-manager.js";
18
+ import { formatHistoryLine } from "./sessions/history-line.js";
19
+ import { conversationIdOf, isThreadSessionKey } from "./sessions/session-key.js";
18
20
  import { extractSessionUuid, openManagedSession, } from "./sessions/store.js";
19
21
  import { HostEventStore } from "./tools/event.js";
20
22
  import { createMikanTools } from "./tools/index.js";
21
23
  import * as Sentry from "@sentry/node";
22
- import { formatLocalTimestamp } from "./utils/date.js";
23
24
  import { emitAgentEvent } from "./agent-events.js";
24
25
  export function getUnresolvedSandboxPathContext(sandboxConfig, hostWorkspaceRoot) {
25
26
  if (sandboxConfig.type === "image") {
@@ -47,9 +48,12 @@ function getImageMimeType(filename) {
47
48
  return IMAGE_MIME_TYPES[filename.toLowerCase().split(".").pop() || ""];
48
49
  }
49
50
  function formatTimestampedUserMessage(message) {
50
- const timestamp = formatLocalTimestamp(new Date());
51
- const threadContext = message.threadTs ? ` [in-thread:${message.threadTs}]` : "";
52
- return `[${timestamp}] [${message.userName || "unknown"}]${threadContext}: ${message.text}`;
51
+ return formatHistoryLine({
52
+ date: new Date(),
53
+ userName: message.userName,
54
+ threadTs: message.threadTs,
55
+ text: message.text,
56
+ });
53
57
  }
54
58
  function collectMessageAttachments(message, workspacePath, pathContext) {
55
59
  const imageAttachments = [];
@@ -84,15 +88,6 @@ export function buildPromptPayload(message, workspacePath, pathContext) {
84
88
  }
85
89
  return { userMessage, imageAttachments };
86
90
  }
87
- async function writePromptDebugContext(conversationDir, systemPrompt, session, userMessage, imageAttachmentCount) {
88
- const debugContext = {
89
- systemPrompt,
90
- messages: session.messages,
91
- newUserMessage: userMessage,
92
- imageAttachmentCount,
93
- };
94
- await writeFile(join(conversationDir, "last_prompt.jsonl"), JSON.stringify(debugContext, null, 2));
95
- }
96
91
  async function getMemory(conversationDir) {
97
92
  const parts = [];
98
93
  // Read workspace-level memory (shared across all conversations)
@@ -684,6 +679,12 @@ function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner,
684
679
  exec(command, options) {
685
680
  return activeExecutor.exec(command, options);
686
681
  },
682
+ readFile(path, options) {
683
+ return activeExecutor.readFile(path, options);
684
+ },
685
+ writeFile(path, content, options) {
686
+ return activeExecutor.writeFile(path, content, options);
687
+ },
687
688
  getWorkspacePath(hostPath) {
688
689
  return activeExecutor.getWorkspacePath(hostPath);
689
690
  },
@@ -712,7 +713,7 @@ function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner,
712
713
  * notify posts through the platform bots when main.ts provides a notifier.
713
714
  */
714
715
  function buildExtensionHostServices(params) {
715
- const { workspaceDir, vaultManager, platformNotifier, platformReactor } = params;
716
+ const { workspaceDir, vaultManager, platformNotifier, platformReactor, platformUploader } = params;
716
717
  const eventStore = HostEventStore.fromWorkspaceDir(workspaceDir);
717
718
  return {
718
719
  stateDir: readEnv("STATE_DIR"),
@@ -723,13 +724,16 @@ function buildExtensionHostServices(params) {
723
724
  await eventStore.write(filename, payload);
724
725
  },
725
726
  delete: async (filename) => (await eventStore.delete(filename)).deleted,
726
- list: async () => (await eventStore.list()).map((entry) => ({
727
+ list: async () => (await eventStore.list())
728
+ .filter((entry) => entry.payload !== null)
729
+ .map((entry) => ({
727
730
  filename: entry.filename,
728
731
  payload: entry.payload,
729
732
  })),
730
733
  },
731
734
  ...(platformNotifier ? { postMessage: platformNotifier } : {}),
732
735
  ...(platformReactor ? { addReaction: platformReactor } : {}),
736
+ ...(platformUploader ? { uploadFile: platformUploader } : {}),
733
737
  ...(vaultManager
734
738
  ? {
735
739
  resolveSecrets: (slug) => vaultManager.resolve(`extensions/${slug}`)?.env ?? {},
@@ -738,7 +742,7 @@ function buildExtensionHostServices(params) {
738
742
  };
739
743
  }
740
744
  async function createConfiguredAgentSession(params) {
741
- const { conversationId, workspaceDir, systemPrompt, model, thinkingLevel, tools, sessionStore, models, vaultManager, platformNotifier, platformReactor, } = params;
745
+ const { conversationId, workspaceDir, systemPrompt, model, thinkingLevel, tools, sessionStore, models, vaultManager, platformNotifier, platformReactor, platformUploader, } = params;
742
746
  // Host-only dirs under the state dir: extension code runs in the mikan
743
747
  // process, so it must never load from workspace paths — those are mounted
744
748
  // into sandbox containers and agent-writable (sandbox escape otherwise).
@@ -750,6 +754,7 @@ async function createConfiguredAgentSession(params) {
750
754
  vaultManager,
751
755
  platformNotifier,
752
756
  platformReactor,
757
+ platformUploader,
753
758
  }),
754
759
  });
755
760
  for (const err of extensionsResult.errors) {
@@ -771,7 +776,12 @@ async function createConfiguredAgentSession(params) {
771
776
  if (reloaded > 0) {
772
777
  log.logInfo(`[${conversationId}] Reloaded ${reloaded} messages from session context`);
773
778
  }
774
- return { session, extensionSkills: extensionsResult.skills };
779
+ return {
780
+ session,
781
+ extensionSkills: extensionsResult.skills,
782
+ extensionRegistry: extensionsResult.registry,
783
+ disposeExtensions: extensionsResult.dispose,
784
+ };
775
785
  }
776
786
  function reloadSessionMessages(session, conversationId) {
777
787
  const reloaded = session.reloadFromSession();
@@ -782,7 +792,7 @@ function reloadSessionMessages(session, conversationId) {
782
792
  async function prepareRunContext(params) {
783
793
  const { message, responder, platform, conversationId, conversationDir, sessionUuid, runState, executor, executionResolver, resolveExecutorForRun, getPathContext, session, setEventContext, setSandboxContext, setUploadFunction, setReactFunction, bindPlatformToolPacks, } = params;
784
794
  let pathContext = params.pathContext;
785
- const sessionConversation = message.sessionKey.split(":")[0];
795
+ const sessionConversation = conversationIdOf(message.sessionKey);
786
796
  await mkdir(join(conversationDir, "scratch"), { recursive: true });
787
797
  if (executionResolver) {
788
798
  await resolveExecutorForRun({
@@ -834,7 +844,6 @@ async function prepareRunContext(params) {
834
844
  const { userMessage, imageAttachments } = buildPromptPayload(message, pathContext.runtimeWorkspaceRoot, pathContext);
835
845
  const turnInstructions = buildTurnInstructions(message.id.startsWith("event:"), triggerAttribution, platform.name);
836
846
  const finalUserMessage = turnInstructions ? `${turnInstructions}\n\n${userMessage}` : userMessage;
837
- await writePromptDebugContext(conversationDir, systemPrompt, session, finalUserMessage, imageAttachments.length);
838
847
  return {
839
848
  sessionConversation,
840
849
  runQueue,
@@ -1120,18 +1129,22 @@ function attachSessionEventHandlers(params) {
1120
1129
  * Runner caching is handled by the caller (channelStates in main.ts).
1121
1130
  * This is a stateless factory function.
1122
1131
  */
1123
- export async function createRunner(sandboxConfig, sessionKey, conversationId, conversationDir, workspaceDir, sessionScope, vaultManager, provisioner, sessionView, platformNotifier, platformReactor, platformToolPackFactories) {
1132
+ export async function createRunner(options) {
1133
+ const { sandboxConfig, sessionKey, conversationId, conversationDir, workspaceDir, sessionScope, vaultManager, provisioner, sessionView, platformNotifier, platformReactor, platformUploader, platformToolPackFactories, } = options;
1124
1134
  const agentConfig = resolveConversationSettings(conversationDir);
1125
1135
  const workspaceBase = join(conversationDir, "..");
1126
1136
  const { executionResolver, executor, getPathContext, resolveExecutorForRun } = createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspaceDir, workspaceBase);
1127
1137
  let pathContext = getUnresolvedSandboxPathContext(sandboxConfig, workspaceBase);
1128
- // Create tools (per-runner, with per-runner upload function setter)
1129
- const { tools, setUploadFunction, setReactFunction, bindPlatformToolPacks, setEventContext, setSandboxContext, } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, provisioner }, platformToolPackFactories ?? []);
1130
- const modelRegistry = MikanModels.create();
1138
+ const modelRegistry = options.models ?? MikanModels.create();
1131
1139
  if (modelRegistry.getError()) {
1132
1140
  log.logWarning("models.json load error", modelRegistry.getError());
1133
1141
  }
1134
1142
  const model = modelRegistry.resolve(agentConfig.provider, agentConfig.model);
1143
+ // Create tools (per-runner, with per-runner upload function setter)
1144
+ const { tools, setUploadFunction, setReactFunction, bindPlatformToolPacks, setEventContext, setSandboxContext, } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, provisioner }, platformToolPackFactories ?? [], {
1145
+ model,
1146
+ getApiKey: () => modelRegistry.getApiKeyForProvider(model.provider),
1147
+ });
1135
1148
  // Initial system prompt (will be updated each run with fresh memory/channels/users/skills)
1136
1149
  const memory = await getMemory(conversationDir);
1137
1150
  const skills = loadMikanSkills(conversationDir, pathContext.runtimeWorkspaceRoot);
@@ -1146,7 +1159,7 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1146
1159
  // Create session manager and settings manager. Top-level/private sessions
1147
1160
  // use the conversation's current pointer; scoped sessions use fixed files.
1148
1161
  // Platform-specific scope behavior is resolved before runner creation.
1149
- const isThread = sessionKey.includes(":");
1162
+ const isThread = isThreadSessionKey(sessionKey);
1150
1163
  const { contextFile, threadRootMessage } = sessionScope;
1151
1164
  const sessionManager = openManagedSession(contextFile, pathContext.runtimeWorkspaceRoot);
1152
1165
  const threadSessionName = buildThreadSessionName(threadRootMessage);
@@ -1155,7 +1168,7 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1155
1168
  }
1156
1169
  const sessionUuid = extractSessionUuid(contextFile);
1157
1170
  const chatSessionManager = new AgentMemoryFileManager();
1158
- const { session, extensionSkills } = await createConfiguredAgentSession({
1171
+ const { session, extensionSkills, extensionRegistry, disposeExtensions } = await createConfiguredAgentSession({
1159
1172
  conversationId,
1160
1173
  workspaceDir,
1161
1174
  systemPrompt,
@@ -1167,6 +1180,7 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1167
1180
  vaultManager,
1168
1181
  platformNotifier,
1169
1182
  platformReactor,
1183
+ platformUploader,
1170
1184
  });
1171
1185
  // Mutable per-run state - event handler references this
1172
1186
  const runState = createRunState();
@@ -1228,10 +1242,39 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1228
1242
  // Autonomous (event/trigger) runs get an explicit resource ceiling since
1229
1243
  // no human is watching the loop; interactive turns stay human-gated.
1230
1244
  const isEventRun = message.id.startsWith("event:");
1231
- await session.prompt(prepared.userMessage, {
1245
+ // Event runs have no triggering platform message, so identity fields
1246
+ // stay unset and extensions must null-check them.
1247
+ const origin = isEventRun
1248
+ ? { kind: "event", platform: platform.name }
1249
+ : {
1250
+ kind: "interactive",
1251
+ platform: platform.name,
1252
+ messageTs: message.id,
1253
+ userId: message.userId,
1254
+ userName: message.userName,
1255
+ threadTs: message.threadTs,
1256
+ attachments: message.attachments,
1257
+ };
1258
+ const outcome = await session.prompt(prepared.userMessage, {
1259
+ origin,
1232
1260
  ...(prepared.imageAttachments.length > 0 ? { images: prepared.imageAttachments } : {}),
1233
1261
  ...(isEventRun ? { budget: DEFAULT_EVENT_BUDGET } : {}),
1234
1262
  });
1263
+ if (outcome?.blocked) {
1264
+ const text = outcome.reason
1265
+ ? `_Turn blocked by an extension: ${outcome.reason}_`
1266
+ : "_Turn blocked by an extension._";
1267
+ sendAgentEvent({
1268
+ sessionId: sessionUuid,
1269
+ actorName: formatAgentActorName(message.userName, prepared.sessionConversation),
1270
+ event: { kind: "diagnostic", text },
1271
+ });
1272
+ await responder.respondDiagnostic(text, { style: "muted" });
1273
+ runState.responder = null;
1274
+ runState.logCtx = null;
1275
+ runState.queue = null;
1276
+ return { stopReason: "blocked" };
1277
+ }
1235
1278
  // Wait for queued messages
1236
1279
  await prepared.runQueue.wait();
1237
1280
  const sessionViewTokenStore = sessionView?.tokenStore;
@@ -1277,6 +1320,21 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1277
1320
  abort() {
1278
1321
  session.abort();
1279
1322
  },
1323
+ async tryExtensionCommand(message, responder) {
1324
+ const parsed = parseCommandInput(message.text);
1325
+ if (!parsed)
1326
+ return false;
1327
+ return extensionRegistry.dispatchCommand(parsed.name, {
1328
+ args: parsed.args,
1329
+ conversationId,
1330
+ userId: message.userId,
1331
+ userName: message.userName,
1332
+ respond: (text) => responder.respond(text),
1333
+ });
1334
+ },
1335
+ async dispose() {
1336
+ await disposeExtensions();
1337
+ },
1280
1338
  getCurrentStep() {
1281
1339
  const pending = runState.pendingTools;
1282
1340
  if (pending.size === 0)