Make the Rust client the sole app
This commit is contained in:
1 parent
a8602c1626
commit
d8bb1699a8
230 files changed
+762
-27300
No files matched your search
@@ -0,0 +1,208 @@
|
||||
use ai_app::client::QuestionOption;
|
||||
use ai_app::client::transcript_fold::{QuestionCard, TranscriptItem, TranscriptRow as FoldedRow};
|
||||
use iris::prelude::*;
|
||||
|
||||
fn main() {
|
||||
DesktopApp::<Client>::run();
|
||||
}
|
||||
|
||||
#[derive(DesktopUiState)]
|
||||
pub struct Client {
|
||||
ui_state: DesktopUiState,
|
||||
#[allow(dead_code)]
|
||||
screen: ai_app::ui::TranscriptScreen,
|
||||
}
|
||||
|
||||
fn msg(seq: u64, from_user: bool, text: &str) -> FoldedRow {
|
||||
FoldedRow::Single(if from_user {
|
||||
TranscriptItem::UserMsg {
|
||||
seq,
|
||||
text: text.to_string(),
|
||||
attachments: Vec::new(),
|
||||
}
|
||||
} else {
|
||||
TranscriptItem::AssistantMsg {
|
||||
seq,
|
||||
text: text.to_string(),
|
||||
settled: true,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn tool_call(id: &str, tool: &str, input: &str, result: Option<(&str, bool)>) -> TranscriptItem {
|
||||
tool_call_in("run1", id, tool, input, result)
|
||||
}
|
||||
|
||||
fn tool_call_in(
|
||||
run: &str,
|
||||
id: &str,
|
||||
tool: &str,
|
||||
input: &str,
|
||||
result: Option<(&str, bool)>,
|
||||
) -> TranscriptItem {
|
||||
TranscriptItem::ToolRun {
|
||||
seq: 3,
|
||||
id: id.into(),
|
||||
run_id: run.into(),
|
||||
tool: tool.into(),
|
||||
input: input.into(),
|
||||
output: result.map(|(out, _)| out.to_string()).unwrap_or_default(),
|
||||
done: result.is_some(),
|
||||
failed: result.is_some_and(|(_, failed)| failed),
|
||||
asks: Vec::new(),
|
||||
images: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn asking(id: &str, tool: &str, input: &str) -> TranscriptItem {
|
||||
let mut call = tool_call_in("run2", id, tool, input, None);
|
||||
if let TranscriptItem::ToolRun { asks, .. } = &mut call {
|
||||
asks.push(QuestionCard {
|
||||
seq: 9,
|
||||
id: format!("{id}-q"),
|
||||
prompt: "Allow this command?".into(),
|
||||
header: None,
|
||||
options: vec![
|
||||
QuestionOption {
|
||||
label: "Allow".into(),
|
||||
description: None,
|
||||
preview: None,
|
||||
},
|
||||
QuestionOption {
|
||||
label: "Deny".into(),
|
||||
description: None,
|
||||
preview: None,
|
||||
},
|
||||
],
|
||||
multi_select: false,
|
||||
answers: Vec::new(),
|
||||
});
|
||||
}
|
||||
call
|
||||
}
|
||||
|
||||
fn long_output() -> String {
|
||||
(0..200)
|
||||
.map(|i| format!("test ai_app::ui::case_{i} ... ok"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
fn synthetic_rows() -> Vec<FoldedRow> {
|
||||
vec and a fenced block:\n\n```rust\nfn main() {\n println!(\"hi\");\n}\n```",
|
||||
),
|
||||
FoldedRow::Tools(vec![
|
||||
tool_call(
|
||||
"t1",
|
||||
"Read",
|
||||
r#"{"file_path": "src/main.rs"}"#,
|
||||
Some(("fn main() {}\n", false)),
|
||||
),
|
||||
tool_call(
|
||||
"t2",
|
||||
"Bash",
|
||||
r#"{"command": "cargo build --release", "timeout": 480000, "description": "Build it"}"#,
|
||||
Some((
|
||||
"error: could not compile `iris`\nCaused by: linker not found",
|
||||
true,
|
||||
)),
|
||||
),
|
||||
tool_call("t3", "Grep", r#"{"pattern": "fn fold_event"}"#, None),
|
||||
]),
|
||||
FoldedRow::Single(tool_call(
|
||||
"t5",
|
||||
"Bash",
|
||||
r#"{"command": "cargo test -p transcript-ui -- --nocapture"}"#,
|
||||
Some((&long_output(), false)),
|
||||
)),
|
||||
msg(6, true, "Looks good, thanks!"),
|
||||
msg(7, false, BLOCK_SAMPLER),
|
||||
]
|
||||
}
|
||||
|
||||
const BLOCK_SAMPLER: &str = "\
|
||||
## What changed
|
||||
|
||||
Iris **fold** render measure session window anchor context transcript \
|
||||
iris measure iris scroll call transcript layout *cursor* context, and a \
|
||||
[bench](https://example.com/bench) link.
|
||||
|
||||
```rust
|
||||
fn fold_event(items: Vec<Item>, seq: u64) -> Vec<Item> {
|
||||
let mut out = items;
|
||||
out.push(Item::new(seq));
|
||||
out
|
||||
}
|
||||
```
|
||||
|
||||
| column | value |
|
||||
|---|---|
|
||||
| a | measure place draw tool call token context window anchor |
|
||||
|
||||
- one bullet
|
||||
- another, with `inline code`
|
||||
- nested one level
|
||||
1. first numbered
|
||||
2. second numbered
|
||||
|
||||
> A quoted line, to show the bar and the indent.
|
||||
";
|
||||
|
||||
impl DesktopAppState for Client {
|
||||
fn new(
|
||||
mut ui_state: DesktopUiState,
|
||||
rsc: &mut DesktopRsc<Self>,
|
||||
_: Proxy<Self::Event>,
|
||||
) -> Self {
|
||||
let mut screen = ai_app::ui::build(rsc, &mut ui_state, synthetic_rows());
|
||||
screen.push_row(
|
||||
rsc,
|
||||
&FoldedRow::Single(TranscriptItem::CommandRow {
|
||||
seq: 8,
|
||||
text: "clear".into(),
|
||||
}),
|
||||
);
|
||||
screen.push_row(
|
||||
rsc,
|
||||
&FoldedRow::Tools(vec![
|
||||
tool_call_in(
|
||||
"run2",
|
||||
"t6",
|
||||
"Read",
|
||||
r#"{"file_path": "docs/RUST.md"}"#,
|
||||
Some(("# Moving the app to Rust\n", false)),
|
||||
),
|
||||
tool_call_in(
|
||||
"run2",
|
||||
"t7",
|
||||
"Bash",
|
||||
r#"{"command": "cargo clippy --workspace --all-targets"}"#,
|
||||
Some(("error: unused variable `x`", true)),
|
||||
),
|
||||
tool_call_in("run2", "t8", "Glob", r#"{"pattern": "**/*.rs"}"#, None),
|
||||
asking(
|
||||
"t9",
|
||||
"Bash",
|
||||
r#"{"command": "rm -rf target", "timeout": 120000, "description": "Clear the build"}"#,
|
||||
),
|
||||
]),
|
||||
);
|
||||
screen.set_session_working(rsc, true);
|
||||
if std::env::var_os("IRIS_TOOLS_EXPANDED").is_some() {
|
||||
assert!(
|
||||
screen.expand_tail_tools(rsc, true),
|
||||
"the newest row must be the tool run this flag is about"
|
||||
);
|
||||
}
|
||||
Self { ui_state, screen }
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user