mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-19 18:04:41 +00:00
allow toggling visibility of the assistant's thinking block
This commit is contained in:
parent
029a04c43b
commit
590db4b6cf
4 changed files with 65 additions and 6 deletions
|
|
@ -16,6 +16,7 @@ export interface Settings {
|
||||||
queueMode?: "all" | "one-at-a-time";
|
queueMode?: "all" | "one-at-a-time";
|
||||||
theme?: string;
|
theme?: string;
|
||||||
compaction?: CompactionSettings;
|
compaction?: CompactionSettings;
|
||||||
|
hideThinkingBlock?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SettingsManager {
|
export class SettingsManager {
|
||||||
|
|
@ -143,4 +144,13 @@ export class SettingsManager {
|
||||||
keepRecentTokens: this.getCompactionKeepRecentTokens(),
|
keepRecentTokens: this.getCompactionKeepRecentTokens(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getHideThinkingBlock(): boolean {
|
||||||
|
return this.settings.hideThinkingBlock ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setHideThinkingBlock(hide: boolean): void {
|
||||||
|
this.settings.hideThinkingBlock = hide;
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,13 @@ import { getMarkdownTheme, theme } from "../theme/theme.js";
|
||||||
*/
|
*/
|
||||||
export class AssistantMessageComponent extends Container {
|
export class AssistantMessageComponent extends Container {
|
||||||
private contentContainer: Container;
|
private contentContainer: Container;
|
||||||
|
private hideThinkingBlock: boolean;
|
||||||
|
|
||||||
constructor(message?: AssistantMessage) {
|
constructor(message?: AssistantMessage, hideThinkingBlock = false) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
this.hideThinkingBlock = hideThinkingBlock;
|
||||||
|
|
||||||
// Container for text/thinking content
|
// Container for text/thinking content
|
||||||
this.contentContainer = new Container();
|
this.contentContainer = new Container();
|
||||||
this.addChild(this.contentContainer);
|
this.addChild(this.contentContainer);
|
||||||
|
|
@ -20,6 +23,10 @@ export class AssistantMessageComponent extends Container {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setHideThinkingBlock(hide: boolean): void {
|
||||||
|
this.hideThinkingBlock = hide;
|
||||||
|
}
|
||||||
|
|
||||||
updateContent(message: AssistantMessage): void {
|
updateContent(message: AssistantMessage): void {
|
||||||
// Clear content container
|
// Clear content container
|
||||||
this.contentContainer.clear();
|
this.contentContainer.clear();
|
||||||
|
|
@ -39,7 +46,7 @@ export class AssistantMessageComponent extends Container {
|
||||||
// Assistant text messages with no background - trim the text
|
// Assistant text messages with no background - trim the text
|
||||||
// Set paddingY=0 to avoid extra spacing before tool executions
|
// Set paddingY=0 to avoid extra spacing before tool executions
|
||||||
this.contentContainer.addChild(new Markdown(content.text.trim(), 1, 0, getMarkdownTheme()));
|
this.contentContainer.addChild(new Markdown(content.text.trim(), 1, 0, getMarkdownTheme()));
|
||||||
} else if (content.type === "thinking" && content.thinking.trim()) {
|
} else if (content.type === "thinking" && content.thinking.trim() && !this.hideThinkingBlock) {
|
||||||
// Thinking traces in muted color, italic
|
// Thinking traces in muted color, italic
|
||||||
// Use Markdown component with default text style for consistent styling
|
// Use Markdown component with default text style for consistent styling
|
||||||
this.contentContainer.addChild(
|
this.contentContainer.addChild(
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,15 @@ export class CustomEditor extends Editor {
|
||||||
public onShiftTab?: () => void;
|
public onShiftTab?: () => void;
|
||||||
public onCtrlP?: () => void;
|
public onCtrlP?: () => void;
|
||||||
public onCtrlO?: () => void;
|
public onCtrlO?: () => void;
|
||||||
|
public onCtrlT?: () => void;
|
||||||
|
|
||||||
handleInput(data: string): void {
|
handleInput(data: string): void {
|
||||||
|
// Intercept Ctrl+T for thinking block visibility toggle
|
||||||
|
if (data === "\x14" && this.onCtrlT) {
|
||||||
|
this.onCtrlT();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Intercept Ctrl+O for tool output expansion
|
// Intercept Ctrl+O for tool output expansion
|
||||||
if (data === "\x0f" && this.onCtrlO) {
|
if (data === "\x0f" && this.onCtrlO) {
|
||||||
this.onCtrlO();
|
this.onCtrlO();
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,9 @@ export class TuiRenderer {
|
||||||
// Tool output expansion state
|
// Tool output expansion state
|
||||||
private toolOutputExpanded = false;
|
private toolOutputExpanded = false;
|
||||||
|
|
||||||
|
// Thinking block visibility state
|
||||||
|
private hideThinkingBlock = false;
|
||||||
|
|
||||||
// Agent subscription unsubscribe function
|
// Agent subscription unsubscribe function
|
||||||
private unsubscribe?: () => void;
|
private unsubscribe?: () => void;
|
||||||
|
|
||||||
|
|
@ -211,6 +214,9 @@ export class TuiRenderer {
|
||||||
description: "Toggle automatic context compaction",
|
description: "Toggle automatic context compaction",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Load hide thinking block setting
|
||||||
|
this.hideThinkingBlock = settingsManager.getHideThinkingBlock();
|
||||||
|
|
||||||
// Load file-based slash commands
|
// Load file-based slash commands
|
||||||
this.fileCommands = loadSlashCommands();
|
this.fileCommands = loadSlashCommands();
|
||||||
|
|
||||||
|
|
@ -272,6 +278,9 @@ export class TuiRenderer {
|
||||||
theme.fg("dim", "ctrl+o") +
|
theme.fg("dim", "ctrl+o") +
|
||||||
theme.fg("muted", " to expand tools") +
|
theme.fg("muted", " to expand tools") +
|
||||||
"\n" +
|
"\n" +
|
||||||
|
theme.fg("dim", "ctrl+t") +
|
||||||
|
theme.fg("muted", " to toggle thinking") +
|
||||||
|
"\n" +
|
||||||
theme.fg("dim", "/") +
|
theme.fg("dim", "/") +
|
||||||
theme.fg("muted", " for commands") +
|
theme.fg("muted", " for commands") +
|
||||||
"\n" +
|
"\n" +
|
||||||
|
|
@ -362,6 +371,10 @@ export class TuiRenderer {
|
||||||
this.toggleToolOutputExpansion();
|
this.toggleToolOutputExpansion();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.editor.onCtrlT = () => {
|
||||||
|
this.toggleThinkingBlockVisibility();
|
||||||
|
};
|
||||||
|
|
||||||
// Handle editor submission
|
// Handle editor submission
|
||||||
this.editor.onSubmit = async (text: string) => {
|
this.editor.onSubmit = async (text: string) => {
|
||||||
text = text.trim();
|
text = text.trim();
|
||||||
|
|
@ -648,7 +661,7 @@ export class TuiRenderer {
|
||||||
this.ui.requestRender();
|
this.ui.requestRender();
|
||||||
} else if (event.message.role === "assistant") {
|
} else if (event.message.role === "assistant") {
|
||||||
// Create assistant component for streaming
|
// Create assistant component for streaming
|
||||||
this.streamingComponent = new AssistantMessageComponent();
|
this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock);
|
||||||
this.chatContainer.addChild(this.streamingComponent);
|
this.chatContainer.addChild(this.streamingComponent);
|
||||||
this.streamingComponent.updateContent(event.message as AssistantMessage);
|
this.streamingComponent.updateContent(event.message as AssistantMessage);
|
||||||
this.ui.requestRender();
|
this.ui.requestRender();
|
||||||
|
|
@ -788,7 +801,7 @@ export class TuiRenderer {
|
||||||
const assistantMsg = message;
|
const assistantMsg = message;
|
||||||
|
|
||||||
// Add assistant message component
|
// Add assistant message component
|
||||||
const assistantComponent = new AssistantMessageComponent(assistantMsg);
|
const assistantComponent = new AssistantMessageComponent(assistantMsg, this.hideThinkingBlock);
|
||||||
this.chatContainer.addChild(assistantComponent);
|
this.chatContainer.addChild(assistantComponent);
|
||||||
}
|
}
|
||||||
// Note: tool calls and results are now handled via tool_execution_start/end events
|
// Note: tool calls and results are now handled via tool_execution_start/end events
|
||||||
|
|
@ -834,7 +847,7 @@ export class TuiRenderer {
|
||||||
}
|
}
|
||||||
} else if (message.role === "assistant") {
|
} else if (message.role === "assistant") {
|
||||||
const assistantMsg = message as AssistantMessage;
|
const assistantMsg = message as AssistantMessage;
|
||||||
const assistantComponent = new AssistantMessageComponent(assistantMsg);
|
const assistantComponent = new AssistantMessageComponent(assistantMsg, this.hideThinkingBlock);
|
||||||
this.chatContainer.addChild(assistantComponent);
|
this.chatContainer.addChild(assistantComponent);
|
||||||
|
|
||||||
// Create tool execution components for any tool calls
|
// Create tool execution components for any tool calls
|
||||||
|
|
@ -918,7 +931,7 @@ export class TuiRenderer {
|
||||||
}
|
}
|
||||||
} else if (message.role === "assistant") {
|
} else if (message.role === "assistant") {
|
||||||
const assistantMsg = message;
|
const assistantMsg = message;
|
||||||
const assistantComponent = new AssistantMessageComponent(assistantMsg);
|
const assistantComponent = new AssistantMessageComponent(assistantMsg, this.hideThinkingBlock);
|
||||||
this.chatContainer.addChild(assistantComponent);
|
this.chatContainer.addChild(assistantComponent);
|
||||||
|
|
||||||
for (const content of assistantMsg.content) {
|
for (const content of assistantMsg.content) {
|
||||||
|
|
@ -1121,6 +1134,28 @@ export class TuiRenderer {
|
||||||
this.ui.requestRender();
|
this.ui.requestRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private toggleThinkingBlockVisibility(): void {
|
||||||
|
this.hideThinkingBlock = !this.hideThinkingBlock;
|
||||||
|
this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock);
|
||||||
|
|
||||||
|
// Update all assistant message components and rebuild their content
|
||||||
|
for (const child of this.chatContainer.children) {
|
||||||
|
if (child instanceof AssistantMessageComponent) {
|
||||||
|
child.setHideThinkingBlock(this.hideThinkingBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebuild chat to apply visibility change
|
||||||
|
this.chatContainer.clear();
|
||||||
|
this.rebuildChatFromMessages();
|
||||||
|
|
||||||
|
// Show brief notification
|
||||||
|
const status = this.hideThinkingBlock ? "hidden" : "visible";
|
||||||
|
this.chatContainer.addChild(new Spacer(1));
|
||||||
|
this.chatContainer.addChild(new Text(theme.fg("dim", `Thinking blocks: ${status}`), 1, 0));
|
||||||
|
this.ui.requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
clearEditor(): void {
|
clearEditor(): void {
|
||||||
this.editor.setText("");
|
this.editor.setText("");
|
||||||
this.ui.requestRender();
|
this.ui.requestRender();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue