mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-16 16:00:58 +00:00
Add interactive UI selector for /thinking command
- /thinking now opens a SelectList UI component to choose thinking level - Temporarily replaces the editor with the selector - Shows 5 levels (off, minimal, low, medium, high) with descriptions - Supports keyboard navigation (arrows, enter, escape) - Shows confirmation message after selection - Maintains backward compatibility with /thinking <level> direct syntax
This commit is contained in:
parent
71fb1b9173
commit
ba8d802999
1 changed files with 64 additions and 13 deletions
|
|
@ -8,6 +8,8 @@ import {
|
|||
Loader,
|
||||
Markdown,
|
||||
ProcessTerminal,
|
||||
type SelectItem,
|
||||
SelectList,
|
||||
Text,
|
||||
TUI,
|
||||
} from "@mariozechner/pi-tui";
|
||||
|
|
@ -283,6 +285,7 @@ export class TuiRenderer {
|
|||
private chatContainer: Container;
|
||||
private statusContainer: Container;
|
||||
private editor: CustomEditor;
|
||||
private editorContainer: Container; // Container to swap between editor and selector
|
||||
private footer: FooterComponent;
|
||||
private agent: Agent;
|
||||
private version: string;
|
||||
|
|
@ -301,6 +304,9 @@ export class TuiRenderer {
|
|||
// Track assistant message with tool calls that needs stats shown after tools complete
|
||||
private deferredStats: { usage: any; toolCallIds: Set<string> } | null = null;
|
||||
|
||||
// Thinking level selector
|
||||
private thinkingSelector: SelectList | null = null;
|
||||
|
||||
constructor(agent: Agent, version: string) {
|
||||
this.agent = agent;
|
||||
this.version = version;
|
||||
|
|
@ -308,22 +314,14 @@ export class TuiRenderer {
|
|||
this.chatContainer = new Container();
|
||||
this.statusContainer = new Container();
|
||||
this.editor = new CustomEditor();
|
||||
this.editorContainer = new Container(); // Container to hold editor or selector
|
||||
this.editorContainer.addChild(this.editor); // Start with editor
|
||||
this.footer = new FooterComponent(agent.state);
|
||||
|
||||
// Define slash commands
|
||||
const thinkingCommand: SlashCommand = {
|
||||
name: "thinking",
|
||||
description: "Set reasoning level (off, minimal, low, medium, high)",
|
||||
getArgumentCompletions: (argumentPrefix: string) => {
|
||||
const levels = ["off", "minimal", "low", "medium", "high"];
|
||||
return levels
|
||||
.filter((level) => level.toLowerCase().startsWith(argumentPrefix.toLowerCase()))
|
||||
.map((level) => ({
|
||||
value: level,
|
||||
label: level,
|
||||
description: `Set thinking level to ${level}`,
|
||||
}));
|
||||
},
|
||||
description: "Select reasoning level (opens selector UI)",
|
||||
};
|
||||
|
||||
// Setup autocomplete for file paths and slash commands
|
||||
|
|
@ -357,7 +355,7 @@ export class TuiRenderer {
|
|||
this.ui.addChild(header);
|
||||
this.ui.addChild(this.chatContainer);
|
||||
this.ui.addChild(this.statusContainer);
|
||||
this.ui.addChild(this.editor);
|
||||
this.ui.addChild(this.editorContainer); // Use container that can hold editor or selector
|
||||
this.ui.addChild(this.footer);
|
||||
this.ui.setFocus(this.editor);
|
||||
|
||||
|
|
@ -378,7 +376,15 @@ export class TuiRenderer {
|
|||
text = text.trim();
|
||||
if (!text) return;
|
||||
|
||||
// Check for slash commands
|
||||
// Check for /thinking command
|
||||
if (text === "/thinking") {
|
||||
// Show thinking level selector
|
||||
this.showThinkingSelector();
|
||||
this.editor.setText("");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for /thinking with argument (direct set)
|
||||
if (text.startsWith("/thinking ")) {
|
||||
const level = text.slice("/thinking ".length).trim() as ThinkingLevel;
|
||||
const validLevels: ThinkingLevel[] = ["off", "minimal", "low", "medium", "high"];
|
||||
|
|
@ -731,6 +737,51 @@ export class TuiRenderer {
|
|||
this.ui.requestRender();
|
||||
}
|
||||
|
||||
private showThinkingSelector(): void {
|
||||
const thinkingLevels: SelectItem[] = [
|
||||
{ value: "off", label: "off", description: "No reasoning" },
|
||||
{ value: "minimal", label: "minimal", description: "Very brief reasoning (~1k tokens)" },
|
||||
{ value: "low", label: "low", description: "Light reasoning (~2k tokens)" },
|
||||
{ value: "medium", label: "medium", description: "Moderate reasoning (~8k tokens)" },
|
||||
{ value: "high", label: "high", description: "Deep reasoning (~16k tokens)" },
|
||||
];
|
||||
|
||||
this.thinkingSelector = new SelectList(thinkingLevels, 5);
|
||||
this.thinkingSelector.onSelect = (item) => {
|
||||
// Apply the selected thinking level
|
||||
const level = item.value as ThinkingLevel;
|
||||
this.agent.setThinkingLevel(level);
|
||||
|
||||
// Show confirmation message
|
||||
const confirmText = new Text(chalk.dim(`Thinking level set to: ${level}`), 1, 0);
|
||||
this.chatContainer.addChild(confirmText);
|
||||
|
||||
// Hide selector and show editor again
|
||||
this.hideThinkingSelector();
|
||||
this.ui.requestRender();
|
||||
};
|
||||
|
||||
this.thinkingSelector.onCancel = () => {
|
||||
// Just hide the selector
|
||||
this.hideThinkingSelector();
|
||||
this.ui.requestRender();
|
||||
};
|
||||
|
||||
// Replace editor with selector in the container
|
||||
this.editorContainer.clear();
|
||||
this.editorContainer.addChild(this.thinkingSelector);
|
||||
this.ui.setFocus(this.thinkingSelector);
|
||||
this.ui.requestRender();
|
||||
}
|
||||
|
||||
private hideThinkingSelector(): void {
|
||||
// Replace selector with editor in the container
|
||||
this.editorContainer.clear();
|
||||
this.editorContainer.addChild(this.editor);
|
||||
this.thinkingSelector = null;
|
||||
this.ui.setFocus(this.editor);
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
if (this.loadingAnimation) {
|
||||
this.loadingAnimation.stop();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue