mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 21:03:56 +00:00
Add thinking trace support and improve bash output formatting
- Render thinking traces in dark gray italic in final messages - Show thinking as italic markdown in streaming view - Remove code fences from bash output for cleaner minimal display - Remove superfluous empty line after tool executions - Thinking blocks now render inline in proper order with text
This commit is contained in:
parent
8fa780e052
commit
ea5097e13e
1 changed files with 41 additions and 26 deletions
|
|
@ -66,13 +66,24 @@ class StreamingMessageComponent extends Container {
|
||||||
if (message.role === "assistant") {
|
if (message.role === "assistant") {
|
||||||
const assistantMsg = message as AssistantMessage;
|
const assistantMsg = message as AssistantMessage;
|
||||||
|
|
||||||
// Update text content
|
// Update text and thinking content
|
||||||
const textContent = assistantMsg.content
|
let combinedContent = "";
|
||||||
.filter((c) => c.type === "text")
|
for (const c of assistantMsg.content) {
|
||||||
.map((c) => c.text)
|
if (c.type === "text") {
|
||||||
.join("");
|
combinedContent += c.text;
|
||||||
|
} else if (c.type === "thinking") {
|
||||||
|
// Add thinking in italic
|
||||||
|
const thinkingLines = c.thinking
|
||||||
|
.split("\n")
|
||||||
|
.map((line) => `*${line}*`)
|
||||||
|
.join("\n");
|
||||||
|
if (combinedContent && !combinedContent.endsWith("\n")) combinedContent += "\n";
|
||||||
|
combinedContent += thinkingLines;
|
||||||
|
if (!combinedContent.endsWith("\n")) combinedContent += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.markdown.setText(textContent);
|
this.markdown.setText(combinedContent);
|
||||||
|
|
||||||
// Update usage stats
|
// Update usage stats
|
||||||
const usage = assistantMsg.usage;
|
const usage = assistantMsg.usage;
|
||||||
|
|
@ -140,16 +151,19 @@ class ToolExecutionComponent extends Container {
|
||||||
const command = this.args.command || "";
|
const command = this.args.command || "";
|
||||||
text = `**$ ${command}**`;
|
text = `**$ ${command}**`;
|
||||||
if (this.result) {
|
if (this.result) {
|
||||||
const lines = this.result.output.split("\n");
|
// Show output without code fences - more minimal
|
||||||
const maxLines = 5;
|
const output = this.result.output.trim();
|
||||||
const displayLines = lines.slice(0, maxLines);
|
if (output) {
|
||||||
const remaining = lines.length - maxLines;
|
const lines = output.split("\n");
|
||||||
|
const maxLines = 5;
|
||||||
|
const displayLines = lines.slice(0, maxLines);
|
||||||
|
const remaining = lines.length - maxLines;
|
||||||
|
|
||||||
text += "\n```\n" + displayLines.join("\n");
|
text += "\n" + displayLines.join("\n");
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
text += `\n... (${remaining} more lines)`;
|
text += `\n... (${remaining} more lines)`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
text += "\n```";
|
|
||||||
|
|
||||||
if (this.result.isError) {
|
if (this.result.isError) {
|
||||||
text += " ❌";
|
text += " ❌";
|
||||||
|
|
@ -504,8 +518,6 @@ export class TuiRenderer {
|
||||||
output: typeof event.result === "string" ? event.result : event.result.output,
|
output: typeof event.result === "string" ? event.result : event.result.output,
|
||||||
isError: event.isError,
|
isError: event.isError,
|
||||||
});
|
});
|
||||||
// Add empty line after tool execution
|
|
||||||
this.chatContainer.addChild(new Text("", 0, 0));
|
|
||||||
this.pendingTools.delete(event.toolCallId);
|
this.pendingTools.delete(event.toolCallId);
|
||||||
|
|
||||||
// Check if this was part of deferred stats and all tools are complete
|
// Check if this was part of deferred stats and all tools are complete
|
||||||
|
|
@ -555,14 +567,19 @@ export class TuiRenderer {
|
||||||
} else if (message.role === "assistant") {
|
} else if (message.role === "assistant") {
|
||||||
const assistantMsg = message as AssistantMessage;
|
const assistantMsg = message as AssistantMessage;
|
||||||
|
|
||||||
// Render text content first (tool calls handled by events)
|
// Render content in order
|
||||||
const textContent = assistantMsg.content
|
for (const content of assistantMsg.content) {
|
||||||
.filter((c) => c.type === "text")
|
if (content.type === "text" && content.text.trim()) {
|
||||||
.map((c) => c.text)
|
// Assistant text messages with no background
|
||||||
.join("");
|
this.chatContainer.addChild(new Markdown(content.text));
|
||||||
if (textContent) {
|
} else if (content.type === "thinking" && content.thinking.trim()) {
|
||||||
// Assistant messages with no background
|
// Thinking traces in dark gray italic
|
||||||
this.chatContainer.addChild(new Markdown(textContent));
|
const thinkingText = content.thinking
|
||||||
|
.split("\n")
|
||||||
|
.map((line) => chalk.gray.italic(line))
|
||||||
|
.join("\n");
|
||||||
|
this.chatContainer.addChild(new Text(thinkingText, 1, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if aborted - show after partial content
|
// Check if aborted - show after partial content
|
||||||
|
|
@ -688,8 +705,6 @@ export class TuiRenderer {
|
||||||
isError: toolResultMsg.isError,
|
isError: toolResultMsg.isError,
|
||||||
});
|
});
|
||||||
this.chatContainer.addChild(component);
|
this.chatContainer.addChild(component);
|
||||||
// Add empty line after tool execution
|
|
||||||
this.chatContainer.addChild(new Text("", 0, 0));
|
|
||||||
|
|
||||||
// Check if this was the last tool call for this assistant message
|
// Check if this was the last tool call for this assistant message
|
||||||
const assistantData = assistantWithTools.get(assistantMsgIndex);
|
const assistantData = assistantWithTools.get(assistantMsgIndex);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue