feat(code): friendly errors, batch history, persistent command history

- Agent errors sanitized: raw hyper/h2/gRPC dumps replaced with
  human-readable messages ("sol disconnected", "connection lost", etc.)
- Batch history loading: single viewport rebuild instead of per-entry
- Persistent command history: saved to .sunbeam/history, loaded on start
- Default model: mistral-medium-latest (personality adherence)
This commit is contained in:
2026-03-23 17:08:24 +00:00
parent 8b4f187d1b
commit d7c5a677da
5 changed files with 329 additions and 17 deletions

View File

@@ -82,7 +82,7 @@ async fn cmd_code_inner(cmd: Option<CodeCommand>) -> anyhow::Result<()> {
let model = model
.or(cfg.model_name.clone())
.unwrap_or_else(|| "devstral-small-latest".into());
.unwrap_or_else(|| "mistral-medium-latest".into());
// Connect to Sol
let mut session = client::connect(&endpoint, &project, &cfg, &model).await?;
@@ -104,7 +104,7 @@ async fn cmd_code_inner(cmd: Option<CodeCommand>) -> anyhow::Result<()> {
// Spawn agent on background task
let project_path = project.path.clone();
let agent = agent::spawn(session);
let agent = agent::spawn(session, endpoint.clone());
// TUI event loop — never blocks on network I/O
use crossterm::event::{self, Event, KeyCode, KeyModifiers, MouseEventKind};
@@ -160,6 +160,12 @@ async fn cmd_code_inner(cmd: Option<CodeCommand>) -> anyhow::Result<()> {
app.sol_status.clear();
app.push_log(tui::LogEntry::Error(message));
}
agent::AgentEvent::Health { connected } => {
if app.sol_connected != connected {
app.sol_connected = connected;
app.needs_redraw = true;
}
}
agent::AgentEvent::SessionEnded => {
break;
}