@geminixiang/mikan 0.5.0-beta.0 → 0.5.1

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 (263) hide show
  1. package/CHANGELOG.md +72 -2
  2. package/README.md +13 -13
  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 +9 -6
  7. package/dist/adapters/discord/bot.d.ts.map +1 -1
  8. package/dist/adapters/discord/bot.js +22 -22
  9. package/dist/adapters/discord/bot.js.map +1 -1
  10. package/dist/adapters/discord/context.d.ts +6 -6
  11. package/dist/adapters/discord/context.d.ts.map +1 -1
  12. package/dist/adapters/discord/context.js +3 -3
  13. package/dist/adapters/discord/context.js.map +1 -1
  14. package/dist/adapters/discord/types.d.ts +2 -2
  15. package/dist/adapters/discord/types.d.ts.map +1 -1
  16. package/dist/adapters/discord/types.js.map +1 -1
  17. package/dist/adapters/intake.d.ts +2 -2
  18. package/dist/adapters/intake.d.ts.map +1 -1
  19. package/dist/adapters/intake.js +4 -4
  20. package/dist/adapters/intake.js.map +1 -1
  21. package/dist/adapters/shared.d.ts +3 -3
  22. package/dist/adapters/shared.d.ts.map +1 -1
  23. package/dist/adapters/shared.js +2 -2
  24. package/dist/adapters/shared.js.map +1 -1
  25. package/dist/adapters/slack/blocks.d.ts +6 -0
  26. package/dist/adapters/slack/blocks.d.ts.map +1 -0
  27. package/dist/adapters/slack/blocks.js +176 -0
  28. package/dist/adapters/slack/blocks.js.map +1 -0
  29. package/dist/adapters/slack/bot.d.ts +10 -8
  30. package/dist/adapters/slack/bot.d.ts.map +1 -1
  31. package/dist/adapters/slack/bot.js +58 -80
  32. package/dist/adapters/slack/bot.js.map +1 -1
  33. package/dist/adapters/slack/context.d.ts +6 -6
  34. package/dist/adapters/slack/context.d.ts.map +1 -1
  35. package/dist/adapters/slack/context.js +2 -2
  36. package/dist/adapters/slack/context.js.map +1 -1
  37. package/dist/adapters/slack/response-lifecycle.d.ts +6 -6
  38. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  39. package/dist/adapters/slack/response-lifecycle.js +8 -33
  40. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  41. package/dist/adapters/slack/session.d.ts.map +1 -1
  42. package/dist/adapters/slack/tools/attach.d.ts.map +1 -1
  43. package/dist/adapters/slack/types.d.ts +1 -1
  44. package/dist/adapters/slack/types.d.ts.map +1 -1
  45. package/dist/adapters/slack/types.js.map +1 -1
  46. package/dist/adapters/streaming.d.ts.map +1 -1
  47. package/dist/adapters/telegram/bot.d.ts +10 -7
  48. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  49. package/dist/adapters/telegram/bot.js +21 -21
  50. package/dist/adapters/telegram/bot.js.map +1 -1
  51. package/dist/adapters/telegram/context.d.ts +6 -6
  52. package/dist/adapters/telegram/context.d.ts.map +1 -1
  53. package/dist/adapters/telegram/context.js +3 -3
  54. package/dist/adapters/telegram/context.js.map +1 -1
  55. package/dist/adapters/telegram/html.d.ts.map +1 -1
  56. package/dist/adapters/telegram/types.d.ts +2 -2
  57. package/dist/adapters/telegram/types.d.ts.map +1 -1
  58. package/dist/adapters/telegram/types.js.map +1 -1
  59. package/dist/adapters/types.d.ts +6 -6
  60. package/dist/adapters/types.d.ts.map +1 -1
  61. package/dist/adapters/types.js.map +1 -1
  62. package/dist/agent-events.d.ts +5 -0
  63. package/dist/agent-events.d.ts.map +1 -0
  64. package/dist/agent-events.js +26 -0
  65. package/dist/agent-events.js.map +1 -0
  66. package/dist/agent.d.ts +7 -7
  67. package/dist/agent.d.ts.map +1 -1
  68. package/dist/agent.js +117 -82
  69. package/dist/agent.js.map +1 -1
  70. package/dist/commands/admin.d.ts.map +1 -1
  71. package/dist/commands/admin.js +1 -1
  72. package/dist/commands/admin.js.map +1 -1
  73. package/dist/commands/auto-reply.d.ts.map +1 -1
  74. package/dist/commands/auto-reply.js +3 -3
  75. package/dist/commands/auto-reply.js.map +1 -1
  76. package/dist/commands/login.d.ts.map +1 -1
  77. package/dist/commands/login.js +1 -1
  78. package/dist/commands/login.js.map +1 -1
  79. package/dist/commands/model.d.ts.map +1 -1
  80. package/dist/commands/model.js +5 -5
  81. package/dist/commands/model.js.map +1 -1
  82. package/dist/commands/new.d.ts.map +1 -1
  83. package/dist/commands/new.js +2 -2
  84. package/dist/commands/new.js.map +1 -1
  85. package/dist/commands/parse.d.ts.map +1 -1
  86. package/dist/commands/registry.d.ts.map +1 -1
  87. package/dist/commands/sandbox.d.ts.map +1 -1
  88. package/dist/commands/sandbox.js +5 -5
  89. package/dist/commands/sandbox.js.map +1 -1
  90. package/dist/commands/session-view.d.ts.map +1 -1
  91. package/dist/commands/session-view.js +1 -1
  92. package/dist/commands/session-view.js.map +1 -1
  93. package/dist/commands/types.d.ts +5 -5
  94. package/dist/commands/types.d.ts.map +1 -1
  95. package/dist/commands/types.js.map +1 -1
  96. package/dist/commands/utils.d.ts +3 -3
  97. package/dist/commands/utils.d.ts.map +1 -1
  98. package/dist/commands/utils.js +6 -6
  99. package/dist/commands/utils.js.map +1 -1
  100. package/dist/config.d.ts.map +1 -1
  101. package/dist/context.d.ts.map +1 -1
  102. package/dist/download.d.ts.map +1 -1
  103. package/dist/events.d.ts +2 -2
  104. package/dist/events.d.ts.map +1 -1
  105. package/dist/events.js.map +1 -1
  106. package/dist/execution-resolver.d.ts.map +1 -1
  107. package/dist/index.d.ts +3 -3
  108. package/dist/index.d.ts.map +1 -1
  109. package/dist/index.js +2 -2
  110. package/dist/index.js.map +1 -1
  111. package/dist/log.d.ts.map +1 -1
  112. package/dist/main.d.ts.map +1 -1
  113. package/dist/main.js +35 -27
  114. package/dist/main.js.map +1 -1
  115. package/dist/model-registry.d.ts.map +1 -1
  116. package/dist/observability/instrument.d.ts.map +1 -1
  117. package/dist/observability/sentry.d.ts.map +1 -1
  118. package/dist/observability/sentry.js +27 -9
  119. package/dist/observability/sentry.js.map +1 -1
  120. package/dist/observability/types.d.ts.map +1 -1
  121. package/dist/platform-messages.d.ts +2 -2
  122. package/dist/platform-messages.d.ts.map +1 -1
  123. package/dist/platform-messages.js +2 -2
  124. package/dist/platform-messages.js.map +1 -1
  125. package/dist/portal-shell.d.ts.map +1 -1
  126. package/dist/provisioner.d.ts.map +1 -1
  127. package/dist/provisioner.js +6 -0
  128. package/dist/provisioner.js.map +1 -1
  129. package/dist/runtime/{conversation-orchestrator.d.ts → agent-run-controller.d.ts} +7 -5
  130. package/dist/runtime/agent-run-controller.d.ts.map +1 -0
  131. package/dist/runtime/{conversation-orchestrator.js → agent-run-controller.js} +18 -17
  132. package/dist/runtime/agent-run-controller.js.map +1 -0
  133. package/dist/runtime/conversation-runtime.d.ts +4 -0
  134. package/dist/runtime/conversation-runtime.d.ts.map +1 -0
  135. package/dist/runtime/{session-runtime.js → conversation-runtime.js} +19 -15
  136. package/dist/runtime/conversation-runtime.js.map +1 -0
  137. package/dist/runtime/types.d.ts +11 -9
  138. package/dist/runtime/types.d.ts.map +1 -1
  139. package/dist/runtime/types.js.map +1 -1
  140. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  141. package/dist/sandbox/cloudflare.js +2 -4
  142. package/dist/sandbox/cloudflare.js.map +1 -1
  143. package/dist/sandbox/container.d.ts.map +1 -1
  144. package/dist/sandbox/container.js +43 -10
  145. package/dist/sandbox/container.js.map +1 -1
  146. package/dist/sandbox/errors.d.ts.map +1 -1
  147. package/dist/sandbox/firecracker.d.ts.map +1 -1
  148. package/dist/sandbox/firecracker.js +2 -4
  149. package/dist/sandbox/firecracker.js.map +1 -1
  150. package/dist/sandbox/host.d.ts.map +1 -1
  151. package/dist/sandbox/image.d.ts.map +1 -1
  152. package/dist/sandbox/index.d.ts.map +1 -1
  153. package/dist/sandbox/path-context.d.ts.map +1 -1
  154. package/dist/sandbox/types.d.ts.map +1 -1
  155. package/dist/sandbox/utils.d.ts.map +1 -1
  156. package/dist/sessions/agent-memory-file-manager.d.ts +19 -0
  157. package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -0
  158. package/dist/sessions/{chat-session-manager.js → agent-memory-file-manager.js} +107 -34
  159. package/dist/sessions/agent-memory-file-manager.js.map +1 -0
  160. package/dist/sessions/metadata.d.ts.map +1 -1
  161. package/dist/sessions/policy.d.ts.map +1 -1
  162. package/dist/sessions/store.d.ts.map +1 -1
  163. package/dist/sessions/store.js +4 -4
  164. package/dist/sessions/store.js.map +1 -1
  165. package/dist/sessions/types.d.ts +5 -3
  166. package/dist/sessions/types.d.ts.map +1 -1
  167. package/dist/sessions/types.js.map +1 -1
  168. package/dist/store.d.ts +3 -0
  169. package/dist/store.d.ts.map +1 -1
  170. package/dist/store.js +1 -1
  171. package/dist/store.js.map +1 -1
  172. package/dist/tools/bash.d.ts.map +1 -1
  173. package/dist/tools/edit.d.ts.map +1 -1
  174. package/dist/tools/event.d.ts.map +1 -1
  175. package/dist/tools/index.d.ts +1 -2
  176. package/dist/tools/index.d.ts.map +1 -1
  177. package/dist/tools/index.js +0 -4
  178. package/dist/tools/index.js.map +1 -1
  179. package/dist/tools/read.d.ts.map +1 -1
  180. package/dist/tools/sandbox.d.ts.map +1 -1
  181. package/dist/tools/truncate.d.ts.map +1 -1
  182. package/dist/tools/types.d.ts.map +1 -1
  183. package/dist/tools/write.d.ts.map +1 -1
  184. package/dist/trigger.d.ts +2 -2
  185. package/dist/trigger.d.ts.map +1 -1
  186. package/dist/trigger.js +1 -1
  187. package/dist/trigger.js.map +1 -1
  188. package/dist/types.d.ts +47 -29
  189. package/dist/types.d.ts.map +1 -1
  190. package/dist/types.js +1 -1
  191. package/dist/types.js.map +1 -1
  192. package/dist/utils/date.d.ts +1 -1
  193. package/dist/utils/date.d.ts.map +1 -1
  194. package/dist/utils/date.js +1 -1
  195. package/dist/utils/date.js.map +1 -1
  196. package/dist/utils/env.d.ts.map +1 -1
  197. package/dist/utils/file-guards.d.ts.map +1 -1
  198. package/dist/utils/fs-atomic.d.ts.map +1 -1
  199. package/dist/utils/html.d.ts.map +1 -1
  200. package/dist/utils/http-body.d.ts.map +1 -1
  201. package/dist/vault/index.d.ts.map +1 -1
  202. package/dist/vault/routing.d.ts.map +1 -1
  203. package/dist/vault/types.d.ts.map +1 -1
  204. package/dist/web/admin/portal.d.ts.map +1 -1
  205. package/dist/web/admin/portal.js +1 -1
  206. package/dist/web/admin/portal.js.map +1 -1
  207. package/dist/web/admin/provider-models.d.ts.map +1 -1
  208. package/dist/web/admin/store.d.ts.map +1 -1
  209. package/dist/web/admin/types.d.ts +1 -1
  210. package/dist/web/admin/types.d.ts.map +1 -1
  211. package/dist/web/admin/types.js.map +1 -1
  212. package/dist/web/agent-events/portal.d.ts +3 -0
  213. package/dist/web/agent-events/portal.d.ts.map +1 -0
  214. package/dist/web/agent-events/portal.js +18 -0
  215. package/dist/web/agent-events/portal.js.map +1 -0
  216. package/dist/web/login/oauth.d.ts.map +1 -1
  217. package/dist/web/login/oauth.js.map +1 -1
  218. package/dist/web/login/portal.d.ts +2 -14
  219. package/dist/web/login/portal.d.ts.map +1 -1
  220. package/dist/web/login/portal.js +53 -130
  221. package/dist/web/login/portal.js.map +1 -1
  222. package/dist/web/login/store.d.ts.map +1 -1
  223. package/dist/web/login/types.d.ts.map +1 -1
  224. package/dist/web/request.d.ts +3 -0
  225. package/dist/web/request.d.ts.map +1 -0
  226. package/dist/web/request.js +13 -0
  227. package/dist/web/request.js.map +1 -0
  228. package/dist/web/server.d.ts +28 -0
  229. package/dist/web/server.d.ts.map +1 -0
  230. package/dist/web/server.js +66 -0
  231. package/dist/web/server.js.map +1 -0
  232. package/dist/web/session-view/command.d.ts.map +1 -1
  233. package/dist/web/session-view/portal.d.ts.map +1 -1
  234. package/dist/web/session-view/portal.js +8 -8
  235. package/dist/web/session-view/portal.js.map +1 -1
  236. package/dist/web/session-view/service.d.ts.map +1 -1
  237. package/dist/web/session-view/store.d.ts.map +1 -1
  238. package/dist/web/session-view/types.d.ts +4 -4
  239. package/dist/web/session-view/types.d.ts.map +1 -1
  240. package/dist/web/session-view/types.js.map +1 -1
  241. package/dist/web/token-store.d.ts.map +1 -1
  242. package/dist/web/types.d.ts.map +1 -1
  243. package/package.json +44 -20
  244. package/dist/adapters/slack/tools/block-kit.d.ts +0 -16
  245. package/dist/adapters/slack/tools/block-kit.d.ts.map +0 -1
  246. package/dist/adapters/slack/tools/block-kit.js +0 -105
  247. package/dist/adapters/slack/tools/block-kit.js.map +0 -1
  248. package/dist/runtime/conversation-orchestrator.d.ts.map +0 -1
  249. package/dist/runtime/conversation-orchestrator.js.map +0 -1
  250. package/dist/runtime/session-runtime.d.ts +0 -4
  251. package/dist/runtime/session-runtime.d.ts.map +0 -1
  252. package/dist/runtime/session-runtime.js.map +0 -1
  253. package/dist/sandbox/credential-policy.d.ts +0 -2
  254. package/dist/sandbox/credential-policy.d.ts.map +0 -1
  255. package/dist/sandbox/credential-policy.js +0 -77
  256. package/dist/sandbox/credential-policy.js.map +0 -1
  257. package/dist/sessions/chat-session-manager.d.ts +0 -18
  258. package/dist/sessions/chat-session-manager.d.ts.map +0 -1
  259. package/dist/sessions/chat-session-manager.js.map +0 -1
  260. package/dist/tool-diagnostics.d.ts +0 -2
  261. package/dist/tool-diagnostics.d.ts.map +0 -1
  262. package/dist/tool-diagnostics.js +0 -7
  263. package/dist/tool-diagnostics.js.map +0 -1
package/dist/agent.js CHANGED
@@ -11,13 +11,13 @@ import { reportUserFacingError } from "./observability/sentry.js";
11
11
  import { createExecutor, } from "./sandbox/index.js";
12
12
  import { createMountedRuntimePathContext } from "./sandbox/path-context.js";
13
13
  import { addLifecycleBreadcrumb, metricAttributes, updateActiveSpanAttribution, } from "./observability/sentry.js";
14
- import { ChatSessionManager } from "./sessions/chat-session-manager.js";
14
+ import { AgentMemoryFileManager } from "./sessions/agent-memory-file-manager.js";
15
15
  import { extractSessionUuid, openManagedSession, } from "./sessions/store.js";
16
- import { shouldSurfaceToolDiagnostic } from "./tool-diagnostics.js";
17
16
  import { createMikanTools } from "./tools/index.js";
18
17
  import * as Sentry from "@sentry/node";
19
18
  import { formatLocalTimestamp } from "./utils/date.js";
20
19
  import { resolveConfiguredModel } from "./model-registry.js";
20
+ import { emitAgentEvent } from "./agent-events.js";
21
21
  const IMAGE_MIME_TYPES = {
22
22
  jpg: "image/jpeg",
23
23
  jpeg: "image/jpeg",
@@ -186,15 +186,9 @@ Do not add this to \`[SILENT]\` responses.
186
186
  : "";
187
187
  const slackBlockKitInstructions = platform.name === "slack"
188
188
  ? `
189
- ## Slack Block Kit
190
- - On Slack, use the \`slack_blockkit\` tool when a response benefits from interaction or structured presentation.
191
- - Good uses: choices, confirmations, clarifying questions, quizzes, status reports, comparisons, summaries, and step lists.
192
- - Do not use it for normal short replies or simple factual answers.
193
- - Supported blocks: section, context, divider, header, actions.
194
- - Put buttons in actions.elements. Put static_select and multi_static_select in section.accessory.
195
- - Every interactive element must include action_id. Buttons must include value.
196
- - Always provide a plain-text fallback in text that matches the visible Block Kit content.
197
- - When using \`slack_blockkit\`, do not also send a normal text response in the same assistant turn; put the fallback in the tool's text field.
189
+ ## Slack Rendering
190
+ - The Slack adapter renders responses with Block Kit automatically. Answer normally using Slack mrkdwn.
191
+ - Do not emit markdown pipe tables; Slack does not render them as tables. Prefer short sections or bullet lists.
198
192
  `
199
193
  : "";
200
194
  return `You are mikan, a ${platform.name} bot assistant. Be concise. No emojis.
@@ -292,7 +286,7 @@ Maintain ${workspaceRoot}/SYSTEM.md to log all environment modifications:
292
286
  Update this file whenever you modify the environment. On fresh container, read it first to restore your setup.
293
287
 
294
288
  ## Log Queries (for older history)
295
- Format: \`{"date":"...","ts":"...","user":"...","userName":"...","text":"...","isBot":false}\`
289
+ Format: \`{"date":"...","ts":"...","user":"...","userName":"...","text":"...","isMessagingBot":false}\`
296
290
  The log contains user messages and your final responses (not tool calls/results).
297
291
  Use \`log.jsonl\` for quick grep-style history. Use \`${conversationPath}/sessions/\` when you need structured turns, tool outputs, or thread/session lineage.
298
292
  ${isContainerLike || isFirecracker ? "Install jq: apt-get install jq" : ""}
@@ -324,11 +318,6 @@ ls -1 sessions/
324
318
  Each tool requires a "label" parameter (shown to user).
325
319
  `;
326
320
  }
327
- function truncate(text, maxLen) {
328
- if (text.length <= maxLen)
329
- return text;
330
- return `${text.substring(0, maxLen - 3)}...`;
331
- }
332
321
  export function getUnresolvedSandboxPathContext(sandboxConfig, hostWorkspaceRoot) {
333
322
  if (sandboxConfig.type === "image") {
334
323
  return createMountedRuntimePathContext(hostWorkspaceRoot, "/workspace");
@@ -439,10 +428,11 @@ function createEmptyUsageTotals() {
439
428
  }
440
429
  function createRunState() {
441
430
  return {
442
- responseCtx: null,
431
+ responder: null,
443
432
  logCtx: null,
444
433
  queue: null,
445
434
  pendingTools: new Map(),
435
+ toolProgress: new Map(),
446
436
  totalUsage: createEmptyUsageTotals(),
447
437
  llmCallCount: 0,
448
438
  stopReason: "stop",
@@ -452,8 +442,8 @@ function createRunState() {
452
442
  triggerAttribution: undefined,
453
443
  };
454
444
  }
455
- function resetRunState(runState, responseCtx, sessionConversation, userName, sessionUuid, triggerAttribution) {
456
- runState.responseCtx = responseCtx;
445
+ function resetRunState(runState, responder, sessionConversation, userName, sessionUuid, triggerAttribution) {
446
+ runState.responder = responder;
457
447
  runState.logCtx = {
458
448
  conversationId: sessionConversation,
459
449
  userName,
@@ -461,6 +451,7 @@ function resetRunState(runState, responseCtx, sessionConversation, userName, ses
461
451
  sessionId: sessionUuid,
462
452
  };
463
453
  runState.pendingTools.clear();
454
+ runState.toolProgress.clear();
464
455
  runState.totalUsage = createEmptyUsageTotals();
465
456
  runState.llmCallCount = 0;
466
457
  runState.stopReason = "stop";
@@ -469,7 +460,7 @@ function resetRunState(runState, responseCtx, sessionConversation, userName, ses
469
460
  runState.finalResponseHandledByTool = false;
470
461
  runState.triggerAttribution = triggerAttribution;
471
462
  }
472
- function createRunQueue(responseCtx, runState) {
463
+ function createRunQueue(responder, runState) {
473
464
  let queueChain = Promise.resolve();
474
465
  return {
475
466
  queue: {
@@ -484,7 +475,7 @@ function createRunQueue(responseCtx, runState) {
484
475
  const errMsg = err instanceof Error ? err.message : String(err);
485
476
  log.logWarning(`API error (${errorContext})`, errMsg);
486
477
  try {
487
- await responseCtx.respondDiagnostic(`Error: ${errMsg}`, { style: "error" });
478
+ await responder.respondDiagnostic(`Error: ${errMsg}`, { style: "error" });
488
479
  }
489
480
  catch {
490
481
  // Ignore
@@ -558,7 +549,29 @@ export function appendTriggerAttribution(text, triggerAttribution) {
558
549
  return text;
559
550
  return `${text.trimEnd()}\n\n${suffix}`;
560
551
  }
561
- async function finalizeRunResponse(responseCtx, session, runState, options) {
552
+ function extractToolLabel(toolName, args) {
553
+ const label = args?.label;
554
+ if (typeof label !== "string")
555
+ return toolName;
556
+ return label.trim() || toolName;
557
+ }
558
+ function formatToolProgress(runState) {
559
+ const lines = Array.from(runState.toolProgress.values()).map((item) => {
560
+ const marker = item.status === "running" ? "•" : item.status === "error" ? "✗" : "✓";
561
+ return `${marker} ${item.label}`;
562
+ });
563
+ return lines.join("\n");
564
+ }
565
+ function formatResponseWithToolProgress(text, runState) {
566
+ const progress = formatToolProgress(runState);
567
+ return progress ? `${progress}\n\n${text}` : text;
568
+ }
569
+ async function replaceResponseWithToolProgress(responder, runState) {
570
+ const progress = formatToolProgress(runState);
571
+ if (progress)
572
+ await responder.replaceResponse(progress);
573
+ }
574
+ async function finalizeRunResponse(responder, session, runState, options) {
562
575
  if (runState.stopReason === "error" && runState.errorMessage) {
563
576
  if (!runState.reportedLlmError) {
564
577
  runState.reportedLlmError = true;
@@ -580,8 +593,8 @@ async function finalizeRunResponse(responseCtx, session, runState, options) {
580
593
  });
581
594
  }
582
595
  try {
583
- await responseCtx.replaceResponse("_Sorry, something went wrong_");
584
- await responseCtx.respondDiagnostic(`Error: ${runState.errorMessage}`, {
596
+ await responder.replaceResponse("_Sorry, something went wrong_");
597
+ await responder.respondDiagnostic(`Error: ${runState.errorMessage}`, {
585
598
  style: "error",
586
599
  });
587
600
  }
@@ -610,7 +623,7 @@ async function finalizeRunResponse(responseCtx, session, runState, options) {
610
623
  }
611
624
  if (finalText.trim() === "[SILENT]" || finalText.trim().startsWith("[SILENT]")) {
612
625
  try {
613
- await responseCtx.deleteResponse();
626
+ await responder.deleteResponse();
614
627
  log.logInfo("Silent response - deleted message and thread");
615
628
  }
616
629
  catch (err) {
@@ -622,7 +635,7 @@ async function finalizeRunResponse(responseCtx, session, runState, options) {
622
635
  if (!finalText.trim())
623
636
  return;
624
637
  try {
625
- await responseCtx.replaceResponse(appendTriggerAttribution(finalText, options?.triggerAttribution), { createOverflowLink: options?.createOverflowLink });
638
+ await responder.replaceResponse(appendTriggerAttribution(formatResponseWithToolProgress(finalText, runState), options?.triggerAttribution), { createOverflowLink: options?.createOverflowLink });
626
639
  }
627
640
  catch (err) {
628
641
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -642,9 +655,7 @@ async function finalizeRunResponse(responseCtx, session, runState, options) {
642
655
  }
643
656
  }
644
657
  async function reportUsageSummary(ctx) {
645
- const { session, runState, responseCtx, platform, model, agentConfig, sessionConversation, sessionUuid, waitForQueue, } = ctx;
646
- if (runState.totalUsage.cost.total <= 0)
647
- return;
658
+ const { session, runState, responder, platform, model, agentConfig, sessionConversation, sessionUuid, waitForQueue, } = ctx;
648
659
  const lastAssistantMessage = session.messages
649
660
  .slice()
650
661
  .toReversed()
@@ -686,7 +697,7 @@ async function reportUsageSummary(ctx) {
686
697
  });
687
698
  const summary = log.logUsageSummary(runState.logCtx, runState.totalUsage, contextTokens, contextWindow);
688
699
  if (platform.diagnostics?.showUsageSummary === true) {
689
- runState.queue.enqueue(() => responseCtx.respondDiagnostic(summary, { style: "muted" }), "usage summary");
700
+ runState.queue.enqueue(() => responder.respondDiagnostic(summary, { style: "muted" }), "usage summary");
690
701
  await waitForQueue();
691
702
  }
692
703
  }
@@ -698,7 +709,7 @@ function reloadSessionMessages(sessionManager, conversationId, agent) {
698
709
  }
699
710
  }
700
711
  async function prepareRunContext(params) {
701
- const { message, responseCtx, platform, conversationId, conversationDir, sessionUuid, runState, executor, executionResolver, resolveExecutorForRun, getPathContext, sessionManager, session, agent, setEventContext, setSandboxContext, setUploadFunction, setBlockKitResponseFunction, } = params;
712
+ const { message, responder, platform, conversationId, conversationDir, sessionUuid, runState, executor, executionResolver, resolveExecutorForRun, getPathContext, sessionManager, session, agent, setEventContext, setSandboxContext, setUploadFunction, } = params;
702
713
  let pathContext = params.pathContext;
703
714
  const sessionConversation = message.sessionKey.split(":")[0];
704
715
  await mkdir(join(conversationDir, "scratch"), { recursive: true });
@@ -725,19 +736,10 @@ async function prepareRunContext(params) {
725
736
  setSandboxContext({ conversationId, userId: message.userId });
726
737
  setUploadFunction(async (filePath, title) => {
727
738
  const hostPath = translateAttachPathToHost(filePath, pathContext);
728
- await responseCtx.uploadFile(hostPath, title);
729
- });
730
- setBlockKitResponseFunction(async (response) => {
731
- if (platform.name === "slack" && responseCtx.respondBlockKit) {
732
- await responseCtx.respondBlockKit(response);
733
- }
734
- else {
735
- await responseCtx.replaceResponse(response.text);
736
- }
737
- runState.finalResponseHandledByTool = true;
739
+ await responder.uploadFile(hostPath, title);
738
740
  });
739
- resetRunState(runState, responseCtx, sessionConversation, message.userName, sessionUuid, triggerAttribution);
740
- const runQueue = createRunQueue(responseCtx, runState);
741
+ resetRunState(runState, responder, sessionConversation, message.userName, sessionUuid, triggerAttribution);
742
+ const runQueue = createRunQueue(responder, runState);
741
743
  runState.queue = runQueue.queue;
742
744
  log.logInfo(`Context sizes - system: ${systemPrompt.length} chars, memory: ${memory.length} chars`);
743
745
  log.logInfo(`Channels: ${platform.channels.length}, Users: ${platform.users.length}`);
@@ -752,21 +754,43 @@ async function prepareRunContext(params) {
752
754
  pathContext,
753
755
  };
754
756
  }
757
+ function formatAgentActorName(userName, fallback) {
758
+ return userName ? `DM:${userName}` : fallback;
759
+ }
760
+ function sendAgentEvent(payload) {
761
+ emitAgentEvent({ source: "mikan", ...payload });
762
+ }
755
763
  function attachSessionEventHandlers(params) {
756
764
  const { session, runState, model, agentConfig } = params;
757
765
  session.subscribe(async (event) => {
758
- if (!runState.responseCtx || !runState.logCtx || !runState.queue)
766
+ if (!runState.responder || !runState.logCtx || !runState.queue)
759
767
  return;
760
- const { responseCtx, logCtx, queue, pendingTools } = runState;
768
+ const { responder, logCtx, queue, pendingTools } = runState;
761
769
  const baseAttrs = { channel_id: logCtx.conversationId, session_id: logCtx.sessionId };
770
+ const agentEventSessionId = logCtx.sessionId ?? logCtx.conversationId;
762
771
  if (event.type === "tool_execution_start") {
763
772
  const args = (event.args ?? {});
764
773
  const label = args.label || event.toolName;
774
+ sendAgentEvent({
775
+ sessionId: agentEventSessionId,
776
+ actorName: formatAgentActorName(logCtx.userName, logCtx.conversationId),
777
+ event: {
778
+ kind: "toolStart",
779
+ toolId: event.toolCallId,
780
+ toolName: event.toolName,
781
+ input: { label },
782
+ },
783
+ });
765
784
  pendingTools.set(event.toolCallId, {
766
785
  toolName: event.toolName,
767
786
  args: event.args,
768
787
  startTime: Date.now(),
769
788
  });
789
+ runState.toolProgress.set(event.toolCallId, {
790
+ label: extractToolLabel(event.toolName, event.args),
791
+ status: "running",
792
+ });
793
+ queue.enqueue(() => replaceResponseWithToolProgress(responder, runState), "tool progress update");
770
794
  addLifecycleBreadcrumb("agent.tool.started", {
771
795
  tool: event.toolName,
772
796
  ...baseAttrs,
@@ -777,6 +801,15 @@ function attachSessionEventHandlers(params) {
777
801
  if (event.type === "tool_execution_end") {
778
802
  const resultStr = extractToolResultText(event.result);
779
803
  const pending = pendingTools.get(event.toolCallId);
804
+ sendAgentEvent({
805
+ sessionId: agentEventSessionId,
806
+ actorName: formatAgentActorName(logCtx.userName, logCtx.conversationId),
807
+ event: { kind: "toolEnd", toolId: event.toolCallId },
808
+ });
809
+ const progress = runState.toolProgress.get(event.toolCallId);
810
+ if (progress)
811
+ progress.status = event.isError ? "error" : "done";
812
+ queue.enqueue(() => replaceResponseWithToolProgress(responder, runState), "tool progress update");
780
813
  pendingTools.delete(event.toolCallId);
781
814
  const durationMs = pending ? Date.now() - pending.startTime : 0;
782
815
  Sentry.metrics.count("agent.tool.calls", 1, {
@@ -805,25 +838,16 @@ function attachSessionEventHandlers(params) {
805
838
  else {
806
839
  log.logToolSuccess(logCtx, event.toolName, durationMs, resultStr);
807
840
  }
808
- if (shouldSurfaceToolDiagnostic(event.toolName)) {
809
- const toolResult = {
810
- toolName: event.toolName,
811
- label: pending?.args ? pending.args.label : undefined,
812
- args: pending?.args,
813
- result: truncate(resultStr, TOOL_RESULT_DIAGNOSTIC_CAP),
814
- isError: event.isError,
815
- durationMs,
816
- };
817
- queue.enqueue(() => responseCtx.respondToolResult(toolResult), "tool result diagnostic");
818
- }
819
- if (event.isError && shouldSurfaceToolDiagnostic(event.toolName)) {
820
- queue.enqueue(() => responseCtx.respond(`_Error: ${truncate(resultStr, 200)}_`), "tool error");
821
- }
822
841
  return;
823
842
  }
824
843
  if (event.type === "message_start") {
825
844
  if (event.message.role === "assistant") {
826
845
  runState.llmCallCount += 1;
846
+ sendAgentEvent({
847
+ sessionId: agentEventSessionId,
848
+ actorName: formatAgentActorName(logCtx.userName, logCtx.conversationId),
849
+ event: { kind: "sessionStart" },
850
+ });
827
851
  addLifecycleBreadcrumb("agent.llm.call.started", {
828
852
  call_index: runState.llmCallCount,
829
853
  provider: model.provider,
@@ -838,9 +862,9 @@ function attachSessionEventHandlers(params) {
838
862
  const assistantMessageEvent = event.assistantMessageEvent;
839
863
  if (assistantMessageEvent?.type === "text_delta" &&
840
864
  assistantMessageEvent.delta &&
841
- responseCtx.appendResponseDelta) {
865
+ responder.appendResponseDelta) {
842
866
  queue.enqueue(async () => {
843
- await responseCtx.appendResponseDelta?.(assistantMessageEvent.delta ?? "");
867
+ await responder.appendResponseDelta?.(assistantMessageEvent.delta ?? "");
844
868
  }, "response delta");
845
869
  }
846
870
  return;
@@ -916,21 +940,26 @@ function attachSessionEventHandlers(params) {
916
940
  const text = textParts.join("\n");
917
941
  for (const thinking of thinkingParts) {
918
942
  log.logThinking(logCtx, thinking);
919
- queue.enqueue(() => responseCtx.respond(`_${thinking}_`), "thinking main");
920
- queue.enqueue(() => responseCtx.respondDiagnostic(`_${thinking}_`), "thinking diagnostic");
943
+ queue.enqueue(() => responder.respond(`_${thinking}_`), "thinking main");
944
+ queue.enqueue(() => responder.respondDiagnostic(`_${thinking}_`), "thinking diagnostic");
921
945
  }
922
946
  if (text.trim() && !hasToolCall) {
923
947
  if (runState.finalResponseHandledByTool)
924
948
  return;
925
- const finalText = appendTriggerAttribution(text, runState.triggerAttribution);
949
+ const finalText = appendTriggerAttribution(formatResponseWithToolProgress(text, runState), runState.triggerAttribution);
926
950
  log.logResponse(logCtx, text);
927
- if (responseCtx.finishResponse) {
951
+ sendAgentEvent({
952
+ sessionId: agentEventSessionId,
953
+ actorName: formatAgentActorName(logCtx.userName, logCtx.conversationId),
954
+ event: { kind: "turnEnd" },
955
+ });
956
+ if (responder.finishResponse) {
928
957
  queue.enqueue(async () => {
929
- await responseCtx.finishResponse?.(finalText);
958
+ await responder.finishResponse?.(finalText);
930
959
  }, "response finish");
931
960
  }
932
961
  else {
933
- queue.enqueue(() => responseCtx.respond(finalText), "response main");
962
+ queue.enqueue(() => responder.respond(finalText), "response main");
934
963
  }
935
964
  }
936
965
  }
@@ -938,7 +967,7 @@ function attachSessionEventHandlers(params) {
938
967
  }
939
968
  if (event.type === "compaction_start") {
940
969
  log.logInfo(`Auto-compaction started (reason: ${event.reason})`);
941
- queue.enqueue(() => responseCtx.respond("_Compacting context..._"), "compaction start");
970
+ queue.enqueue(() => responder.respond("_Compacting context..._"), "compaction start");
942
971
  return;
943
972
  }
944
973
  if (event.type === "compaction_end") {
@@ -952,13 +981,15 @@ function attachSessionEventHandlers(params) {
952
981
  }
953
982
  if (event.type === "auto_retry_start") {
954
983
  log.logWarning(`Retrying (${event.attempt}/${event.maxAttempts})`, event.errorMessage);
955
- queue.enqueue(() => responseCtx.respond(`_Retrying (${event.attempt}/${event.maxAttempts})..._`), "retry");
984
+ sendAgentEvent({
985
+ sessionId: agentEventSessionId,
986
+ actorName: formatAgentActorName(logCtx.userName, logCtx.conversationId),
987
+ event: { kind: "sessionStart" },
988
+ });
989
+ queue.enqueue(() => responder.respond(`_Retrying (${event.attempt}/${event.maxAttempts})..._`), "retry");
956
990
  }
957
991
  });
958
992
  }
959
- // Cap raw tool output before handing it to adapters. Bash output can be MB; without
960
- // this each adapter's splitter would fan it out into many sequential platform posts.
961
- const TOOL_RESULT_DIAGNOSTIC_CAP = 8000;
962
993
  function extractToolResultText(result) {
963
994
  if (typeof result === "string") {
964
995
  return result;
@@ -981,7 +1012,7 @@ function extractToolResultText(result) {
981
1012
  return JSON.stringify(result);
982
1013
  }
983
1014
  /**
984
- * Create a new AgentRunner for a channel.
1015
+ * Create a new PiAgentWrapper for a channel.
985
1016
  * Sets up the session and subscribes to events once.
986
1017
  *
987
1018
  * Runner caching is handled by the caller (channelStates in main.ts).
@@ -993,7 +1024,7 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
993
1024
  const { executionResolver, executor, getPathContext, resolveExecutorForRun } = createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspaceDir, workspaceBase);
994
1025
  let pathContext = getUnresolvedSandboxPathContext(sandboxConfig, workspaceBase);
995
1026
  // Create tools (per-runner, with per-runner upload function setter)
996
- const { tools, setUploadFunction, setBlockKitResponseFunction, setEventContext, setSandboxContext, } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, provisioner });
1027
+ const { tools, setUploadFunction, setEventContext, setSandboxContext } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, provisioner });
997
1028
  const authStorage = AuthStorage.create(join(homedir(), ".pi", "mikan", "auth.json"));
998
1029
  const modelRegistry = ModelRegistry.create(authStorage);
999
1030
  const model = resolveConfiguredModel(modelRegistry, agentConfig.provider, agentConfig.model);
@@ -1018,7 +1049,7 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1018
1049
  sessionManager.appendSessionInfo(threadSessionName);
1019
1050
  }
1020
1051
  const sessionUuid = extractSessionUuid(contextFile);
1021
- const chatSessionManager = new ChatSessionManager();
1052
+ const chatSessionManager = new AgentMemoryFileManager();
1022
1053
  const settingsManager = SettingsManager.inMemory();
1023
1054
  const { agent, session } = await createConfiguredAgentSession({
1024
1055
  conversationId,
@@ -1044,10 +1075,10 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1044
1075
  currentMessageId,
1045
1076
  });
1046
1077
  },
1047
- async run(message, responseCtx, platform) {
1078
+ async run(message, responder, platform) {
1048
1079
  const prepared = await prepareRunContext({
1049
1080
  message,
1050
- responseCtx,
1081
+ responder,
1051
1082
  platform,
1052
1083
  conversationId,
1053
1084
  conversationDir,
@@ -1063,7 +1094,6 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1063
1094
  setEventContext,
1064
1095
  setSandboxContext,
1065
1096
  setUploadFunction,
1066
- setBlockKitResponseFunction,
1067
1097
  pathContext,
1068
1098
  });
1069
1099
  pathContext = prepared.pathContext;
@@ -1084,6 +1114,11 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1084
1114
  attachment_count: message.attachments?.length ?? 0,
1085
1115
  image_attachment_count: prepared.imageAttachments.length,
1086
1116
  });
1117
+ sendAgentEvent({
1118
+ sessionId: sessionUuid,
1119
+ actorName: formatAgentActorName(message.userName, prepared.sessionConversation),
1120
+ event: { kind: "sessionStart" },
1121
+ });
1087
1122
  await session.prompt(prepared.userMessage, prepared.imageAttachments.length > 0 ? { images: prepared.imageAttachments } : undefined);
1088
1123
  // Wait for queued messages
1089
1124
  await prepared.runQueue.wait();
@@ -1095,7 +1130,7 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1095
1130
  return `${sessionViewPortalBaseUrl}/session?token=${token.token}`;
1096
1131
  }
1097
1132
  : undefined;
1098
- await finalizeRunResponse(responseCtx, session, runState, {
1133
+ await finalizeRunResponse(responder, session, runState, {
1099
1134
  triggerAttribution: prepared.triggerAttribution,
1100
1135
  createOverflowLink,
1101
1136
  platform: platform.name,
@@ -1106,7 +1141,7 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1106
1141
  await reportUsageSummary({
1107
1142
  session,
1108
1143
  runState,
1109
- responseCtx,
1144
+ responder,
1110
1145
  platform,
1111
1146
  model,
1112
1147
  agentConfig,
@@ -1115,7 +1150,7 @@ export async function createRunner(sandboxConfig, sessionKey, conversationId, co
1115
1150
  waitForQueue: () => prepared.runQueue.wait(),
1116
1151
  });
1117
1152
  // Clear run state
1118
- runState.responseCtx = null;
1153
+ runState.responder = null;
1119
1154
  runState.logCtx = null;
1120
1155
  runState.queue = null;
1121
1156
  return { stopReason: runState.stopReason, errorMessage: runState.errorMessage };