first commit
This commit is contained in:
commit
91b44fcc16
27 files changed
+4104
No files matched your search
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "agent-tui"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
agent-core = { path = "../agent-core" }
|
||||
crossterm = { workspace = true }
|
||||
ratatui = { workspace = true }
|
||||
color-eyre = { workspace = true }
|
||||
dotenvy = { workspace = true }
|
||||
@@ -0,0 +1,13 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use agent_core::ReActAgent;
|
||||
use agent_providers::ChatCompletionsProvider;
|
||||
use agent_tui::App;
|
||||
use color_eyre::eyre::Ok;
|
||||
|
||||
fn main() -> color_eyre::Result<()> {
|
||||
color_eyre::install()?;
|
||||
let app = App::default();
|
||||
app.run()?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
mod ui;
|
||||
pub use ui::App;
|
||||
|
||||
pub fn add(left: u64, right: u64) -> u64 {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use crossterm::event::{Event, KeyCode, KeyEvent};
|
||||
use ratatui::{
|
||||
Frame,
|
||||
layout::{Constraint, Direction, Layout},
|
||||
text::Line,
|
||||
widgets::{Block, List, ListItem, Paragraph},
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct App {
|
||||
messages: Vec<Message>,
|
||||
input: String,
|
||||
pending: bool,
|
||||
}
|
||||
|
||||
struct Message {
|
||||
role: Role,
|
||||
content: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum Role {
|
||||
System,
|
||||
User,
|
||||
Assistant,
|
||||
Tool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum Flow {
|
||||
Continue,
|
||||
Quit,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
messages: vec![Message {
|
||||
role: Role::System,
|
||||
content: "hi there ~".into(),
|
||||
}],
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resume(messages: Vec<Message>) -> Self {
|
||||
Self {
|
||||
messages,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(mut self, act: ) -> std::io::Result<()> {
|
||||
ratatui::run(|terminal| {
|
||||
loop {
|
||||
terminal.draw(|frame| self.render(frame))?;
|
||||
if crossterm::event::poll(Duration::from_millis(16))? {
|
||||
match crossterm::event::read()? {
|
||||
Event::Key(key) => {
|
||||
if self.handle_key(key) == Flow::Quit {
|
||||
break Ok(());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn handle_key(&mut self, key: KeyEvent) -> Flow {
|
||||
match key.code {
|
||||
KeyCode::Esc => Flow::Quit,
|
||||
KeyCode::Backspace => {
|
||||
self.input.pop();
|
||||
Flow::Continue
|
||||
}
|
||||
KeyCode::Char(ch) => {
|
||||
self.input.push(ch);
|
||||
Flow::Continue
|
||||
}
|
||||
KeyCode::Enter => {
|
||||
self.submit();
|
||||
Flow::Continue
|
||||
}
|
||||
_ => Flow::Continue,
|
||||
}
|
||||
}
|
||||
|
||||
fn submit(&mut self) {
|
||||
self.messages.push(Message {
|
||||
role: Role::User,
|
||||
content: self.input.clone(),
|
||||
});
|
||||
self.input.clear();
|
||||
}
|
||||
|
||||
fn render(&self, frame: &mut Frame) {
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([
|
||||
Constraint::Length(3),
|
||||
Constraint::Min(0),
|
||||
Constraint::Length(3),
|
||||
])
|
||||
.split(frame.area());
|
||||
|
||||
let header = Paragraph::new("Agent Chat").block(Block::bordered().title("Title"));
|
||||
frame.render_widget(header, chunks[0]);
|
||||
|
||||
let items: Vec<ListItem> = self
|
||||
.messages
|
||||
.iter()
|
||||
.map(|msg| {
|
||||
let name = match msg.role {
|
||||
Role::System => "System",
|
||||
Role::User => "User",
|
||||
Role::Assistant => "Assistant",
|
||||
Role::Tool => "Tool",
|
||||
};
|
||||
|
||||
let mut lines = vec![Line::from(name)];
|
||||
for line in msg.content.lines() {
|
||||
lines.push(Line::from(line));
|
||||
}
|
||||
|
||||
ListItem::new(lines)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let messages = List::new(items).block(Block::bordered().title("Messages"));
|
||||
frame.render_widget(messages, chunks[1]);
|
||||
|
||||
let input = Paragraph::new(self.input.as_str()).block(Block::bordered().title("Input"));
|
||||
frame.render_widget(input, chunks[2]);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user