@bastani/atomic 0.9.4-alpha.5 → 0.9.4-alpha.7

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 (202) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/builtin/cursor/CHANGELOG.md +6 -0
  3. package/dist/builtin/cursor/package.json +4 -4
  4. package/dist/builtin/intercom/CHANGELOG.md +6 -0
  5. package/dist/builtin/intercom/package.json +2 -2
  6. package/dist/builtin/mcp/CHANGELOG.md +6 -0
  7. package/dist/builtin/mcp/package.json +4 -4
  8. package/dist/builtin/subagents/CHANGELOG.md +20 -0
  9. package/dist/builtin/subagents/package.json +4 -4
  10. package/dist/builtin/subagents/src/runs/background/async-execution-chain.ts +11 -1
  11. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +11 -1
  12. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +2 -0
  13. package/dist/builtin/subagents/src/runs/background/subagent-runner-step.ts +27 -4
  14. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +25 -0
  15. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
  16. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
  17. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
  18. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +1 -0
  19. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +2 -0
  20. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +3 -1
  21. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +22 -0
  22. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +15 -5
  23. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +5 -1
  24. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
  25. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +4 -1
  26. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +4 -1
  27. package/dist/builtin/subagents/src/runs/shared/attempt-watchdog.ts +126 -0
  28. package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +53 -0
  29. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +52 -53
  30. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +2 -0
  31. package/dist/builtin/subagents/src/shared/model-info.ts +16 -0
  32. package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
  33. package/dist/builtin/web-access/CHANGELOG.md +6 -0
  34. package/dist/builtin/web-access/package.json +2 -2
  35. package/dist/builtin/workflows/CHANGELOG.md +12 -0
  36. package/dist/builtin/workflows/package.json +2 -2
  37. package/dist/builtin/workflows/src/runs/shared/model-fallback-failures.ts +34 -4
  38. package/dist/cli/file-processor.d.ts.map +1 -1
  39. package/dist/cli/file-processor.js +13 -25
  40. package/dist/cli/file-processor.js.map +1 -1
  41. package/dist/core/agent-session-extension-bindings.d.ts +2 -0
  42. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  43. package/dist/core/agent-session-extension-bindings.js +11 -3
  44. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  45. package/dist/core/agent-session-methods.d.ts +4 -1
  46. package/dist/core/agent-session-methods.d.ts.map +1 -1
  47. package/dist/core/agent-session-methods.js.map +1 -1
  48. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  49. package/dist/core/agent-session-prompt.js +11 -4
  50. package/dist/core/agent-session-prompt.js.map +1 -1
  51. package/dist/core/agent-session-state.d.ts.map +1 -1
  52. package/dist/core/agent-session-state.js +2 -2
  53. package/dist/core/agent-session-state.js.map +1 -1
  54. package/dist/core/agent-session-tool-hooks.d.ts +7 -1
  55. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  56. package/dist/core/agent-session-tool-hooks.js +26 -4
  57. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  58. package/dist/core/agent-session-tree.d.ts.map +1 -1
  59. package/dist/core/agent-session-tree.js +3 -1
  60. package/dist/core/agent-session-tree.js.map +1 -1
  61. package/dist/core/agent-session.d.ts +1 -0
  62. package/dist/core/agent-session.d.ts.map +1 -1
  63. package/dist/core/agent-session.js +1 -0
  64. package/dist/core/agent-session.js.map +1 -1
  65. package/dist/core/copilot-model-catalog.d.ts +25 -74
  66. package/dist/core/copilot-model-catalog.d.ts.map +1 -1
  67. package/dist/core/copilot-model-catalog.js +118 -68
  68. package/dist/core/copilot-model-catalog.js.map +1 -1
  69. package/dist/core/copilot-model-synthesis.d.ts +10 -0
  70. package/dist/core/copilot-model-synthesis.d.ts.map +1 -0
  71. package/dist/core/copilot-model-synthesis.js +89 -0
  72. package/dist/core/copilot-model-synthesis.js.map +1 -0
  73. package/dist/core/extensions/api-types.d.ts +2 -1
  74. package/dist/core/extensions/api-types.d.ts.map +1 -1
  75. package/dist/core/extensions/api-types.js.map +1 -1
  76. package/dist/core/extensions/index.d.ts +1 -1
  77. package/dist/core/extensions/index.d.ts.map +1 -1
  78. package/dist/core/extensions/index.js.map +1 -1
  79. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  80. package/dist/core/extensions/loader-core.js +3 -3
  81. package/dist/core/extensions/loader-core.js.map +1 -1
  82. package/dist/core/extensions/session-events.d.ts +7 -1
  83. package/dist/core/extensions/session-events.d.ts.map +1 -1
  84. package/dist/core/extensions/session-events.js.map +1 -1
  85. package/dist/core/http-dispatcher.d.ts.map +1 -1
  86. package/dist/core/http-dispatcher.js +28 -1
  87. package/dist/core/http-dispatcher.js.map +1 -1
  88. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  89. package/dist/core/model-registry-builtins.js +21 -3
  90. package/dist/core/model-registry-builtins.js.map +1 -1
  91. package/dist/core/model-resolver-defaults.d.ts.map +1 -1
  92. package/dist/core/model-resolver-defaults.js +1 -1
  93. package/dist/core/model-resolver-defaults.js.map +1 -1
  94. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  95. package/dist/core/resource-loader-reload.js +2 -1
  96. package/dist/core/resource-loader-reload.js.map +1 -1
  97. package/dist/core/session-manager-core.d.ts +2 -12
  98. package/dist/core/session-manager-core.d.ts.map +1 -1
  99. package/dist/core/session-manager-core.js +8 -16
  100. package/dist/core/session-manager-core.js.map +1 -1
  101. package/dist/core/settings-manager-resource-accessors.d.ts +1 -0
  102. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  103. package/dist/core/settings-manager-resource-accessors.js +11 -0
  104. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  105. package/dist/core/settings-manager-ui-accessors.d.ts +2 -0
  106. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  107. package/dist/core/settings-manager-ui-accessors.js +9 -0
  108. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  109. package/dist/core/settings-types.d.ts +2 -0
  110. package/dist/core/settings-types.d.ts.map +1 -1
  111. package/dist/core/settings-types.js.map +1 -1
  112. package/dist/core/timings.d.ts +7 -5
  113. package/dist/core/timings.d.ts.map +1 -1
  114. package/dist/core/timings.js +42 -24
  115. package/dist/core/timings.js.map +1 -1
  116. package/dist/core/tools/read-selectors.d.ts.map +1 -1
  117. package/dist/core/tools/read-selectors.js +19 -1
  118. package/dist/core/tools/read-selectors.js.map +1 -1
  119. package/dist/core/tools/read.d.ts.map +1 -1
  120. package/dist/core/tools/read.js +12 -23
  121. package/dist/core/tools/read.js.map +1 -1
  122. package/dist/index-extensions.d.ts +1 -1
  123. package/dist/index-extensions.d.ts.map +1 -1
  124. package/dist/index-extensions.js.map +1 -1
  125. package/dist/index.d.ts +1 -1
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js.map +1 -1
  128. package/dist/main-session.d.ts.map +1 -1
  129. package/dist/main-session.js +14 -5
  130. package/dist/main-session.js.map +1 -1
  131. package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  132. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  133. package/dist/modes/interactive/components/assistant-message.js +22 -15
  134. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  135. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
  136. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  137. package/dist/modes/interactive/components/chat-message-renderer.js +5 -5
  138. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  139. package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
  140. package/dist/modes/interactive/components/chat-session-host-rendering.js +1 -0
  141. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  142. package/dist/modes/interactive/components/user-message.d.ts +6 -2
  143. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  144. package/dist/modes/interactive/components/user-message.js +16 -5
  145. package/dist/modes/interactive/components/user-message.js.map +1 -1
  146. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  147. package/dist/modes/interactive/interactive-agent-events.js +1 -1
  148. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  149. package/dist/modes/interactive/interactive-editor-actions.d.ts.map +1 -1
  150. package/dist/modes/interactive/interactive-editor-actions.js +1 -0
  151. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  152. package/dist/modes/interactive/interactive-extension-context.d.ts.map +1 -1
  153. package/dist/modes/interactive/interactive-extension-context.js +1 -0
  154. package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
  155. package/dist/modes/interactive/interactive-mode-base.d.ts +1 -0
  156. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  157. package/dist/modes/interactive/interactive-mode-base.js +2 -0
  158. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  159. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  160. package/dist/modes/interactive/interactive-model-routing.js +1 -0
  161. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  162. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  163. package/dist/modes/interactive/interactive-render-chat.js +4 -3
  164. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  165. package/dist/modes/interactive/interactive-session-runtime.d.ts.map +1 -1
  166. package/dist/modes/interactive/interactive-session-runtime.js +1 -0
  167. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  168. package/dist/modes/rpc/rpc-client.d.ts +28 -51
  169. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  170. package/dist/modes/rpc/rpc-client.js +27 -51
  171. package/dist/modes/rpc/rpc-client.js.map +1 -1
  172. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  173. package/dist/modes/rpc/rpc-command-handler.js +19 -0
  174. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  175. package/dist/modes/rpc/rpc-types.d.ts +26 -0
  176. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  177. package/dist/modes/rpc/rpc-types.js.map +1 -1
  178. package/dist/rpc-entry.d.ts +3 -0
  179. package/dist/rpc-entry.d.ts.map +1 -0
  180. package/dist/rpc-entry.js +12 -0
  181. package/dist/rpc-entry.js.map +1 -0
  182. package/dist/utils/image-convert.d.ts +1 -0
  183. package/dist/utils/image-convert.d.ts.map +1 -1
  184. package/dist/utils/image-convert.js +21 -15
  185. package/dist/utils/image-convert.js.map +1 -1
  186. package/dist/utils/image-process.d.ts +18 -0
  187. package/dist/utils/image-process.d.ts.map +1 -0
  188. package/dist/utils/image-process.js +83 -0
  189. package/dist/utils/image-process.js.map +1 -0
  190. package/dist/utils/mime.d.ts.map +1 -1
  191. package/dist/utils/mime.js +41 -0
  192. package/dist/utils/mime.js.map +1 -1
  193. package/docs/extensions.md +11 -0
  194. package/docs/models.md +3 -3
  195. package/docs/providers.md +1 -1
  196. package/docs/rpc.md +60 -2
  197. package/docs/sdk.md +1 -1
  198. package/docs/settings.md +4 -1
  199. package/docs/subagents.md +6 -0
  200. package/docs/workflows.md +2 -0
  201. package/npm-shrinkwrap.json +138 -140
  202. package/package.json +15 -10
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message-renderer.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-message-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage, ToolResultMessage } from \"@earendil-works/pi-ai/compat\";\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport { Container, Text, type Component, type MarkdownTheme, type TUI } from \"@earendil-works/pi-tui\";\nimport type { TSchema } from \"typebox\";\nimport type { MessageRenderer, ToolDefinition } from \"../../../core/extensions/types.ts\";\nimport type { BashExecutionMessage, BranchSummaryMessage, CustomMessage } from \"../../../core/messages.ts\";\nimport { parseSkillBlock } from \"../../../core/agent-session.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { AssistantMessageComponent } from \"./assistant-message.ts\";\nimport { BashExecutionComponent } from \"./bash-execution.ts\";\nimport { BranchSummaryMessageComponent } from \"./branch-summary-message.ts\";\nimport { CustomMessageComponent } from \"./custom-message.ts\";\nimport { SkillInvocationMessageComponent } from \"./skill-invocation-message.ts\";\nimport { ToolExecutionComponent } from \"./tool-execution.ts\";\nimport { UserMessageComponent } from \"./user-message.ts\";\nexport type ChatMessageEntry =\n | { role: \"assistant\"; kind: \"assistant\"; message: AssistantMessage }\n | { role: \"tool\"; kind: \"tool\"; toolName: string; toolCallId: string; args: unknown; result?: ToolResultMessage; isPartial?: boolean }\n | { role: \"tool\"; kind: \"bashExecution\"; message: BashExecutionMessage; isPartial?: boolean }\n | { role: \"user\"; kind: \"user\"; text: string }\n | { role: \"custom\"; kind: \"custom\"; message: CustomMessage<unknown> }\n | { role: \"summary\"; kind: \"branchSummary\"; message: BranchSummaryMessage }\n | { role: \"system\"; kind: \"system\"; text: string };\nexport interface ChatMessageRenderOptions {\n ui: Pick<TUI, \"requestRender\">; cwd: string; markdownTheme?: MarkdownTheme;\n hideThinkingBlock?: boolean; hiddenThinkingLabel?: string; toolOutputExpanded?: boolean;\n showImages?: boolean; imageWidthCells?: number;\n getToolDefinition?: (toolName: string) => ToolDefinition<TSchema, unknown> | undefined;\n getCustomMessageRenderer?: (customType: string) => MessageRenderer | undefined;\n}\nexport function chatEntriesFromAgentMessages(\n messages: readonly AgentMessage[],\n): ChatMessageEntry[] {\n const entries: ChatMessageEntry[] = [];\n const pendingTools = new Map<string, Extract<ChatMessageEntry, { kind: \"tool\" }>>();\n for (const message of messages) {\n if (isLegacyCompactionSummaryMessage(message)) continue;\n switch (message.role) {\n case \"assistant\": {\n entries.push({ role: \"assistant\", kind: \"assistant\", message });\n for (const content of message.content) {\n if (content.type !== \"toolCall\") continue;\n const toolEntry: ChatMessageEntry = {\n role: \"tool\",\n kind: \"tool\",\n toolName: content.name,\n toolCallId: content.id,\n args: content.arguments,\n isPartial: true,\n };\n entries.push(toolEntry);\n pendingTools.set(content.id, toolEntry);\n }\n if (message.stopReason === \"aborted\" || message.stopReason === \"error\") {\n const errorText = message.stopReason === \"aborted\"\n ? message.errorMessage || \"Operation aborted\"\n : message.errorMessage || \"Unknown error\";\n for (const toolEntry of pendingTools.values()) {\n toolEntry.result = {\n role: \"toolResult\",\n toolCallId: toolEntry.toolCallId,\n toolName: toolEntry.toolName,\n content: [{ type: \"text\", text: errorText }],\n isError: true,\n timestamp: message.timestamp,\n };\n toolEntry.isPartial = false;\n }\n pendingTools.clear();\n }\n break;\n }\n case \"toolResult\": {\n const toolEntry = pendingTools.get(message.toolCallId);\n if (toolEntry) {\n toolEntry.result = message;\n toolEntry.isPartial = false;\n pendingTools.delete(message.toolCallId);\n } else {\n entries.push({\n role: \"tool\",\n kind: \"tool\",\n toolName: message.toolName,\n toolCallId: message.toolCallId,\n args: {},\n result: message,\n isPartial: false,\n });\n }\n break;\n }\n case \"user\": {\n const text = getMessageText(message);\n if (text) entries.push({ role: \"user\", kind: \"user\", text });\n break;\n }\n case \"bashExecution\":\n entries.push({ role: \"tool\", kind: \"bashExecution\", message });\n break;\n case \"custom\":\n if (message.display) entries.push({ role: \"custom\", kind: \"custom\", message });\n break;\n case \"branchSummary\":\n entries.push({ role: \"summary\", kind: \"branchSummary\", message });\n break;\n default: {\n const role = (message as { role: string }).role;\n entries.push({ role: \"system\", kind: \"system\", text: role });\n break;\n }\n }\n }\n return entries;\n}\nexport interface LiveChatEventLike {\n readonly type?: unknown;\n readonly message?: unknown;\n readonly assistantMessageEvent?: { readonly type?: unknown; readonly delta?: unknown };\n readonly toolCallId?: unknown;\n readonly toolName?: unknown;\n readonly args?: unknown;\n readonly partialResult?: unknown;\n readonly result?: unknown;\n readonly isError?: unknown;\n}\ntype LiveChatEntry = ChatMessageEntry | { role: string };\nexport class LiveChatEntriesController {\n private streamingAssistantIndex: number | undefined;\n private pendingToolIndexes = new Map<string, number>();\n declare private readonly entries: LiveChatEntry[];\n constructor(entries: LiveChatEntry[]) {\n this.entries = entries;\n\t}\n appendMessages(messages: readonly AgentMessage[]): void {\n this.entries.push(...chatEntriesFromAgentMessages(messages));\n this.reindexPendingTools();\n }\n appendUserText(text: string): void {\n this.entries.push({ role: \"user\", kind: \"user\", text });\n }\n applyEvent(event: LiveChatEventLike): boolean {\n const type = String(event.type ?? \"\");\n switch (type) {\n case \"message_start\":\n return this.handleMessageStart(event.message);\n case \"message_update\":\n return this.handleMessageUpdate(event);\n case \"message_end\":\n return this.handleMessageEnd(event.message);\n case \"tool_execution_start\":\n return this.upsertToolEntry({\n toolCallId: typeof event.toolCallId === \"string\" ? event.toolCallId : undefined,\n toolName: typeof event.toolName === \"string\" ? event.toolName : \"tool\",\n args: event.args,\n isPartial: true,\n });\n case \"tool_execution_update\": {\n const toolCallId = typeof event.toolCallId === \"string\" ? event.toolCallId : undefined;\n if (!toolCallId) return false;\n return this.updateToolResult(toolCallId, event.partialResult, true, false);\n }\n case \"tool_execution_end\": {\n const toolCallId = typeof event.toolCallId === \"string\" ? event.toolCallId : undefined;\n if (!toolCallId) return false;\n return this.updateToolResult(toolCallId, event.result, false, event.isError === true);\n }\n default:\n return false;\n }\n }\n pendingToolIds(): string[] {\n return [...this.pendingToolIndexes.keys()];\n }\n clearPendingTools(): void {\n this.pendingToolIndexes.clear();\n }\n private handleMessageStart(message: unknown): boolean {\n if (!isAgentMessageLike(message)) return false;\n if (message.role === \"assistant\") {\n this.streamingAssistantIndex = undefined;\n return this.updateAssistantMessage(message as AssistantMessage);\n }\n if (message.role === \"toolResult\") {\n const toolResult = message as ToolResultMessage;\n if (this.findToolEntryIndex(toolResult.toolCallId) >= 0) return true;\n }\n const entries = chatEntriesFromAgentMessages([message as AgentMessage]);\n if (entries.length === 0) return false;\n this.entries.push(...entries);\n this.reindexPendingTools();\n return true;\n }\n private handleMessageUpdate(event: LiveChatEventLike): boolean {\n const message = event.message;\n let changed = false;\n const snapshotHasPayload = isAgentMessageLike(message) &&\n message.role === \"assistant\" &&\n assistantContentHasRenderablePayload((message as { content?: unknown }).content);\n if (isAgentMessageLike(message) && message.role === \"assistant\" && snapshotHasPayload) {\n changed = this.updateAssistantMessage(message as AssistantMessage) || changed;\n }\n const assistantEvent = event.assistantMessageEvent;\n const streamType = String(assistantEvent?.type ?? \"\");\n const delta = typeof assistantEvent?.delta === \"string\" ? assistantEvent.delta : \"\";\n if (!changed && streamType === \"text_delta\" && delta) {\n changed = this.appendAssistantTextDelta(delta);\n } else if (!changed && streamType === \"thinking_delta\" && delta) {\n changed = this.appendAssistantThinkingDelta(delta);\n }\n return changed;\n }\n private handleMessageEnd(message: unknown): boolean {\n if (!isAgentMessageLike(message) || message.role !== \"assistant\") return false;\n const changed = this.updateAssistantMessage(message as AssistantMessage);\n const stopReason = typeof message.stopReason === \"string\" ? message.stopReason : \"\";\n if (stopReason === \"aborted\" || stopReason === \"error\") {\n const errorText = typeof message.errorMessage === \"string\" && message.errorMessage\n ? message.errorMessage\n : stopReason === \"aborted\"\n ? \"Operation aborted\"\n : \"Unknown error\";\n for (const toolCallId of this.pendingToolIds()) {\n this.updateToolResult(toolCallId, { content: [{ type: \"text\", text: errorText }] }, false, true);\n }\n this.clearPendingTools();\n }\n this.streamingAssistantIndex = undefined;\n return changed || true;\n }\n private updateAssistantMessage(message: AssistantMessage): boolean {\n if (this.streamingAssistantIndex !== undefined && this.isAssistantEntry(this.entries[this.streamingAssistantIndex])) {\n this.entries[this.streamingAssistantIndex] = {\n ...(this.entries[this.streamingAssistantIndex] as Extract<ChatMessageEntry, { kind: \"assistant\" }>),\n message,\n };\n } else {\n this.entries.push({ role: \"assistant\", kind: \"assistant\", message });\n this.streamingAssistantIndex = this.entries.length - 1;\n }\n for (const content of message.content) {\n if (content.type !== \"toolCall\") continue;\n this.upsertToolEntry({\n toolCallId: content.id,\n toolName: content.name,\n args: content.arguments,\n isPartial: true,\n });\n }\n return true;\n }\n private appendAssistantTextDelta(delta: string): boolean {\n const current = this.currentStreamingAssistantMessage();\n const content = current ? [...current.content] : [];\n const lastText = [...content].reverse().find((item) => item.type === \"text\");\n if (lastText && lastText.type === \"text\") lastText.text += delta;\n else content.push({ type: \"text\", text: delta });\n return this.updateAssistantMessage({\n ...(current ?? minimalAssistantMessage()),\n content,\n });\n }\n private appendAssistantThinkingDelta(delta: string): boolean {\n const current = this.currentStreamingAssistantMessage();\n const content = current ? [...current.content] : [];\n const lastThinking = [...content].reverse().find((item) => item.type === \"thinking\");\n if (lastThinking && lastThinking.type === \"thinking\") lastThinking.thinking += delta;\n else content.push({ type: \"thinking\", thinking: delta });\n return this.updateAssistantMessage({\n ...(current ?? minimalAssistantMessage()),\n content,\n });\n }\n private currentStreamingAssistantMessage(): AssistantMessage | undefined {\n const entry = this.streamingAssistantIndex !== undefined ? this.entries[this.streamingAssistantIndex] : undefined;\n return this.isAssistantEntry(entry) ? entry.message : undefined;\n }\n private upsertToolEntry(update: {\n toolCallId?: string;\n toolName: string;\n args?: unknown;\n isPartial: boolean;\n }): boolean {\n const toolCallId = update.toolCallId ?? `live-${update.toolName}`;\n const index = this.pendingToolIndexes.get(toolCallId) ?? this.findToolEntryIndex(toolCallId, update.toolName);\n const previous = index >= 0 ? this.entries[index] : undefined;\n const previousTool = this.isToolEntry(previous) ? previous : undefined;\n const next: ChatMessageEntry = {\n role: \"tool\",\n kind: \"tool\",\n toolName: previousTool?.toolName ?? update.toolName,\n toolCallId,\n args: update.args ?? previousTool?.args ?? {},\n result: previousTool?.result,\n isPartial: update.isPartial,\n };\n if (index >= 0) this.entries[index] = next;\n else this.entries.push(next);\n this.pendingToolIndexes.set(toolCallId, index >= 0 ? index : this.entries.length - 1);\n return true;\n }\n private updateToolResult(toolCallId: string, result: unknown, isPartial: boolean, isError: boolean): boolean {\n const index = this.pendingToolIndexes.get(toolCallId) ?? this.findToolEntryIndex(toolCallId);\n if (index < 0) return false;\n const entry = this.entries[index];\n if (!this.isToolEntry(entry)) return false;\n const resultObject = toolResultFromUnknown(result, entry.toolName, toolCallId, isError);\n this.entries[index] = { ...entry, result: resultObject, isPartial };\n if (!isPartial) this.pendingToolIndexes.delete(toolCallId);\n return true;\n }\n private isSyntheticToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(\"live-\");\n }\n private findToolEntryIndex(toolCallId: string, toolName?: string): number {\n for (let i = this.entries.length - 1; i >= 0; i--) {\n const entry = this.entries[i];\n if (!this.isToolEntry(entry)) continue;\n if (entry.toolCallId === toolCallId) return i;\n if (\n toolName &&\n entry.toolName === toolName &&\n entry.isPartial !== false &&\n (this.isSyntheticToolCallId(toolCallId) || this.isSyntheticToolCallId(entry.toolCallId))\n ) {\n return i;\n }\n }\n return -1;\n }\n private reindexPendingTools(): void {\n this.pendingToolIndexes.clear();\n for (let i = 0; i < this.entries.length; i++) {\n const entry = this.entries[i];\n if (this.isToolEntry(entry) && entry.isPartial !== false) this.pendingToolIndexes.set(entry.toolCallId, i);\n }\n }\n private isAssistantEntry(entry: LiveChatEntry | undefined): entry is Extract<ChatMessageEntry, { kind: \"assistant\" }> {\n return isChatMessageEntry(entry) && entry.kind === \"assistant\";\n }\n private isToolEntry(entry: LiveChatEntry | undefined): entry is Extract<ChatMessageEntry, { kind: \"tool\" }> {\n return isChatMessageEntry(entry) && entry.kind === \"tool\";\n }\n}\nfunction isChatMessageEntry(entry: LiveChatEntry | undefined): entry is ChatMessageEntry {\n return entry !== undefined && \"kind\" in entry;\n}\nfunction isLegacyCompactionSummaryMessage(message: AgentMessage): boolean {\n return message.role === \"compaction\" + \"Summary\";\n}\nfunction isAgentMessageLike(message: unknown): message is AgentMessage & { stopReason?: unknown; errorMessage?: unknown } {\n return message !== null && typeof message === \"object\" && \"role\" in message;\n}\nfunction assistantContentHasRenderablePayload(content: unknown): boolean {\n if (typeof content === \"string\") return content.length > 0;\n if (!Array.isArray(content)) return false;\n return content.some((item) => {\n if (typeof item === \"string\") return item.length > 0;\n if (item == null || typeof item !== \"object\") return false;\n const obj = item as { type?: unknown; text?: unknown; thinking?: unknown };\n return (obj.type === \"text\" && typeof obj.text === \"string\" && obj.text.length > 0) ||\n (obj.type === \"thinking\" && typeof obj.thinking === \"string\" && obj.thinking.length > 0) ||\n obj.type === \"toolCall\";\n });\n}\nfunction minimalAssistantMessage(): AssistantMessage {\n return {\n role: \"assistant\",\n content: [],\n stopReason: \"stop\",\n } as unknown as AssistantMessage;\n}\nfunction toolResultFromUnknown(\n result: unknown,\n toolName: string,\n toolCallId: string,\n isError: boolean,\n): ToolResultMessage {\n if (result !== null && typeof result === \"object\" && \"content\" in result) {\n const candidate = result as { content?: unknown; details?: unknown };\n const content = Array.isArray(candidate.content) ? candidate.content : [];\n return {\n role: \"toolResult\",\n toolCallId,\n toolName,\n content: content as ToolResultMessage[\"content\"],\n details: candidate.details,\n isError,\n timestamp: Date.now(),\n };\n }\n return {\n role: \"toolResult\",\n toolCallId,\n toolName,\n content: typeof result === \"string\" ? [{ type: \"text\", text: result }] : [],\n isError,\n timestamp: Date.now(),\n };\n}\nexport function renderChatMessageEntry(\n entry: ChatMessageEntry,\n options: ChatMessageRenderOptions,\n): Component {\n const messageEntry = entry as ChatMessageEntry;\n const markdownTheme = options.markdownTheme ?? getMarkdownTheme();\n switch (messageEntry.kind) {\n case \"assistant\":\n return new AssistantMessageComponent(\n messageEntry.message,\n options.hideThinkingBlock ?? false,\n markdownTheme,\n options.hiddenThinkingLabel ?? \"Thinking...\",\n );\n case \"tool\": {\n const component = new ToolExecutionComponent(\n messageEntry.toolName,\n messageEntry.toolCallId,\n messageEntry.args,\n {\n showImages: options.showImages ?? true,\n imageWidthCells: options.imageWidthCells,\n },\n options.getToolDefinition?.(messageEntry.toolName),\n options.ui as TUI,\n options.cwd,\n );\n component.setExpanded(options.toolOutputExpanded ?? false);\n if (messageEntry.result) component.updateResult(messageEntry.result, messageEntry.isPartial ?? false);\n return component;\n }\n case \"bashExecution\": {\n const component = new BashExecutionComponent(\n messageEntry.message.command,\n options.ui as TUI,\n messageEntry.message.excludeFromContext,\n );\n if (messageEntry.message.output) component.appendOutput(messageEntry.message.output);\n if (messageEntry.isPartial !== true) {\n component.setComplete(\n messageEntry.message.exitCode,\n messageEntry.message.cancelled,\n messageEntry.message.truncated\n ? ({ truncated: true } as Parameters<BashExecutionComponent[\"setComplete\"]>[2])\n : undefined,\n messageEntry.message.fullOutputPath,\n );\n }\n return component;\n }\n case \"user\":\n return userMessageComponent(messageEntry.text, markdownTheme, options.toolOutputExpanded ?? false);\n case \"custom\": {\n const component = new CustomMessageComponent(\n messageEntry.message,\n options.getCustomMessageRenderer?.(messageEntry.message.customType),\n markdownTheme,\n );\n component.setExpanded(options.toolOutputExpanded ?? false);\n return component;\n }\n case \"branchSummary\": {\n const component = new BranchSummaryMessageComponent(messageEntry.message, markdownTheme);\n component.setExpanded(options.toolOutputExpanded ?? false);\n return component;\n }\n case \"system\":\n return new Text(theme.fg(\"dim\", messageEntry.text), 1, 0);\n }\n}\nfunction userMessageComponent(text: string, markdownTheme: MarkdownTheme, expanded: boolean): Component {\n const skillBlock = parseSkillBlock(text);\n if (!skillBlock) return new UserMessageComponent(text, markdownTheme);\n const container = new Container();\n const skillComponent = new SkillInvocationMessageComponent(skillBlock, markdownTheme);\n skillComponent.setExpanded(expanded);\n container.addChild(skillComponent);\n if (skillBlock.userMessage) {\n container.addChild(new UserMessageComponent(skillBlock.userMessage, markdownTheme));\n }\n return container;\n}\nfunction getMessageText(message: Extract<AgentMessage, { role: \"user\" }>): string {\n return messageContentText(message.content).trim();\n}\nfunction messageContentText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const parts: string[] = [];\n for (const item of content) {\n if (item == null) continue;\n if (typeof item === \"string\") {\n parts.push(item);\n continue;\n }\n if (typeof item !== \"object\") continue;\n const text = (item as { text?: unknown }).text;\n if (typeof text === \"string\") parts.push(text);\n }\n return parts.join(\"\");\n}\n"]}
1
+ {"version":3,"file":"chat-message-renderer.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-message-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage, ToolResultMessage } from \"@earendil-works/pi-ai/compat\";\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport { Container, Text, type Component, type MarkdownTheme, type TUI } from \"@earendil-works/pi-tui\";\nimport type { TSchema } from \"typebox\";\nimport type { MessageRenderer, ToolDefinition } from \"../../../core/extensions/types.ts\";\nimport type { BashExecutionMessage, BranchSummaryMessage, CustomMessage } from \"../../../core/messages.ts\";\nimport { parseSkillBlock } from \"../../../core/agent-session.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { AssistantMessageComponent } from \"./assistant-message.ts\";\nimport { BashExecutionComponent } from \"./bash-execution.ts\";\nimport { BranchSummaryMessageComponent } from \"./branch-summary-message.ts\";\nimport { CustomMessageComponent } from \"./custom-message.ts\";\nimport { SkillInvocationMessageComponent } from \"./skill-invocation-message.ts\";\nimport { ToolExecutionComponent } from \"./tool-execution.ts\";\nimport { UserMessageComponent } from \"./user-message.ts\";\nexport type ChatMessageEntry =\n | { role: \"assistant\"; kind: \"assistant\"; message: AssistantMessage }\n | { role: \"tool\"; kind: \"tool\"; toolName: string; toolCallId: string; args: unknown; result?: ToolResultMessage; isPartial?: boolean }\n | { role: \"tool\"; kind: \"bashExecution\"; message: BashExecutionMessage; isPartial?: boolean }\n | { role: \"user\"; kind: \"user\"; text: string }\n | { role: \"custom\"; kind: \"custom\"; message: CustomMessage<unknown> }\n | { role: \"summary\"; kind: \"branchSummary\"; message: BranchSummaryMessage }\n | { role: \"system\"; kind: \"system\"; text: string };\nexport interface ChatMessageRenderOptions {\n ui: Pick<TUI, \"requestRender\">; cwd: string; markdownTheme?: MarkdownTheme;\n hideThinkingBlock?: boolean; hiddenThinkingLabel?: string; toolOutputExpanded?: boolean;\n showImages?: boolean; imageWidthCells?: number; outputPad?: number; getToolDefinition?: (toolName: string) => ToolDefinition<TSchema, unknown> | undefined;\n getCustomMessageRenderer?: (customType: string) => MessageRenderer | undefined;\n}\nexport function chatEntriesFromAgentMessages(\n messages: readonly AgentMessage[],\n): ChatMessageEntry[] {\n const entries: ChatMessageEntry[] = [];\n const pendingTools = new Map<string, Extract<ChatMessageEntry, { kind: \"tool\" }>>();\n for (const message of messages) {\n if (isLegacyCompactionSummaryMessage(message)) continue;\n switch (message.role) {\n case \"assistant\": {\n entries.push({ role: \"assistant\", kind: \"assistant\", message });\n for (const content of message.content) {\n if (content.type !== \"toolCall\") continue;\n const toolEntry: ChatMessageEntry = {\n role: \"tool\",\n kind: \"tool\",\n toolName: content.name,\n toolCallId: content.id,\n args: content.arguments,\n isPartial: true,\n };\n entries.push(toolEntry);\n pendingTools.set(content.id, toolEntry);\n }\n if (message.stopReason === \"aborted\" || message.stopReason === \"error\") {\n const errorText = message.stopReason === \"aborted\"\n ? message.errorMessage || \"Operation aborted\"\n : message.errorMessage || \"Unknown error\";\n for (const toolEntry of pendingTools.values()) {\n toolEntry.result = {\n role: \"toolResult\",\n toolCallId: toolEntry.toolCallId,\n toolName: toolEntry.toolName,\n content: [{ type: \"text\", text: errorText }],\n isError: true,\n timestamp: message.timestamp,\n };\n toolEntry.isPartial = false;\n }\n pendingTools.clear();\n }\n break;\n }\n case \"toolResult\": {\n const toolEntry = pendingTools.get(message.toolCallId);\n if (toolEntry) {\n toolEntry.result = message;\n toolEntry.isPartial = false;\n pendingTools.delete(message.toolCallId);\n } else {\n entries.push({\n role: \"tool\",\n kind: \"tool\",\n toolName: message.toolName,\n toolCallId: message.toolCallId,\n args: {},\n result: message,\n isPartial: false,\n });\n }\n break;\n }\n case \"user\": {\n const text = getMessageText(message);\n if (text) entries.push({ role: \"user\", kind: \"user\", text });\n break;\n }\n case \"bashExecution\":\n entries.push({ role: \"tool\", kind: \"bashExecution\", message });\n break;\n case \"custom\":\n if (message.display) entries.push({ role: \"custom\", kind: \"custom\", message });\n break;\n case \"branchSummary\":\n entries.push({ role: \"summary\", kind: \"branchSummary\", message });\n break;\n default: {\n const role = (message as { role: string }).role;\n entries.push({ role: \"system\", kind: \"system\", text: role });\n break;\n }\n }\n }\n return entries;\n}\nexport interface LiveChatEventLike {\n readonly type?: unknown;\n readonly message?: unknown;\n readonly assistantMessageEvent?: { readonly type?: unknown; readonly delta?: unknown };\n readonly toolCallId?: unknown;\n readonly toolName?: unknown;\n readonly args?: unknown;\n readonly partialResult?: unknown;\n readonly result?: unknown;\n readonly isError?: unknown;\n}\ntype LiveChatEntry = ChatMessageEntry | { role: string };\nexport class LiveChatEntriesController {\n private streamingAssistantIndex: number | undefined;\n private pendingToolIndexes = new Map<string, number>();\n declare private readonly entries: LiveChatEntry[];\n constructor(entries: LiveChatEntry[]) {\n this.entries = entries;\n\t}\n appendMessages(messages: readonly AgentMessage[]): void {\n this.entries.push(...chatEntriesFromAgentMessages(messages));\n this.reindexPendingTools();\n }\n appendUserText(text: string): void {\n this.entries.push({ role: \"user\", kind: \"user\", text });\n }\n applyEvent(event: LiveChatEventLike): boolean {\n const type = String(event.type ?? \"\");\n switch (type) {\n case \"message_start\":\n return this.handleMessageStart(event.message);\n case \"message_update\":\n return this.handleMessageUpdate(event);\n case \"message_end\":\n return this.handleMessageEnd(event.message);\n case \"tool_execution_start\":\n return this.upsertToolEntry({\n toolCallId: typeof event.toolCallId === \"string\" ? event.toolCallId : undefined,\n toolName: typeof event.toolName === \"string\" ? event.toolName : \"tool\",\n args: event.args,\n isPartial: true,\n });\n case \"tool_execution_update\": {\n const toolCallId = typeof event.toolCallId === \"string\" ? event.toolCallId : undefined;\n if (!toolCallId) return false;\n return this.updateToolResult(toolCallId, event.partialResult, true, false);\n }\n case \"tool_execution_end\": {\n const toolCallId = typeof event.toolCallId === \"string\" ? event.toolCallId : undefined;\n if (!toolCallId) return false;\n return this.updateToolResult(toolCallId, event.result, false, event.isError === true);\n }\n default:\n return false;\n }\n }\n pendingToolIds(): string[] {\n return [...this.pendingToolIndexes.keys()];\n }\n clearPendingTools(): void {\n this.pendingToolIndexes.clear();\n }\n private handleMessageStart(message: unknown): boolean {\n if (!isAgentMessageLike(message)) return false;\n if (message.role === \"assistant\") {\n this.streamingAssistantIndex = undefined;\n return this.updateAssistantMessage(message as AssistantMessage);\n }\n if (message.role === \"toolResult\") {\n const toolResult = message as ToolResultMessage;\n if (this.findToolEntryIndex(toolResult.toolCallId) >= 0) return true;\n }\n const entries = chatEntriesFromAgentMessages([message as AgentMessage]);\n if (entries.length === 0) return false;\n this.entries.push(...entries);\n this.reindexPendingTools();\n return true;\n }\n private handleMessageUpdate(event: LiveChatEventLike): boolean {\n const message = event.message;\n let changed = false;\n const snapshotHasPayload = isAgentMessageLike(message) &&\n message.role === \"assistant\" &&\n assistantContentHasRenderablePayload((message as { content?: unknown }).content);\n if (isAgentMessageLike(message) && message.role === \"assistant\" && snapshotHasPayload) {\n changed = this.updateAssistantMessage(message as AssistantMessage) || changed;\n }\n const assistantEvent = event.assistantMessageEvent;\n const streamType = String(assistantEvent?.type ?? \"\");\n const delta = typeof assistantEvent?.delta === \"string\" ? assistantEvent.delta : \"\";\n if (!changed && streamType === \"text_delta\" && delta) {\n changed = this.appendAssistantTextDelta(delta);\n } else if (!changed && streamType === \"thinking_delta\" && delta) {\n changed = this.appendAssistantThinkingDelta(delta);\n }\n return changed;\n }\n private handleMessageEnd(message: unknown): boolean {\n if (!isAgentMessageLike(message) || message.role !== \"assistant\") return false;\n const changed = this.updateAssistantMessage(message as AssistantMessage);\n const stopReason = typeof message.stopReason === \"string\" ? message.stopReason : \"\";\n if (stopReason === \"aborted\" || stopReason === \"error\") {\n const errorText = typeof message.errorMessage === \"string\" && message.errorMessage\n ? message.errorMessage\n : stopReason === \"aborted\"\n ? \"Operation aborted\"\n : \"Unknown error\";\n for (const toolCallId of this.pendingToolIds()) {\n this.updateToolResult(toolCallId, { content: [{ type: \"text\", text: errorText }] }, false, true);\n }\n this.clearPendingTools();\n }\n this.streamingAssistantIndex = undefined;\n return changed || true;\n }\n private updateAssistantMessage(message: AssistantMessage): boolean {\n if (this.streamingAssistantIndex !== undefined && this.isAssistantEntry(this.entries[this.streamingAssistantIndex])) {\n this.entries[this.streamingAssistantIndex] = {\n ...(this.entries[this.streamingAssistantIndex] as Extract<ChatMessageEntry, { kind: \"assistant\" }>),\n message,\n };\n } else {\n this.entries.push({ role: \"assistant\", kind: \"assistant\", message });\n this.streamingAssistantIndex = this.entries.length - 1;\n }\n for (const content of message.content) {\n if (content.type !== \"toolCall\") continue;\n this.upsertToolEntry({\n toolCallId: content.id,\n toolName: content.name,\n args: content.arguments,\n isPartial: true,\n });\n }\n return true;\n }\n private appendAssistantTextDelta(delta: string): boolean {\n const current = this.currentStreamingAssistantMessage();\n const content = current ? [...current.content] : [];\n const lastText = [...content].reverse().find((item) => item.type === \"text\");\n if (lastText && lastText.type === \"text\") lastText.text += delta;\n else content.push({ type: \"text\", text: delta });\n return this.updateAssistantMessage({\n ...(current ?? minimalAssistantMessage()),\n content,\n });\n }\n private appendAssistantThinkingDelta(delta: string): boolean {\n const current = this.currentStreamingAssistantMessage();\n const content = current ? [...current.content] : [];\n const lastThinking = [...content].reverse().find((item) => item.type === \"thinking\");\n if (lastThinking && lastThinking.type === \"thinking\") lastThinking.thinking += delta;\n else content.push({ type: \"thinking\", thinking: delta });\n return this.updateAssistantMessage({\n ...(current ?? minimalAssistantMessage()),\n content,\n });\n }\n private currentStreamingAssistantMessage(): AssistantMessage | undefined {\n const entry = this.streamingAssistantIndex !== undefined ? this.entries[this.streamingAssistantIndex] : undefined;\n return this.isAssistantEntry(entry) ? entry.message : undefined;\n }\n private upsertToolEntry(update: {\n toolCallId?: string;\n toolName: string;\n args?: unknown;\n isPartial: boolean;\n }): boolean {\n const toolCallId = update.toolCallId ?? `live-${update.toolName}`;\n const index = this.pendingToolIndexes.get(toolCallId) ?? this.findToolEntryIndex(toolCallId, update.toolName);\n const previous = index >= 0 ? this.entries[index] : undefined;\n const previousTool = this.isToolEntry(previous) ? previous : undefined;\n const next: ChatMessageEntry = {\n role: \"tool\",\n kind: \"tool\",\n toolName: previousTool?.toolName ?? update.toolName,\n toolCallId,\n args: update.args ?? previousTool?.args ?? {},\n result: previousTool?.result,\n isPartial: update.isPartial,\n };\n if (index >= 0) this.entries[index] = next;\n else this.entries.push(next);\n this.pendingToolIndexes.set(toolCallId, index >= 0 ? index : this.entries.length - 1);\n return true;\n }\n private updateToolResult(toolCallId: string, result: unknown, isPartial: boolean, isError: boolean): boolean {\n const index = this.pendingToolIndexes.get(toolCallId) ?? this.findToolEntryIndex(toolCallId);\n if (index < 0) return false;\n const entry = this.entries[index];\n if (!this.isToolEntry(entry)) return false;\n const resultObject = toolResultFromUnknown(result, entry.toolName, toolCallId, isError);\n this.entries[index] = { ...entry, result: resultObject, isPartial };\n if (!isPartial) this.pendingToolIndexes.delete(toolCallId);\n return true;\n }\n private isSyntheticToolCallId(toolCallId: string): boolean {\n return toolCallId.startsWith(\"live-\");\n }\n private findToolEntryIndex(toolCallId: string, toolName?: string): number {\n for (let i = this.entries.length - 1; i >= 0; i--) {\n const entry = this.entries[i];\n if (!this.isToolEntry(entry)) continue;\n if (entry.toolCallId === toolCallId) return i;\n if (\n toolName &&\n entry.toolName === toolName &&\n entry.isPartial !== false &&\n (this.isSyntheticToolCallId(toolCallId) || this.isSyntheticToolCallId(entry.toolCallId))\n ) {\n return i;\n }\n }\n return -1;\n }\n private reindexPendingTools(): void {\n this.pendingToolIndexes.clear();\n for (let i = 0; i < this.entries.length; i++) {\n const entry = this.entries[i];\n if (this.isToolEntry(entry) && entry.isPartial !== false) this.pendingToolIndexes.set(entry.toolCallId, i);\n }\n }\n private isAssistantEntry(entry: LiveChatEntry | undefined): entry is Extract<ChatMessageEntry, { kind: \"assistant\" }> {\n return isChatMessageEntry(entry) && entry.kind === \"assistant\";\n }\n private isToolEntry(entry: LiveChatEntry | undefined): entry is Extract<ChatMessageEntry, { kind: \"tool\" }> {\n return isChatMessageEntry(entry) && entry.kind === \"tool\";\n }\n}\nfunction isChatMessageEntry(entry: LiveChatEntry | undefined): entry is ChatMessageEntry {\n return entry !== undefined && \"kind\" in entry;\n}\nfunction isLegacyCompactionSummaryMessage(message: AgentMessage): boolean {\n return message.role === \"compaction\" + \"Summary\";\n}\nfunction isAgentMessageLike(message: unknown): message is AgentMessage & { stopReason?: unknown; errorMessage?: unknown } {\n return message !== null && typeof message === \"object\" && \"role\" in message;\n}\nfunction assistantContentHasRenderablePayload(content: unknown): boolean {\n if (typeof content === \"string\") return content.length > 0;\n if (!Array.isArray(content)) return false;\n return content.some((item) => {\n if (typeof item === \"string\") return item.length > 0;\n if (item == null || typeof item !== \"object\") return false;\n const obj = item as { type?: unknown; text?: unknown; thinking?: unknown };\n return (obj.type === \"text\" && typeof obj.text === \"string\" && obj.text.length > 0) ||\n (obj.type === \"thinking\" && typeof obj.thinking === \"string\" && obj.thinking.length > 0) ||\n obj.type === \"toolCall\";\n });\n}\nfunction minimalAssistantMessage(): AssistantMessage {\n return {\n role: \"assistant\",\n content: [],\n stopReason: \"stop\",\n } as unknown as AssistantMessage;\n}\nfunction toolResultFromUnknown(\n result: unknown,\n toolName: string,\n toolCallId: string,\n isError: boolean,\n): ToolResultMessage {\n if (result !== null && typeof result === \"object\" && \"content\" in result) {\n const candidate = result as { content?: unknown; details?: unknown };\n const content = Array.isArray(candidate.content) ? candidate.content : [];\n return {\n role: \"toolResult\",\n toolCallId,\n toolName,\n content: content as ToolResultMessage[\"content\"],\n details: candidate.details,\n isError,\n timestamp: Date.now(),\n };\n }\n return {\n role: \"toolResult\",\n toolCallId,\n toolName,\n content: typeof result === \"string\" ? [{ type: \"text\", text: result }] : [],\n isError,\n timestamp: Date.now(),\n };\n}\nexport function renderChatMessageEntry(\n entry: ChatMessageEntry,\n options: ChatMessageRenderOptions,\n): Component {\n const messageEntry = entry as ChatMessageEntry;\n const markdownTheme = options.markdownTheme ?? getMarkdownTheme();\n switch (messageEntry.kind) {\n case \"assistant\":\n return new AssistantMessageComponent(\n messageEntry.message,\n options.hideThinkingBlock ?? false,\n markdownTheme,\n options.hiddenThinkingLabel ?? \"Thinking...\",\n options.outputPad ?? 1,\n );\n case \"tool\": {\n const component = new ToolExecutionComponent(\n messageEntry.toolName,\n messageEntry.toolCallId,\n messageEntry.args,\n {\n showImages: options.showImages ?? true,\n imageWidthCells: options.imageWidthCells,\n },\n options.getToolDefinition?.(messageEntry.toolName),\n options.ui as TUI,\n options.cwd,\n );\n component.setExpanded(options.toolOutputExpanded ?? false);\n if (messageEntry.result) component.updateResult(messageEntry.result, messageEntry.isPartial ?? false);\n return component;\n }\n case \"bashExecution\": {\n const component = new BashExecutionComponent(\n messageEntry.message.command,\n options.ui as TUI,\n messageEntry.message.excludeFromContext,\n );\n if (messageEntry.message.output) component.appendOutput(messageEntry.message.output);\n if (messageEntry.isPartial !== true) {\n component.setComplete(\n messageEntry.message.exitCode,\n messageEntry.message.cancelled,\n messageEntry.message.truncated\n ? ({ truncated: true } as Parameters<BashExecutionComponent[\"setComplete\"]>[2])\n : undefined,\n messageEntry.message.fullOutputPath,\n );\n }\n return component;\n }\n case \"user\":\n return userMessageComponent(messageEntry.text, markdownTheme, options.toolOutputExpanded ?? false, options.outputPad ?? 1);\n case \"custom\": {\n const component = new CustomMessageComponent(\n messageEntry.message,\n options.getCustomMessageRenderer?.(messageEntry.message.customType),\n markdownTheme,\n );\n component.setExpanded(options.toolOutputExpanded ?? false);\n return component;\n }\n case \"branchSummary\": {\n const component = new BranchSummaryMessageComponent(messageEntry.message, markdownTheme);\n component.setExpanded(options.toolOutputExpanded ?? false);\n return component;\n }\n case \"system\":\n return new Text(theme.fg(\"dim\", messageEntry.text), 1, 0);\n }\n}\nfunction userMessageComponent(text: string, markdownTheme: MarkdownTheme, expanded: boolean, outputPad = 1): Component {\n const skillBlock = parseSkillBlock(text);\n if (!skillBlock) return new UserMessageComponent(text, markdownTheme, outputPad);\n const container = new Container();\n const skillComponent = new SkillInvocationMessageComponent(skillBlock, markdownTheme);\n skillComponent.setExpanded(expanded);\n container.addChild(skillComponent);\n if (skillBlock.userMessage) {\n container.addChild(new UserMessageComponent(skillBlock.userMessage, markdownTheme, outputPad));\n }\n return container;\n}\nfunction getMessageText(message: Extract<AgentMessage, { role: \"user\" }>): string {\n return messageContentText(message.content).trim();\n}\nfunction messageContentText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const parts: string[] = [];\n for (const item of content) {\n if (item == null) continue;\n if (typeof item === \"string\") {\n parts.push(item);\n continue;\n }\n if (typeof item !== \"object\") continue;\n const text = (item as { text?: unknown }).text;\n if (typeof text === \"string\") parts.push(text);\n }\n return parts.join(\"\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"chat-session-host-rendering.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-session-host-rendering.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EAMf,MAAM,wBAAwB,CAAC;AAOhC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAgBzE,wBAAgB,qBAAqB,CACnC,WAAW,SAAS,uBAAuB,EAE3C,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,EAAE,CAaV;AAED,wBAAgB,gCAAgC,CAC9C,WAAW,SAAS,uBAAuB,EAC3C,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBnE;AAED,wBAAgB,8BAA8B,CAC5C,WAAW,SAAS,uBAAuB,EAC3C,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CASnE;AAED,wBAAgB,sBAAsB,CAAC,WAAW,SAAS,uBAAuB,EAChF,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,GACZ,MAAM,EAAE,CAIV;AAED,wBAAgB,uBAAuB,CAAC,WAAW,SAAS,uBAAuB,EACjF,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,GACf,MAAM,EAAE,CAwBV;AAED,wBAAgB,uBAAuB,CAAC,WAAW,SAAS,uBAAuB,EACjF,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,GACZ,MAAM,EAAE,CAMV;AAED,wBAAgB,sBAAsB,CACpC,WAAW,SAAS,uBAAuB,EAE3C,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,GACvC,SAAS,CAWX;AAED,wBAAgB,kBAAkB,CAAC,WAAW,SAAS,uBAAuB,EAC5E,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,GACZ,MAAM,CAQR","sourcesContent":["import {\n type Component,\n type TUI,\n Spacer,\n Text,\n truncateToWidth,\n visibleWidth,\n} from \"@earendil-works/pi-tui\";\nimport { UsageMeterComponent, FooterComponent } from \"./footer.ts\";\nimport {\n renderChatMessageEntry,\n type ChatMessageEntry,\n type ChatMessageRenderOptions,\n} from \"./chat-message-renderer.ts\";\nimport type { ChatTranscriptEntryLike } from \"./chat-transcript.ts\";\nimport type { ChatSessionHostState } from \"./chat-session-host-state.ts\";\nimport type { ChatSessionHostEntry } from \"./chat-session-host-types.ts\";\nimport {\n setEditorBorderColor,\n setEditorFocused,\n setEditorPlaceholder,\n} from \"./chat-session-host-editor.ts\";\nimport { isChatSessionStreaming } from \"./chat-session-host-runtime.ts\";\nimport {\n cacheKey,\n isChatMessageEntry,\n spinnerFrame,\n stripAnsi,\n tailStreamingText,\n} from \"./chat-session-host-utils.ts\";\nimport { WorkingStatusComponent } from \"./working-status.ts\";\n\nexport function renderChatSessionBody<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n budget: number,\n): string[] {\n const components: Component[] = [];\n state.transcriptRenderSettingsKey = chatRenderSettingsCacheKey(state);\n if (state.transcript.length > 0) {\n components.push(state.transcriptComponent);\n }\n if (state.statusMessage) {\n components.push(new Spacer(1));\n components.push(new Text(state.style.dim(state.statusMessage), 2, 0));\n }\n state.bodyViewport.setVisibleRows(budget);\n state.bodyViewport.setComponents(components);\n return state.bodyViewport.render(width);\n}\n\nexport function renderChatSessionPendingMessages<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(state: ChatSessionHostState<TExtraEntry>, width: number): string[] {\n if (\n state.pendingSteeringMessages.length === 0 &&\n state.pendingFollowUpMessages.length === 0 &&\n state.compactionQueuedMessages.length === 0\n ) {\n return [];\n }\n const lines = [state.style.blank(width)];\n for (const message of state.pendingSteeringMessages) {\n lines.push(...pendingMessageLine(state, width, \"Steering\", message));\n }\n for (const message of state.pendingFollowUpMessages) {\n lines.push(...pendingMessageLine(state, width, \"Follow-up\", message));\n }\n for (const message of state.compactionQueuedMessages) {\n lines.push(...pendingMessageLine(state, width, \"Queued\", message));\n }\n const hint = state.getActionKeyDisplay?.(\"app.message.dequeue\") ?? \"alt+up\";\n lines.push(...new Text(state.style.dim(`↳ ${hint} to edit all queued messages`), 1, 0).render(width));\n return lines;\n}\n\nexport function renderChatSessionWorkingStatus<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(state: ChatSessionHostState<TExtraEntry>, width: number): string[] {\n if (!isChatSessionStreaming(state)) return [];\n const message = state.workingMessage ?? \"Working...\";\n return new WorkingStatusComponent({\n spinner: spinnerFrame(),\n message,\n spinnerColor: (text) => state.style.accentBold(text),\n messageColor: (text) => state.style.textMuted(text),\n }).render(width);\n}\n\nexport function renderChatSessionUsage<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n): string[] {\n const agentSession = state.getAgentSession?.();\n if (!agentSession) return [];\n return new UsageMeterComponent(agentSession).render(width);\n}\n\nexport function renderChatSessionEditor<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n focused: boolean,\n): string[] {\n const disabled = state.isDisabled?.() === true;\n const agentSession = state.getAgentSession?.();\n const ruleHex = state.style.editorRuleColor(disabled, agentSession, {\n isBashMode: state.isBashMode,\n });\n if (!disabled && state.editor) {\n setEditorFocused(state.editor, focused);\n setEditorPlaceholder(state.editor, undefined);\n setEditorBorderColor(state.editor, (text) => state.style.rule(ruleHex, text));\n return state.editor.render(width);\n }\n if (state.editor) setEditorFocused(state.editor, false);\n const rule = state.style.rule(ruleHex, \"─\".repeat(width));\n const available = Math.max(1, width - 3);\n const value = state.inputBuffer\n ? state.style.text(truncateToWidth(state.inputBuffer, available)) + state.style.cursor()\n : disabled\n ? \"\"\n : state.style.cursor();\n const left = state.style.accentBold(\"❯\") + \" \" + value;\n const gap = Math.max(0, width - visibleWidth(stripAnsi(left)));\n const body = left + \" \".repeat(gap);\n return [rule, body, rule];\n}\n\nexport function renderChatSessionFooter<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n): string[] {\n const agentSession = state.getAgentSession?.();\n if (agentSession && state.footerData) {\n return new FooterComponent(agentSession, state.footerData).render(width);\n }\n return [];\n}\n\nexport function renderChatSessionEntry<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n): Component {\n if (isChatMessageEntry(entry)) {\n return renderChatMessageEntry(\n streamingWindowedEntry(state, entry),\n chatMessageRenderOptions(state),\n );\n }\n if (!state.renderExtraEntry) {\n return new Text(\"\", 0, 0);\n }\n return state.renderExtraEntry(entry);\n}\n\nexport function transcriptCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n index: number,\n): string {\n return cacheKey([\n state.transcriptRenderSettingsKey,\n index,\n entry.role,\n renderIdentityKey(state, entry),\n entryContentCacheKey(state, entry),\n ]);\n}\n\nfunction streamingWindowedEntry<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatMessageEntry,\n): ChatMessageEntry {\n if (!isChatSessionStreaming(state) || state.bodyViewport.getScrollFromBottom() !== 0) {\n return entry;\n }\n if (entry.kind !== \"assistant\") return entry;\n const content = entry.message.content.map((item) => {\n if (item.type === \"text\") return { ...item, text: tailStreamingText(item.text) };\n if (item.type === \"thinking\") return { ...item, thinking: tailStreamingText(item.thinking) };\n return item;\n });\n return { ...entry, message: { ...entry.message, content } };\n}\n\nfunction chatMessageRenderOptions<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): ChatMessageRenderOptions {\n const inherited = state.getChatRenderSettings?.();\n return {\n ...inherited,\n ui: toolTui(state),\n cwd: state.getCwd?.() ?? state.getAgentSession?.()?.sessionManager.getCwd() ?? process.cwd(),\n markdownTheme: inherited?.markdownTheme ?? state.getMarkdownTheme?.(),\n showImages: inherited?.showImages ?? true,\n };\n}\n\nfunction toolTui<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): Pick<TUI, \"requestRender\"> {\n return { requestRender: () => state.requestRender?.() };\n}\n\nfunction chatRenderSettingsCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): string {\n const inherited = state.getChatRenderSettings?.();\n return cacheKey([\n \"settings\",\n inherited?.hideThinkingBlock === true,\n inherited?.hiddenThinkingLabel ?? \"\",\n inherited?.toolOutputExpanded === true,\n inherited?.showImages !== false,\n inherited?.imageWidthCells ?? null,\n state.getCwd?.() ?? state.getAgentSession?.()?.sessionManager.getCwd() ?? process.cwd(),\n state.bodyViewport.getScrollFromBottom() === 0,\n isChatSessionStreaming(state),\n ]);\n}\n\nfunction entryContentCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n): string {\n if (!isChatMessageEntry(entry)) return cacheKey([\"extra\"]);\n switch (entry.kind) {\n case \"assistant\":\n return cacheKey([\"assistant\", renderIdentityKey(state, entry.message)]);\n case \"tool\":\n return cacheKey([\"tool\", entry.toolCallId, entry.toolName, entry.isPartial === true, entry.result === undefined ? null : renderIdentityKey(state, entry.result)]);\n case \"bashExecution\":\n return cacheKey([\"bashExecution\", entry.isPartial === true, entry.message.command, entry.message.output, entry.message.exitCode ?? null, entry.message.cancelled, entry.message.truncated, entry.message.fullOutputPath ?? null]);\n case \"user\":\n return cacheKey([\"user\", entry.text]);\n case \"custom\":\n return cacheKey([\"custom\", renderIdentityKey(state, entry.message)]);\n case \"branchSummary\":\n return cacheKey([\"branchSummary\", renderIdentityKey(state, entry.message)]);\n case \"system\":\n return cacheKey([\"system\", entry.text]);\n }\n}\n\nfunction renderIdentityKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n value: object,\n): string {\n const existing = state.renderIdentityIds.get(value);\n if (existing !== undefined) return String(existing);\n const id = state.nextRenderIdentityId;\n state.nextRenderIdentityId += 1;\n state.renderIdentityIds.set(value, id);\n return String(id);\n}\n\nfunction pendingMessageLine<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n label: \"Steering\" | \"Follow-up\" | \"Queued\",\n message: string,\n): string[] {\n const text = `${label}: ${message}`;\n return new Text(\n state.style.dim(truncateToWidth(text, Math.max(1, width - 2))),\n 1,\n 0,\n ).render(width);\n}\n"]}
1
+ {"version":3,"file":"chat-session-host-rendering.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-session-host-rendering.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EAMf,MAAM,wBAAwB,CAAC;AAOhC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAgBzE,wBAAgB,qBAAqB,CACnC,WAAW,SAAS,uBAAuB,EAE3C,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,EAAE,CAaV;AAED,wBAAgB,gCAAgC,CAC9C,WAAW,SAAS,uBAAuB,EAC3C,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBnE;AAED,wBAAgB,8BAA8B,CAC5C,WAAW,SAAS,uBAAuB,EAC3C,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CASnE;AAED,wBAAgB,sBAAsB,CAAC,WAAW,SAAS,uBAAuB,EAChF,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,GACZ,MAAM,EAAE,CAIV;AAED,wBAAgB,uBAAuB,CAAC,WAAW,SAAS,uBAAuB,EACjF,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,GACf,MAAM,EAAE,CAwBV;AAED,wBAAgB,uBAAuB,CAAC,WAAW,SAAS,uBAAuB,EACjF,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,GACZ,MAAM,EAAE,CAMV;AAED,wBAAgB,sBAAsB,CACpC,WAAW,SAAS,uBAAuB,EAE3C,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,GACvC,SAAS,CAWX;AAED,wBAAgB,kBAAkB,CAAC,WAAW,SAAS,uBAAuB,EAC5E,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,oBAAoB,CAAC,WAAW,CAAC,EACxC,KAAK,EAAE,MAAM,GACZ,MAAM,CAQR","sourcesContent":["import {\n type Component,\n type TUI,\n Spacer,\n Text,\n truncateToWidth,\n visibleWidth,\n} from \"@earendil-works/pi-tui\";\nimport { UsageMeterComponent, FooterComponent } from \"./footer.ts\";\nimport {\n renderChatMessageEntry,\n type ChatMessageEntry,\n type ChatMessageRenderOptions,\n} from \"./chat-message-renderer.ts\";\nimport type { ChatTranscriptEntryLike } from \"./chat-transcript.ts\";\nimport type { ChatSessionHostState } from \"./chat-session-host-state.ts\";\nimport type { ChatSessionHostEntry } from \"./chat-session-host-types.ts\";\nimport {\n setEditorBorderColor,\n setEditorFocused,\n setEditorPlaceholder,\n} from \"./chat-session-host-editor.ts\";\nimport { isChatSessionStreaming } from \"./chat-session-host-runtime.ts\";\nimport {\n cacheKey,\n isChatMessageEntry,\n spinnerFrame,\n stripAnsi,\n tailStreamingText,\n} from \"./chat-session-host-utils.ts\";\nimport { WorkingStatusComponent } from \"./working-status.ts\";\n\nexport function renderChatSessionBody<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n budget: number,\n): string[] {\n const components: Component[] = [];\n state.transcriptRenderSettingsKey = chatRenderSettingsCacheKey(state);\n if (state.transcript.length > 0) {\n components.push(state.transcriptComponent);\n }\n if (state.statusMessage) {\n components.push(new Spacer(1));\n components.push(new Text(state.style.dim(state.statusMessage), 2, 0));\n }\n state.bodyViewport.setVisibleRows(budget);\n state.bodyViewport.setComponents(components);\n return state.bodyViewport.render(width);\n}\n\nexport function renderChatSessionPendingMessages<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(state: ChatSessionHostState<TExtraEntry>, width: number): string[] {\n if (\n state.pendingSteeringMessages.length === 0 &&\n state.pendingFollowUpMessages.length === 0 &&\n state.compactionQueuedMessages.length === 0\n ) {\n return [];\n }\n const lines = [state.style.blank(width)];\n for (const message of state.pendingSteeringMessages) {\n lines.push(...pendingMessageLine(state, width, \"Steering\", message));\n }\n for (const message of state.pendingFollowUpMessages) {\n lines.push(...pendingMessageLine(state, width, \"Follow-up\", message));\n }\n for (const message of state.compactionQueuedMessages) {\n lines.push(...pendingMessageLine(state, width, \"Queued\", message));\n }\n const hint = state.getActionKeyDisplay?.(\"app.message.dequeue\") ?? \"alt+up\";\n lines.push(...new Text(state.style.dim(`↳ ${hint} to edit all queued messages`), 1, 0).render(width));\n return lines;\n}\n\nexport function renderChatSessionWorkingStatus<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(state: ChatSessionHostState<TExtraEntry>, width: number): string[] {\n if (!isChatSessionStreaming(state)) return [];\n const message = state.workingMessage ?? \"Working...\";\n return new WorkingStatusComponent({\n spinner: spinnerFrame(),\n message,\n spinnerColor: (text) => state.style.accentBold(text),\n messageColor: (text) => state.style.textMuted(text),\n }).render(width);\n}\n\nexport function renderChatSessionUsage<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n): string[] {\n const agentSession = state.getAgentSession?.();\n if (!agentSession) return [];\n return new UsageMeterComponent(agentSession).render(width);\n}\n\nexport function renderChatSessionEditor<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n focused: boolean,\n): string[] {\n const disabled = state.isDisabled?.() === true;\n const agentSession = state.getAgentSession?.();\n const ruleHex = state.style.editorRuleColor(disabled, agentSession, {\n isBashMode: state.isBashMode,\n });\n if (!disabled && state.editor) {\n setEditorFocused(state.editor, focused);\n setEditorPlaceholder(state.editor, undefined);\n setEditorBorderColor(state.editor, (text) => state.style.rule(ruleHex, text));\n return state.editor.render(width);\n }\n if (state.editor) setEditorFocused(state.editor, false);\n const rule = state.style.rule(ruleHex, \"─\".repeat(width));\n const available = Math.max(1, width - 3);\n const value = state.inputBuffer\n ? state.style.text(truncateToWidth(state.inputBuffer, available)) + state.style.cursor()\n : disabled\n ? \"\"\n : state.style.cursor();\n const left = state.style.accentBold(\"❯\") + \" \" + value;\n const gap = Math.max(0, width - visibleWidth(stripAnsi(left)));\n const body = left + \" \".repeat(gap);\n return [rule, body, rule];\n}\n\nexport function renderChatSessionFooter<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n): string[] {\n const agentSession = state.getAgentSession?.();\n if (agentSession && state.footerData) {\n return new FooterComponent(agentSession, state.footerData).render(width);\n }\n return [];\n}\n\nexport function renderChatSessionEntry<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n): Component {\n if (isChatMessageEntry(entry)) {\n return renderChatMessageEntry(\n streamingWindowedEntry(state, entry),\n chatMessageRenderOptions(state),\n );\n }\n if (!state.renderExtraEntry) {\n return new Text(\"\", 0, 0);\n }\n return state.renderExtraEntry(entry);\n}\n\nexport function transcriptCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n index: number,\n): string {\n return cacheKey([\n state.transcriptRenderSettingsKey,\n index,\n entry.role,\n renderIdentityKey(state, entry),\n entryContentCacheKey(state, entry),\n ]);\n}\n\nfunction streamingWindowedEntry<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatMessageEntry,\n): ChatMessageEntry {\n if (!isChatSessionStreaming(state) || state.bodyViewport.getScrollFromBottom() !== 0) {\n return entry;\n }\n if (entry.kind !== \"assistant\") return entry;\n const content = entry.message.content.map((item) => {\n if (item.type === \"text\") return { ...item, text: tailStreamingText(item.text) };\n if (item.type === \"thinking\") return { ...item, thinking: tailStreamingText(item.thinking) };\n return item;\n });\n return { ...entry, message: { ...entry.message, content } };\n}\n\nfunction chatMessageRenderOptions<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): ChatMessageRenderOptions {\n const inherited = state.getChatRenderSettings?.();\n return {\n ...inherited,\n ui: toolTui(state),\n cwd: state.getCwd?.() ?? state.getAgentSession?.()?.sessionManager.getCwd() ?? process.cwd(),\n markdownTheme: inherited?.markdownTheme ?? state.getMarkdownTheme?.(),\n showImages: inherited?.showImages ?? true,\n };\n}\n\nfunction toolTui<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): Pick<TUI, \"requestRender\"> {\n return { requestRender: () => state.requestRender?.() };\n}\n\nfunction chatRenderSettingsCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): string {\n const inherited = state.getChatRenderSettings?.();\n return cacheKey([\n \"settings\",\n inherited?.hideThinkingBlock === true,\n inherited?.hiddenThinkingLabel ?? \"\",\n inherited?.toolOutputExpanded === true,\n inherited?.showImages !== false,\n inherited?.imageWidthCells ?? null,\n inherited?.outputPad ?? null,\n state.getCwd?.() ?? state.getAgentSession?.()?.sessionManager.getCwd() ?? process.cwd(),\n state.bodyViewport.getScrollFromBottom() === 0,\n isChatSessionStreaming(state),\n ]);\n}\n\nfunction entryContentCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n): string {\n if (!isChatMessageEntry(entry)) return cacheKey([\"extra\"]);\n switch (entry.kind) {\n case \"assistant\":\n return cacheKey([\"assistant\", renderIdentityKey(state, entry.message)]);\n case \"tool\":\n return cacheKey([\"tool\", entry.toolCallId, entry.toolName, entry.isPartial === true, entry.result === undefined ? null : renderIdentityKey(state, entry.result)]);\n case \"bashExecution\":\n return cacheKey([\"bashExecution\", entry.isPartial === true, entry.message.command, entry.message.output, entry.message.exitCode ?? null, entry.message.cancelled, entry.message.truncated, entry.message.fullOutputPath ?? null]);\n case \"user\":\n return cacheKey([\"user\", entry.text]);\n case \"custom\":\n return cacheKey([\"custom\", renderIdentityKey(state, entry.message)]);\n case \"branchSummary\":\n return cacheKey([\"branchSummary\", renderIdentityKey(state, entry.message)]);\n case \"system\":\n return cacheKey([\"system\", entry.text]);\n }\n}\n\nfunction renderIdentityKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n value: object,\n): string {\n const existing = state.renderIdentityIds.get(value);\n if (existing !== undefined) return String(existing);\n const id = state.nextRenderIdentityId;\n state.nextRenderIdentityId += 1;\n state.renderIdentityIds.set(value, id);\n return String(id);\n}\n\nfunction pendingMessageLine<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n label: \"Steering\" | \"Follow-up\" | \"Queued\",\n message: string,\n): string[] {\n const text = `${label}: ${message}`;\n return new Text(\n state.style.dim(truncateToWidth(text, Math.max(1, width - 2))),\n 1,\n 0,\n ).render(width);\n}\n"]}
@@ -144,6 +144,7 @@ function chatRenderSettingsCacheKey(state) {
144
144
  inherited?.toolOutputExpanded === true,
145
145
  inherited?.showImages !== false,
146
146
  inherited?.imageWidthCells ?? null,
147
+ inherited?.outputPad ?? null,
147
148
  state.getCwd?.() ?? state.getAgentSession?.()?.sessionManager.getCwd() ?? process.cwd(),
148
149
  state.bodyViewport.getScrollFromBottom() === 0,
149
150
  isChatSessionStreaming(state),
@@ -1 +1 @@
1
- {"version":3,"file":"chat-session-host-rendering.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-session-host-rendering.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type Component,\n type TUI,\n Spacer,\n Text,\n truncateToWidth,\n visibleWidth,\n} from \"@earendil-works/pi-tui\";\nimport { UsageMeterComponent, FooterComponent } from \"./footer.ts\";\nimport {\n renderChatMessageEntry,\n type ChatMessageEntry,\n type ChatMessageRenderOptions,\n} from \"./chat-message-renderer.ts\";\nimport type { ChatTranscriptEntryLike } from \"./chat-transcript.ts\";\nimport type { ChatSessionHostState } from \"./chat-session-host-state.ts\";\nimport type { ChatSessionHostEntry } from \"./chat-session-host-types.ts\";\nimport {\n setEditorBorderColor,\n setEditorFocused,\n setEditorPlaceholder,\n} from \"./chat-session-host-editor.ts\";\nimport { isChatSessionStreaming } from \"./chat-session-host-runtime.ts\";\nimport {\n cacheKey,\n isChatMessageEntry,\n spinnerFrame,\n stripAnsi,\n tailStreamingText,\n} from \"./chat-session-host-utils.ts\";\nimport { WorkingStatusComponent } from \"./working-status.ts\";\n\nexport function renderChatSessionBody<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n budget: number,\n): string[] {\n const components: Component[] = [];\n state.transcriptRenderSettingsKey = chatRenderSettingsCacheKey(state);\n if (state.transcript.length > 0) {\n components.push(state.transcriptComponent);\n }\n if (state.statusMessage) {\n components.push(new Spacer(1));\n components.push(new Text(state.style.dim(state.statusMessage), 2, 0));\n }\n state.bodyViewport.setVisibleRows(budget);\n state.bodyViewport.setComponents(components);\n return state.bodyViewport.render(width);\n}\n\nexport function renderChatSessionPendingMessages<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(state: ChatSessionHostState<TExtraEntry>, width: number): string[] {\n if (\n state.pendingSteeringMessages.length === 0 &&\n state.pendingFollowUpMessages.length === 0 &&\n state.compactionQueuedMessages.length === 0\n ) {\n return [];\n }\n const lines = [state.style.blank(width)];\n for (const message of state.pendingSteeringMessages) {\n lines.push(...pendingMessageLine(state, width, \"Steering\", message));\n }\n for (const message of state.pendingFollowUpMessages) {\n lines.push(...pendingMessageLine(state, width, \"Follow-up\", message));\n }\n for (const message of state.compactionQueuedMessages) {\n lines.push(...pendingMessageLine(state, width, \"Queued\", message));\n }\n const hint = state.getActionKeyDisplay?.(\"app.message.dequeue\") ?? \"alt+up\";\n lines.push(...new Text(state.style.dim(`↳ ${hint} to edit all queued messages`), 1, 0).render(width));\n return lines;\n}\n\nexport function renderChatSessionWorkingStatus<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(state: ChatSessionHostState<TExtraEntry>, width: number): string[] {\n if (!isChatSessionStreaming(state)) return [];\n const message = state.workingMessage ?? \"Working...\";\n return new WorkingStatusComponent({\n spinner: spinnerFrame(),\n message,\n spinnerColor: (text) => state.style.accentBold(text),\n messageColor: (text) => state.style.textMuted(text),\n }).render(width);\n}\n\nexport function renderChatSessionUsage<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n): string[] {\n const agentSession = state.getAgentSession?.();\n if (!agentSession) return [];\n return new UsageMeterComponent(agentSession).render(width);\n}\n\nexport function renderChatSessionEditor<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n focused: boolean,\n): string[] {\n const disabled = state.isDisabled?.() === true;\n const agentSession = state.getAgentSession?.();\n const ruleHex = state.style.editorRuleColor(disabled, agentSession, {\n isBashMode: state.isBashMode,\n });\n if (!disabled && state.editor) {\n setEditorFocused(state.editor, focused);\n setEditorPlaceholder(state.editor, undefined);\n setEditorBorderColor(state.editor, (text) => state.style.rule(ruleHex, text));\n return state.editor.render(width);\n }\n if (state.editor) setEditorFocused(state.editor, false);\n const rule = state.style.rule(ruleHex, \"─\".repeat(width));\n const available = Math.max(1, width - 3);\n const value = state.inputBuffer\n ? state.style.text(truncateToWidth(state.inputBuffer, available)) + state.style.cursor()\n : disabled\n ? \"\"\n : state.style.cursor();\n const left = state.style.accentBold(\"❯\") + \" \" + value;\n const gap = Math.max(0, width - visibleWidth(stripAnsi(left)));\n const body = left + \" \".repeat(gap);\n return [rule, body, rule];\n}\n\nexport function renderChatSessionFooter<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n): string[] {\n const agentSession = state.getAgentSession?.();\n if (agentSession && state.footerData) {\n return new FooterComponent(agentSession, state.footerData).render(width);\n }\n return [];\n}\n\nexport function renderChatSessionEntry<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n): Component {\n if (isChatMessageEntry(entry)) {\n return renderChatMessageEntry(\n streamingWindowedEntry(state, entry),\n chatMessageRenderOptions(state),\n );\n }\n if (!state.renderExtraEntry) {\n return new Text(\"\", 0, 0);\n }\n return state.renderExtraEntry(entry);\n}\n\nexport function transcriptCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n index: number,\n): string {\n return cacheKey([\n state.transcriptRenderSettingsKey,\n index,\n entry.role,\n renderIdentityKey(state, entry),\n entryContentCacheKey(state, entry),\n ]);\n}\n\nfunction streamingWindowedEntry<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatMessageEntry,\n): ChatMessageEntry {\n if (!isChatSessionStreaming(state) || state.bodyViewport.getScrollFromBottom() !== 0) {\n return entry;\n }\n if (entry.kind !== \"assistant\") return entry;\n const content = entry.message.content.map((item) => {\n if (item.type === \"text\") return { ...item, text: tailStreamingText(item.text) };\n if (item.type === \"thinking\") return { ...item, thinking: tailStreamingText(item.thinking) };\n return item;\n });\n return { ...entry, message: { ...entry.message, content } };\n}\n\nfunction chatMessageRenderOptions<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): ChatMessageRenderOptions {\n const inherited = state.getChatRenderSettings?.();\n return {\n ...inherited,\n ui: toolTui(state),\n cwd: state.getCwd?.() ?? state.getAgentSession?.()?.sessionManager.getCwd() ?? process.cwd(),\n markdownTheme: inherited?.markdownTheme ?? state.getMarkdownTheme?.(),\n showImages: inherited?.showImages ?? true,\n };\n}\n\nfunction toolTui<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): Pick<TUI, \"requestRender\"> {\n return { requestRender: () => state.requestRender?.() };\n}\n\nfunction chatRenderSettingsCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): string {\n const inherited = state.getChatRenderSettings?.();\n return cacheKey([\n \"settings\",\n inherited?.hideThinkingBlock === true,\n inherited?.hiddenThinkingLabel ?? \"\",\n inherited?.toolOutputExpanded === true,\n inherited?.showImages !== false,\n inherited?.imageWidthCells ?? null,\n state.getCwd?.() ?? state.getAgentSession?.()?.sessionManager.getCwd() ?? process.cwd(),\n state.bodyViewport.getScrollFromBottom() === 0,\n isChatSessionStreaming(state),\n ]);\n}\n\nfunction entryContentCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n): string {\n if (!isChatMessageEntry(entry)) return cacheKey([\"extra\"]);\n switch (entry.kind) {\n case \"assistant\":\n return cacheKey([\"assistant\", renderIdentityKey(state, entry.message)]);\n case \"tool\":\n return cacheKey([\"tool\", entry.toolCallId, entry.toolName, entry.isPartial === true, entry.result === undefined ? null : renderIdentityKey(state, entry.result)]);\n case \"bashExecution\":\n return cacheKey([\"bashExecution\", entry.isPartial === true, entry.message.command, entry.message.output, entry.message.exitCode ?? null, entry.message.cancelled, entry.message.truncated, entry.message.fullOutputPath ?? null]);\n case \"user\":\n return cacheKey([\"user\", entry.text]);\n case \"custom\":\n return cacheKey([\"custom\", renderIdentityKey(state, entry.message)]);\n case \"branchSummary\":\n return cacheKey([\"branchSummary\", renderIdentityKey(state, entry.message)]);\n case \"system\":\n return cacheKey([\"system\", entry.text]);\n }\n}\n\nfunction renderIdentityKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n value: object,\n): string {\n const existing = state.renderIdentityIds.get(value);\n if (existing !== undefined) return String(existing);\n const id = state.nextRenderIdentityId;\n state.nextRenderIdentityId += 1;\n state.renderIdentityIds.set(value, id);\n return String(id);\n}\n\nfunction pendingMessageLine<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n label: \"Steering\" | \"Follow-up\" | \"Queued\",\n message: string,\n): string[] {\n const text = `${label}: ${message}`;\n return new Text(\n state.style.dim(truncateToWidth(text, Math.max(1, width - 2))),\n 1,\n 0,\n ).render(width);\n}\n"]}
1
+ {"version":3,"file":"chat-session-host-rendering.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/chat-session-host-rendering.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type Component,\n type TUI,\n Spacer,\n Text,\n truncateToWidth,\n visibleWidth,\n} from \"@earendil-works/pi-tui\";\nimport { UsageMeterComponent, FooterComponent } from \"./footer.ts\";\nimport {\n renderChatMessageEntry,\n type ChatMessageEntry,\n type ChatMessageRenderOptions,\n} from \"./chat-message-renderer.ts\";\nimport type { ChatTranscriptEntryLike } from \"./chat-transcript.ts\";\nimport type { ChatSessionHostState } from \"./chat-session-host-state.ts\";\nimport type { ChatSessionHostEntry } from \"./chat-session-host-types.ts\";\nimport {\n setEditorBorderColor,\n setEditorFocused,\n setEditorPlaceholder,\n} from \"./chat-session-host-editor.ts\";\nimport { isChatSessionStreaming } from \"./chat-session-host-runtime.ts\";\nimport {\n cacheKey,\n isChatMessageEntry,\n spinnerFrame,\n stripAnsi,\n tailStreamingText,\n} from \"./chat-session-host-utils.ts\";\nimport { WorkingStatusComponent } from \"./working-status.ts\";\n\nexport function renderChatSessionBody<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n budget: number,\n): string[] {\n const components: Component[] = [];\n state.transcriptRenderSettingsKey = chatRenderSettingsCacheKey(state);\n if (state.transcript.length > 0) {\n components.push(state.transcriptComponent);\n }\n if (state.statusMessage) {\n components.push(new Spacer(1));\n components.push(new Text(state.style.dim(state.statusMessage), 2, 0));\n }\n state.bodyViewport.setVisibleRows(budget);\n state.bodyViewport.setComponents(components);\n return state.bodyViewport.render(width);\n}\n\nexport function renderChatSessionPendingMessages<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(state: ChatSessionHostState<TExtraEntry>, width: number): string[] {\n if (\n state.pendingSteeringMessages.length === 0 &&\n state.pendingFollowUpMessages.length === 0 &&\n state.compactionQueuedMessages.length === 0\n ) {\n return [];\n }\n const lines = [state.style.blank(width)];\n for (const message of state.pendingSteeringMessages) {\n lines.push(...pendingMessageLine(state, width, \"Steering\", message));\n }\n for (const message of state.pendingFollowUpMessages) {\n lines.push(...pendingMessageLine(state, width, \"Follow-up\", message));\n }\n for (const message of state.compactionQueuedMessages) {\n lines.push(...pendingMessageLine(state, width, \"Queued\", message));\n }\n const hint = state.getActionKeyDisplay?.(\"app.message.dequeue\") ?? \"alt+up\";\n lines.push(...new Text(state.style.dim(`↳ ${hint} to edit all queued messages`), 1, 0).render(width));\n return lines;\n}\n\nexport function renderChatSessionWorkingStatus<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(state: ChatSessionHostState<TExtraEntry>, width: number): string[] {\n if (!isChatSessionStreaming(state)) return [];\n const message = state.workingMessage ?? \"Working...\";\n return new WorkingStatusComponent({\n spinner: spinnerFrame(),\n message,\n spinnerColor: (text) => state.style.accentBold(text),\n messageColor: (text) => state.style.textMuted(text),\n }).render(width);\n}\n\nexport function renderChatSessionUsage<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n): string[] {\n const agentSession = state.getAgentSession?.();\n if (!agentSession) return [];\n return new UsageMeterComponent(agentSession).render(width);\n}\n\nexport function renderChatSessionEditor<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n focused: boolean,\n): string[] {\n const disabled = state.isDisabled?.() === true;\n const agentSession = state.getAgentSession?.();\n const ruleHex = state.style.editorRuleColor(disabled, agentSession, {\n isBashMode: state.isBashMode,\n });\n if (!disabled && state.editor) {\n setEditorFocused(state.editor, focused);\n setEditorPlaceholder(state.editor, undefined);\n setEditorBorderColor(state.editor, (text) => state.style.rule(ruleHex, text));\n return state.editor.render(width);\n }\n if (state.editor) setEditorFocused(state.editor, false);\n const rule = state.style.rule(ruleHex, \"─\".repeat(width));\n const available = Math.max(1, width - 3);\n const value = state.inputBuffer\n ? state.style.text(truncateToWidth(state.inputBuffer, available)) + state.style.cursor()\n : disabled\n ? \"\"\n : state.style.cursor();\n const left = state.style.accentBold(\"❯\") + \" \" + value;\n const gap = Math.max(0, width - visibleWidth(stripAnsi(left)));\n const body = left + \" \".repeat(gap);\n return [rule, body, rule];\n}\n\nexport function renderChatSessionFooter<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n): string[] {\n const agentSession = state.getAgentSession?.();\n if (agentSession && state.footerData) {\n return new FooterComponent(agentSession, state.footerData).render(width);\n }\n return [];\n}\n\nexport function renderChatSessionEntry<\n TExtraEntry extends ChatTranscriptEntryLike,\n>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n): Component {\n if (isChatMessageEntry(entry)) {\n return renderChatMessageEntry(\n streamingWindowedEntry(state, entry),\n chatMessageRenderOptions(state),\n );\n }\n if (!state.renderExtraEntry) {\n return new Text(\"\", 0, 0);\n }\n return state.renderExtraEntry(entry);\n}\n\nexport function transcriptCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n index: number,\n): string {\n return cacheKey([\n state.transcriptRenderSettingsKey,\n index,\n entry.role,\n renderIdentityKey(state, entry),\n entryContentCacheKey(state, entry),\n ]);\n}\n\nfunction streamingWindowedEntry<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatMessageEntry,\n): ChatMessageEntry {\n if (!isChatSessionStreaming(state) || state.bodyViewport.getScrollFromBottom() !== 0) {\n return entry;\n }\n if (entry.kind !== \"assistant\") return entry;\n const content = entry.message.content.map((item) => {\n if (item.type === \"text\") return { ...item, text: tailStreamingText(item.text) };\n if (item.type === \"thinking\") return { ...item, thinking: tailStreamingText(item.thinking) };\n return item;\n });\n return { ...entry, message: { ...entry.message, content } };\n}\n\nfunction chatMessageRenderOptions<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): ChatMessageRenderOptions {\n const inherited = state.getChatRenderSettings?.();\n return {\n ...inherited,\n ui: toolTui(state),\n cwd: state.getCwd?.() ?? state.getAgentSession?.()?.sessionManager.getCwd() ?? process.cwd(),\n markdownTheme: inherited?.markdownTheme ?? state.getMarkdownTheme?.(),\n showImages: inherited?.showImages ?? true,\n };\n}\n\nfunction toolTui<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): Pick<TUI, \"requestRender\"> {\n return { requestRender: () => state.requestRender?.() };\n}\n\nfunction chatRenderSettingsCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n): string {\n const inherited = state.getChatRenderSettings?.();\n return cacheKey([\n \"settings\",\n inherited?.hideThinkingBlock === true,\n inherited?.hiddenThinkingLabel ?? \"\",\n inherited?.toolOutputExpanded === true,\n inherited?.showImages !== false,\n inherited?.imageWidthCells ?? null,\n inherited?.outputPad ?? null,\n state.getCwd?.() ?? state.getAgentSession?.()?.sessionManager.getCwd() ?? process.cwd(),\n state.bodyViewport.getScrollFromBottom() === 0,\n isChatSessionStreaming(state),\n ]);\n}\n\nfunction entryContentCacheKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n entry: ChatSessionHostEntry<TExtraEntry>,\n): string {\n if (!isChatMessageEntry(entry)) return cacheKey([\"extra\"]);\n switch (entry.kind) {\n case \"assistant\":\n return cacheKey([\"assistant\", renderIdentityKey(state, entry.message)]);\n case \"tool\":\n return cacheKey([\"tool\", entry.toolCallId, entry.toolName, entry.isPartial === true, entry.result === undefined ? null : renderIdentityKey(state, entry.result)]);\n case \"bashExecution\":\n return cacheKey([\"bashExecution\", entry.isPartial === true, entry.message.command, entry.message.output, entry.message.exitCode ?? null, entry.message.cancelled, entry.message.truncated, entry.message.fullOutputPath ?? null]);\n case \"user\":\n return cacheKey([\"user\", entry.text]);\n case \"custom\":\n return cacheKey([\"custom\", renderIdentityKey(state, entry.message)]);\n case \"branchSummary\":\n return cacheKey([\"branchSummary\", renderIdentityKey(state, entry.message)]);\n case \"system\":\n return cacheKey([\"system\", entry.text]);\n }\n}\n\nfunction renderIdentityKey<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n value: object,\n): string {\n const existing = state.renderIdentityIds.get(value);\n if (existing !== undefined) return String(existing);\n const id = state.nextRenderIdentityId;\n state.nextRenderIdentityId += 1;\n state.renderIdentityIds.set(value, id);\n return String(id);\n}\n\nfunction pendingMessageLine<TExtraEntry extends ChatTranscriptEntryLike>(\n state: ChatSessionHostState<TExtraEntry>,\n width: number,\n label: \"Steering\" | \"Follow-up\" | \"Queued\",\n message: string,\n): string[] {\n const text = `${label}: ${message}`;\n return new Text(\n state.style.dim(truncateToWidth(text, Math.max(1, width - 2))),\n 1,\n 0,\n ).render(width);\n}\n"]}
@@ -3,8 +3,12 @@ import { Container, type MarkdownTheme } from "@earendil-works/pi-tui";
3
3
  * Component that renders a user message
4
4
  */
5
5
  export declare class UserMessageComponent extends Container {
6
- private contentBox;
7
- constructor(text: string, markdownTheme?: MarkdownTheme);
6
+ private text;
7
+ private markdownTheme;
8
+ private outputPad;
9
+ constructor(text: string, markdownTheme?: MarkdownTheme, outputPad?: number);
10
+ setOutputPad(padding: number): void;
11
+ private rebuild;
8
12
  render(width: number): string[];
9
13
  }
10
14
  //# sourceMappingURL=user-message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/user-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,SAAS,EAAY,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAOtF;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;IAClD,OAAO,CAAC,UAAU,CAAM;IAExB,YAAY,IAAI,EAAE,MAAM,EAAE,aAAa,GAAE,aAAkC,EAgB1E;IAEQ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CASvC;CACD","sourcesContent":["import { Box, Container, Markdown, type MarkdownTheme } from \"@earendil-works/pi-tui\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a user message\n */\nexport class UserMessageComponent extends Container {\n\tprivate contentBox: Box;\n\n\tconstructor(text: string, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper();\n\t\tthis.contentBox = new Box(1, 1, (content: string) => theme.bg(\"userMessageBg\", content));\n\t\tthis.contentBox.addChild(\n\t\t\tnew Markdown(\n\t\t\t\ttext,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tmarkdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (content: string) => theme.fg(\"userMessageText\", content),\n\t\t\t\t},\n\t\t\t\t{ preserveOrderedListMarkers: true },\n\t\t\t),\n\t\t);\n\t\tthis.addChild(this.contentBox);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (lines.length === 0) {\n\t\t\treturn lines;\n\t\t}\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"user-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/user-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,SAAS,EAAY,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAOtF;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;IAClD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,SAAS,CAAS;IAE1B,YAAY,IAAI,EAAE,MAAM,EAAE,aAAa,GAAE,aAAkC,EAAE,SAAS,SAAI,EAMzF;IAED,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAGlC;IAED,OAAO,CAAC,OAAO;IAkBN,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CASvC;CACD","sourcesContent":["import { Box, Container, Markdown, type MarkdownTheme } from \"@earendil-works/pi-tui\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a user message\n */\nexport class UserMessageComponent extends Container {\n\tprivate text: string;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate outputPad: number;\n\n\tconstructor(text: string, markdownTheme: MarkdownTheme = getMarkdownTheme(), outputPad = 1) {\n\t\tsuper();\n\t\tthis.text = text;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.outputPad = outputPad;\n\t\tthis.rebuild();\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tthis.rebuild();\n\t}\n\n\tprivate rebuild(): void {\n\t\tthis.clear();\n\t\tconst contentBox = new Box(this.outputPad, 1, (content: string) => theme.bg(\"userMessageBg\", content));\n\t\tcontentBox.addChild(\n\t\t\tnew Markdown(\n\t\t\t\tthis.text,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.markdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (content: string) => theme.fg(\"userMessageText\", content),\n\t\t\t\t},\n\t\t\t\t{ preserveOrderedListMarkers: true, preserveBackslashEscapes: true },\n\t\t\t),\n\t\t);\n\t\tthis.addChild(contentBox);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (lines.length === 0) {\n\t\t\treturn lines;\n\t\t}\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\t\treturn lines;\n\t}\n}\n"]}
@@ -7,13 +7,24 @@ const OSC133_ZONE_FINAL = "\x1b]133;C\x07";
7
7
  * Component that renders a user message
8
8
  */
9
9
  export class UserMessageComponent extends Container {
10
- constructor(text, markdownTheme = getMarkdownTheme()) {
10
+ constructor(text, markdownTheme = getMarkdownTheme(), outputPad = 1) {
11
11
  super();
12
- this.contentBox = new Box(1, 1, (content) => theme.bg("userMessageBg", content));
13
- this.contentBox.addChild(new Markdown(text, 0, 0, markdownTheme, {
12
+ this.text = text;
13
+ this.markdownTheme = markdownTheme;
14
+ this.outputPad = outputPad;
15
+ this.rebuild();
16
+ }
17
+ setOutputPad(padding) {
18
+ this.outputPad = padding;
19
+ this.rebuild();
20
+ }
21
+ rebuild() {
22
+ this.clear();
23
+ const contentBox = new Box(this.outputPad, 1, (content) => theme.bg("userMessageBg", content));
24
+ contentBox.addChild(new Markdown(this.text, 0, 0, this.markdownTheme, {
14
25
  color: (content) => theme.fg("userMessageText", content),
15
- }, { preserveOrderedListMarkers: true }));
16
- this.addChild(this.contentBox);
26
+ }, { preserveOrderedListMarkers: true, preserveBackslashEscapes: true }));
27
+ this.addChild(contentBox);
17
28
  }
18
29
  render(width) {
19
30
  const lines = super.render(width);
@@ -1 +1 @@
1
- {"version":3,"file":"user-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/user-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAsB,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAC3C,MAAM,eAAe,GAAG,gBAAgB,CAAC;AACzC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IAGlD,YAAY,IAAY,EAAE,aAAa,GAAkB,gBAAgB,EAAE;QAC1E,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;QACzF,IAAI,CAAC,UAAU,CAAC,QAAQ,CACvB,IAAI,QAAQ,CACX,IAAI,EACJ,CAAC,EACD,CAAC,EACD,aAAa,EACb;YACC,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,OAAO,CAAC;SAChE,EACD,EAAE,0BAA0B,EAAE,IAAI,EAAE,CACpC,CACD,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChC,CAAC;IAEQ,MAAM,CAAC,KAAa;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACd,CAAC;QAED,KAAK,CAAC,CAAC,CAAC,GAAG,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,eAAe,GAAG,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxF,OAAO,KAAK,CAAC;IACd,CAAC;CACD","sourcesContent":["import { Box, Container, Markdown, type MarkdownTheme } from \"@earendil-works/pi-tui\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a user message\n */\nexport class UserMessageComponent extends Container {\n\tprivate contentBox: Box;\n\n\tconstructor(text: string, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper();\n\t\tthis.contentBox = new Box(1, 1, (content: string) => theme.bg(\"userMessageBg\", content));\n\t\tthis.contentBox.addChild(\n\t\t\tnew Markdown(\n\t\t\t\ttext,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tmarkdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (content: string) => theme.fg(\"userMessageText\", content),\n\t\t\t\t},\n\t\t\t\t{ preserveOrderedListMarkers: true },\n\t\t\t),\n\t\t);\n\t\tthis.addChild(this.contentBox);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (lines.length === 0) {\n\t\t\treturn lines;\n\t\t}\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"user-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/user-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAsB,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAC3C,MAAM,eAAe,GAAG,gBAAgB,CAAC;AACzC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IAKlD,YAAY,IAAY,EAAE,aAAa,GAAkB,gBAAgB,EAAE,EAAE,SAAS,GAAG,CAAC;QACzF,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAED,YAAY,CAAC,OAAe;QAC3B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;QACzB,IAAI,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAEO,OAAO;QACd,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;QACvG,UAAU,CAAC,QAAQ,CAClB,IAAI,QAAQ,CACX,IAAI,CAAC,IAAI,EACT,CAAC,EACD,CAAC,EACD,IAAI,CAAC,aAAa,EAClB;YACC,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,OAAO,CAAC;SAChE,EACD,EAAE,0BAA0B,EAAE,IAAI,EAAE,wBAAwB,EAAE,IAAI,EAAE,CACpE,CACD,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAEQ,MAAM,CAAC,KAAa;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACd,CAAC;QAED,KAAK,CAAC,CAAC,CAAC,GAAG,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,eAAe,GAAG,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxF,OAAO,KAAK,CAAC;IACd,CAAC;CACD","sourcesContent":["import { Box, Container, Markdown, type MarkdownTheme } from \"@earendil-works/pi-tui\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a user message\n */\nexport class UserMessageComponent extends Container {\n\tprivate text: string;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate outputPad: number;\n\n\tconstructor(text: string, markdownTheme: MarkdownTheme = getMarkdownTheme(), outputPad = 1) {\n\t\tsuper();\n\t\tthis.text = text;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.outputPad = outputPad;\n\t\tthis.rebuild();\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tthis.rebuild();\n\t}\n\n\tprivate rebuild(): void {\n\t\tthis.clear();\n\t\tconst contentBox = new Box(this.outputPad, 1, (content: string) => theme.bg(\"userMessageBg\", content));\n\t\tcontentBox.addChild(\n\t\t\tnew Markdown(\n\t\t\t\tthis.text,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.markdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (content: string) => theme.fg(\"userMessageText\", content),\n\t\t\t\t},\n\t\t\t\t{ preserveOrderedListMarkers: true, preserveBackslashEscapes: true },\n\t\t\t),\n\t\t);\n\t\tthis.addChild(contentBox);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (lines.length === 0) {\n\t\t\treturn lines;\n\t\t}\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\t\treturn lines;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-agent-events.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-agent-events.ts"],"names":[],"mappings":"","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type Message, type AgentSessionEvent, type ContextCompactionResult, Loader, Spacer, Text, pickWhimsicalWorkingMessage, AssistantMessageComponent, CountdownTimer, keyText, ToolExecutionComponent, theme } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.subscribeToAgent = function(this: InteractiveModeBase): void {\n this.unsubscribe = this.session.subscribe(async (event) => {\n await this.handleEvent(event);\n });\n };\n\nInteractiveModeBase.prototype.handleEvent = async function(this: InteractiveModeBase, event: AgentSessionEvent): Promise<void> {\n if (!this.isInitialized) {\n await this.init();\n }\n\n this.footer.invalidate();\n\n switch (event.type) {\n case \"agent_start\":\n this.pendingTools.clear();\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(true);\n }\n // Restore main escape handler if retry handler is still active\n // (retry success event fires later, but we need main handler now)\n if (this.retryEscapeHandler) {\n this.defaultEditor.onEscape = this.retryEscapeHandler;\n this.retryEscapeHandler = undefined;\n }\n if (this.retryCountdown) {\n this.retryCountdown.dispose();\n this.retryCountdown = undefined;\n }\n if (this.retryLoader) {\n this.retryLoader.stop();\n this.retryLoader = undefined;\n }\n this.stopWorkingLoader();\n if (this.workingVisible) {\n this.loadingAnimation = this.createWorkingLoader();\n this.statusContainer.addChild(this.loadingAnimation);\n }\n this.ui.requestRender();\n break;\n\n case \"turn_start\": {\n this.workingMessage = pickWhimsicalWorkingMessage();\n if (this.loadingAnimation) {\n this.loadingAnimation.setMessage(this.workingMessage);\n }\n break;\n }\n\n case \"turn_end\": {\n this.workingMessage = undefined;\n if (this.loadingAnimation) {\n this.loadingAnimation.setMessage(this.defaultWorkingMessage);\n }\n break;\n }\n\n case \"queue_update\":\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n break;\n\n case \"session_info_changed\":\n this.updateTerminalTitle();\n this.footer.invalidate();\n this.ui.requestRender();\n break;\n\n case \"model_changed\":\n this.refreshBuiltInHeader();\n this.updateEditorBorderColor();\n break;\n\n case \"thinking_level_changed\":\n this.footer.invalidate();\n this.refreshBuiltInHeader();\n this.updateEditorBorderColor();\n break;\n\n case \"context_window_changed\":\n this.footer.invalidate();\n this.usageMeter.invalidate();\n this.ui.requestRender();\n break;\n\n case \"message_start\":\n if (event.message.role === \"custom\") {\n this.addMessageToChat(event.message);\n this.ui.requestRender();\n } else if (event.message.role === \"user\") {\n this.addMessageToChat(event.message);\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n } else if (event.message.role === \"assistant\") {\n this.streamingComponent = new AssistantMessageComponent(\n undefined,\n this.hideThinkingBlock,\n this.getMarkdownThemeWithSettings(),\n this.hiddenThinkingLabel,\n );\n this.streamingMessage = event.message;\n this.chatContainer.addChild(this.streamingComponent);\n this.streamingComponent.updateContent(this.streamingMessage);\n this.ui.requestRender();\n }\n break;\n\n case \"message_update\":\n if (this.streamingComponent && event.message.role === \"assistant\") {\n this.streamingMessage = event.message;\n this.streamingComponent.updateContent(this.streamingMessage);\n\n for (const content of this.streamingMessage.content) {\n if (content.type === \"toolCall\") {\n if (!this.pendingTools.has(content.id)) {\n const component = new ToolExecutionComponent(\n content.name,\n content.id,\n content.arguments,\n {\n showImages: this.settingsManager.getShowImages(),\n imageWidthCells: this.settingsManager.getImageWidthCells(),\n },\n this.getRegisteredToolDefinition(content.name),\n this.ui,\n this.sessionManager.getCwd(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n this.pendingTools.set(content.id, component);\n } else {\n const component = this.pendingTools.get(content.id);\n if (component) {\n component.updateArgs(content.arguments);\n }\n }\n }\n }\n this.ui.requestRender();\n }\n break;\n\n case \"message_end\":\n if (event.message.role === \"user\") break;\n if (this.streamingComponent && event.message.role === \"assistant\") {\n this.streamingMessage = event.message;\n let errorMessage: string | undefined;\n if (this.streamingMessage.stopReason === \"aborted\") {\n const existingAbortMessage =\n this.streamingMessage.errorMessage && this.streamingMessage.errorMessage !== \"Request was aborted\"\n ? this.streamingMessage.errorMessage\n : undefined;\n const retryAttempt = this.session.retryAttempt;\n errorMessage = existingAbortMessage ?? (\n retryAttempt > 0\n ? `Aborted after ${retryAttempt} retry attempt${retryAttempt > 1 ? \"s\" : \"\"}`\n : \"Operation aborted\"\n );\n this.streamingMessage.errorMessage = errorMessage;\n }\n this.streamingComponent.updateContent(this.streamingMessage);\n\n if (\n this.streamingMessage.stopReason === \"aborted\" ||\n this.streamingMessage.stopReason === \"error\"\n ) {\n if (!errorMessage) {\n errorMessage = this.streamingMessage.errorMessage || \"Error\";\n }\n for (const [, component] of this.pendingTools.entries()) {\n component.updateResult({\n content: [{ type: \"text\", text: errorMessage }],\n isError: true,\n });\n }\n this.pendingTools.clear();\n } else {\n // Args are now complete - trigger diff computation for edit tools\n for (const [, component] of this.pendingTools.entries()) {\n component.setArgsComplete();\n }\n }\n this.streamingComponent = undefined;\n this.streamingMessage = undefined;\n this.footer.invalidate();\n }\n this.ui.requestRender();\n break;\n\n case \"tool_execution_start\": {\n let component = this.pendingTools.get(event.toolCallId);\n if (!component) {\n component = new ToolExecutionComponent(\n event.toolName,\n event.toolCallId,\n event.args,\n {\n showImages: this.settingsManager.getShowImages(),\n imageWidthCells: this.settingsManager.getImageWidthCells(),\n },\n this.getRegisteredToolDefinition(event.toolName),\n this.ui,\n this.sessionManager.getCwd(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n this.pendingTools.set(event.toolCallId, component);\n }\n component.markExecutionStarted();\n this.ui.requestRender();\n break;\n }\n\n case \"tool_execution_update\": {\n const component = this.pendingTools.get(event.toolCallId);\n if (component) {\n component.updateResult(\n { ...event.partialResult, isError: false },\n true,\n );\n this.ui.requestRender();\n }\n break;\n }\n\n case \"tool_execution_end\": {\n const component = this.pendingTools.get(event.toolCallId);\n if (component) {\n component.updateResult({ ...event.result, isError: event.isError });\n this.pendingTools.delete(event.toolCallId);\n this.ui.requestRender();\n }\n break;\n }\n\n case \"agent_end\":\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(false);\n }\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n this.statusContainer.clear();\n }\n if (this.streamingComponent) {\n this.chatContainer.removeChild(this.streamingComponent);\n this.streamingComponent = undefined;\n this.streamingMessage = undefined;\n }\n this.pendingTools.clear();\n\n await this.checkShutdownRequested();\n\n this.ui.requestRender();\n break;\n\n case \"compaction_start\": {\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(true);\n }\n // Keep editor active; submissions are queued during compaction.\n this.autoCompactionEscapeHandler = this.defaultEditor.onEscape;\n this.defaultEditor.onEscape = () => {\n this.session.abortCompaction();\n };\n this.statusContainer.clear();\n const cancelHint = `(${keyText(\"app.interrupt\")} Cancel)`;\n const isOverflowAutoCompaction = event.reason === \"overflow\";\n const label =\n event.reason === \"manual\"\n ? `Compacting context... ${cancelHint}`\n : `${isOverflowAutoCompaction ? \"Context overflow detected. \" : \"\"}Auto-compacting... ${cancelHint}`;\n this.autoCompactionLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"accent\", spinner),\n (text) => theme.fg(isOverflowAutoCompaction ? \"warning\" : \"muted\", text),\n label,\n );\n this.statusContainer.addChild(this.autoCompactionLoader);\n this.ui.requestRender();\n break;\n }\n\n case \"compaction_end\": {\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(false);\n }\n if (this.autoCompactionEscapeHandler) {\n this.defaultEditor.onEscape = this.autoCompactionEscapeHandler;\n this.autoCompactionEscapeHandler = undefined;\n }\n if (this.autoCompactionLoader) {\n this.autoCompactionLoader.stop();\n this.autoCompactionLoader = undefined;\n this.statusContainer.clear();\n }\n if (event.aborted) {\n if (event.reason === \"manual\") {\n this.showError(\"Compaction cancelled\");\n } else {\n this.showStatus(\"Auto-compaction cancelled\");\n }\n } else if (event.result) {\n this.chatContainer.clear();\n this.rebuildChatFromMessages();\n this.addContextCompactionSummaryToChat(event.result as ContextCompactionResult);\n this.footer.invalidate();\n } else if (event.errorMessage) {\n if (event.reason === \"manual\") {\n this.showError(event.errorMessage);\n } else {\n this.chatContainer.addChild(new Spacer(1));\n this.chatContainer.addChild(\n new Text(theme.fg(\"error\", event.errorMessage), 1, 0),\n );\n }\n }\n void this.flushCompactionQueue({ willRetry: event.willRetry });\n this.ui.requestRender();\n break;\n }\n\n case \"context_compaction_start\": {\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(true);\n }\n this.autoCompactionEscapeHandler = this.defaultEditor.onEscape;\n this.defaultEditor.onEscape = () => {\n this.session.abortCompaction();\n };\n this.statusContainer.clear();\n const cancelHint = `(${keyText(\"app.interrupt\")} Cancel)`;\n this.autoCompactionLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"accent\", spinner),\n (text) => theme.fg(\"muted\", text),\n `Compacting context... ${cancelHint}`,\n );\n this.statusContainer.addChild(this.autoCompactionLoader);\n this.ui.requestRender();\n break;\n }\n\n case \"context_compaction_end\": {\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(false);\n }\n if (this.autoCompactionEscapeHandler) {\n this.defaultEditor.onEscape = this.autoCompactionEscapeHandler;\n this.autoCompactionEscapeHandler = undefined;\n }\n if (this.autoCompactionLoader) {\n this.autoCompactionLoader.stop();\n this.autoCompactionLoader = undefined;\n this.statusContainer.clear();\n }\n if (event.aborted) {\n this.showError(\"Context compaction cancelled\");\n } else if (event.result) {\n this.chatContainer.clear();\n this.rebuildChatFromMessages();\n this.addContextCompactionSummaryToChat(event.result);\n this.footer.invalidate();\n } else if (event.errorMessage) {\n this.showError(event.errorMessage);\n }\n void this.flushCompactionQueue({ willRetry: event.willRetry });\n this.ui.requestRender();\n break;\n }\n\n case \"auto_retry_start\": {\n // Set up escape to abort retry\n this.retryEscapeHandler = this.defaultEditor.onEscape;\n this.defaultEditor.onEscape = () => {\n this.session.abortRetry();\n };\n // Show retry indicator\n this.statusContainer.clear();\n this.retryCountdown?.dispose();\n const retryMessage = (seconds: number) =>\n `Retrying (${event.attempt}/${event.maxAttempts}) in ${seconds}s... (${keyText(\"app.interrupt\")} Cancel)`;\n this.retryLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"warning\", spinner),\n (text) => theme.fg(\"muted\", text),\n retryMessage(Math.ceil(event.delayMs / 1000)),\n );\n this.retryCountdown = new CountdownTimer(\n event.delayMs,\n this.ui,\n (seconds) => {\n this.retryLoader?.setMessage(retryMessage(seconds));\n },\n () => {\n this.retryCountdown = undefined;\n },\n );\n this.statusContainer.addChild(this.retryLoader);\n this.ui.requestRender();\n break;\n }\n\n case \"auto_retry_end\": {\n // Restore escape handler\n if (this.retryEscapeHandler) {\n this.defaultEditor.onEscape = this.retryEscapeHandler;\n this.retryEscapeHandler = undefined;\n }\n if (this.retryCountdown) {\n this.retryCountdown.dispose();\n this.retryCountdown = undefined;\n }\n // Stop loader\n if (this.retryLoader) {\n this.retryLoader.stop();\n this.retryLoader = undefined;\n this.statusContainer.clear();\n }\n // Show error only on final failure (success shows normal response)\n if (!event.success) {\n this.showError(\n `Retry failed after ${event.attempt} attempts: ${event.finalError || \"Unknown error\"}`,\n );\n }\n this.ui.requestRender();\n break;\n }\n\n case \"agent_continue_error\": {\n this.showError(event.errorMessage);\n this.ui.requestRender();\n break;\n }\n }\n };\n\nInteractiveModeBase.prototype.getUserMessageText = function(this: InteractiveModeBase, message: Message): string {\n if (message.role !== \"user\") return \"\";\n const textBlocks =\n typeof message.content === \"string\"\n ? [{ type: \"text\", text: message.content }]\n : message.content.filter((c: { type: string }) => c.type === \"text\");\n return textBlocks.map((c) => (c as { text: string }).text).join(\"\");\n };\n"]}
1
+ {"version":3,"file":"interactive-agent-events.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-agent-events.ts"],"names":[],"mappings":"","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type Message, type AgentSessionEvent, type ContextCompactionResult, Loader, Spacer, Text, pickWhimsicalWorkingMessage, AssistantMessageComponent, CountdownTimer, keyText, ToolExecutionComponent, theme } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.subscribeToAgent = function(this: InteractiveModeBase): void {\n this.unsubscribe = this.session.subscribe(async (event) => {\n await this.handleEvent(event);\n });\n };\n\nInteractiveModeBase.prototype.handleEvent = async function(this: InteractiveModeBase, event: AgentSessionEvent): Promise<void> {\n if (!this.isInitialized) {\n await this.init();\n }\n\n this.footer.invalidate();\n\n switch (event.type) {\n case \"agent_start\":\n this.pendingTools.clear();\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(true);\n }\n // Restore main escape handler if retry handler is still active\n // (retry success event fires later, but we need main handler now)\n if (this.retryEscapeHandler) {\n this.defaultEditor.onEscape = this.retryEscapeHandler;\n this.retryEscapeHandler = undefined;\n }\n if (this.retryCountdown) {\n this.retryCountdown.dispose();\n this.retryCountdown = undefined;\n }\n if (this.retryLoader) {\n this.retryLoader.stop();\n this.retryLoader = undefined;\n }\n this.stopWorkingLoader();\n if (this.workingVisible) {\n this.loadingAnimation = this.createWorkingLoader();\n this.statusContainer.addChild(this.loadingAnimation);\n }\n this.ui.requestRender();\n break;\n\n case \"turn_start\": {\n this.workingMessage = pickWhimsicalWorkingMessage();\n if (this.loadingAnimation) {\n this.loadingAnimation.setMessage(this.workingMessage);\n }\n break;\n }\n\n case \"turn_end\": {\n this.workingMessage = undefined;\n if (this.loadingAnimation) {\n this.loadingAnimation.setMessage(this.defaultWorkingMessage);\n }\n break;\n }\n\n case \"queue_update\":\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n break;\n\n case \"session_info_changed\":\n this.updateTerminalTitle();\n this.footer.invalidate();\n this.ui.requestRender();\n break;\n\n case \"model_changed\":\n this.refreshBuiltInHeader();\n this.updateEditorBorderColor();\n break;\n\n case \"thinking_level_changed\":\n this.footer.invalidate();\n this.refreshBuiltInHeader();\n this.updateEditorBorderColor();\n break;\n\n case \"context_window_changed\":\n this.footer.invalidate();\n this.usageMeter.invalidate();\n this.ui.requestRender();\n break;\n\n case \"message_start\":\n if (event.message.role === \"custom\") {\n this.addMessageToChat(event.message);\n this.ui.requestRender();\n } else if (event.message.role === \"user\") {\n this.addMessageToChat(event.message);\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n } else if (event.message.role === \"assistant\") {\n this.streamingComponent = new AssistantMessageComponent(\n undefined,\n this.hideThinkingBlock,\n this.getMarkdownThemeWithSettings(),\n this.hiddenThinkingLabel,\n this.outputPad,\n );\n this.streamingMessage = event.message;\n this.chatContainer.addChild(this.streamingComponent);\n this.streamingComponent.updateContent(this.streamingMessage);\n this.ui.requestRender();\n }\n break;\n\n case \"message_update\":\n if (this.streamingComponent && event.message.role === \"assistant\") {\n this.streamingMessage = event.message;\n this.streamingComponent.updateContent(this.streamingMessage);\n\n for (const content of this.streamingMessage.content) {\n if (content.type === \"toolCall\") {\n if (!this.pendingTools.has(content.id)) {\n const component = new ToolExecutionComponent(\n content.name,\n content.id,\n content.arguments,\n {\n showImages: this.settingsManager.getShowImages(),\n imageWidthCells: this.settingsManager.getImageWidthCells(),\n },\n this.getRegisteredToolDefinition(content.name),\n this.ui,\n this.sessionManager.getCwd(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n this.pendingTools.set(content.id, component);\n } else {\n const component = this.pendingTools.get(content.id);\n if (component) {\n component.updateArgs(content.arguments);\n }\n }\n }\n }\n this.ui.requestRender();\n }\n break;\n\n case \"message_end\":\n if (event.message.role === \"user\") break;\n if (this.streamingComponent && event.message.role === \"assistant\") {\n this.streamingMessage = event.message;\n let errorMessage: string | undefined;\n if (this.streamingMessage.stopReason === \"aborted\") {\n const existingAbortMessage =\n this.streamingMessage.errorMessage && this.streamingMessage.errorMessage !== \"Request was aborted\"\n ? this.streamingMessage.errorMessage\n : undefined;\n const retryAttempt = this.session.retryAttempt;\n errorMessage = existingAbortMessage ?? (\n retryAttempt > 0\n ? `Aborted after ${retryAttempt} retry attempt${retryAttempt > 1 ? \"s\" : \"\"}`\n : \"Operation aborted\"\n );\n this.streamingMessage.errorMessage = errorMessage;\n }\n this.streamingComponent.updateContent(this.streamingMessage);\n\n if (\n this.streamingMessage.stopReason === \"aborted\" ||\n this.streamingMessage.stopReason === \"error\"\n ) {\n if (!errorMessage) {\n errorMessage = this.streamingMessage.errorMessage || \"Error\";\n }\n for (const [, component] of this.pendingTools.entries()) {\n component.updateResult({\n content: [{ type: \"text\", text: errorMessage }],\n isError: true,\n });\n }\n this.pendingTools.clear();\n } else {\n // Args are now complete - trigger diff computation for edit tools\n for (const [, component] of this.pendingTools.entries()) {\n component.setArgsComplete();\n }\n }\n this.streamingComponent = undefined;\n this.streamingMessage = undefined;\n this.footer.invalidate();\n }\n this.ui.requestRender();\n break;\n\n case \"tool_execution_start\": {\n let component = this.pendingTools.get(event.toolCallId);\n if (!component) {\n component = new ToolExecutionComponent(\n event.toolName,\n event.toolCallId,\n event.args,\n {\n showImages: this.settingsManager.getShowImages(),\n imageWidthCells: this.settingsManager.getImageWidthCells(),\n },\n this.getRegisteredToolDefinition(event.toolName),\n this.ui,\n this.sessionManager.getCwd(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n this.pendingTools.set(event.toolCallId, component);\n }\n component.markExecutionStarted();\n this.ui.requestRender();\n break;\n }\n\n case \"tool_execution_update\": {\n const component = this.pendingTools.get(event.toolCallId);\n if (component) {\n component.updateResult(\n { ...event.partialResult, isError: false },\n true,\n );\n this.ui.requestRender();\n }\n break;\n }\n\n case \"tool_execution_end\": {\n const component = this.pendingTools.get(event.toolCallId);\n if (component) {\n component.updateResult({ ...event.result, isError: event.isError });\n this.pendingTools.delete(event.toolCallId);\n this.ui.requestRender();\n }\n break;\n }\n\n case \"agent_end\":\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(false);\n }\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n this.statusContainer.clear();\n }\n if (this.streamingComponent) {\n this.chatContainer.removeChild(this.streamingComponent);\n this.streamingComponent = undefined;\n this.streamingMessage = undefined;\n }\n this.pendingTools.clear();\n\n await this.checkShutdownRequested();\n\n this.ui.requestRender();\n break;\n\n case \"compaction_start\": {\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(true);\n }\n // Keep editor active; submissions are queued during compaction.\n this.autoCompactionEscapeHandler = this.defaultEditor.onEscape;\n this.defaultEditor.onEscape = () => {\n this.session.abortCompaction();\n };\n this.statusContainer.clear();\n const cancelHint = `(${keyText(\"app.interrupt\")} Cancel)`;\n const isOverflowAutoCompaction = event.reason === \"overflow\";\n const label =\n event.reason === \"manual\"\n ? `Compacting context... ${cancelHint}`\n : `${isOverflowAutoCompaction ? \"Context overflow detected. \" : \"\"}Auto-compacting... ${cancelHint}`;\n this.autoCompactionLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"accent\", spinner),\n (text) => theme.fg(isOverflowAutoCompaction ? \"warning\" : \"muted\", text),\n label,\n );\n this.statusContainer.addChild(this.autoCompactionLoader);\n this.ui.requestRender();\n break;\n }\n\n case \"compaction_end\": {\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(false);\n }\n if (this.autoCompactionEscapeHandler) {\n this.defaultEditor.onEscape = this.autoCompactionEscapeHandler;\n this.autoCompactionEscapeHandler = undefined;\n }\n if (this.autoCompactionLoader) {\n this.autoCompactionLoader.stop();\n this.autoCompactionLoader = undefined;\n this.statusContainer.clear();\n }\n if (event.aborted) {\n if (event.reason === \"manual\") {\n this.showError(\"Compaction cancelled\");\n } else {\n this.showStatus(\"Auto-compaction cancelled\");\n }\n } else if (event.result) {\n this.chatContainer.clear();\n this.rebuildChatFromMessages();\n this.addContextCompactionSummaryToChat(event.result as ContextCompactionResult);\n this.footer.invalidate();\n } else if (event.errorMessage) {\n if (event.reason === \"manual\") {\n this.showError(event.errorMessage);\n } else {\n this.chatContainer.addChild(new Spacer(1));\n this.chatContainer.addChild(\n new Text(theme.fg(\"error\", event.errorMessage), 1, 0),\n );\n }\n }\n void this.flushCompactionQueue({ willRetry: event.willRetry });\n this.ui.requestRender();\n break;\n }\n\n case \"context_compaction_start\": {\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(true);\n }\n this.autoCompactionEscapeHandler = this.defaultEditor.onEscape;\n this.defaultEditor.onEscape = () => {\n this.session.abortCompaction();\n };\n this.statusContainer.clear();\n const cancelHint = `(${keyText(\"app.interrupt\")} Cancel)`;\n this.autoCompactionLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"accent\", spinner),\n (text) => theme.fg(\"muted\", text),\n `Compacting context... ${cancelHint}`,\n );\n this.statusContainer.addChild(this.autoCompactionLoader);\n this.ui.requestRender();\n break;\n }\n\n case \"context_compaction_end\": {\n if (this.settingsManager.getShowTerminalProgress()) {\n this.ui.terminal.setProgress(false);\n }\n if (this.autoCompactionEscapeHandler) {\n this.defaultEditor.onEscape = this.autoCompactionEscapeHandler;\n this.autoCompactionEscapeHandler = undefined;\n }\n if (this.autoCompactionLoader) {\n this.autoCompactionLoader.stop();\n this.autoCompactionLoader = undefined;\n this.statusContainer.clear();\n }\n if (event.aborted) {\n this.showError(\"Context compaction cancelled\");\n } else if (event.result) {\n this.chatContainer.clear();\n this.rebuildChatFromMessages();\n this.addContextCompactionSummaryToChat(event.result);\n this.footer.invalidate();\n } else if (event.errorMessage) {\n this.showError(event.errorMessage);\n }\n void this.flushCompactionQueue({ willRetry: event.willRetry });\n this.ui.requestRender();\n break;\n }\n\n case \"auto_retry_start\": {\n // Set up escape to abort retry\n this.retryEscapeHandler = this.defaultEditor.onEscape;\n this.defaultEditor.onEscape = () => {\n this.session.abortRetry();\n };\n // Show retry indicator\n this.statusContainer.clear();\n this.retryCountdown?.dispose();\n const retryMessage = (seconds: number) =>\n `Retrying (${event.attempt}/${event.maxAttempts}) in ${seconds}s... (${keyText(\"app.interrupt\")} Cancel)`;\n this.retryLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"warning\", spinner),\n (text) => theme.fg(\"muted\", text),\n retryMessage(Math.ceil(event.delayMs / 1000)),\n );\n this.retryCountdown = new CountdownTimer(\n event.delayMs,\n this.ui,\n (seconds) => {\n this.retryLoader?.setMessage(retryMessage(seconds));\n },\n () => {\n this.retryCountdown = undefined;\n },\n );\n this.statusContainer.addChild(this.retryLoader);\n this.ui.requestRender();\n break;\n }\n\n case \"auto_retry_end\": {\n // Restore escape handler\n if (this.retryEscapeHandler) {\n this.defaultEditor.onEscape = this.retryEscapeHandler;\n this.retryEscapeHandler = undefined;\n }\n if (this.retryCountdown) {\n this.retryCountdown.dispose();\n this.retryCountdown = undefined;\n }\n // Stop loader\n if (this.retryLoader) {\n this.retryLoader.stop();\n this.retryLoader = undefined;\n this.statusContainer.clear();\n }\n // Show error only on final failure (success shows normal response)\n if (!event.success) {\n this.showError(\n `Retry failed after ${event.attempt} attempts: ${event.finalError || \"Unknown error\"}`,\n );\n }\n this.ui.requestRender();\n break;\n }\n\n case \"agent_continue_error\": {\n this.showError(event.errorMessage);\n this.ui.requestRender();\n break;\n }\n }\n };\n\nInteractiveModeBase.prototype.getUserMessageText = function(this: InteractiveModeBase, message: Message): string {\n if (message.role !== \"user\") return \"\";\n const textBlocks =\n typeof message.content === \"string\"\n ? [{ type: \"text\", text: message.content }]\n : message.content.filter((c: { type: string }) => c.type === \"text\");\n return textBlocks.map((c) => (c as { text: string }).text).join(\"\");\n };\n"]}
@@ -85,7 +85,7 @@ InteractiveModeBase.prototype.handleEvent = async function (event) {
85
85
  this.ui.requestRender();
86
86
  }
87
87
  else if (event.message.role === "assistant") {
88
- this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel);
88
+ this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad);
89
89
  this.streamingMessage = event.message;
90
90
  this.chatContainer.addChild(this.streamingComponent);
91
91
  this.streamingComponent.updateContent(this.streamingMessage);