@geminixiang/mikan 1.0.0-beta.14 → 1.0.0-beta.16

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 (74) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +33 -7
  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/slack/response-lifecycle.js +1 -1
  7. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  8. package/dist/agent.d.ts +2 -1
  9. package/dist/agent.d.ts.map +1 -1
  10. package/dist/agent.js +66 -21
  11. package/dist/agent.js.map +1 -1
  12. package/dist/execution-resolver.d.ts +2 -1
  13. package/dist/execution-resolver.d.ts.map +1 -1
  14. package/dist/execution-resolver.js +15 -2
  15. package/dist/execution-resolver.js.map +1 -1
  16. package/dist/harness/extensions/loader.d.ts +6 -0
  17. package/dist/harness/extensions/loader.d.ts.map +1 -1
  18. package/dist/harness/extensions/loader.js +24 -4
  19. package/dist/harness/extensions/loader.js.map +1 -1
  20. package/dist/harness/extensions/registry.d.ts +48 -1
  21. package/dist/harness/extensions/registry.d.ts.map +1 -1
  22. package/dist/harness/extensions/registry.js +146 -0
  23. package/dist/harness/extensions/registry.js.map +1 -1
  24. package/dist/harness/extensions/types.d.ts +123 -12
  25. package/dist/harness/extensions/types.d.ts.map +1 -1
  26. package/dist/harness/extensions/types.js.map +1 -1
  27. package/dist/harness/index.d.ts +3 -3
  28. package/dist/harness/index.d.ts.map +1 -1
  29. package/dist/harness/index.js +1 -1
  30. package/dist/harness/index.js.map +1 -1
  31. package/dist/harness/runner.d.ts +13 -2
  32. package/dist/harness/runner.d.ts.map +1 -1
  33. package/dist/harness/runner.js +59 -16
  34. package/dist/harness/runner.js.map +1 -1
  35. package/dist/main.js +25 -15
  36. package/dist/main.js.map +1 -1
  37. package/dist/runtime/conversation-runtime.js +32 -4
  38. package/dist/runtime/conversation-runtime.js.map +1 -1
  39. package/dist/runtime/types.d.ts +3 -1
  40. package/dist/runtime/types.d.ts.map +1 -1
  41. package/dist/runtime/types.js.map +1 -1
  42. package/dist/sandbox/identity.d.ts +1 -1
  43. package/dist/sandbox/identity.d.ts.map +1 -1
  44. package/dist/sandbox/identity.js +2 -1
  45. package/dist/sandbox/identity.js.map +1 -1
  46. package/dist/sandbox/index.d.ts +4 -3
  47. package/dist/sandbox/index.d.ts.map +1 -1
  48. package/dist/sandbox/index.js +5 -3
  49. package/dist/sandbox/index.js.map +1 -1
  50. package/dist/sandbox/microvm.d.ts +17 -0
  51. package/dist/sandbox/microvm.d.ts.map +1 -0
  52. package/dist/sandbox/microvm.js +145 -0
  53. package/dist/sandbox/microvm.js.map +1 -0
  54. package/dist/sandbox/types.d.ts +8 -1
  55. package/dist/sandbox/types.d.ts.map +1 -1
  56. package/dist/sandbox/types.js.map +1 -1
  57. package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -1
  58. package/dist/sessions/agent-memory-file-manager.js +0 -11
  59. package/dist/sessions/agent-memory-file-manager.js.map +1 -1
  60. package/dist/tools/generate-image.d.ts +17 -0
  61. package/dist/tools/generate-image.d.ts.map +1 -0
  62. package/dist/tools/generate-image.js +63 -0
  63. package/dist/tools/generate-image.js.map +1 -0
  64. package/dist/tools/index.d.ts +5 -1
  65. package/dist/tools/index.d.ts.map +1 -1
  66. package/dist/tools/index.js +10 -2
  67. package/dist/tools/index.js.map +1 -1
  68. package/dist/types.d.ts +19 -0
  69. package/dist/types.d.ts.map +1 -1
  70. package/dist/types.js.map +1 -1
  71. package/dist/vault/index.d.ts.map +1 -1
  72. package/dist/vault/index.js +1 -17
  73. package/dist/vault/index.js.map +1 -1
  74. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -9,6 +9,51 @@ any release.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.0.0-beta.16]
13
+
14
+ ### Added
15
+
16
+ - Add a preview `microvm:default` sandbox backed by Gondolin and QEMU.
17
+ - Add a curated microVM guest image build with Node.js, Python, uv, Git, ripgrep, fd, jq, SSH, and build tools.
18
+ - Manage one process-local microVM per conversation with idle shutdown and recreation on demand.
19
+
20
+ ### Changed
21
+
22
+ - Broaden the coverage gate across all source modules.
23
+
24
+ ### Fixed
25
+
26
+ - Keep top-level Slack file uploads out of threads.
27
+
28
+ ### Tests
29
+
30
+ - Add coverage for microVM execution and lifecycle, events, logging, disabled vaults, channel storage, and core file and shell tools.
31
+
32
+ ## [1.0.0-beta.15]
33
+
34
+ ### Added
35
+
36
+ - Add native image generation with automatic upload through the active model provider.
37
+ - Add extension chat commands via `api.registerCommand`: deterministic `/name` dispatch with no model call; built-ins and first registrations win.
38
+ - Add an extension disposal lifecycle (`api.onDispose` or an `activate` return value), run when a harness instance is discarded (`/pi-new`, idle eviction, session rotation).
39
+ - Add `api.triggerRun(text)` to fire an immediate autonomous agent run, `api.uploadFile(path, title)` for proactive file uploads, and an explicit `conversationId` option on `api.notify` for cross-conversation posting.
40
+ - Add `agent_error` and `budget_exceeded` extension hooks so monitoring extensions see failed turns and tripped run budgets.
41
+ - Pass a `RunOrigin` (platform, triggering message id, user identity, attachments) to extension hook events, making `api.react` and per-user extension policy usable.
42
+ - Let `before_agent_start` extensions rewrite the user prompt or block the turn before the model runs; blocked turns leave no trace in the transcript or session store.
43
+ - Let `tool_result` extensions rewrite tool output (content and error flag) before the model and the session store see it, enabling secret redaction and output truncation.
44
+
45
+ ### Changed
46
+
47
+ - Dispatch `before_agent_start` and `tool_result` hooks with chaining semantics (each handler sees earlier handlers' rewrites; any `block` wins) instead of first-result-wins.
48
+
49
+ ### Fixed
50
+
51
+ - Dispose cached runners when models switch or environment credentials refresh.
52
+
53
+ ### Tests
54
+
55
+ - Add coverage for image generation, extension lifecycle and hook rewrites, and runner disposal.
56
+
12
57
  ## [1.0.0-beta.14]
13
58
 
14
59
  ### Added
package/README.md CHANGED
@@ -51,19 +51,45 @@ npm install && npm run build
51
51
 
52
52
  ## Quick Start
53
53
 
54
- All platforms share the same CLI:
54
+ Run mikan under [PM2](https://pm2.keymetrics.io/) so it stays up, restarts after failures, and starts on boot:
55
55
 
56
56
  ```bash
57
- mikan [--state-dir=~/.mikan] [--sandbox=<mode>] <working-directory>
57
+ npm i -g @geminixiang/mikan pm2
58
+
59
+ # One-time setup: create the state directory and settings
60
+ mikan --onboard --state-dir=~/.mikan
61
+
62
+ # Grab the maintained ecosystem file, then edit `args` and `env`
63
+ curl -O https://raw.githubusercontent.com/geminixiang/mikan/main/deploy/pm2/ecosystem.config.cjs
64
+
65
+ pm2 start ecosystem.config.cjs
66
+ pm2 save
67
+ pm2 startup # run the printed command to enable boot autostart
68
+ ```
69
+
70
+ In `ecosystem.config.cjs`, point `args` at your state dir, sandbox mode, and working directory:
71
+
72
+ ```js
73
+ args: "--state-dir=/srv/mikan/state --sandbox=host /srv/mikan/workspace",
74
+ ```
75
+
76
+ Then set the platform tokens you need in `env`; you can run multiple platforms at once:
77
+
78
+ ```js
79
+ env: {
80
+ SLACK_APP_TOKEN: "xapp-...",
81
+ SLACK_BOT_TOKEN: "xoxb-...",
82
+ TELEGRAM_BOT_TOKEN: "123456:ABC-...",
83
+ DISCORD_BOT_TOKEN: "MTI...",
84
+ },
58
85
  ```
59
86
 
60
- Set the platform tokens you need; you can run multiple platforms at once:
87
+ Tail logs with `pm2 logs mikan`; upgrade with `npm i -g @geminixiang/mikan && pm2 reload mikan`. See [the deployment guide](src/content/docs/deployment.mdx) for sandbox images, graceful shutdown, and the health endpoint.
88
+
89
+ For a one-off foreground run, the same CLI works directly:
61
90
 
62
91
  ```bash
63
- export SLACK_APP_TOKEN=xapp-...
64
- export SLACK_BOT_TOKEN=xoxb-...
65
- export TELEGRAM_BOT_TOKEN=123456:ABC-...
66
- export DISCORD_BOT_TOKEN=MTI...
92
+ mikan [--state-dir=~/.mikan] [--sandbox=<mode>] <working-directory>
67
93
  ```
68
94
 
69
95
  ## Platforms
package/dist/adapter.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export type { MessagingBot, ConversationContext, ConversationEvent, MessagingEventHandler, ChatAdapter, ConversationMessage, ConversationResponder, ChatToolResult, ConversationKind, MessagingInfo, PlatformName, PlatformNotifier, PlatformReactor, RunningSession, } from "./types.js";
1
+ export type { MessagingBot, ConversationContext, ConversationEvent, MessagingEventHandler, ChatAdapter, ConversationMessage, ConversationResponder, ChatToolResult, ConversationKind, MessagingInfo, PlatformName, PlatformNotifier, PlatformReactor, PlatformUploader, RunningSession, } from "./types.js";
2
2
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,cAAc,GACf,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"","sourcesContent":["export type {\n MessagingBot,\n ConversationContext,\n ConversationEvent,\n MessagingEventHandler,\n ChatAdapter,\n ConversationMessage,\n ConversationResponder,\n ChatToolResult,\n ConversationKind,\n MessagingInfo,\n PlatformName,\n PlatformNotifier,\n PlatformReactor,\n RunningSession,\n} from \"./types.js\";\n"]}
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"","sourcesContent":["export type {\n MessagingBot,\n ConversationContext,\n ConversationEvent,\n MessagingEventHandler,\n ChatAdapter,\n ConversationMessage,\n ConversationResponder,\n ChatToolResult,\n ConversationKind,\n MessagingInfo,\n PlatformName,\n PlatformNotifier,\n PlatformReactor,\n PlatformUploader,\n RunningSession,\n} from \"./types.js\";\n"]}
@@ -335,7 +335,7 @@ export function createSlackResponseContext({ event, slack, sessionPlan, replyMod
335
335
  }
336
336
  },
337
337
  uploadFile: async (filePath, title) => {
338
- await slack.uploadFile(channelId, filePath, title, rootTs);
338
+ await slack.uploadFile(channelId, filePath, title, replyInThread ? rootTs : undefined);
339
339
  },
340
340
  react: async (emoji) => {
341
341
  // React to the triggering message. Event runs have no real message ts.
@@ -1 +1 @@
1
- {"version":3,"file":"response-lifecycle.js","sourceRoot":"","sources":["../../../src/adapters/slack/response-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ConversationMessage, ConversationResponder, ChatToolResult } from \"../../adapter.js\";\nimport * as log from \"../../log.js\";\nimport {\n createChatResponseErrorReporter,\n formatToolArgs,\n splitText,\n type ChatResponseErrorOperation,\n} from \"../shared.js\";\nimport { BufferedResponseStream, OrderedResponseOperations } from \"../streaming.js\";\nimport { buildMrkdwnContextBlock, type SlackMessagingBot, type SlackEvent } from \"./bot.js\";\nimport type { SlackAdapterSessionPlan } from \"./types.js\";\n\nconst MAX_MAIN_LENGTH = 35000; // Best-effort streaming cap; final responses use Slack error-driven fallback.\nconst MAX_THREAD_LENGTH = 20000;\nconst FALLBACK_MAIN_LENGTH = 3000;\nconst WORKING_INDICATOR = \" ...\";\nconst TRUNCATION_NOTE_INCREMENTAL =\n \"\\n\\n_(message truncated, ask me to elaborate on specific parts)_\";\n\nconst formatSlackContinuation = (partNum: number): string => `_(continued ${partNum})_`;\n\nfunction isSlackMsgTooLong(err: unknown): boolean {\n const data = (err as { data?: { error?: string } } | undefined)?.data;\n const message = err instanceof Error ? err.message : String(err);\n return data?.error === \"msg_too_long\" || message.includes(\"msg_too_long\");\n}\n\nfunction fallbackLongSlackText(\n text: string,\n overflowLink?: string,\n prefixLength = FALLBACK_MAIN_LENGTH,\n): string {\n const suffix = overflowLink\n ? `\\n\\n_(message too long for Slack; continued in thread; session view: <${overflowLink}|open>)_`\n : \"\\n\\n_(message too long for Slack; continued in thread)_\";\n return `${text.slice(0, prefixLength)}${suffix}`;\n}\n\nasync function postSlackTextWithFallback(\n post: (text: string) => Promise<string | void>,\n text: string,\n overflowLink?: string,\n): Promise<{ result: string | void; text: string; prefixLength: number }> {\n let prefixLength = FALLBACK_MAIN_LENGTH;\n let lastErr: unknown;\n\n for (;;) {\n const fallbackText = fallbackLongSlackText(text, overflowLink, prefixLength);\n try {\n const result = await post(fallbackText);\n return { result, text: fallbackText, prefixLength };\n } catch (err) {\n if (!isSlackMsgTooLong(err)) throw err;\n lastErr = err;\n if (prefixLength === 0) {\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));\n }\n prefixLength = Math.max(0, Math.floor(prefixLength / 2));\n }\n }\n}\n\nfunction formatSlackToolResult(result: ChatToolResult): string {\n const argsFormatted = formatToolArgs(result.args);\n const duration = (result.durationMs / 1000).toFixed(1);\n let text = `*${result.isError ? \"✗\" : \"✓\"} ${result.toolName}*`;\n if (result.label) text += `: ${result.label}`;\n text += ` (${duration}s)\\n`;\n if (argsFormatted) text += `\\`\\`\\`\\n${argsFormatted}\\n\\`\\`\\`\\n`;\n text += `*Result:*\\n\\`\\`\\`\\n${result.result}\\n\\`\\`\\``;\n return text;\n}\n\nexport function createSlackResponseContext({\n event,\n slack,\n sessionPlan,\n replyMode,\n message,\n}: {\n event: SlackEvent;\n slack: SlackMessagingBot;\n sessionPlan: SlackAdapterSessionPlan;\n replyMode: \"top-level\" | \"thread\";\n message: ConversationMessage;\n}): ConversationResponder {\n let messageTs: string | null = sessionPlan.initialMessageTs ?? null;\n let assistantStatusFailureWarned = false;\n const onAssistantStatusError = (label: string, err: unknown): void => {\n if (assistantStatusFailureWarned) return;\n assistantStatusFailureWarned = true;\n log.logWarning(\n `Slack setAssistantStatus failed (${label}; further occurrences suppressed for this session)`,\n err instanceof Error ? err.message : String(err),\n );\n };\n const threadMessageTs: string[] = [];\n let accumulatedText = \"\";\n let isWorking = true;\n let mainResponseLogged = false;\n let streamActive = false;\n let streamUnavailable = false;\n let streamedText = \"\";\n const responseOperations = new OrderedResponseOperations();\n\n const channelId = event.channel;\n const conversationId = event.conversationId;\n\n // Slack message timestamps are numeric; event-file triggers use `event:<filename>`.\n const eventFilename = event.ts.match(/^event:([^:]+(?:\\.json)?)/)?.[1];\n\n const { rootTs, isThreaded } = sessionPlan;\n const replyInThread = Boolean(rootTs && (isThreaded || replyMode === \"thread\"));\n\n /**\n * Post the first visible reply.\n * Default Slack behavior is now top-level channel replies.\n * If the triggering message is already inside a thread, stay in that thread.\n */\n const postFirstMessage = async (text: string): Promise<string> => {\n if (replyInThread && rootTs) {\n return slack.postInThread(channelId, rootTs, text);\n }\n return slack.postMessage(channelId, text);\n };\n\n const postDiagnosticDirect = async (\n text: string,\n options?: { style?: \"muted\" | \"error\" },\n ): Promise<void> => {\n const threadAnchor = messageTs ?? rootTs;\n if (!threadAnchor) return;\n\n for (const part of splitText(text, MAX_THREAD_LENGTH, formatSlackContinuation)) {\n if (options?.style === \"muted\") {\n const ts = await slack.postInThreadBlocks(channelId, threadAnchor, part, [\n buildMrkdwnContextBlock(part),\n ]);\n threadMessageTs.push(ts);\n } else {\n const diagnosticText = options?.style === \"error\" ? `_${part}_` : part;\n const ts = await slack.postInThread(channelId, threadAnchor, diagnosticText);\n threadMessageTs.push(ts);\n }\n }\n };\n\n const reportResponseError = createChatResponseErrorReporter(() => ({\n platform: \"slack\",\n conversationId,\n channelId,\n messageId: message.id,\n sessionKey: message.sessionKey,\n responseMessageId: messageTs,\n threadTs: rootTs,\n conversationKind: message.conversationKind,\n isThreaded,\n }));\n\n const postOrUpdateMain = async (body: string, handleMsgTooLong = true): Promise<void> => {\n const writeMain = async (text: string): Promise<string | void> => {\n if (messageTs) {\n await slack.updateMessage(channelId, messageTs, text);\n return;\n }\n if (replyInThread && rootTs) {\n messageTs = await slack.postInThread(channelId, rootTs, text);\n return messageTs;\n }\n messageTs = await postFirstMessage(text);\n return messageTs;\n };\n\n try {\n await writeMain(body);\n } catch (err) {\n if (!handleMsgTooLong || !isSlackMsgTooLong(err)) throw err;\n const fallback = await postSlackTextWithFallback(writeMain, body);\n accumulatedText = fallback.text;\n stream.setText(accumulatedText);\n }\n };\n\n const abandonActiveStream = async (): Promise<void> => {\n if (!streamActive || !messageTs) return;\n const failedStreamTs = messageTs;\n streamActive = false;\n streamedText = \"\";\n await slack.stopMessageStream(channelId, failedStreamTs).catch(() => undefined);\n if (messageTs === failedStreamTs) messageTs = null;\n };\n\n const startOrAppendStream = async (text: string, displayText: string): Promise<void> => {\n if (streamUnavailable) {\n await postOrUpdateMain(displayText);\n return;\n }\n\n try {\n if (messageTs && streamActive) {\n if (!text.startsWith(streamedText)) {\n await abandonActiveStream();\n await postOrUpdateMain(displayText);\n return;\n }\n const delta = text.slice(streamedText.length);\n if (delta) {\n await slack.appendMessageStream(channelId, messageTs, delta);\n streamedText = text;\n }\n return;\n }\n if (!replyInThread || !rootTs) {\n streamUnavailable = true;\n await postOrUpdateMain(displayText);\n return;\n }\n messageTs = await slack.startMessageStream(channelId, text, rootTs, event.user);\n streamActive = true;\n streamedText = text;\n } catch (err) {\n streamUnavailable = true;\n log.logWarning(\n \"Slack streaming unavailable; falling back to chat.update\",\n err instanceof Error ? err.message : String(err),\n );\n await abandonActiveStream();\n await postOrUpdateMain(displayText);\n }\n };\n\n const stream = new BufferedResponseStream({\n flush: async (text) => {\n accumulatedText = text;\n const mainLimit = isWorking ? MAX_MAIN_LENGTH - WORKING_INDICATOR.length : MAX_MAIN_LENGTH;\n if (accumulatedText.length > mainLimit) {\n accumulatedText =\n accumulatedText.substring(0, mainLimit - TRUNCATION_NOTE_INCREMENTAL.length) +\n TRUNCATION_NOTE_INCREMENTAL;\n stream.setText(accumulatedText);\n }\n const displayText = isWorking ? accumulatedText + WORKING_INDICATOR : accumulatedText;\n await startOrAppendStream(text, displayText);\n },\n finish: async (text) => {\n accumulatedText = text;\n isWorking = false;\n if (streamActive && messageTs) {\n try {\n if (!accumulatedText.startsWith(streamedText)) {\n await abandonActiveStream();\n await postOrUpdateMain(accumulatedText);\n return;\n }\n const delta = accumulatedText.slice(streamedText.length);\n if (delta) {\n await slack.appendMessageStream(channelId, messageTs, delta);\n streamedText = accumulatedText;\n }\n await slack.stopMessageStream(channelId, messageTs);\n streamActive = false;\n streamedText = \"\";\n return;\n } catch (err) {\n streamUnavailable = true;\n log.logWarning(\n \"Slack streaming unavailable; falling back to chat.update\",\n err instanceof Error ? err.message : String(err),\n );\n await abandonActiveStream();\n }\n }\n if (messageTs || accumulatedText) {\n await postOrUpdateMain(accumulatedText);\n }\n },\n });\n\n const queueResponseOperation = (\n label: string,\n operation: ChatResponseErrorOperation,\n work: () => Promise<void>,\n context: (err: unknown) => Record<string, unknown>,\n ): Promise<void> =>\n responseOperations.run(work, (err) => {\n log.logWarning(`Slack ${label} error`, err instanceof Error ? err.message : String(err));\n reportResponseError(err, operation, context(err));\n });\n\n const responder: ConversationResponder = {\n respond: async (text: string) => {\n await queueResponseOperation(\n \"respond\",\n \"respond\",\n async () => {\n accumulatedText = accumulatedText ? `${accumulatedText}\\n${text}` : text;\n\n const mainLimit = isWorking\n ? MAX_MAIN_LENGTH - WORKING_INDICATOR.length\n : MAX_MAIN_LENGTH;\n if (accumulatedText.length > mainLimit) {\n accumulatedText =\n accumulatedText.substring(0, mainLimit - TRUNCATION_NOTE_INCREMENTAL.length) +\n TRUNCATION_NOTE_INCREMENTAL;\n }\n\n stream.setText(accumulatedText);\n const displayText = isWorking ? accumulatedText + WORKING_INDICATOR : accumulatedText;\n await startOrAppendStream(text, displayText);\n },\n () => ({\n phase: messageTs ? \"update\" : \"initial_post\",\n textLength: text.length,\n accumulatedLength: accumulatedText.length,\n }),\n );\n },\n\n appendResponseDelta: async (delta: string) => {\n await queueResponseOperation(\n \"appendResponseDelta\",\n \"respond\",\n async () => {\n await stream.append(delta);\n },\n () => ({ textLength: delta.length, accumulatedLength: stream.getText().length }),\n );\n },\n\n finishResponse: async (finalText?: string) => {\n await queueResponseOperation(\n \"finishResponse\",\n \"set_working\",\n async () => {\n await stream.finish(finalText);\n accumulatedText = stream.getText();\n if (messageTs && accumulatedText.trim() && !mainResponseLogged) {\n slack.logBotResponse(\n channelId,\n accumulatedText,\n messageTs,\n replyInThread ? rootTs : undefined,\n );\n mainResponseLogged = true;\n }\n if (!rootTs) return;\n await slack\n .setAssistantStatus(channelId, rootTs, \"\")\n .catch((err) => onAssistantStatusError(\"clear-on-idle\", err));\n },\n () => ({ finalTextLength: finalText?.length }),\n );\n },\n\n replaceResponse: async (text: string, options?: { createOverflowLink?: () => string }) => {\n await queueResponseOperation(\n \"replaceResponse\",\n \"replace_response\",\n async () => {\n // Lazy: only mint a token if Slack actually rejects the message.\n let overflowLink: string | undefined;\n const resolveOverflowLink = (): string | undefined => {\n if (overflowLink === undefined && options?.createOverflowLink) {\n overflowLink = options.createOverflowLink();\n }\n return overflowLink;\n };\n\n accumulatedText = text;\n stream.setText(accumulatedText);\n const displayText = isWorking ? accumulatedText + WORKING_INDICATOR : accumulatedText;\n\n try {\n if (streamActive && messageTs) {\n await slack.stopMessageStream(channelId, messageTs);\n streamActive = false;\n streamedText = \"\";\n }\n await postOrUpdateMain(displayText, false);\n } catch (err) {\n if (!isSlackMsgTooLong(err)) throw err;\n const link = resolveOverflowLink();\n const fallback = await postSlackTextWithFallback(\n async (body) => {\n await postOrUpdateMain(body);\n },\n text,\n link,\n );\n accumulatedText = fallback.text;\n const continuation = text.slice(fallback.prefixLength).trimStart();\n if (continuation) {\n await postDiagnosticDirect(`_(continued from truncated message)_\\n\\n${continuation}`);\n }\n }\n },\n () => ({\n textLength: text.length,\n hadExistingResponse: Boolean(messageTs),\n }),\n );\n },\n\n respondDiagnostic: async (text: string, options?: { style?: \"muted\" | \"error\" }) => {\n await queueResponseOperation(\n \"respondDiagnostic\",\n \"respond_diagnostic\",\n async () => {\n await postDiagnosticDirect(text, options);\n },\n () => ({\n textLength: text.length,\n style: options?.style,\n }),\n );\n },\n\n respondToolResult: async (result: ChatToolResult) => {\n await responder.respondDiagnostic(formatSlackToolResult(result));\n },\n\n setTyping: async (isTyping: boolean) => {\n if (isTyping && !messageTs && rootTs) {\n try {\n const statusText = eventFilename ? `Starting event: ${eventFilename}` : \"Thinking\";\n await slack.setAssistantStatus(channelId, rootTs, statusText);\n } catch (err) {\n // Assistant API not available — first respond() call will create the message.\n onAssistantStatusError(\"typing\", err);\n }\n }\n },\n\n uploadFile: async (filePath: string, title?: string) => {\n await slack.uploadFile(channelId, filePath, title, rootTs);\n },\n\n react: async (emoji: string) => {\n // React to the triggering message. Event runs have no real message ts.\n if (eventFilename) return;\n await slack.addReaction(channelId, event.ts, emoji);\n },\n\n setWorking: async (working: boolean) => {\n await queueResponseOperation(\n \"setWorking\",\n \"set_working\",\n async () => {\n isWorking = working;\n if (messageTs) {\n const displayText = isWorking ? accumulatedText + WORKING_INDICATOR : accumulatedText;\n const updates: Promise<void>[] =\n streamActive && !isWorking\n ? [\n slack.stopMessageStream(channelId, messageTs).then(() => {\n streamActive = false;\n }),\n ]\n : [slack.updateMessage(channelId, messageTs, displayText)];\n if (!working && rootTs) {\n updates.push(\n slack\n .setAssistantStatus(channelId, rootTs, \"\")\n .catch((err) => onAssistantStatusError(\"clear-on-idle\", err)),\n );\n }\n await Promise.all(updates);\n }\n },\n () => ({ working }),\n );\n },\n\n deleteResponse: async () => {\n await responseOperations.run(async () => {\n // Clear assistant status first\n if (rootTs) {\n try {\n await slack.setAssistantStatus(channelId, rootTs, \"\");\n } catch {\n // Ignore errors clearing status\n }\n }\n\n // Delete thread messages first (in reverse order)\n for (let i = threadMessageTs.length - 1; i >= 0; i--) {\n try {\n await slack.deleteMessage(channelId, threadMessageTs[i]);\n } catch {\n // Ignore errors deleting thread messages\n }\n }\n threadMessageTs.length = 0;\n // Then delete main message\n if (messageTs) {\n await slack.deleteMessage(channelId, messageTs);\n messageTs = null;\n }\n });\n },\n };\n\n return responder;\n}\n"]}
1
+ {"version":3,"file":"response-lifecycle.js","sourceRoot":"","sources":["../../../src/adapters/slack/response-lifecycle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EACL,+BAA+B,EAC/B,cAAc,EACd,SAAS,GAEV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAA2C,MAAM,UAAU,CAAC;AAG5F,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,8EAA8E;AAC7G,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAChC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAClC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACjC,MAAM,2BAA2B,GAC/B,kEAAkE,CAAC;AAErE,MAAM,uBAAuB,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,eAAe,OAAO,IAAI,CAAC;AAExF,SAAS,iBAAiB,CAAC,GAAY;IACrC,MAAM,IAAI,GAAI,GAAiD,EAAE,IAAI,CAAC;IACtE,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,IAAI,EAAE,KAAK,KAAK,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,qBAAqB,CAC5B,IAAY,EACZ,YAAqB,EACrB,YAAY,GAAG,oBAAoB;IAEnC,MAAM,MAAM,GAAG,YAAY;QACzB,CAAC,CAAC,yEAAyE,YAAY,UAAU;QACjG,CAAC,CAAC,yDAAyD,CAAC;IAC9D,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,MAAM,EAAE,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,IAA8C,EAC9C,IAAY,EACZ,YAAqB;IAErB,IAAI,YAAY,GAAG,oBAAoB,CAAC;IACxC,IAAI,OAAgB,CAAC;IAErB,SAAS,CAAC;QACR,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;QAC7E,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC;YACxC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;QACtD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YACvC,OAAO,GAAG,GAAG,CAAC;YACd,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YACxE,CAAC;YACD,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAsB;IACnD,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACvD,IAAI,IAAI,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC;IAChE,IAAI,MAAM,CAAC,KAAK;QAAE,IAAI,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC;IAC9C,IAAI,IAAI,KAAK,QAAQ,MAAM,CAAC;IAC5B,IAAI,aAAa;QAAE,IAAI,IAAI,WAAW,aAAa,YAAY,CAAC;IAChE,IAAI,IAAI,sBAAsB,MAAM,CAAC,MAAM,UAAU,CAAC;IACtD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,EACzC,KAAK,EACL,KAAK,EACL,WAAW,EACX,SAAS,EACT,OAAO,GAOR;IACC,IAAI,SAAS,GAAkB,WAAW,CAAC,gBAAgB,IAAI,IAAI,CAAC;IACpE,IAAI,4BAA4B,GAAG,KAAK,CAAC;IACzC,MAAM,sBAAsB,GAAG,CAAC,KAAa,EAAE,GAAY,EAAQ,EAAE;QACnE,IAAI,4BAA4B;YAAE,OAAO;QACzC,4BAA4B,GAAG,IAAI,CAAC;QACpC,GAAG,CAAC,UAAU,CACZ,oCAAoC,KAAK,oDAAoD,EAC7F,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,IAAI,eAAe,GAAG,EAAE,CAAC;IACzB,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAC/B,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,MAAM,kBAAkB,GAAG,IAAI,yBAAyB,EAAE,CAAC;IAE3D,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC;IAChC,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;IAE5C,oFAAoF;IACpF,MAAM,aAAa,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,2BAA2B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC;IAC3C,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,IAAI,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC;IAEhF;;;;OAIG;IACH,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAY,EAAmB,EAAE;QAC/D,IAAI,aAAa,IAAI,MAAM,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,KAAK,EAChC,IAAY,EACZ,OAAuC,EACxB,EAAE;QACjB,MAAM,YAAY,GAAG,SAAS,IAAI,MAAM,CAAC;QACzC,IAAI,CAAC,YAAY;YAAE,OAAO;QAE1B,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,IAAI,EAAE,iBAAiB,EAAE,uBAAuB,CAAC,EAAE,CAAC;YAC/E,IAAI,OAAO,EAAE,KAAK,KAAK,OAAO,EAAE,CAAC;gBAC/B,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE;oBACvE,uBAAuB,CAAC,IAAI,CAAC;iBAC9B,CAAC,CAAC;gBACH,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,MAAM,cAAc,GAAG,OAAO,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;gBACvE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;gBAC7E,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,+BAA+B,CAAC,GAAG,EAAE,CAAC,CAAC;QACjE,QAAQ,EAAE,OAAO;QACjB,cAAc;QACd,SAAS;QACT,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,iBAAiB,EAAE,SAAS;QAC5B,QAAQ,EAAE,MAAM;QAChB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,UAAU;KACX,CAAC,CAAC,CAAC;IAEJ,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAY,EAAE,gBAAgB,GAAG,IAAI,EAAiB,EAAE;QACtF,MAAM,SAAS,GAAG,KAAK,EAAE,IAAY,EAA0B,EAAE;YAC/D,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;gBACtD,OAAO;YACT,CAAC;YACD,IAAI,aAAa,IAAI,MAAM,EAAE,CAAC;gBAC5B,SAAS,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;gBAC9D,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,SAAS,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACzC,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,gBAAgB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YAC5D,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAClE,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC;YAChC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAClC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,KAAK,IAAmB,EAAE;QACpD,IAAI,CAAC,YAAY,IAAI,CAAC,SAAS;YAAE,OAAO;QACxC,MAAM,cAAc,GAAG,SAAS,CAAC;QACjC,YAAY,GAAG,KAAK,CAAC;QACrB,YAAY,GAAG,EAAE,CAAC;QAClB,MAAM,KAAK,CAAC,iBAAiB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAChF,IAAI,SAAS,KAAK,cAAc;YAAE,SAAS,GAAG,IAAI,CAAC;IACrD,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,KAAK,EAAE,IAAY,EAAE,WAAmB,EAAiB,EAAE;QACrF,IAAI,iBAAiB,EAAE,CAAC;YACtB,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,IAAI,SAAS,IAAI,YAAY,EAAE,CAAC;gBAC9B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;oBACnC,MAAM,mBAAmB,EAAE,CAAC;oBAC5B,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;oBACpC,OAAO;gBACT,CAAC;gBACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;gBAC9C,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,KAAK,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;oBAC7D,YAAY,GAAG,IAAI,CAAC;gBACtB,CAAC;gBACD,OAAO;YACT,CAAC;YACD,IAAI,CAAC,aAAa,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC9B,iBAAiB,GAAG,IAAI,CAAC;gBACzB,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;gBACpC,OAAO;YACT,CAAC;YACD,SAAS,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAChF,YAAY,GAAG,IAAI,CAAC;YACpB,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,iBAAiB,GAAG,IAAI,CAAC;YACzB,GAAG,CAAC,UAAU,CACZ,0DAA0D,EAC1D,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;YACF,MAAM,mBAAmB,EAAE,CAAC;YAC5B,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,sBAAsB,CAAC;QACxC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACpB,eAAe,GAAG,IAAI,CAAC;YACvB,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,eAAe,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC;YAC3F,IAAI,eAAe,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;gBACvC,eAAe;oBACb,eAAe,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,2BAA2B,CAAC,MAAM,CAAC;wBAC5E,2BAA2B,CAAC;gBAC9B,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAClC,CAAC;YACD,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC;YACtF,MAAM,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACrB,eAAe,GAAG,IAAI,CAAC;YACvB,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,YAAY,IAAI,SAAS,EAAE,CAAC;gBAC9B,IAAI,CAAC;oBACH,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;wBAC9C,MAAM,mBAAmB,EAAE,CAAC;wBAC5B,MAAM,gBAAgB,CAAC,eAAe,CAAC,CAAC;wBACxC,OAAO;oBACT,CAAC;oBACD,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;oBACzD,IAAI,KAAK,EAAE,CAAC;wBACV,MAAM,KAAK,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;wBAC7D,YAAY,GAAG,eAAe,CAAC;oBACjC,CAAC;oBACD,MAAM,KAAK,CAAC,iBAAiB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;oBACpD,YAAY,GAAG,KAAK,CAAC;oBACrB,YAAY,GAAG,EAAE,CAAC;oBAClB,OAAO;gBACT,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,iBAAiB,GAAG,IAAI,CAAC;oBACzB,GAAG,CAAC,UAAU,CACZ,0DAA0D,EAC1D,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;oBACF,MAAM,mBAAmB,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;YACD,IAAI,SAAS,IAAI,eAAe,EAAE,CAAC;gBACjC,MAAM,gBAAgB,CAAC,eAAe,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,sBAAsB,GAAG,CAC7B,KAAa,EACb,SAAqC,EACrC,IAAyB,EACzB,OAAkD,EACnC,EAAE,CACjB,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;QACnC,GAAG,CAAC,UAAU,CAAC,SAAS,KAAK,QAAQ,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACzF,mBAAmB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEL,MAAM,SAAS,GAA0B;QACvC,OAAO,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE;YAC9B,MAAM,sBAAsB,CAC1B,SAAS,EACT,SAAS,EACT,KAAK,IAAI,EAAE;gBACT,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;gBAEzE,MAAM,SAAS,GAAG,SAAS;oBACzB,CAAC,CAAC,eAAe,GAAG,iBAAiB,CAAC,MAAM;oBAC5C,CAAC,CAAC,eAAe,CAAC;gBACpB,IAAI,eAAe,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;oBACvC,eAAe;wBACb,eAAe,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,2BAA2B,CAAC,MAAM,CAAC;4BAC5E,2BAA2B,CAAC;gBAChC,CAAC;gBAED,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;gBAChC,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC;gBACtF,MAAM,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC/C,CAAC,EACD,GAAG,EAAE,CAAC,CAAC;gBACL,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc;gBAC5C,UAAU,EAAE,IAAI,CAAC,MAAM;gBACvB,iBAAiB,EAAE,eAAe,CAAC,MAAM;aAC1C,CAAC,CACH,CAAC;QACJ,CAAC;QAED,mBAAmB,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;YAC3C,MAAM,sBAAsB,CAC1B,qBAAqB,EACrB,SAAS,EACT,KAAK,IAAI,EAAE;gBACT,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,iBAAiB,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,CACjF,CAAC;QACJ,CAAC;QAED,cAAc,EAAE,KAAK,EAAE,SAAkB,EAAE,EAAE;YAC3C,MAAM,sBAAsB,CAC1B,gBAAgB,EAChB,aAAa,EACb,KAAK,IAAI,EAAE;gBACT,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC/B,eAAe,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnC,IAAI,SAAS,IAAI,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAC/D,KAAK,CAAC,cAAc,CAClB,SAAS,EACT,eAAe,EACf,SAAS,EACT,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CACnC,CAAC;oBACF,kBAAkB,GAAG,IAAI,CAAC;gBAC5B,CAAC;gBACD,IAAI,CAAC,MAAM;oBAAE,OAAO;gBACpB,MAAM,KAAK;qBACR,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;qBACzC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,sBAAsB,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAAC;YAClE,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAC/C,CAAC;QACJ,CAAC;QAED,eAAe,EAAE,KAAK,EAAE,IAAY,EAAE,OAA+C,EAAE,EAAE;YACvF,MAAM,sBAAsB,CAC1B,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,IAAI,EAAE;gBACT,iEAAiE;gBACjE,IAAI,YAAgC,CAAC;gBACrC,MAAM,mBAAmB,GAAG,GAAuB,EAAE;oBACnD,IAAI,YAAY,KAAK,SAAS,IAAI,OAAO,EAAE,kBAAkB,EAAE,CAAC;wBAC9D,YAAY,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;oBAC9C,CAAC;oBACD,OAAO,YAAY,CAAC;gBACtB,CAAC,CAAC;gBAEF,eAAe,GAAG,IAAI,CAAC;gBACvB,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;gBAChC,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC;gBAEtF,IAAI,CAAC;oBACH,IAAI,YAAY,IAAI,SAAS,EAAE,CAAC;wBAC9B,MAAM,KAAK,CAAC,iBAAiB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;wBACpD,YAAY,GAAG,KAAK,CAAC;wBACrB,YAAY,GAAG,EAAE,CAAC;oBACpB,CAAC;oBACD,MAAM,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;gBAC7C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC;wBAAE,MAAM,GAAG,CAAC;oBACvC,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;oBACnC,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAC9C,KAAK,EAAE,IAAI,EAAE,EAAE;wBACb,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;oBAC/B,CAAC,EACD,IAAI,EACJ,IAAI,CACL,CAAC;oBACF,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC;oBAChC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;oBACnE,IAAI,YAAY,EAAE,CAAC;wBACjB,MAAM,oBAAoB,CAAC,2CAA2C,YAAY,EAAE,CAAC,CAAC;oBACxF,CAAC;gBACH,CAAC;YACH,CAAC,EACD,GAAG,EAAE,CAAC,CAAC;gBACL,UAAU,EAAE,IAAI,CAAC,MAAM;gBACvB,mBAAmB,EAAE,OAAO,CAAC,SAAS,CAAC;aACxC,CAAC,CACH,CAAC;QACJ,CAAC;QAED,iBAAiB,EAAE,KAAK,EAAE,IAAY,EAAE,OAAuC,EAAE,EAAE;YACjF,MAAM,sBAAsB,CAC1B,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,IAAI,EAAE;gBACT,MAAM,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC5C,CAAC,EACD,GAAG,EAAE,CAAC,CAAC;gBACL,UAAU,EAAE,IAAI,CAAC,MAAM;gBACvB,KAAK,EAAE,OAAO,EAAE,KAAK;aACtB,CAAC,CACH,CAAC;QACJ,CAAC;QAED,iBAAiB,EAAE,KAAK,EAAE,MAAsB,EAAE,EAAE;YAClD,MAAM,SAAS,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,SAAS,EAAE,KAAK,EAAE,QAAiB,EAAE,EAAE;YACrC,IAAI,QAAQ,IAAI,CAAC,SAAS,IAAI,MAAM,EAAE,CAAC;gBACrC,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,mBAAmB,aAAa,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;oBACnF,MAAM,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;gBAChE,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,8EAA8E;oBAC9E,sBAAsB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;QAED,UAAU,EAAE,KAAK,EAAE,QAAgB,EAAE,KAAc,EAAE,EAAE;YACrD,MAAM,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACzF,CAAC;QAED,KAAK,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;YAC7B,uEAAuE;YACvE,IAAI,aAAa;gBAAE,OAAO;YAC1B,MAAM,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;QAED,UAAU,EAAE,KAAK,EAAE,OAAgB,EAAE,EAAE;YACrC,MAAM,sBAAsB,CAC1B,YAAY,EACZ,aAAa,EACb,KAAK,IAAI,EAAE;gBACT,SAAS,GAAG,OAAO,CAAC;gBACpB,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC;oBACtF,MAAM,OAAO,GACX,YAAY,IAAI,CAAC,SAAS;wBACxB,CAAC,CAAC;4BACE,KAAK,CAAC,iBAAiB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gCACtD,YAAY,GAAG,KAAK,CAAC;4BACvB,CAAC,CAAC;yBACH;wBACH,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;oBAC/D,IAAI,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC;wBACvB,OAAO,CAAC,IAAI,CACV,KAAK;6BACF,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;6BACzC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,sBAAsB,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAChE,CAAC;oBACJ,CAAC;oBACD,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CACpB,CAAC;QACJ,CAAC;QAED,cAAc,EAAE,KAAK,IAAI,EAAE;YACzB,MAAM,kBAAkB,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;gBACtC,+BAA+B;gBAC/B,IAAI,MAAM,EAAE,CAAC;oBACX,IAAI,CAAC;wBACH,MAAM,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;oBACxD,CAAC;oBAAC,MAAM,CAAC;wBACP,gCAAgC;oBAClC,CAAC;gBACH,CAAC;gBAED,kDAAkD;gBAClD,KAAK,IAAI,CAAC,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBACrD,IAAI,CAAC;wBACH,MAAM,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC3D,CAAC;oBAAC,MAAM,CAAC;wBACP,yCAAyC;oBAC3C,CAAC;gBACH,CAAC;gBACD,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC3B,2BAA2B;gBAC3B,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;oBAChD,SAAS,GAAG,IAAI,CAAC;gBACnB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IAEF,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { ConversationMessage, ConversationResponder, ChatToolResult } from \"../../adapter.js\";\nimport * as log from \"../../log.js\";\nimport {\n createChatResponseErrorReporter,\n formatToolArgs,\n splitText,\n type ChatResponseErrorOperation,\n} from \"../shared.js\";\nimport { BufferedResponseStream, OrderedResponseOperations } from \"../streaming.js\";\nimport { buildMrkdwnContextBlock, type SlackMessagingBot, type SlackEvent } from \"./bot.js\";\nimport type { SlackAdapterSessionPlan } from \"./types.js\";\n\nconst MAX_MAIN_LENGTH = 35000; // Best-effort streaming cap; final responses use Slack error-driven fallback.\nconst MAX_THREAD_LENGTH = 20000;\nconst FALLBACK_MAIN_LENGTH = 3000;\nconst WORKING_INDICATOR = \" ...\";\nconst TRUNCATION_NOTE_INCREMENTAL =\n \"\\n\\n_(message truncated, ask me to elaborate on specific parts)_\";\n\nconst formatSlackContinuation = (partNum: number): string => `_(continued ${partNum})_`;\n\nfunction isSlackMsgTooLong(err: unknown): boolean {\n const data = (err as { data?: { error?: string } } | undefined)?.data;\n const message = err instanceof Error ? err.message : String(err);\n return data?.error === \"msg_too_long\" || message.includes(\"msg_too_long\");\n}\n\nfunction fallbackLongSlackText(\n text: string,\n overflowLink?: string,\n prefixLength = FALLBACK_MAIN_LENGTH,\n): string {\n const suffix = overflowLink\n ? `\\n\\n_(message too long for Slack; continued in thread; session view: <${overflowLink}|open>)_`\n : \"\\n\\n_(message too long for Slack; continued in thread)_\";\n return `${text.slice(0, prefixLength)}${suffix}`;\n}\n\nasync function postSlackTextWithFallback(\n post: (text: string) => Promise<string | void>,\n text: string,\n overflowLink?: string,\n): Promise<{ result: string | void; text: string; prefixLength: number }> {\n let prefixLength = FALLBACK_MAIN_LENGTH;\n let lastErr: unknown;\n\n for (;;) {\n const fallbackText = fallbackLongSlackText(text, overflowLink, prefixLength);\n try {\n const result = await post(fallbackText);\n return { result, text: fallbackText, prefixLength };\n } catch (err) {\n if (!isSlackMsgTooLong(err)) throw err;\n lastErr = err;\n if (prefixLength === 0) {\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));\n }\n prefixLength = Math.max(0, Math.floor(prefixLength / 2));\n }\n }\n}\n\nfunction formatSlackToolResult(result: ChatToolResult): string {\n const argsFormatted = formatToolArgs(result.args);\n const duration = (result.durationMs / 1000).toFixed(1);\n let text = `*${result.isError ? \"✗\" : \"✓\"} ${result.toolName}*`;\n if (result.label) text += `: ${result.label}`;\n text += ` (${duration}s)\\n`;\n if (argsFormatted) text += `\\`\\`\\`\\n${argsFormatted}\\n\\`\\`\\`\\n`;\n text += `*Result:*\\n\\`\\`\\`\\n${result.result}\\n\\`\\`\\``;\n return text;\n}\n\nexport function createSlackResponseContext({\n event,\n slack,\n sessionPlan,\n replyMode,\n message,\n}: {\n event: SlackEvent;\n slack: SlackMessagingBot;\n sessionPlan: SlackAdapterSessionPlan;\n replyMode: \"top-level\" | \"thread\";\n message: ConversationMessage;\n}): ConversationResponder {\n let messageTs: string | null = sessionPlan.initialMessageTs ?? null;\n let assistantStatusFailureWarned = false;\n const onAssistantStatusError = (label: string, err: unknown): void => {\n if (assistantStatusFailureWarned) return;\n assistantStatusFailureWarned = true;\n log.logWarning(\n `Slack setAssistantStatus failed (${label}; further occurrences suppressed for this session)`,\n err instanceof Error ? err.message : String(err),\n );\n };\n const threadMessageTs: string[] = [];\n let accumulatedText = \"\";\n let isWorking = true;\n let mainResponseLogged = false;\n let streamActive = false;\n let streamUnavailable = false;\n let streamedText = \"\";\n const responseOperations = new OrderedResponseOperations();\n\n const channelId = event.channel;\n const conversationId = event.conversationId;\n\n // Slack message timestamps are numeric; event-file triggers use `event:<filename>`.\n const eventFilename = event.ts.match(/^event:([^:]+(?:\\.json)?)/)?.[1];\n\n const { rootTs, isThreaded } = sessionPlan;\n const replyInThread = Boolean(rootTs && (isThreaded || replyMode === \"thread\"));\n\n /**\n * Post the first visible reply.\n * Default Slack behavior is now top-level channel replies.\n * If the triggering message is already inside a thread, stay in that thread.\n */\n const postFirstMessage = async (text: string): Promise<string> => {\n if (replyInThread && rootTs) {\n return slack.postInThread(channelId, rootTs, text);\n }\n return slack.postMessage(channelId, text);\n };\n\n const postDiagnosticDirect = async (\n text: string,\n options?: { style?: \"muted\" | \"error\" },\n ): Promise<void> => {\n const threadAnchor = messageTs ?? rootTs;\n if (!threadAnchor) return;\n\n for (const part of splitText(text, MAX_THREAD_LENGTH, formatSlackContinuation)) {\n if (options?.style === \"muted\") {\n const ts = await slack.postInThreadBlocks(channelId, threadAnchor, part, [\n buildMrkdwnContextBlock(part),\n ]);\n threadMessageTs.push(ts);\n } else {\n const diagnosticText = options?.style === \"error\" ? `_${part}_` : part;\n const ts = await slack.postInThread(channelId, threadAnchor, diagnosticText);\n threadMessageTs.push(ts);\n }\n }\n };\n\n const reportResponseError = createChatResponseErrorReporter(() => ({\n platform: \"slack\",\n conversationId,\n channelId,\n messageId: message.id,\n sessionKey: message.sessionKey,\n responseMessageId: messageTs,\n threadTs: rootTs,\n conversationKind: message.conversationKind,\n isThreaded,\n }));\n\n const postOrUpdateMain = async (body: string, handleMsgTooLong = true): Promise<void> => {\n const writeMain = async (text: string): Promise<string | void> => {\n if (messageTs) {\n await slack.updateMessage(channelId, messageTs, text);\n return;\n }\n if (replyInThread && rootTs) {\n messageTs = await slack.postInThread(channelId, rootTs, text);\n return messageTs;\n }\n messageTs = await postFirstMessage(text);\n return messageTs;\n };\n\n try {\n await writeMain(body);\n } catch (err) {\n if (!handleMsgTooLong || !isSlackMsgTooLong(err)) throw err;\n const fallback = await postSlackTextWithFallback(writeMain, body);\n accumulatedText = fallback.text;\n stream.setText(accumulatedText);\n }\n };\n\n const abandonActiveStream = async (): Promise<void> => {\n if (!streamActive || !messageTs) return;\n const failedStreamTs = messageTs;\n streamActive = false;\n streamedText = \"\";\n await slack.stopMessageStream(channelId, failedStreamTs).catch(() => undefined);\n if (messageTs === failedStreamTs) messageTs = null;\n };\n\n const startOrAppendStream = async (text: string, displayText: string): Promise<void> => {\n if (streamUnavailable) {\n await postOrUpdateMain(displayText);\n return;\n }\n\n try {\n if (messageTs && streamActive) {\n if (!text.startsWith(streamedText)) {\n await abandonActiveStream();\n await postOrUpdateMain(displayText);\n return;\n }\n const delta = text.slice(streamedText.length);\n if (delta) {\n await slack.appendMessageStream(channelId, messageTs, delta);\n streamedText = text;\n }\n return;\n }\n if (!replyInThread || !rootTs) {\n streamUnavailable = true;\n await postOrUpdateMain(displayText);\n return;\n }\n messageTs = await slack.startMessageStream(channelId, text, rootTs, event.user);\n streamActive = true;\n streamedText = text;\n } catch (err) {\n streamUnavailable = true;\n log.logWarning(\n \"Slack streaming unavailable; falling back to chat.update\",\n err instanceof Error ? err.message : String(err),\n );\n await abandonActiveStream();\n await postOrUpdateMain(displayText);\n }\n };\n\n const stream = new BufferedResponseStream({\n flush: async (text) => {\n accumulatedText = text;\n const mainLimit = isWorking ? MAX_MAIN_LENGTH - WORKING_INDICATOR.length : MAX_MAIN_LENGTH;\n if (accumulatedText.length > mainLimit) {\n accumulatedText =\n accumulatedText.substring(0, mainLimit - TRUNCATION_NOTE_INCREMENTAL.length) +\n TRUNCATION_NOTE_INCREMENTAL;\n stream.setText(accumulatedText);\n }\n const displayText = isWorking ? accumulatedText + WORKING_INDICATOR : accumulatedText;\n await startOrAppendStream(text, displayText);\n },\n finish: async (text) => {\n accumulatedText = text;\n isWorking = false;\n if (streamActive && messageTs) {\n try {\n if (!accumulatedText.startsWith(streamedText)) {\n await abandonActiveStream();\n await postOrUpdateMain(accumulatedText);\n return;\n }\n const delta = accumulatedText.slice(streamedText.length);\n if (delta) {\n await slack.appendMessageStream(channelId, messageTs, delta);\n streamedText = accumulatedText;\n }\n await slack.stopMessageStream(channelId, messageTs);\n streamActive = false;\n streamedText = \"\";\n return;\n } catch (err) {\n streamUnavailable = true;\n log.logWarning(\n \"Slack streaming unavailable; falling back to chat.update\",\n err instanceof Error ? err.message : String(err),\n );\n await abandonActiveStream();\n }\n }\n if (messageTs || accumulatedText) {\n await postOrUpdateMain(accumulatedText);\n }\n },\n });\n\n const queueResponseOperation = (\n label: string,\n operation: ChatResponseErrorOperation,\n work: () => Promise<void>,\n context: (err: unknown) => Record<string, unknown>,\n ): Promise<void> =>\n responseOperations.run(work, (err) => {\n log.logWarning(`Slack ${label} error`, err instanceof Error ? err.message : String(err));\n reportResponseError(err, operation, context(err));\n });\n\n const responder: ConversationResponder = {\n respond: async (text: string) => {\n await queueResponseOperation(\n \"respond\",\n \"respond\",\n async () => {\n accumulatedText = accumulatedText ? `${accumulatedText}\\n${text}` : text;\n\n const mainLimit = isWorking\n ? MAX_MAIN_LENGTH - WORKING_INDICATOR.length\n : MAX_MAIN_LENGTH;\n if (accumulatedText.length > mainLimit) {\n accumulatedText =\n accumulatedText.substring(0, mainLimit - TRUNCATION_NOTE_INCREMENTAL.length) +\n TRUNCATION_NOTE_INCREMENTAL;\n }\n\n stream.setText(accumulatedText);\n const displayText = isWorking ? accumulatedText + WORKING_INDICATOR : accumulatedText;\n await startOrAppendStream(text, displayText);\n },\n () => ({\n phase: messageTs ? \"update\" : \"initial_post\",\n textLength: text.length,\n accumulatedLength: accumulatedText.length,\n }),\n );\n },\n\n appendResponseDelta: async (delta: string) => {\n await queueResponseOperation(\n \"appendResponseDelta\",\n \"respond\",\n async () => {\n await stream.append(delta);\n },\n () => ({ textLength: delta.length, accumulatedLength: stream.getText().length }),\n );\n },\n\n finishResponse: async (finalText?: string) => {\n await queueResponseOperation(\n \"finishResponse\",\n \"set_working\",\n async () => {\n await stream.finish(finalText);\n accumulatedText = stream.getText();\n if (messageTs && accumulatedText.trim() && !mainResponseLogged) {\n slack.logBotResponse(\n channelId,\n accumulatedText,\n messageTs,\n replyInThread ? rootTs : undefined,\n );\n mainResponseLogged = true;\n }\n if (!rootTs) return;\n await slack\n .setAssistantStatus(channelId, rootTs, \"\")\n .catch((err) => onAssistantStatusError(\"clear-on-idle\", err));\n },\n () => ({ finalTextLength: finalText?.length }),\n );\n },\n\n replaceResponse: async (text: string, options?: { createOverflowLink?: () => string }) => {\n await queueResponseOperation(\n \"replaceResponse\",\n \"replace_response\",\n async () => {\n // Lazy: only mint a token if Slack actually rejects the message.\n let overflowLink: string | undefined;\n const resolveOverflowLink = (): string | undefined => {\n if (overflowLink === undefined && options?.createOverflowLink) {\n overflowLink = options.createOverflowLink();\n }\n return overflowLink;\n };\n\n accumulatedText = text;\n stream.setText(accumulatedText);\n const displayText = isWorking ? accumulatedText + WORKING_INDICATOR : accumulatedText;\n\n try {\n if (streamActive && messageTs) {\n await slack.stopMessageStream(channelId, messageTs);\n streamActive = false;\n streamedText = \"\";\n }\n await postOrUpdateMain(displayText, false);\n } catch (err) {\n if (!isSlackMsgTooLong(err)) throw err;\n const link = resolveOverflowLink();\n const fallback = await postSlackTextWithFallback(\n async (body) => {\n await postOrUpdateMain(body);\n },\n text,\n link,\n );\n accumulatedText = fallback.text;\n const continuation = text.slice(fallback.prefixLength).trimStart();\n if (continuation) {\n await postDiagnosticDirect(`_(continued from truncated message)_\\n\\n${continuation}`);\n }\n }\n },\n () => ({\n textLength: text.length,\n hadExistingResponse: Boolean(messageTs),\n }),\n );\n },\n\n respondDiagnostic: async (text: string, options?: { style?: \"muted\" | \"error\" }) => {\n await queueResponseOperation(\n \"respondDiagnostic\",\n \"respond_diagnostic\",\n async () => {\n await postDiagnosticDirect(text, options);\n },\n () => ({\n textLength: text.length,\n style: options?.style,\n }),\n );\n },\n\n respondToolResult: async (result: ChatToolResult) => {\n await responder.respondDiagnostic(formatSlackToolResult(result));\n },\n\n setTyping: async (isTyping: boolean) => {\n if (isTyping && !messageTs && rootTs) {\n try {\n const statusText = eventFilename ? `Starting event: ${eventFilename}` : \"Thinking\";\n await slack.setAssistantStatus(channelId, rootTs, statusText);\n } catch (err) {\n // Assistant API not available — first respond() call will create the message.\n onAssistantStatusError(\"typing\", err);\n }\n }\n },\n\n uploadFile: async (filePath: string, title?: string) => {\n await slack.uploadFile(channelId, filePath, title, replyInThread ? rootTs : undefined);\n },\n\n react: async (emoji: string) => {\n // React to the triggering message. Event runs have no real message ts.\n if (eventFilename) return;\n await slack.addReaction(channelId, event.ts, emoji);\n },\n\n setWorking: async (working: boolean) => {\n await queueResponseOperation(\n \"setWorking\",\n \"set_working\",\n async () => {\n isWorking = working;\n if (messageTs) {\n const displayText = isWorking ? accumulatedText + WORKING_INDICATOR : accumulatedText;\n const updates: Promise<void>[] =\n streamActive && !isWorking\n ? [\n slack.stopMessageStream(channelId, messageTs).then(() => {\n streamActive = false;\n }),\n ]\n : [slack.updateMessage(channelId, messageTs, displayText)];\n if (!working && rootTs) {\n updates.push(\n slack\n .setAssistantStatus(channelId, rootTs, \"\")\n .catch((err) => onAssistantStatusError(\"clear-on-idle\", err)),\n );\n }\n await Promise.all(updates);\n }\n },\n () => ({ working }),\n );\n },\n\n deleteResponse: async () => {\n await responseOperations.run(async () => {\n // Clear assistant status first\n if (rootTs) {\n try {\n await slack.setAssistantStatus(channelId, rootTs, \"\");\n } catch {\n // Ignore errors clearing status\n }\n }\n\n // Delete thread messages first (in reverse order)\n for (let i = threadMessageTs.length - 1; i >= 0; i--) {\n try {\n await slack.deleteMessage(channelId, threadMessageTs[i]);\n } catch {\n // Ignore errors deleting thread messages\n }\n }\n threadMessageTs.length = 0;\n // Then delete main message\n if (messageTs) {\n await slack.deleteMessage(channelId, messageTs);\n messageTs = null;\n }\n });\n },\n };\n\n return responder;\n}\n"]}
package/dist/agent.d.ts CHANGED
@@ -7,7 +7,7 @@ import type { PiAgentWrapper } from "./types.js";
7
7
  import { type ImageContent } from "@earendil-works/pi-ai";
8
8
  import { MikanModels } from "./harness/index.js";
9
9
  import type { ConversationMessage } from "./adapter.js";
10
- import type { PlatformNotifier, PlatformReactor } from "./types.js";
10
+ import type { PlatformNotifier, PlatformReactor, PlatformUploader } from "./types.js";
11
11
  import type { SessionViewTokenStoreLike } from "./commands/types.js";
12
12
  import type { DockerContainerManager } from "./provisioner.js";
13
13
  import { type RuntimePathContext, type SandboxConfig } from "./sandbox/index.js";
@@ -46,6 +46,7 @@ export interface CreateRunnerOptions {
46
46
  };
47
47
  platformNotifier?: PlatformNotifier;
48
48
  platformReactor?: PlatformReactor;
49
+ platformUploader?: PlatformUploader;
49
50
  platformToolPackFactories?: readonly PlatformToolPackFactory[];
50
51
  /** Model registry override; defaults to the process-wide models.json load. */
51
52
  models?: MikanModels;
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD,OAAO,EAAY,KAAK,YAAY,EAAc,MAAM,uBAAuB,CAAC;AAChF,OAAO,EASL,WAAW,EAGZ,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EAEV,mBAAmB,EAIpB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAGV,gBAAgB,EAChB,eAAe,EAEhB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAKrE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIrD,OAAO,EAGL,KAAK,oBAAoB,EAE1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAKhE,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,aAAa,EAC5B,iBAAiB,EAAE,MAAM,GACxB,kBAAkB,CAMpB;AAED,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,kBAAkB,GAC9B,MAAM,CAER;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,kBAAkB,GAC9B,MAAM,CAKR;AAsDD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,mBAAmB,EAC5B,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,kBAAkB,GAC/B;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,YAAY,EAAE,CAAC;CAClC,CAaA;AAyID,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,GAAG,MAAM,GAAG,UAAU,CAAC,GAC7D,MAAM,GAAG,SAAS,CAOpB;AA6KD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,OAAO,EACvB,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,YAAY,EAAE,MAAM,GACnB,MAAM,CAkBR;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAYR;AAqhCD,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,oBAAoB,CAAC;IACnC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,WAAW,CAAC,EAAE;QACZ,UAAU,EAAE,yBAAyB,CAAC;QACtC,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,yBAAyB,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC/D,8EAA8E;IAC9E,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CAmPxF"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
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";
@@ -88,15 +88,6 @@ export function buildPromptPayload(message, workspacePath, pathContext) {
88
88
  }
89
89
  return { userMessage, imageAttachments };
90
90
  }
91
- async function writePromptDebugContext(conversationDir, systemPrompt, session, userMessage, imageAttachmentCount) {
92
- const debugContext = {
93
- systemPrompt,
94
- messages: session.messages,
95
- newUserMessage: userMessage,
96
- imageAttachmentCount,
97
- };
98
- await writeFile(join(conversationDir, "last_prompt.jsonl"), JSON.stringify(debugContext, null, 2));
99
- }
100
91
  async function getMemory(conversationDir) {
101
92
  const parts = [];
102
93
  // Read workspace-level memory (shared across all conversations)
@@ -677,7 +668,7 @@ function buildThreadSessionName(message) {
677
668
  }
678
669
  function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspaceDir, hostWorkspacePath) {
679
670
  const executionResolver = vaultManager && sandboxConfig.type !== "host"
680
- ? new ActorExecutionResolver(sandboxConfig, vaultManager, provisioner, workspaceDir)
671
+ ? new ActorExecutionResolver(sandboxConfig, vaultManager, provisioner, workspaceDir, hostWorkspacePath)
681
672
  : undefined;
682
673
  // activeExecutor is replaced at the start of each run() call when executionResolver
683
674
  // is present, so the stable `executor` wrapper always delegates to the latest resolved value.
@@ -722,7 +713,7 @@ function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner,
722
713
  * notify posts through the platform bots when main.ts provides a notifier.
723
714
  */
724
715
  function buildExtensionHostServices(params) {
725
- const { workspaceDir, vaultManager, platformNotifier, platformReactor } = params;
716
+ const { workspaceDir, vaultManager, platformNotifier, platformReactor, platformUploader } = params;
726
717
  const eventStore = HostEventStore.fromWorkspaceDir(workspaceDir);
727
718
  return {
728
719
  stateDir: readEnv("STATE_DIR"),
@@ -742,6 +733,7 @@ function buildExtensionHostServices(params) {
742
733
  },
743
734
  ...(platformNotifier ? { postMessage: platformNotifier } : {}),
744
735
  ...(platformReactor ? { addReaction: platformReactor } : {}),
736
+ ...(platformUploader ? { uploadFile: platformUploader } : {}),
745
737
  ...(vaultManager
746
738
  ? {
747
739
  resolveSecrets: (slug) => vaultManager.resolve(`extensions/${slug}`)?.env ?? {},
@@ -750,7 +742,7 @@ function buildExtensionHostServices(params) {
750
742
  };
751
743
  }
752
744
  async function createConfiguredAgentSession(params) {
753
- 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;
754
746
  // Host-only dirs under the state dir: extension code runs in the mikan
755
747
  // process, so it must never load from workspace paths — those are mounted
756
748
  // into sandbox containers and agent-writable (sandbox escape otherwise).
@@ -762,6 +754,7 @@ async function createConfiguredAgentSession(params) {
762
754
  vaultManager,
763
755
  platformNotifier,
764
756
  platformReactor,
757
+ platformUploader,
765
758
  }),
766
759
  });
767
760
  for (const err of extensionsResult.errors) {
@@ -783,7 +776,12 @@ async function createConfiguredAgentSession(params) {
783
776
  if (reloaded > 0) {
784
777
  log.logInfo(`[${conversationId}] Reloaded ${reloaded} messages from session context`);
785
778
  }
786
- return { session, extensionSkills: extensionsResult.skills };
779
+ return {
780
+ session,
781
+ extensionSkills: extensionsResult.skills,
782
+ extensionRegistry: extensionsResult.registry,
783
+ disposeExtensions: extensionsResult.dispose,
784
+ };
787
785
  }
788
786
  function reloadSessionMessages(session, conversationId) {
789
787
  const reloaded = session.reloadFromSession();
@@ -846,7 +844,6 @@ async function prepareRunContext(params) {
846
844
  const { userMessage, imageAttachments } = buildPromptPayload(message, pathContext.runtimeWorkspaceRoot, pathContext);
847
845
  const turnInstructions = buildTurnInstructions(message.id.startsWith("event:"), triggerAttribution, platform.name);
848
846
  const finalUserMessage = turnInstructions ? `${turnInstructions}\n\n${userMessage}` : userMessage;
849
- await writePromptDebugContext(conversationDir, systemPrompt, session, finalUserMessage, imageAttachments.length);
850
847
  return {
851
848
  sessionConversation,
852
849
  runQueue,
@@ -1133,18 +1130,21 @@ function attachSessionEventHandlers(params) {
1133
1130
  * This is a stateless factory function.
1134
1131
  */
1135
1132
  export async function createRunner(options) {
1136
- const { sandboxConfig, sessionKey, conversationId, conversationDir, workspaceDir, sessionScope, vaultManager, provisioner, sessionView, platformNotifier, platformReactor, platformToolPackFactories, } = options;
1133
+ const { sandboxConfig, sessionKey, conversationId, conversationDir, workspaceDir, sessionScope, vaultManager, provisioner, sessionView, platformNotifier, platformReactor, platformUploader, platformToolPackFactories, } = options;
1137
1134
  const agentConfig = resolveConversationSettings(conversationDir);
1138
1135
  const workspaceBase = join(conversationDir, "..");
1139
1136
  const { executionResolver, executor, getPathContext, resolveExecutorForRun } = createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspaceDir, workspaceBase);
1140
1137
  let pathContext = getUnresolvedSandboxPathContext(sandboxConfig, workspaceBase);
1141
- // Create tools (per-runner, with per-runner upload function setter)
1142
- const { tools, setUploadFunction, setReactFunction, bindPlatformToolPacks, setEventContext, setSandboxContext, } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, provisioner }, platformToolPackFactories ?? []);
1143
1138
  const modelRegistry = options.models ?? MikanModels.create();
1144
1139
  if (modelRegistry.getError()) {
1145
1140
  log.logWarning("models.json load error", modelRegistry.getError());
1146
1141
  }
1147
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
+ });
1148
1148
  // Initial system prompt (will be updated each run with fresh memory/channels/users/skills)
1149
1149
  const memory = await getMemory(conversationDir);
1150
1150
  const skills = loadMikanSkills(conversationDir, pathContext.runtimeWorkspaceRoot);
@@ -1168,7 +1168,7 @@ export async function createRunner(options) {
1168
1168
  }
1169
1169
  const sessionUuid = extractSessionUuid(contextFile);
1170
1170
  const chatSessionManager = new AgentMemoryFileManager();
1171
- const { session, extensionSkills } = await createConfiguredAgentSession({
1171
+ const { session, extensionSkills, extensionRegistry, disposeExtensions } = await createConfiguredAgentSession({
1172
1172
  conversationId,
1173
1173
  workspaceDir,
1174
1174
  systemPrompt,
@@ -1180,6 +1180,7 @@ export async function createRunner(options) {
1180
1180
  vaultManager,
1181
1181
  platformNotifier,
1182
1182
  platformReactor,
1183
+ platformUploader,
1183
1184
  });
1184
1185
  // Mutable per-run state - event handler references this
1185
1186
  const runState = createRunState();
@@ -1241,10 +1242,39 @@ export async function createRunner(options) {
1241
1242
  // Autonomous (event/trigger) runs get an explicit resource ceiling since
1242
1243
  // no human is watching the loop; interactive turns stay human-gated.
1243
1244
  const isEventRun = message.id.startsWith("event:");
1244
- 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,
1245
1260
  ...(prepared.imageAttachments.length > 0 ? { images: prepared.imageAttachments } : {}),
1246
1261
  ...(isEventRun ? { budget: DEFAULT_EVENT_BUDGET } : {}),
1247
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
+ }
1248
1278
  // Wait for queued messages
1249
1279
  await prepared.runQueue.wait();
1250
1280
  const sessionViewTokenStore = sessionView?.tokenStore;
@@ -1290,6 +1320,21 @@ export async function createRunner(options) {
1290
1320
  abort() {
1291
1321
  session.abort();
1292
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
+ },
1293
1338
  getCurrentStep() {
1294
1339
  const pending = runState.pendingTools;
1295
1340
  if (pending.size === 0)