mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-07 08:27:12 +00:00
Switch LLM chat input to dialoguer and use ColorfulTheme everywhere
Replace raw stdin.lock().lines() in run_chat with dialoguer::Input using spawn_blocking for TTY, with a stdin fallback for non-TTY. Apply ColorfulTheme::default() to all dialoguer widgets in both arc-llm and arc-workflows ConsoleInterviewer. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
859da7d035
commit
d101892bdf
3 changed files with 31 additions and 15 deletions
|
|
@ -28,6 +28,7 @@ base64.workspace = true
|
|||
bytes.workspace = true
|
||||
tokio-util.workspace = true
|
||||
clap.workspace = true
|
||||
dialoguer.workspace = true
|
||||
tracing.workspace = true
|
||||
arc-util = { path = "../arc-util" }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
use std::io::{self, BufRead, IsTerminal, Read, Write};
|
||||
use std::io::{self, IsTerminal, Read, Write};
|
||||
|
||||
use dialoguer::console::Term;
|
||||
use dialoguer::theme::ColorfulTheme;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
|
@ -221,17 +224,28 @@ pub async fn run_chat(args: ChatArgs) -> Result<()> {
|
|||
eprintln!("Using model: {model_id}");
|
||||
|
||||
let mut messages: Vec<Message> = Vec::new();
|
||||
let stdin = io::stdin();
|
||||
let mut lines = stdin.lock().lines();
|
||||
let is_tty = io::stdin().is_terminal();
|
||||
|
||||
loop {
|
||||
eprint!("> ");
|
||||
io::stderr().flush()?;
|
||||
|
||||
let line = match lines.next() {
|
||||
Some(Ok(line)) => line,
|
||||
Some(Err(e)) => return Err(e.into()),
|
||||
None => break, // EOF
|
||||
let line = if is_tty {
|
||||
let result = tokio::task::spawn_blocking(|| {
|
||||
dialoguer::Input::<String>::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt(">")
|
||||
.interact_on(&Term::stderr())
|
||||
})
|
||||
.await?;
|
||||
match result {
|
||||
Ok(line) => line,
|
||||
Err(_) => break,
|
||||
}
|
||||
} else {
|
||||
eprint!("> ");
|
||||
io::stderr().flush()?;
|
||||
let mut buf = String::new();
|
||||
if io::stdin().read_line(&mut buf)? == 0 {
|
||||
break;
|
||||
}
|
||||
buf.trim_end().to_string()
|
||||
};
|
||||
|
||||
let trimmed = line.trim();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::io::IsTerminal;
|
|||
use arc_util::terminal::Styles;
|
||||
use async_trait::async_trait;
|
||||
use dialoguer::console::Term;
|
||||
use dialoguer::theme::ColorfulTheme;
|
||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||
|
||||
use super::{Answer, AnswerValue, Interviewer, Question, QuestionType};
|
||||
|
|
@ -69,7 +70,7 @@ fn ask_select_interactive(question: &Question) -> Answer {
|
|||
all_items.push("Other (free text)...".to_string());
|
||||
}
|
||||
|
||||
let selection = dialoguer::Select::new()
|
||||
let selection = dialoguer::Select::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt(&question.text)
|
||||
.items(&all_items)
|
||||
.default(0)
|
||||
|
|
@ -78,7 +79,7 @@ fn ask_select_interactive(question: &Question) -> Answer {
|
|||
match selection {
|
||||
Ok(Some(idx)) if has_freeform && idx == question.options.len() => {
|
||||
// User chose the free-text option
|
||||
dialoguer::Input::<String>::new()
|
||||
dialoguer::Input::<String>::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt("Enter your response")
|
||||
.interact_on(&Term::stderr())
|
||||
.map_or_else(|_| Answer::skipped(), Answer::text)
|
||||
|
|
@ -103,7 +104,7 @@ fn ask_multi_select_interactive(question: &Question) -> Answer {
|
|||
.map(|opt| format!("{} - {}", opt.key, opt.label))
|
||||
.collect();
|
||||
|
||||
let selection = dialoguer::MultiSelect::new()
|
||||
let selection = dialoguer::MultiSelect::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt(&question.text)
|
||||
.items(&items)
|
||||
.interact_on_opt(&Term::stderr());
|
||||
|
|
@ -124,7 +125,7 @@ fn ask_multi_select_interactive(question: &Question) -> Answer {
|
|||
|
||||
/// Ask a yes/no or confirmation question using dialoguer's `Confirm` widget on a TTY.
|
||||
fn ask_confirm_interactive(question: &Question) -> Answer {
|
||||
let confirmed = dialoguer::Confirm::new()
|
||||
let confirmed = dialoguer::Confirm::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt(&question.text)
|
||||
.default(true)
|
||||
.interact_on_opt(&Term::stderr());
|
||||
|
|
@ -137,7 +138,7 @@ fn ask_confirm_interactive(question: &Question) -> Answer {
|
|||
|
||||
/// Ask a freeform question using dialoguer's `Input` widget on a TTY.
|
||||
fn ask_freeform_interactive(question: &Question) -> Answer {
|
||||
dialoguer::Input::<String>::new()
|
||||
dialoguer::Input::<String>::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt(&question.text)
|
||||
.interact_on(&Term::stderr())
|
||||
.map_or_else(|_| Answer::skipped(), Answer::text)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue