Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 84 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ strip = true
anyhow = "1.0.99"
async-recursion = "1.1.1"
async-trait = "0.1.89"

axum = "0.7.5"
tower-http = "0.5.2"
aws-config = { version = "1.8.12", features = ["behavior-version-latest"], default-features = false }
aws-sdk-bedrockruntime = { version = "1.120.0", features = ["behavior-version-latest"], default-features = false }
aws-smithy-types = "1.3"
Expand Down
65 changes: 65 additions & 0 deletions crates/paws_app/src/agent_protocol_service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use std::collections::HashMap;
use std::sync::Arc;

use anyhow::Result;
use paws_domain::{Step, StepInput, Task};
use tokio::sync::RwLock;

pub struct AgentProtocolService {
tasks: Arc<RwLock<HashMap<String, Task>>>,
steps: Arc<RwLock<HashMap<String, Vec<Step>>>>,
}

impl AgentProtocolService {
pub fn new() -> Self {
Self {
tasks: Arc::new(RwLock::new(HashMap::new())),
steps: Arc::new(RwLock::new(HashMap::new())),
}
}

pub async fn create_task(&self, input: String) -> Task {
let task = Task::new(input);
let mut tasks = self.tasks.write().await;
tasks.insert(task.task_id.clone(), task.clone());
task
}

pub async fn list_tasks(&self) -> Vec<Task> {
let tasks = self.tasks.read().await;
tasks.values().cloned().collect()
}

pub async fn get_task(&self, task_id: &str) -> Option<Task> {
let tasks = self.tasks.read().await;
tasks.get(task_id).cloned()
}

pub async fn list_steps(&self, task_id: &str) -> Vec<Step> {
let steps = self.steps.read().await;
steps.get(task_id).cloned().unwrap_or_default()
}

pub async fn create_step(&self, task_id: &str, input: StepInput) -> Result<Step> {
let mut steps_guard = self.steps.write().await;
let task_steps = steps_guard.entry(task_id.to_string()).or_default();

let step = Step::new(task_id.to_string(), input.input, true);
task_steps.push(step.clone());

Ok(step)
}

pub async fn get_step(&self, task_id: &str, step_id: &str) -> Option<Step> {
let steps = self.steps.read().await;
steps
.get(task_id)
.and_then(|steps| steps.iter().find(|s| s.step_id == step_id).cloned())
}
}

impl Default for AgentProtocolService {
fn default() -> Self {
Self::new()
}
}
3 changes: 3 additions & 0 deletions crates/paws_app/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod agent;
mod agent_executor;
pub mod agent_protocol_service;
mod agent_provider_resolver;
mod app;
mod apply_tunable_parameters;
Expand Down Expand Up @@ -39,6 +40,8 @@ pub mod utils;
mod walker;

pub use agent::*;
pub use agent_executor::*;
pub use agent_protocol_service::*;
pub use agent_provider_resolver::*;
pub use app::*;
pub use command_generator::*;
Expand Down
73 changes: 73 additions & 0 deletions crates/paws_domain/src/agent_protocol.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Task {
pub task_id: String,
pub input: String,
pub artifacts: Vec<Artifact>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskInput {
pub input: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Step {
pub task_id: String,
pub step_id: String,
pub name: Option<String>,
pub input: Option<String>,
pub output: Option<String>,
pub status: StepStatus,
pub is_last: bool,
pub artifacts: Vec<Artifact>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum StepStatus {
Created,
Running,
Completed,
Failed,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StepInput {
pub name: Option<String>,
pub input: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Artifact {
pub artifact_id: String,
pub file_name: String,
pub relative_path: Option<String>,
}

impl Task {
pub fn new(input: String) -> Self {
Self {
task_id: Uuid::new_v4().to_string(),
input,
artifacts: Vec::new(),
}
}
}

impl Step {
pub fn new(task_id: String, input: Option<String>, is_last: bool) -> Self {
Self {
task_id,
step_id: Uuid::new_v4().to_string(),
name: None,
input,
output: None,
status: StepStatus::Created,
is_last,
artifacts: Vec::new(),
}
}
}
2 changes: 2 additions & 0 deletions crates/paws_domain/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod agent;
mod agent_definition;
pub mod agent_protocol;
mod app_config;
mod attachment;
mod auth;
Expand Down Expand Up @@ -53,6 +54,7 @@ mod xml;

pub use agent::*;
pub use agent_definition::*;
pub use agent_protocol::*;
pub use attachment::*;
pub use chat_request::*;
pub use chat_response::*;
Expand Down
7 changes: 7 additions & 0 deletions crates/paws_infra/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ workspace = true
[dependencies.paws_common]
workspace = true

[dependencies.axum]
workspace = true

[dependencies.tower-http]
workspace = true
features = ["cors", "trace"]

[dev-dependencies.tokio]
workspace = true
features = [ "macros", "rt", "time", "test-util",]
Expand Down
Loading
Loading