@code-yeongyu/senpi 2026.8.5 → 2026.8.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 (127) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/dist/core/agent-abort-provenance.d.ts +20 -0
  3. package/dist/core/agent-abort-provenance.d.ts.map +1 -0
  4. package/dist/core/agent-abort-provenance.js +83 -0
  5. package/dist/core/agent-abort-provenance.js.map +1 -0
  6. package/dist/core/agent-session.d.ts +15 -1
  7. package/dist/core/agent-session.d.ts.map +1 -1
  8. package/dist/core/agent-session.js +123 -80
  9. package/dist/core/agent-session.js.map +1 -1
  10. package/dist/core/agent-settled-delivery.d.ts +9 -0
  11. package/dist/core/agent-settled-delivery.d.ts.map +1 -0
  12. package/dist/core/agent-settled-delivery.js +25 -0
  13. package/dist/core/agent-settled-delivery.js.map +1 -0
  14. package/dist/core/extensions/builtin/bash-timeout/index.d.ts +2 -2
  15. package/dist/core/extensions/builtin/bash-timeout/index.d.ts.map +1 -1
  16. package/dist/core/extensions/builtin/bash-timeout/index.js +17 -20
  17. package/dist/core/extensions/builtin/bash-timeout/index.js.map +1 -1
  18. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts +7 -12
  19. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/bash-timeout/timeout.js +11 -19
  21. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  22. package/dist/core/extensions/builtin/compaction/index.js +3 -3
  23. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  24. package/dist/core/extensions/builtin/compaction/per-turn-cap.d.ts +8 -8
  25. package/dist/core/extensions/builtin/compaction/per-turn-cap.d.ts.map +1 -1
  26. package/dist/core/extensions/builtin/compaction/per-turn-cap.js +9 -16
  27. package/dist/core/extensions/builtin/compaction/per-turn-cap.js.map +1 -1
  28. package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts +11 -0
  29. package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts.map +1 -0
  30. package/dist/core/extensions/builtin/goal/agent-end-continuation.js +13 -0
  31. package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -0
  32. package/dist/core/extensions/builtin/goal/cache-warm.d.ts +0 -2
  33. package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/goal/cache-warm.js +0 -34
  35. package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
  36. package/dist/core/extensions/builtin/goal/continuation.d.ts +1 -1
  37. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  38. package/dist/core/extensions/builtin/goal/continuation.js +2 -0
  39. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  40. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  41. package/dist/core/extensions/builtin/goal/index.js +17 -19
  42. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  43. package/dist/core/extensions/builtin/goal/last-assistant-message.d.ts +5 -0
  44. package/dist/core/extensions/builtin/goal/last-assistant-message.d.ts.map +1 -0
  45. package/dist/core/extensions/builtin/goal/last-assistant-message.js +9 -0
  46. package/dist/core/extensions/builtin/goal/last-assistant-message.js.map +1 -0
  47. package/dist/core/extensions/builtin/goal/monitor-continuation-types.d.ts +23 -0
  48. package/dist/core/extensions/builtin/goal/monitor-continuation-types.d.ts.map +1 -0
  49. package/dist/core/extensions/builtin/goal/monitor-continuation-types.js +2 -0
  50. package/dist/core/extensions/builtin/goal/monitor-continuation-types.js.map +1 -0
  51. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +4 -10
  52. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  53. package/dist/core/extensions/builtin/goal/monitor-continuation.js +31 -21
  54. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  55. package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts +3 -0
  56. package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts.map +1 -0
  57. package/dist/core/extensions/builtin/goal/terminal-provider-error.js +10 -0
  58. package/dist/core/extensions/builtin/goal/terminal-provider-error.js.map +1 -0
  59. package/dist/core/extensions/builtin/gpt-apply-patch/apply.d.ts.map +1 -1
  60. package/dist/core/extensions/builtin/gpt-apply-patch/apply.js +55 -11
  61. package/dist/core/extensions/builtin/gpt-apply-patch/apply.js.map +1 -1
  62. package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.d.ts.map +1 -1
  63. package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.js +8 -5
  64. package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.js.map +1 -1
  65. package/dist/core/extensions/builtin/gpt-apply-patch/preview.d.ts +2 -0
  66. package/dist/core/extensions/builtin/gpt-apply-patch/preview.d.ts.map +1 -1
  67. package/dist/core/extensions/builtin/gpt-apply-patch/preview.js +39 -7
  68. package/dist/core/extensions/builtin/gpt-apply-patch/preview.js.map +1 -1
  69. package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts +1 -0
  70. package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts.map +1 -1
  71. package/dist/core/extensions/builtin/gpt-apply-patch/types.js.map +1 -1
  72. package/dist/core/extensions/builtin/terminal/tools/bash.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/terminal/tools/bash.js +22 -10
  74. package/dist/core/extensions/builtin/terminal/tools/bash.js.map +1 -1
  75. package/dist/core/extensions/builtin/terminal/tools/foreground-window.d.ts +11 -0
  76. package/dist/core/extensions/builtin/terminal/tools/foreground-window.d.ts.map +1 -0
  77. package/dist/core/extensions/builtin/terminal/tools/foreground-window.js +16 -0
  78. package/dist/core/extensions/builtin/terminal/tools/foreground-window.js.map +1 -0
  79. package/dist/core/extensions/builtin/terminal/tools/sleep-wait.d.ts +28 -0
  80. package/dist/core/extensions/builtin/terminal/tools/sleep-wait.d.ts.map +1 -0
  81. package/dist/core/extensions/builtin/terminal/tools/sleep-wait.js +75 -0
  82. package/dist/core/extensions/builtin/terminal/tools/sleep-wait.js.map +1 -0
  83. package/dist/core/extensions/builtin/tps.d.ts.map +1 -1
  84. package/dist/core/extensions/builtin/tps.js +3 -3
  85. package/dist/core/extensions/builtin/tps.js.map +1 -1
  86. package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin/ttsr/index.js +35 -34
  88. package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
  89. package/dist/core/extensions/runner.d.ts.map +1 -1
  90. package/dist/core/extensions/runner.js +2 -2
  91. package/dist/core/extensions/runner.js.map +1 -1
  92. package/dist/core/extensions/types.d.ts +2 -2
  93. package/dist/core/extensions/types.d.ts.map +1 -1
  94. package/dist/core/extensions/types.js.map +1 -1
  95. package/dist/core/retry-fallback/hint-policy.d.ts +14 -0
  96. package/dist/core/retry-fallback/hint-policy.d.ts.map +1 -1
  97. package/dist/core/retry-fallback/hint-policy.js +14 -0
  98. package/dist/core/retry-fallback/hint-policy.js.map +1 -1
  99. package/dist/modes/interactive/components/assistant-message.d.ts +0 -1
  100. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  101. package/dist/modes/interactive/components/assistant-message.js +8 -128
  102. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  103. package/dist/modes/interactive/components/assistant-render-descriptors.d.ts +17 -0
  104. package/dist/modes/interactive/components/assistant-render-descriptors.d.ts.map +1 -0
  105. package/dist/modes/interactive/components/assistant-render-descriptors.js +133 -0
  106. package/dist/modes/interactive/components/assistant-render-descriptors.js.map +1 -0
  107. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +41 -0
  108. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  109. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +2 -1
  110. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  111. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +30 -0
  112. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  113. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +30 -0
  114. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  115. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  116. package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.json +1 -1
  117. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  118. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  119. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  120. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  121. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  122. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  123. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  124. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +14 -1
  125. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  126. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  127. package/package.json +7 -7
@@ -1,30 +1,14 @@
1
1
  import { Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
2
- import { formatDuration } from "../../../utils/duration.js";
3
- import { formatProviderNativeBody, formatProviderNativeSummary } from "../../provider-native-rendering.js";
4
2
  import { getMarkdownTheme, theme } from "../theme/theme.js";
3
+ import { createAssistantRenderDescriptors } from "./assistant-render-descriptors.js";
5
4
  import { createMarkdownTransform } from "./markdown-transform.js";
6
5
  import { createBoundedRenderSignature } from "./render-signature.js";
7
6
  const OSC133_ZONE_START = "\x1b]133;A\x07";
8
7
  const OSC133_ZONE_END = "\x1b]133;B\x07";
9
8
  const OSC133_ZONE_FINAL = "\x1b]133;C\x07";
10
- const SPACER_DESCRIPTOR = { kind: "spacer", text: "" };
11
9
  function assertNever(value) {
12
10
  throw new TypeError(`Unexpected assistant render variant: ${String(value)}`);
13
11
  }
14
- function isVisibleContent(content, providerNativeVisible) {
15
- switch (content.type) {
16
- case "text":
17
- return Boolean(content.text.trim());
18
- case "thinking":
19
- return Boolean(content.thinking.trim());
20
- case "providerNative":
21
- return providerNativeVisible;
22
- case "toolCall":
23
- return false;
24
- default:
25
- return assertNever(content);
26
- }
27
- }
28
12
  export class AssistantMessageComponent extends Container {
29
13
  constructor(message, hideThinkingBlock = false, markdownTheme = getMarkdownTheme(), hiddenThinkingLabel = "Thinking...", outputPad = 1, markdownTransformers = []) {
30
14
  super();
@@ -101,118 +85,14 @@ export class AssistantMessageComponent extends Container {
101
85
  if (streamingChanged)
102
86
  this.renderDescriptors = [];
103
87
  this.hasToolCalls = message.content.some((content) => content.type === "toolCall");
104
- const descriptors = this.createRenderDescriptors(message);
88
+ const descriptors = createAssistantRenderDescriptors(message, {
89
+ expanded: this.expanded,
90
+ hiddenThinkingLabel: this.hiddenThinkingLabel,
91
+ hideThinkingBlock: this.hideThinkingBlock,
92
+ hasToolCalls: this.hasToolCalls,
93
+ });
105
94
  this.reconcileRenderDescriptors(descriptors);
106
95
  }
107
- createRenderDescriptors(message) {
108
- const descriptors = [];
109
- if (message.content.some((content) => isVisibleContent(content, true)))
110
- descriptors.push(SPACER_DESCRIPTOR);
111
- for (let i = 0; i < message.content.length; i++) {
112
- const content = message.content[i];
113
- switch (content.type) {
114
- case "text": {
115
- const text = content.text.trim();
116
- if (text)
117
- descriptors.push({ kind: "text-md", text });
118
- break;
119
- }
120
- case "thinking": {
121
- const thinkingBlocks = [];
122
- let hasTiming = false;
123
- let isDone = true;
124
- let minStart = Number.POSITIVE_INFINITY;
125
- let maxEnd = Number.NEGATIVE_INFINITY;
126
- for (; i < message.content.length; i++) {
127
- const thinkingContent = message.content[i];
128
- if (thinkingContent.type !== "thinking")
129
- break;
130
- const startedAt = thinkingContent.startedAt;
131
- if (startedAt !== undefined) {
132
- hasTiming = true;
133
- minStart = Math.min(minStart, startedAt);
134
- const endedAt = thinkingContent.endedAt;
135
- if (endedAt === undefined) {
136
- isDone = false;
137
- }
138
- else {
139
- maxEnd = Math.max(maxEnd, endedAt);
140
- }
141
- }
142
- const thinking = thinkingContent.thinking.trim();
143
- if (thinking)
144
- thinkingBlocks.push(thinking);
145
- }
146
- i--;
147
- if (thinkingBlocks.length === 0)
148
- break;
149
- if (!hasTiming) {
150
- const text = this.hideThinkingBlock
151
- ? theme.italic(theme.fg("thinkingText", this.hiddenThinkingLabel))
152
- : thinkingBlocks.join("\n\n");
153
- descriptors.push({ kind: this.hideThinkingBlock ? "thinking-label" : "thinking-md", text });
154
- }
155
- else {
156
- const label = isDone
157
- ? theme.italic(theme.fg("thinkingText", `Thought: ${formatDuration(Math.max(0, maxEnd - minStart))}`))
158
- : theme.italic(theme.fg("thinkingText", this.hiddenThinkingLabel));
159
- if (this.hideThinkingBlock) {
160
- descriptors.push({ kind: "thinking-label", text: label });
161
- }
162
- else {
163
- descriptors.push({ kind: "thinking-label", text: label }, { kind: "thinking-md", text: thinkingBlocks.join("\n\n") });
164
- }
165
- }
166
- if (message.content.slice(i + 1).some((following) => isVisibleContent(following, false)))
167
- descriptors.push(SPACER_DESCRIPTOR);
168
- break;
169
- }
170
- case "providerNative":
171
- descriptors.push({
172
- kind: "provider-native-summary",
173
- text: theme.fg("muted", formatProviderNativeSummary(message, content, this.expanded)),
174
- }, {
175
- kind: "provider-native-body",
176
- text: theme.fg("dim", formatProviderNativeBody(content, this.expanded)),
177
- });
178
- if (message.content.slice(i + 1).some((following) => isVisibleContent(following, true)))
179
- descriptors.push(SPACER_DESCRIPTOR);
180
- break;
181
- case "toolCall":
182
- break;
183
- default:
184
- assertNever(content);
185
- }
186
- }
187
- const addError = (text) => {
188
- descriptors.push(SPACER_DESCRIPTOR, { kind: "error-text", text: theme.fg("error", text) });
189
- };
190
- switch (message.stopReason) {
191
- case "length":
192
- addError("Error: Model stopped because it reached the maximum output token limit. The response may be incomplete.");
193
- break;
194
- case "aborted": {
195
- if (this.hasToolCalls)
196
- break;
197
- const abortMessage = message.errorMessage && message.errorMessage !== "Request was aborted"
198
- ? message.errorMessage
199
- : "Operation aborted";
200
- addError(abortMessage);
201
- break;
202
- }
203
- case "error":
204
- if (!this.hasToolCalls)
205
- addError(`Error: ${message.errorMessage || "Unknown error"}`);
206
- break;
207
- case "pending":
208
- case "stop":
209
- case "toolUse":
210
- break;
211
- default:
212
- assertNever(message.stopReason);
213
- }
214
- return descriptors;
215
- }
216
96
  reconcileRenderDescriptors(descriptors) {
217
97
  let divergentIndex = 0;
218
98
  const sharedLength = Math.min(this.renderDescriptors.length, descriptors.length);
@@ -268,7 +148,7 @@ export class AssistantMessageComponent extends Container {
268
148
  content: message.content,
269
149
  hiddenThinkingLabel: this.hiddenThinkingLabel,
270
150
  hideThinkingBlock: this.hideThinkingBlock,
271
- errorMessage: message.errorMessage,
151
+ errorState: [message.diagnostics, message.errorMessage],
272
152
  stopReason: message.stopReason,
273
153
  });
274
154
  }
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-message.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport { type Component, Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport type { MarkdownTransformer } from \"../../../core/extensions/types.ts\";\nimport { formatDuration } from \"../../../utils/duration.ts\";\nimport { formatProviderNativeBody, formatProviderNativeSummary } from \"../../provider-native-rendering.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { createMarkdownTransform } from \"./markdown-transform.ts\";\nimport { createBoundedRenderSignature } from \"./render-signature.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\ntype MarkdownDescriptorKind = \"text-md\" | \"thinking-md\";\ntype TextDescriptorKind = \"thinking-label\" | \"provider-native-summary\" | \"provider-native-body\" | \"error-text\";\ntype RenderDescriptorKind = \"spacer\" | MarkdownDescriptorKind | TextDescriptorKind;\ntype RenderDescriptor = { readonly kind: RenderDescriptorKind; readonly text: string };\n\nconst SPACER_DESCRIPTOR = { kind: \"spacer\", text: \"\" } as const satisfies RenderDescriptor;\n\nfunction assertNever(value: never): never {\n\tthrow new TypeError(`Unexpected assistant render variant: ${String(value)}`);\n}\n\nfunction isVisibleContent(content: AssistantMessage[\"content\"][number], providerNativeVisible: boolean): boolean {\n\tswitch (content.type) {\n\t\tcase \"text\":\n\t\t\treturn Boolean(content.text.trim());\n\t\tcase \"thinking\":\n\t\t\treturn Boolean(content.thinking.trim());\n\t\tcase \"providerNative\":\n\t\t\treturn providerNativeVisible;\n\t\tcase \"toolCall\":\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn assertNever(content);\n\t}\n}\n\nexport class AssistantMessageComponent extends Container {\n\tprivate renderCache?: { readonly lines: string[]; readonly signature: string; readonly width: number };\n\tprivate contentContainer: Container;\n\tprivate hideThinkingBlock: boolean;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate hiddenThinkingLabel: string;\n\tprivate outputPad: number;\n\tprivate markdownTransformers: readonly MarkdownTransformer[];\n\tprivate lastMessage?: AssistantMessage;\n\tprivate lastMessageSignature?: string;\n\tprivate renderDescriptors: readonly RenderDescriptor[] = [];\n\tprivate hasToolCalls = false;\n\tprivate expanded = false;\n\tprivate isStreaming = false;\n\n\tconstructor(\n\t\tmessage?: AssistantMessage,\n\t\thideThinkingBlock = false,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\thiddenThinkingLabel = \"Thinking...\",\n\t\toutputPad = 1,\n\t\tmarkdownTransformers: readonly MarkdownTransformer[] = [],\n\t) {\n\t\tsuper();\n\n\t\tthis.hideThinkingBlock = hideThinkingBlock;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.hiddenThinkingLabel = hiddenThinkingLabel;\n\t\tthis.outputPad = outputPad;\n\t\tthis.markdownTransformers = markdownTransformers;\n\n\t\t// Container for text/thinking content\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\tif (message) this.updateContent(message);\n\t}\n\n\toverride invalidate(): void {\n\t\tthis.renderCache = undefined;\n\t\tsuper.invalidate();\n\t\tthis.renderDescriptors = [];\n\t\tthis.refreshContent();\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tif (this.hideThinkingBlock === hide) return;\n\t\tthis.hideThinkingBlock = hide;\n\t\tthis.refreshContent();\n\t}\n\n\tsetHiddenThinkingLabel(label: string): void {\n\t\tif (this.hiddenThinkingLabel === label) return;\n\t\tthis.hiddenThinkingLabel = label;\n\t\tthis.refreshContent();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tif (this.expanded === expanded) return;\n\t\tthis.expanded = expanded;\n\t\tthis.refreshContent();\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tthis.renderDescriptors = [];\n\t\tthis.refreshContent();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst signature = this.lastMessageSignature ?? \"\";\n\t\tif (this.renderCache?.width === width && this.renderCache.signature === signature) {\n\t\t\treturn [...this.renderCache.lines];\n\t\t}\n\n\t\tconst lines = super.render(width);\n\t\tif (this.hasToolCalls || lines.length === 0) {\n\t\t\tthis.cacheRender(width, signature, lines);\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\tthis.cacheRender(width, signature, lines);\n\t\treturn lines;\n\t}\n\n\tupdateContent(message: AssistantMessage, isStreaming = this.isStreaming): void {\n\t\tconst previousMessage = this.lastMessage;\n\t\tconst streamingChanged = this.isStreaming !== isStreaming;\n\t\tthis.isStreaming = isStreaming;\n\t\tthis.lastMessage = message;\n\t\tconst messageSignature = this.createMessageSignature(message);\n\t\tif (!streamingChanged && previousMessage === message && this.lastMessageSignature === messageSignature) {\n\t\t\treturn;\n\t\t}\n\t\tthis.lastMessageSignature = messageSignature;\n\t\tthis.renderCache = undefined;\n\t\tif (streamingChanged) this.renderDescriptors = [];\n\t\tthis.hasToolCalls = message.content.some((content) => content.type === \"toolCall\");\n\t\tconst descriptors = this.createRenderDescriptors(message);\n\t\tthis.reconcileRenderDescriptors(descriptors);\n\t}\n\n\tprivate createRenderDescriptors(message: AssistantMessage): readonly RenderDescriptor[] {\n\t\tconst descriptors: RenderDescriptor[] = [];\n\t\tif (message.content.some((content) => isVisibleContent(content, true))) descriptors.push(SPACER_DESCRIPTOR);\n\t\tfor (let i = 0; i < message.content.length; i++) {\n\t\t\tconst content = message.content[i];\n\t\t\tswitch (content.type) {\n\t\t\t\tcase \"text\": {\n\t\t\t\t\tconst text = content.text.trim();\n\t\t\t\t\tif (text) descriptors.push({ kind: \"text-md\", text });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"thinking\": {\n\t\t\t\t\tconst thinkingBlocks: string[] = [];\n\t\t\t\t\tlet hasTiming = false;\n\t\t\t\t\tlet isDone = true;\n\t\t\t\t\tlet minStart = Number.POSITIVE_INFINITY;\n\t\t\t\t\tlet maxEnd = Number.NEGATIVE_INFINITY;\n\t\t\t\t\tfor (; i < message.content.length; i++) {\n\t\t\t\t\t\tconst thinkingContent = message.content[i];\n\t\t\t\t\t\tif (thinkingContent.type !== \"thinking\") break;\n\t\t\t\t\t\tconst startedAt = thinkingContent.startedAt;\n\t\t\t\t\t\tif (startedAt !== undefined) {\n\t\t\t\t\t\t\thasTiming = true;\n\t\t\t\t\t\t\tminStart = Math.min(minStart, startedAt);\n\t\t\t\t\t\t\tconst endedAt = thinkingContent.endedAt;\n\t\t\t\t\t\t\tif (endedAt === undefined) {\n\t\t\t\t\t\t\t\tisDone = false;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tmaxEnd = Math.max(maxEnd, endedAt);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\t\t\t\tif (thinking) thinkingBlocks.push(thinking);\n\t\t\t\t\t}\n\t\t\t\t\ti--;\n\t\t\t\t\tif (thinkingBlocks.length === 0) break;\n\t\t\t\t\tif (!hasTiming) {\n\t\t\t\t\t\tconst text = this.hideThinkingBlock\n\t\t\t\t\t\t\t? theme.italic(theme.fg(\"thinkingText\", this.hiddenThinkingLabel))\n\t\t\t\t\t\t\t: thinkingBlocks.join(\"\\n\\n\");\n\t\t\t\t\t\tdescriptors.push({ kind: this.hideThinkingBlock ? \"thinking-label\" : \"thinking-md\", text });\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst label = isDone\n\t\t\t\t\t\t\t? theme.italic(\n\t\t\t\t\t\t\t\t\ttheme.fg(\"thinkingText\", `Thought: ${formatDuration(Math.max(0, maxEnd - minStart))}`),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: theme.italic(theme.fg(\"thinkingText\", this.hiddenThinkingLabel));\n\t\t\t\t\t\tif (this.hideThinkingBlock) {\n\t\t\t\t\t\t\tdescriptors.push({ kind: \"thinking-label\", text: label });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdescriptors.push(\n\t\t\t\t\t\t\t\t{ kind: \"thinking-label\", text: label },\n\t\t\t\t\t\t\t\t{ kind: \"thinking-md\", text: thinkingBlocks.join(\"\\n\\n\") },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (message.content.slice(i + 1).some((following) => isVisibleContent(following, false)))\n\t\t\t\t\t\tdescriptors.push(SPACER_DESCRIPTOR);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"providerNative\":\n\t\t\t\t\tdescriptors.push(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: \"provider-native-summary\",\n\t\t\t\t\t\t\ttext: theme.fg(\"muted\", formatProviderNativeSummary(message, content, this.expanded)),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: \"provider-native-body\",\n\t\t\t\t\t\t\ttext: theme.fg(\"dim\", formatProviderNativeBody(content, this.expanded)),\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tif (message.content.slice(i + 1).some((following) => isVisibleContent(following, true)))\n\t\t\t\t\t\tdescriptors.push(SPACER_DESCRIPTOR);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"toolCall\":\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tassertNever(content);\n\t\t\t}\n\t\t}\n\t\tconst addError = (text: string): void => {\n\t\t\tdescriptors.push(SPACER_DESCRIPTOR, { kind: \"error-text\", text: theme.fg(\"error\", text) });\n\t\t};\n\t\tswitch (message.stopReason) {\n\t\t\tcase \"length\":\n\t\t\t\taddError(\n\t\t\t\t\t\"Error: Model stopped because it reached the maximum output token limit. The response may be incomplete.\",\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"aborted\": {\n\t\t\t\tif (this.hasToolCalls) break;\n\t\t\t\tconst abortMessage =\n\t\t\t\t\tmessage.errorMessage && message.errorMessage !== \"Request was aborted\"\n\t\t\t\t\t\t? message.errorMessage\n\t\t\t\t\t\t: \"Operation aborted\";\n\t\t\t\taddError(abortMessage);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"error\":\n\t\t\t\tif (!this.hasToolCalls) addError(`Error: ${message.errorMessage || \"Unknown error\"}`);\n\t\t\t\tbreak;\n\t\t\tcase \"pending\":\n\t\t\tcase \"stop\":\n\t\t\tcase \"toolUse\":\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tassertNever(message.stopReason);\n\t\t}\n\t\treturn descriptors;\n\t}\n\n\tprivate reconcileRenderDescriptors(descriptors: readonly RenderDescriptor[]): void {\n\t\tlet divergentIndex = 0;\n\t\tconst sharedLength = Math.min(this.renderDescriptors.length, descriptors.length);\n\t\twhile (divergentIndex < sharedLength) {\n\t\t\tconst previous = this.renderDescriptors[divergentIndex];\n\t\t\tconst next = descriptors[divergentIndex];\n\t\t\tconst child = this.contentContainer.children[divergentIndex];\n\t\t\tif (!previous || !next || !child || previous.kind !== next.kind) break;\n\t\t\tif (previous.text !== next.text) {\n\t\t\t\tif ((next.kind === \"text-md\" || next.kind === \"thinking-md\") && child instanceof Markdown) {\n\t\t\t\t\tchild.setText(next.text);\n\t\t\t\t} else break;\n\t\t\t}\n\t\t\tdivergentIndex++;\n\t\t}\n\t\tfor (const child of this.contentContainer.children.splice(divergentIndex)) child.dispose?.();\n\t\tfor (const descriptor of descriptors.slice(divergentIndex))\n\t\t\tthis.contentContainer.addChild(this.createRenderChild(descriptor));\n\t\tthis.renderDescriptors = descriptors;\n\t}\n\n\tprivate createRenderChild(descriptor: RenderDescriptor): Component {\n\t\tswitch (descriptor.kind) {\n\t\t\tcase \"spacer\":\n\t\t\t\treturn new Spacer(1);\n\t\t\tcase \"text-md\":\n\t\t\t\treturn new Markdown(descriptor.text, this.outputPad, 0, this.markdownTheme, undefined, {\n\t\t\t\t\ttransform: createMarkdownTransform(\"assistant\", this.isStreaming, this.markdownTransformers),\n\t\t\t\t});\n\t\t\tcase \"thinking-md\":\n\t\t\t\treturn new Markdown(\n\t\t\t\t\tdescriptor.text,\n\t\t\t\t\tthis.outputPad,\n\t\t\t\t\t0,\n\t\t\t\t\tthis.markdownTheme,\n\t\t\t\t\t{\n\t\t\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\t\t\titalic: true,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttransform: createMarkdownTransform(\"assistant-thinking\", this.isStreaming, this.markdownTransformers),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\tcase \"thinking-label\":\n\t\t\tcase \"error-text\":\n\t\t\t\treturn new Text(descriptor.text, this.outputPad, 0);\n\t\t\tcase \"provider-native-summary\":\n\t\t\t\treturn new Text(descriptor.text, 1, 0);\n\t\t\tcase \"provider-native-body\":\n\t\t\t\treturn new Text(descriptor.text, 3, 0);\n\t\t\tdefault:\n\t\t\t\treturn assertNever(descriptor.kind);\n\t\t}\n\t}\n\n\tprivate createMessageSignature(message: AssistantMessage): string {\n\t\treturn createBoundedRenderSignature({\n\t\t\tcontent: message.content,\n\t\t\thiddenThinkingLabel: this.hiddenThinkingLabel,\n\t\t\thideThinkingBlock: this.hideThinkingBlock,\n\t\t\terrorMessage: message.errorMessage,\n\t\t\tstopReason: message.stopReason,\n\t\t});\n\t}\n\n\tprivate cacheRender(width: number, signature: string, lines: string[]): void {\n\t\tthis.renderCache = { lines: [...lines], signature, width };\n\t}\n\n\tprivate refreshContent(): void {\n\t\tif (!this.lastMessage) return;\n\t\tthis.lastMessageSignature = undefined;\n\t\tthis.updateContent(this.lastMessage);\n\t}\n}\n"]}
1
+ {"version":3,"file":"assistant-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-message.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,SAAS,EAAE,QAAQ,EAAsB,MAAM,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAE/G,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAkC,gCAAgC,EAAE,MAAM,mCAAmC,CAAC;AACrH,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAErE,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAC3C,MAAM,eAAe,GAAG,gBAAgB,CAAC;AACzC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAE3C,SAAS,WAAW,CAAC,KAAY;IAChC,MAAM,IAAI,SAAS,CAAC,wCAAwC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,OAAO,yBAA0B,SAAQ,SAAS;IAevD,YACC,OAA0B,EAC1B,iBAAiB,GAAG,KAAK,EACzB,aAAa,GAAkB,gBAAgB,EAAE,EACjD,mBAAmB,GAAG,aAAa,EACnC,SAAS,GAAG,CAAC,EACb,oBAAoB,GAAmC,EAAE;QAEzD,KAAK,EAAE,CAAC;QAbD,sBAAiB,GAAyC,EAAE,CAAC;QAC7D,iBAAY,GAAG,KAAK,CAAC;QACrB,aAAQ,GAAG,KAAK,CAAC;QACjB,gBAAW,GAAG,KAAK,CAAC;QAY3B,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;QAC/C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;QAEjD,sCAAsC;QACtC,IAAI,CAAC,gBAAgB,GAAG,IAAI,SAAS,EAAE,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAErC,IAAI,OAAO;YAAE,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAEQ,UAAU;QAClB,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC7B,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAED,oBAAoB,CAAC,IAAa;QACjC,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI;YAAE,OAAO;QAC5C,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAED,sBAAsB,CAAC,KAAa;QACnC,IAAI,IAAI,CAAC,mBAAmB,KAAK,KAAK;YAAE,OAAO;QAC/C,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;QACjC,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAED,WAAW,CAAC,QAAiB;QAC5B,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAED,YAAY,CAAC,OAAe;QAC3B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAEQ,MAAM,CAAC,KAAa;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAC;QAClD,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACnF,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YAC1C,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,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACd,CAAC;IAED,aAAa,CAAC,OAAyB,EAAE,WAAW,GAAG,IAAI,CAAC,WAAW;QACtE,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC;QACzC,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,KAAK,WAAW,CAAC;QAC1D,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;QAC3B,MAAM,gBAAgB,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC9D,IAAI,CAAC,gBAAgB,IAAI,eAAe,KAAK,OAAO,IAAI,IAAI,CAAC,oBAAoB,KAAK,gBAAgB,EAAE,CAAC;YACxG,OAAO;QACR,CAAC;QACD,IAAI,CAAC,oBAAoB,GAAG,gBAAgB,CAAC;QAC7C,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC7B,IAAI,gBAAgB;YAAE,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAClD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QACnF,MAAM,WAAW,GAAG,gCAAgC,CAAC,OAAO,EAAE;YAC7D,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;YAC7C,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,YAAY,EAAE,IAAI,CAAC,YAAY;SAC/B,CAAC,CAAC;QACH,IAAI,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAEO,0BAA0B,CAAC,WAAiD;QACnF,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACjF,OAAO,cAAc,GAAG,YAAY,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;YACxD,MAAM,IAAI,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAC7D,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;gBAAE,MAAM;YACvE,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBACjC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;oBAC3F,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;;oBAAM,MAAM;YACd,CAAC;YACD,cAAc,EAAE,CAAC;QAClB,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC;YAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC7F,KAAK,MAAM,UAAU,IAAI,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC;YACzD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,iBAAiB,GAAG,WAAW,CAAC;IACtC,CAAC;IAEO,iBAAiB,CAAC,UAAqC;QAC9D,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;YACzB,KAAK,QAAQ;gBACZ,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;YACtB,KAAK,SAAS;gBACb,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE;oBACtF,SAAS,EAAE,uBAAuB,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,oBAAoB,CAAC;iBAC5F,CAAC,CAAC;YACJ,KAAK,aAAa;gBACjB,OAAO,IAAI,QAAQ,CAClB,UAAU,CAAC,IAAI,EACf,IAAI,CAAC,SAAS,EACd,CAAC,EACD,IAAI,CAAC,aAAa,EAClB;oBACC,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC;oBACvD,MAAM,EAAE,IAAI;iBACZ,EACD;oBACC,SAAS,EAAE,uBAAuB,CAAC,oBAAoB,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,oBAAoB,CAAC;iBACrG,CACD,CAAC;YACH,KAAK,gBAAgB,CAAC;YACtB,KAAK,YAAY;gBAChB,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YACrD,KAAK,yBAAyB;gBAC7B,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACxC,KAAK,sBAAsB;gBAC1B,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACxC;gBACC,OAAO,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;IACF,CAAC;IAEO,sBAAsB,CAAC,OAAyB;QACvD,OAAO,4BAA4B,CAAC;YACnC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;YAC7C,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,UAAU,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC;YACvD,UAAU,EAAE,OAAO,CAAC,UAAU;SAC9B,CAAC,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,KAAa,EAAE,SAAiB,EAAE,KAAe;QACpE,IAAI,CAAC,WAAW,GAAG,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC5D,CAAC;IAEO,cAAc;QACrB,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO;QAC9B,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC;QACtC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC;CACD","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport { type Component, Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport type { MarkdownTransformer } from \"../../../core/extensions/types.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { type AssistantRenderDescriptor, createAssistantRenderDescriptors } from \"./assistant-render-descriptors.ts\";\nimport { createMarkdownTransform } from \"./markdown-transform.ts\";\nimport { createBoundedRenderSignature } from \"./render-signature.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\nfunction assertNever(value: never): never {\n\tthrow new TypeError(`Unexpected assistant render variant: ${String(value)}`);\n}\n\nexport class AssistantMessageComponent extends Container {\n\tprivate renderCache?: { readonly lines: string[]; readonly signature: string; readonly width: number };\n\tprivate contentContainer: Container;\n\tprivate hideThinkingBlock: boolean;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate hiddenThinkingLabel: string;\n\tprivate outputPad: number;\n\tprivate markdownTransformers: readonly MarkdownTransformer[];\n\tprivate lastMessage?: AssistantMessage;\n\tprivate lastMessageSignature?: string;\n\tprivate renderDescriptors: readonly AssistantRenderDescriptor[] = [];\n\tprivate hasToolCalls = false;\n\tprivate expanded = false;\n\tprivate isStreaming = false;\n\n\tconstructor(\n\t\tmessage?: AssistantMessage,\n\t\thideThinkingBlock = false,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\thiddenThinkingLabel = \"Thinking...\",\n\t\toutputPad = 1,\n\t\tmarkdownTransformers: readonly MarkdownTransformer[] = [],\n\t) {\n\t\tsuper();\n\n\t\tthis.hideThinkingBlock = hideThinkingBlock;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.hiddenThinkingLabel = hiddenThinkingLabel;\n\t\tthis.outputPad = outputPad;\n\t\tthis.markdownTransformers = markdownTransformers;\n\n\t\t// Container for text/thinking content\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\tif (message) this.updateContent(message);\n\t}\n\n\toverride invalidate(): void {\n\t\tthis.renderCache = undefined;\n\t\tsuper.invalidate();\n\t\tthis.renderDescriptors = [];\n\t\tthis.refreshContent();\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tif (this.hideThinkingBlock === hide) return;\n\t\tthis.hideThinkingBlock = hide;\n\t\tthis.refreshContent();\n\t}\n\n\tsetHiddenThinkingLabel(label: string): void {\n\t\tif (this.hiddenThinkingLabel === label) return;\n\t\tthis.hiddenThinkingLabel = label;\n\t\tthis.refreshContent();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tif (this.expanded === expanded) return;\n\t\tthis.expanded = expanded;\n\t\tthis.refreshContent();\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tthis.renderDescriptors = [];\n\t\tthis.refreshContent();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst signature = this.lastMessageSignature ?? \"\";\n\t\tif (this.renderCache?.width === width && this.renderCache.signature === signature) {\n\t\t\treturn [...this.renderCache.lines];\n\t\t}\n\n\t\tconst lines = super.render(width);\n\t\tif (this.hasToolCalls || lines.length === 0) {\n\t\t\tthis.cacheRender(width, signature, lines);\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\tthis.cacheRender(width, signature, lines);\n\t\treturn lines;\n\t}\n\n\tupdateContent(message: AssistantMessage, isStreaming = this.isStreaming): void {\n\t\tconst previousMessage = this.lastMessage;\n\t\tconst streamingChanged = this.isStreaming !== isStreaming;\n\t\tthis.isStreaming = isStreaming;\n\t\tthis.lastMessage = message;\n\t\tconst messageSignature = this.createMessageSignature(message);\n\t\tif (!streamingChanged && previousMessage === message && this.lastMessageSignature === messageSignature) {\n\t\t\treturn;\n\t\t}\n\t\tthis.lastMessageSignature = messageSignature;\n\t\tthis.renderCache = undefined;\n\t\tif (streamingChanged) this.renderDescriptors = [];\n\t\tthis.hasToolCalls = message.content.some((content) => content.type === \"toolCall\");\n\t\tconst descriptors = createAssistantRenderDescriptors(message, {\n\t\t\texpanded: this.expanded,\n\t\t\thiddenThinkingLabel: this.hiddenThinkingLabel,\n\t\t\thideThinkingBlock: this.hideThinkingBlock,\n\t\t\thasToolCalls: this.hasToolCalls,\n\t\t});\n\t\tthis.reconcileRenderDescriptors(descriptors);\n\t}\n\n\tprivate reconcileRenderDescriptors(descriptors: readonly AssistantRenderDescriptor[]): void {\n\t\tlet divergentIndex = 0;\n\t\tconst sharedLength = Math.min(this.renderDescriptors.length, descriptors.length);\n\t\twhile (divergentIndex < sharedLength) {\n\t\t\tconst previous = this.renderDescriptors[divergentIndex];\n\t\t\tconst next = descriptors[divergentIndex];\n\t\t\tconst child = this.contentContainer.children[divergentIndex];\n\t\t\tif (!previous || !next || !child || previous.kind !== next.kind) break;\n\t\t\tif (previous.text !== next.text) {\n\t\t\t\tif ((next.kind === \"text-md\" || next.kind === \"thinking-md\") && child instanceof Markdown) {\n\t\t\t\t\tchild.setText(next.text);\n\t\t\t\t} else break;\n\t\t\t}\n\t\t\tdivergentIndex++;\n\t\t}\n\t\tfor (const child of this.contentContainer.children.splice(divergentIndex)) child.dispose?.();\n\t\tfor (const descriptor of descriptors.slice(divergentIndex))\n\t\t\tthis.contentContainer.addChild(this.createRenderChild(descriptor));\n\t\tthis.renderDescriptors = descriptors;\n\t}\n\n\tprivate createRenderChild(descriptor: AssistantRenderDescriptor): Component {\n\t\tswitch (descriptor.kind) {\n\t\t\tcase \"spacer\":\n\t\t\t\treturn new Spacer(1);\n\t\t\tcase \"text-md\":\n\t\t\t\treturn new Markdown(descriptor.text, this.outputPad, 0, this.markdownTheme, undefined, {\n\t\t\t\t\ttransform: createMarkdownTransform(\"assistant\", this.isStreaming, this.markdownTransformers),\n\t\t\t\t});\n\t\t\tcase \"thinking-md\":\n\t\t\t\treturn new Markdown(\n\t\t\t\t\tdescriptor.text,\n\t\t\t\t\tthis.outputPad,\n\t\t\t\t\t0,\n\t\t\t\t\tthis.markdownTheme,\n\t\t\t\t\t{\n\t\t\t\t\t\tcolor: (text: string) => theme.fg(\"thinkingText\", text),\n\t\t\t\t\t\titalic: true,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttransform: createMarkdownTransform(\"assistant-thinking\", this.isStreaming, this.markdownTransformers),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\tcase \"thinking-label\":\n\t\t\tcase \"error-text\":\n\t\t\t\treturn new Text(descriptor.text, this.outputPad, 0);\n\t\t\tcase \"provider-native-summary\":\n\t\t\t\treturn new Text(descriptor.text, 1, 0);\n\t\t\tcase \"provider-native-body\":\n\t\t\t\treturn new Text(descriptor.text, 3, 0);\n\t\t\tdefault:\n\t\t\t\treturn assertNever(descriptor.kind);\n\t\t}\n\t}\n\n\tprivate createMessageSignature(message: AssistantMessage): string {\n\t\treturn createBoundedRenderSignature({\n\t\t\tcontent: message.content,\n\t\t\thiddenThinkingLabel: this.hiddenThinkingLabel,\n\t\t\thideThinkingBlock: this.hideThinkingBlock,\n\t\t\terrorState: [message.diagnostics, message.errorMessage],\n\t\t\tstopReason: message.stopReason,\n\t\t});\n\t}\n\n\tprivate cacheRender(width: number, signature: string, lines: string[]): void {\n\t\tthis.renderCache = { lines: [...lines], signature, width };\n\t}\n\n\tprivate refreshContent(): void {\n\t\tif (!this.lastMessage) return;\n\t\tthis.lastMessageSignature = undefined;\n\t\tthis.updateContent(this.lastMessage);\n\t}\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { type AssistantMessage } from "@earendil-works/pi-ai";
2
+ type MarkdownDescriptorKind = "text-md" | "thinking-md";
3
+ type TextDescriptorKind = "thinking-label" | "provider-native-summary" | "provider-native-body" | "error-text";
4
+ type AssistantRenderDescriptorKind = "spacer" | MarkdownDescriptorKind | TextDescriptorKind;
5
+ export type AssistantRenderDescriptor = {
6
+ readonly kind: AssistantRenderDescriptorKind;
7
+ readonly text: string;
8
+ };
9
+ type AssistantRenderDescriptorOptions = {
10
+ readonly expanded: boolean;
11
+ readonly hiddenThinkingLabel: string;
12
+ readonly hideThinkingBlock: boolean;
13
+ readonly hasToolCalls: boolean;
14
+ };
15
+ export declare function createAssistantRenderDescriptors(message: AssistantMessage, options: AssistantRenderDescriptorOptions): readonly AssistantRenderDescriptor[];
16
+ export {};
17
+ //# sourceMappingURL=assistant-render-descriptors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant-render-descriptors.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-render-descriptors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAsC,MAAM,uBAAuB,CAAC;AAKlG,KAAK,sBAAsB,GAAG,SAAS,GAAG,aAAa,CAAC;AACxD,KAAK,kBAAkB,GAAG,gBAAgB,GAAG,yBAAyB,GAAG,sBAAsB,GAAG,YAAY,CAAC;AAC/G,KAAK,6BAA6B,GAAG,QAAQ,GAAG,sBAAsB,GAAG,kBAAkB,CAAC;AAE5F,MAAM,MAAM,yBAAyB,GAAG;IACvC,QAAQ,CAAC,IAAI,EAAE,6BAA6B,CAAC;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,KAAK,gCAAgC,GAAG;IACvC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAC/B,CAAC;AAuBF,wBAAgB,gCAAgC,CAC/C,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,gCAAgC,GACvC,SAAS,yBAAyB,EAAE,CA+GtC"}
@@ -0,0 +1,133 @@
1
+ import { SERVER_FALLBACK_ABORTED_DIAGNOSTIC } from "@earendil-works/pi-ai";
2
+ import { formatDuration } from "../../../utils/duration.js";
3
+ import { formatProviderNativeBody, formatProviderNativeSummary } from "../../provider-native-rendering.js";
4
+ import { theme } from "../theme/theme.js";
5
+ const SPACER_DESCRIPTOR = { kind: "spacer", text: "" };
6
+ function assertNever(value) {
7
+ throw new TypeError(`Unexpected assistant render variant: ${String(value)}`);
8
+ }
9
+ function isVisibleContent(content, providerNativeVisible) {
10
+ switch (content.type) {
11
+ case "text":
12
+ return Boolean(content.text.trim());
13
+ case "thinking":
14
+ return Boolean(content.thinking.trim());
15
+ case "providerNative":
16
+ return providerNativeVisible;
17
+ case "toolCall":
18
+ return false;
19
+ default:
20
+ return assertNever(content);
21
+ }
22
+ }
23
+ export function createAssistantRenderDescriptors(message, options) {
24
+ const descriptors = [];
25
+ if (message.content.some((content) => isVisibleContent(content, true)))
26
+ descriptors.push(SPACER_DESCRIPTOR);
27
+ for (let i = 0; i < message.content.length; i++) {
28
+ const content = message.content[i];
29
+ switch (content.type) {
30
+ case "text": {
31
+ const text = content.text.trim();
32
+ if (text)
33
+ descriptors.push({ kind: "text-md", text });
34
+ break;
35
+ }
36
+ case "thinking": {
37
+ const thinkingBlocks = [];
38
+ let hasTiming = false;
39
+ let isDone = true;
40
+ let minStart = Number.POSITIVE_INFINITY;
41
+ let maxEnd = Number.NEGATIVE_INFINITY;
42
+ for (; i < message.content.length; i++) {
43
+ const thinkingContent = message.content[i];
44
+ if (thinkingContent.type !== "thinking")
45
+ break;
46
+ const startedAt = thinkingContent.startedAt;
47
+ if (startedAt !== undefined) {
48
+ hasTiming = true;
49
+ minStart = Math.min(minStart, startedAt);
50
+ const endedAt = thinkingContent.endedAt;
51
+ if (endedAt === undefined) {
52
+ isDone = false;
53
+ }
54
+ else {
55
+ maxEnd = Math.max(maxEnd, endedAt);
56
+ }
57
+ }
58
+ const thinking = thinkingContent.thinking.trim();
59
+ if (thinking)
60
+ thinkingBlocks.push(thinking);
61
+ }
62
+ i--;
63
+ if (thinkingBlocks.length === 0)
64
+ break;
65
+ if (!hasTiming) {
66
+ const text = options.hideThinkingBlock
67
+ ? theme.italic(theme.fg("thinkingText", options.hiddenThinkingLabel))
68
+ : thinkingBlocks.join("\n\n");
69
+ descriptors.push({ kind: options.hideThinkingBlock ? "thinking-label" : "thinking-md", text });
70
+ }
71
+ else {
72
+ const label = isDone
73
+ ? theme.italic(theme.fg("thinkingText", `Thought: ${formatDuration(Math.max(0, maxEnd - minStart))}`))
74
+ : theme.italic(theme.fg("thinkingText", options.hiddenThinkingLabel));
75
+ if (options.hideThinkingBlock) {
76
+ descriptors.push({ kind: "thinking-label", text: label });
77
+ }
78
+ else {
79
+ descriptors.push({ kind: "thinking-label", text: label }, { kind: "thinking-md", text: thinkingBlocks.join("\n\n") });
80
+ }
81
+ }
82
+ if (message.content.slice(i + 1).some((following) => isVisibleContent(following, false)))
83
+ descriptors.push(SPACER_DESCRIPTOR);
84
+ break;
85
+ }
86
+ case "providerNative":
87
+ descriptors.push({
88
+ kind: "provider-native-summary",
89
+ text: theme.fg("muted", formatProviderNativeSummary(message, content, options.expanded)),
90
+ }, {
91
+ kind: "provider-native-body",
92
+ text: theme.fg("dim", formatProviderNativeBody(content, options.expanded)),
93
+ });
94
+ if (message.content.slice(i + 1).some((following) => isVisibleContent(following, true)))
95
+ descriptors.push(SPACER_DESCRIPTOR);
96
+ break;
97
+ case "toolCall":
98
+ break;
99
+ default:
100
+ assertNever(content);
101
+ }
102
+ }
103
+ const addError = (text) => {
104
+ descriptors.push(SPACER_DESCRIPTOR, { kind: "error-text", text: theme.fg("error", text) });
105
+ };
106
+ switch (message.stopReason) {
107
+ case "length":
108
+ addError("Error: Model stopped because it reached the maximum output token limit. The response may be incomplete.");
109
+ break;
110
+ case "aborted": {
111
+ if (options.hasToolCalls)
112
+ break;
113
+ const abortMessage = message.errorMessage && message.errorMessage !== "Request was aborted"
114
+ ? message.errorMessage
115
+ : "Operation aborted";
116
+ addError(abortMessage);
117
+ break;
118
+ }
119
+ case "error":
120
+ if (!options.hasToolCalls &&
121
+ !message.diagnostics?.some((entry) => entry.type === SERVER_FALLBACK_ABORTED_DIAGNOSTIC))
122
+ addError(`Error: ${message.errorMessage || "Unknown error"}`);
123
+ break;
124
+ case "pending":
125
+ case "stop":
126
+ case "toolUse":
127
+ break;
128
+ default:
129
+ assertNever(message.stopReason);
130
+ }
131
+ return descriptors;
132
+ }
133
+ //# sourceMappingURL=assistant-render-descriptors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant-render-descriptors.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/assistant-render-descriptors.ts"],"names":[],"mappings":"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","sourcesContent":["import { type AssistantMessage, SERVER_FALLBACK_ABORTED_DIAGNOSTIC } from \"@earendil-works/pi-ai\";\nimport { formatDuration } from \"../../../utils/duration.ts\";\nimport { formatProviderNativeBody, formatProviderNativeSummary } from \"../../provider-native-rendering.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\ntype MarkdownDescriptorKind = \"text-md\" | \"thinking-md\";\ntype TextDescriptorKind = \"thinking-label\" | \"provider-native-summary\" | \"provider-native-body\" | \"error-text\";\ntype AssistantRenderDescriptorKind = \"spacer\" | MarkdownDescriptorKind | TextDescriptorKind;\n\nexport type AssistantRenderDescriptor = {\n\treadonly kind: AssistantRenderDescriptorKind;\n\treadonly text: string;\n};\n\ntype AssistantRenderDescriptorOptions = {\n\treadonly expanded: boolean;\n\treadonly hiddenThinkingLabel: string;\n\treadonly hideThinkingBlock: boolean;\n\treadonly hasToolCalls: boolean;\n};\n\nconst SPACER_DESCRIPTOR = { kind: \"spacer\", text: \"\" } as const satisfies AssistantRenderDescriptor;\n\nfunction assertNever(value: never): never {\n\tthrow new TypeError(`Unexpected assistant render variant: ${String(value)}`);\n}\n\nfunction isVisibleContent(content: AssistantMessage[\"content\"][number], providerNativeVisible: boolean): boolean {\n\tswitch (content.type) {\n\t\tcase \"text\":\n\t\t\treturn Boolean(content.text.trim());\n\t\tcase \"thinking\":\n\t\t\treturn Boolean(content.thinking.trim());\n\t\tcase \"providerNative\":\n\t\t\treturn providerNativeVisible;\n\t\tcase \"toolCall\":\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn assertNever(content);\n\t}\n}\n\nexport function createAssistantRenderDescriptors(\n\tmessage: AssistantMessage,\n\toptions: AssistantRenderDescriptorOptions,\n): readonly AssistantRenderDescriptor[] {\n\tconst descriptors: AssistantRenderDescriptor[] = [];\n\tif (message.content.some((content) => isVisibleContent(content, true))) descriptors.push(SPACER_DESCRIPTOR);\n\tfor (let i = 0; i < message.content.length; i++) {\n\t\tconst content = message.content[i];\n\t\tswitch (content.type) {\n\t\t\tcase \"text\": {\n\t\t\t\tconst text = content.text.trim();\n\t\t\t\tif (text) descriptors.push({ kind: \"text-md\", text });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"thinking\": {\n\t\t\t\tconst thinkingBlocks: string[] = [];\n\t\t\t\tlet hasTiming = false;\n\t\t\t\tlet isDone = true;\n\t\t\t\tlet minStart = Number.POSITIVE_INFINITY;\n\t\t\t\tlet maxEnd = Number.NEGATIVE_INFINITY;\n\t\t\t\tfor (; i < message.content.length; i++) {\n\t\t\t\t\tconst thinkingContent = message.content[i];\n\t\t\t\t\tif (thinkingContent.type !== \"thinking\") break;\n\t\t\t\t\tconst startedAt = thinkingContent.startedAt;\n\t\t\t\t\tif (startedAt !== undefined) {\n\t\t\t\t\t\thasTiming = true;\n\t\t\t\t\t\tminStart = Math.min(minStart, startedAt);\n\t\t\t\t\t\tconst endedAt = thinkingContent.endedAt;\n\t\t\t\t\t\tif (endedAt === undefined) {\n\t\t\t\t\t\t\tisDone = false;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tmaxEnd = Math.max(maxEnd, endedAt);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst thinking = thinkingContent.thinking.trim();\n\t\t\t\t\tif (thinking) thinkingBlocks.push(thinking);\n\t\t\t\t}\n\t\t\t\ti--;\n\t\t\t\tif (thinkingBlocks.length === 0) break;\n\t\t\t\tif (!hasTiming) {\n\t\t\t\t\tconst text = options.hideThinkingBlock\n\t\t\t\t\t\t? theme.italic(theme.fg(\"thinkingText\", options.hiddenThinkingLabel))\n\t\t\t\t\t\t: thinkingBlocks.join(\"\\n\\n\");\n\t\t\t\t\tdescriptors.push({ kind: options.hideThinkingBlock ? \"thinking-label\" : \"thinking-md\", text });\n\t\t\t\t} else {\n\t\t\t\t\tconst label = isDone\n\t\t\t\t\t\t? theme.italic(theme.fg(\"thinkingText\", `Thought: ${formatDuration(Math.max(0, maxEnd - minStart))}`))\n\t\t\t\t\t\t: theme.italic(theme.fg(\"thinkingText\", options.hiddenThinkingLabel));\n\t\t\t\t\tif (options.hideThinkingBlock) {\n\t\t\t\t\t\tdescriptors.push({ kind: \"thinking-label\", text: label });\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdescriptors.push(\n\t\t\t\t\t\t\t{ kind: \"thinking-label\", text: label },\n\t\t\t\t\t\t\t{ kind: \"thinking-md\", text: thinkingBlocks.join(\"\\n\\n\") },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (message.content.slice(i + 1).some((following) => isVisibleContent(following, false)))\n\t\t\t\t\tdescriptors.push(SPACER_DESCRIPTOR);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"providerNative\":\n\t\t\t\tdescriptors.push(\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: \"provider-native-summary\",\n\t\t\t\t\t\ttext: theme.fg(\"muted\", formatProviderNativeSummary(message, content, options.expanded)),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: \"provider-native-body\",\n\t\t\t\t\t\ttext: theme.fg(\"dim\", formatProviderNativeBody(content, options.expanded)),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (message.content.slice(i + 1).some((following) => isVisibleContent(following, true)))\n\t\t\t\t\tdescriptors.push(SPACER_DESCRIPTOR);\n\t\t\t\tbreak;\n\t\t\tcase \"toolCall\":\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tassertNever(content);\n\t\t}\n\t}\n\tconst addError = (text: string): void => {\n\t\tdescriptors.push(SPACER_DESCRIPTOR, { kind: \"error-text\", text: theme.fg(\"error\", text) });\n\t};\n\tswitch (message.stopReason) {\n\t\tcase \"length\":\n\t\t\taddError(\n\t\t\t\t\"Error: Model stopped because it reached the maximum output token limit. The response may be incomplete.\",\n\t\t\t);\n\t\t\tbreak;\n\t\tcase \"aborted\": {\n\t\t\tif (options.hasToolCalls) break;\n\t\t\tconst abortMessage =\n\t\t\t\tmessage.errorMessage && message.errorMessage !== \"Request was aborted\"\n\t\t\t\t\t? message.errorMessage\n\t\t\t\t\t: \"Operation aborted\";\n\t\t\taddError(abortMessage);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"error\":\n\t\t\tif (\n\t\t\t\t!options.hasToolCalls &&\n\t\t\t\t!message.diagnostics?.some((entry) => entry.type === SERVER_FALLBACK_ABORTED_DIAGNOSTIC)\n\t\t\t)\n\t\t\t\taddError(`Error: ${message.errorMessage || \"Unknown error\"}`);\n\t\t\tbreak;\n\t\tcase \"pending\":\n\t\tcase \"stop\":\n\t\tcase \"toolUse\":\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassertNever(message.stopReason);\n\t}\n\treturn descriptors;\n}\n"]}
@@ -12,6 +12,47 @@
12
12
 
13
13
  ### Removed
14
14
 
15
+ ## [2026.8.7] - 2026-08-07
16
+
17
+ ### Breaking Changes
18
+
19
+ ### Added
20
+
21
+ ### Changed
22
+
23
+ ### Fixed
24
+
25
+ - Formatted completed eval durations in the simple-result transcript branch with the same compact human-readable units
26
+ used by detailed cell headers and nested tool widgets, so sub-second, seconds, minutes, and hours values render as
27
+ labels such as `<1s`, `12s`, `3m 5s`, or `1h 2m` instead of raw millisecond counts. Live footer, working-status, and
28
+ thinking-duration policies are unchanged ([#743](https://github.com/code-yeongyu/senpi/pull/743)).
29
+
30
+ ### Removed
31
+
32
+ ## [2026.8.6] - 2026-08-06
33
+
34
+ ### Breaking Changes
35
+
36
+ ### Added
37
+
38
+ ### Changed
39
+
40
+ ### Fixed
41
+
42
+ ### Removed
43
+
44
+ ## [2026.8.5-2] - 2026-08-05
45
+
46
+ ### Breaking Changes
47
+
48
+ ### Added
49
+
50
+ ### Changed
51
+
52
+ ### Fixed
53
+
54
+ ### Removed
55
+
15
56
  ## [2026.8.5] - 2026-08-05
16
57
 
17
58
  ### Breaking Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-codemode",
3
- "version": "2026.8.5",
3
+ "version": "2026.8.7",
4
4
  "description": "Source-only senpi extension package for codemode evaluation tools",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -30,14 +30,14 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@babel/parser": "8.0.4",
33
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.5",
33
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.7",
34
34
  "typebox": "1.3.8"
35
35
  },
36
36
  "peerDependencies": {
37
- "@code-yeongyu/senpi": "2026.8.5"
37
+ "@code-yeongyu/senpi": "2026.8.7"
38
38
  },
39
39
  "devDependencies": {
40
- "@code-yeongyu/senpi": "2026.8.5"
40
+ "@code-yeongyu/senpi": "2026.8.7"
41
41
  },
42
42
  "keywords": [
43
43
  "senpi",
@@ -757,7 +757,8 @@ function resultMetadata(
757
757
  ): RenderBlock[] {
758
758
  const metadata: string[] = [];
759
759
  if (details?.phase) metadata.push(`phase ${details.phase}`);
760
- if (!options.isPartial && typeof details?.durationMs === "number") metadata.push(`took ${details.durationMs}ms`);
760
+ if (!options.isPartial && typeof details?.durationMs === "number")
761
+ metadata.push(`took ${formatDuration(details.durationMs)}`);
761
762
  if (metadata.length === 0) return [];
762
763
  return [{ kind: "text", text: style(theme, "muted", metadata.join(" | ")) }];
763
764
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-agent-core",
3
3
  "private": true,
4
- "version": "2026.8.5",
4
+ "version": "2026.8.7",
5
5
  "description": "General-purpose agent with transport abstraction, state management, and attachment support",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -30,7 +30,7 @@
30
30
  "prepublishOnly": "npm run build"
31
31
  },
32
32
  "dependencies": {
33
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.5",
33
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.7",
34
34
  "diff": "9.0.0",
35
35
  "ignore": "7.0.6",
36
36
  "typebox": "1.3.8",
@@ -360,6 +360,36 @@ export declare const IMAGE_MODELS: {
360
360
  cacheWrite: number;
361
361
  };
362
362
  };
363
+ readonly "qwen/qwen-image-3": {
364
+ id: string;
365
+ name: string;
366
+ api: "openrouter-images";
367
+ provider: string;
368
+ baseUrl: string;
369
+ input: ("image" | "text")[];
370
+ output: "image"[];
371
+ cost: {
372
+ input: number;
373
+ output: number;
374
+ cacheRead: number;
375
+ cacheWrite: number;
376
+ };
377
+ };
378
+ readonly "qwen/qwen-image-3-pro": {
379
+ id: string;
380
+ name: string;
381
+ api: "openrouter-images";
382
+ provider: string;
383
+ baseUrl: string;
384
+ input: ("image" | "text")[];
385
+ output: "image"[];
386
+ cost: {
387
+ input: number;
388
+ output: number;
389
+ cacheRead: number;
390
+ cacheWrite: number;
391
+ };
392
+ };
363
393
  readonly "recraft/recraft-v3": {
364
394
  id: string;
365
395
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"image-models.generated.d.ts","sourceRoot":"","sources":["../src/image-models.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"image-models.generated.d.ts","sourceRoot":"","sources":["../src/image-models.generated.ts"],"names":[],"mappings":"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"}
@@ -362,6 +362,36 @@ export const IMAGE_MODELS = {
362
362
  cacheWrite: 0,
363
363
  },
364
364
  },
365
+ "qwen/qwen-image-3": {
366
+ id: "qwen/qwen-image-3",
367
+ name: "Qwen: Qwen Image 3",
368
+ api: "openrouter-images",
369
+ provider: "openrouter",
370
+ baseUrl: "https://openrouter.ai/api/v1",
371
+ input: ["text", "image"],
372
+ output: ["image"],
373
+ cost: {
374
+ input: 0,
375
+ output: 0,
376
+ cacheRead: 0,
377
+ cacheWrite: 0,
378
+ },
379
+ },
380
+ "qwen/qwen-image-3-pro": {
381
+ id: "qwen/qwen-image-3-pro",
382
+ name: "Qwen: Qwen Image 3 Pro",
383
+ api: "openrouter-images",
384
+ provider: "openrouter",
385
+ baseUrl: "https://openrouter.ai/api/v1",
386
+ input: ["text", "image"],
387
+ output: ["image"],
388
+ cost: {
389
+ input: 0,
390
+ output: 0,
391
+ cacheRead: 0,
392
+ cacheWrite: 0,
393
+ },
394
+ },
365
395
  "recraft/recraft-v3": {
366
396
  id: "recraft/recraft-v3",
367
397
  name: "Recraft: Recraft V3",