Add thinking level persistence and fix UI issues
- Save and restore thinking level when continuing sessions - Fix thinking level confirmation message spacing and styling - Fix thinking text wrapping to preserve ANSI formatting across lines
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Agent, ProviderTransport } from "@mariozechner/pi-agent";
|
import { Agent, ProviderTransport, type ThinkingLevel } from "@mariozechner/pi-agent";
|
||||||
import { getModel } from "@mariozechner/pi-ai";
|
import { getModel } from "@mariozechner/pi-ai";
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
@@ -227,6 +227,13 @@ export async function main(args: string[]) {
|
|||||||
console.log(chalk.dim(`Loaded ${messages.length} messages from previous session`));
|
console.log(chalk.dim(`Loaded ${messages.length} messages from previous session`));
|
||||||
agent.replaceMessages(messages);
|
agent.replaceMessages(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load and restore thinking level
|
||||||
|
const thinkingLevel = sessionManager.loadThinkingLevel() as ThinkingLevel;
|
||||||
|
if (thinkingLevel && thinkingLevel !== "off") {
|
||||||
|
agent.setThinkingLevel(thinkingLevel);
|
||||||
|
console.log(chalk.dim(`Restored thinking level: ${thinkingLevel}`));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start session
|
// Start session
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export interface SessionHeader {
|
|||||||
cwd: string;
|
cwd: string;
|
||||||
systemPrompt: string;
|
systemPrompt: string;
|
||||||
model: string;
|
model: string;
|
||||||
|
thinkingLevel: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SessionMessageEntry {
|
export interface SessionMessageEntry {
|
||||||
@@ -115,6 +116,7 @@ export class SessionManager {
|
|||||||
cwd: process.cwd(),
|
cwd: process.cwd(),
|
||||||
systemPrompt: state.systemPrompt,
|
systemPrompt: state.systemPrompt,
|
||||||
model: `${state.model.provider}/${state.model.id}`,
|
model: `${state.model.provider}/${state.model.id}`,
|
||||||
|
thinkingLevel: state.thinkingLevel,
|
||||||
};
|
};
|
||||||
appendFileSync(this.sessionFile, JSON.stringify(entry) + "\n");
|
appendFileSync(this.sessionFile, JSON.stringify(entry) + "\n");
|
||||||
}
|
}
|
||||||
@@ -157,6 +159,27 @@ export class SessionManager {
|
|||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadThinkingLevel(): string {
|
||||||
|
if (!existsSync(this.sessionFile)) return "off";
|
||||||
|
|
||||||
|
const lines = readFileSync(this.sessionFile, "utf8").trim().split("\n");
|
||||||
|
|
||||||
|
// Find the most recent session header with thinking level
|
||||||
|
let lastThinkingLevel = "off";
|
||||||
|
for (const line of lines) {
|
||||||
|
try {
|
||||||
|
const entry = JSON.parse(line);
|
||||||
|
if (entry.type === "session" && entry.thinkingLevel) {
|
||||||
|
lastThinkingLevel = entry.thinkingLevel;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Skip malformed lines
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastThinkingLevel;
|
||||||
|
}
|
||||||
|
|
||||||
getSessionId(): string {
|
getSessionId(): string {
|
||||||
return this.sessionId;
|
return this.sessionId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ export class AssistantMessageComponent extends Container {
|
|||||||
this.contentContainer.addChild(new Markdown(content.text.trim(), undefined, undefined, undefined, 1, 0));
|
this.contentContainer.addChild(new Markdown(content.text.trim(), undefined, undefined, undefined, 1, 0));
|
||||||
} else if (content.type === "thinking" && content.thinking.trim()) {
|
} else if (content.type === "thinking" && content.thinking.trim()) {
|
||||||
// Thinking traces in dark gray italic
|
// Thinking traces in dark gray italic
|
||||||
// Apply styling to entire block so wrapping preserves it
|
// Use Markdown component because it preserves ANSI codes across wrapped lines
|
||||||
const thinkingText = chalk.gray.italic(content.thinking);
|
const thinkingText = chalk.gray.italic(content.thinking);
|
||||||
this.contentContainer.addChild(new Text(thinkingText, 1, 0));
|
this.contentContainer.addChild(new Markdown(thinkingText, undefined, undefined, undefined, 1, 0));
|
||||||
this.contentContainer.addChild(new Spacer(1));
|
this.contentContainer.addChild(new Spacer(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ export class TuiRenderer {
|
|||||||
// Setup UI layout
|
// Setup UI layout
|
||||||
this.ui.addChild(new Spacer(1));
|
this.ui.addChild(new Spacer(1));
|
||||||
this.ui.addChild(header);
|
this.ui.addChild(header);
|
||||||
|
this.ui.addChild(new Spacer(1));
|
||||||
this.ui.addChild(this.chatContainer);
|
this.ui.addChild(this.chatContainer);
|
||||||
this.ui.addChild(this.statusContainer);
|
this.ui.addChild(this.statusContainer);
|
||||||
this.ui.addChild(new Spacer(1));
|
this.ui.addChild(new Spacer(1));
|
||||||
@@ -377,11 +378,10 @@ export class TuiRenderer {
|
|||||||
// Apply the selected thinking level
|
// Apply the selected thinking level
|
||||||
this.agent.setThinkingLevel(level);
|
this.agent.setThinkingLevel(level);
|
||||||
|
|
||||||
// Show confirmation message with padding and blue color
|
// Show confirmation message with proper spacing
|
||||||
this.chatContainer.addChild(new Text("", 0, 0)); // Blank line before
|
this.chatContainer.addChild(new Spacer(1));
|
||||||
const confirmText = new Text(chalk.blue(`Thinking level set to: ${level}`), 0, 0);
|
const confirmText = new Text(chalk.dim(`Thinking level: ${level}`), 1, 0);
|
||||||
this.chatContainer.addChild(confirmText);
|
this.chatContainer.addChild(confirmText);
|
||||||
this.chatContainer.addChild(new Text("", 0, 0)); // Blank line after
|
|
||||||
|
|
||||||
// Hide selector and show editor again
|
// Hide selector and show editor again
|
||||||
this.hideThinkingSelector();
|
this.hideThinkingSelector();
|
||||||
|
|||||||
Reference in New Issue
Block a user