Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Backend Architecture

The Kuse Cowork backend is built with Rust and Tauri, providing high performance and native system integration.

Technology Stack

Technology
Version
Purpose
Rust
2021 Edition
Systems programming
Tauri
2.0.x
Desktop framework
Tokio
1.x
Async runtime
Reqwest
0.12.x
HTTP client
SQLite
3.x
Local database
Bollard
0.18.x
Docker API

Project Structure

src-tauri/
├── Cargo.toml           # Dependencies
├── tauri.conf.json      # Tauri configuration
├── src/
│   ├── main.rs          # Entry point
│   ├── lib.rs           # Library root
│   ├── commands.rs      # Tauri commands (1800+ lines)
│   ├── database.rs      # Database operations
│   ├── llm_client.rs    # LLM providers (950+ lines)
│   ├── agent/
│   │   ├── mod.rs
│   │   ├── agent_loop.rs    # Agent execution (1000+ lines)
│   │   ├── message_builder.rs
│   │   ├── tool_executor.rs
│   │   └── types.rs
│   ├── tools/
│   │   ├── mod.rs
│   │   ├── bash.rs
│   │   ├── docker.rs
│   │   ├── file_read.rs
│   │   ├── file_write.rs
│   │   ├── file_edit.rs
│   │   ├── glob.rs
│   │   ├── grep.rs
│   │   └── list_dir.rs
│   ├── mcp/
│   │   ├── mod.rs
│   │   ├── client.rs
│   │   ├── http_client.rs
│   │   ├── config.rs
│   │   └── types.rs
│   └── skills/
│       └── mod.rs

Core Modules

Commands (commands.rs)

Tauri command handlers that bridge frontend and backend:

#[tauri::command]
pub async fn send_chat_message(
    state: tauri::State<'_, AppState>,
    window: tauri::Window,
    conversation_id: String,
    content: String,
) -> Result<String, CommandError> {
    // Get settings
    let settings = state.db.get_settings()?;

    // Create LLM client
    let client = LLMClient::new(
        settings.api_key,
        settings.base_url,
        settings.model,
    );

    // Stream response
    let response = client.send_message_stream(
        messages,
        |chunk| {
            window.emit("chat-stream", chunk)?;
            Ok(())
        }
    ).await?;

    // Save to database
    state.db.add_message(&response)?;

    Ok(response)
}

Database (database.rs)

SQLite operations for persistent storage:

pub struct Database {
    conn: Mutex<Connection>,
}

impl Database {
    pub fn new(data_dir: &Path) -> Result<Self, DatabaseError> {
        let db_path = data_dir.join("settings.db");
        let conn = Connection::open(&db_path)?;

        // Initialize schema
        conn.execute_batch(SCHEMA)?;

        Ok(Self {
            conn: Mutex::new(conn),
        })
    }

    pub fn get_settings(&self) -> Result<Settings, DatabaseError> {
        let conn = self.conn.lock().unwrap();
        // Query settings...
    }

    pub fn save_settings(&self, settings: &Settings) -> Result<(), DatabaseError> {
        let conn = self.conn.lock().unwrap();
        // Insert/update settings...
    }
}

LLM Client (llm_client.rs)

Multi-provider LLM integration:

pub struct LLMClient {
    client: Client,
    api_key: String,
    base_url: String,
    model: String,
    provider_config: ProviderConfig,
}

impl LLMClient {
    pub async fn send_message_stream(
        &self,
        messages: Vec<Message>,
        on_chunk: impl Fn(String) -> Result<(), LLMError>,
    ) -> Result<String, LLMError> {
        match self.provider_config.api_format {
            ApiFormat::Anthropic => self.send_anthropic_stream(messages, on_chunk).await,
            ApiFormat::OpenAI => self.send_openai_stream(messages, on_chunk).await,
            ApiFormat::Google => self.send_google_stream(messages, on_chunk).await,
            // ...
        }
    }
}

Agent System

Agent Loop (agent/agent_loop.rs)

Core autonomous agent execution:

pub struct AgentLoop {
    client: Client,
    api_key: String,
    base_url: String,
    config: AgentConfig,
    tool_executor: ToolExecutor,
    message_builder: MessageBuilder,
    provider_config: ProviderConfig,
}

impl AgentLoop {
    pub async fn run_with_history(
        &mut self,
        messages: Vec<AgentMessage>,
        event_tx: mpsc::Sender<AgentEvent>,
    ) -> Result<String, String> {
        let max_turns = self.config.max_turns;

        for turn in 1..=max_turns {
            // Build API request
            let request = self.message_builder.build_request(&messages).await;

            // Send to LLM
            let response = self.send_request(&request, &event_tx).await?;

            // Parse response
            let (text, tool_uses) = self.parse_response(&response)?;

            // Execute tools if needed
            if !tool_uses.is_empty() {
                for tool_use in &tool_uses {
                    let result = self.tool_executor.execute(tool_use).await;
                    // Add result to messages...
                }
            } else {
                // No more tools, we're done
                return Ok(text);
            }
        }

        Err("Max turns exceeded".to_string())
    }
}

Message Builder (agent/message_builder.rs)

Constructs API requests:

pub struct MessageBuilder {
    config: AgentConfig,
    model: String,
    max_tokens: u32,
    mcp_manager: Option<Arc<MCPManager>>,
}

impl MessageBuilder {
    pub async fn build_request(
        &self,
        messages: &[AgentMessage],
    ) -> ClaudeApiRequest {
        let mut tools = tools::get_tools(&self.config.allowed_tools);

        // Add MCP tools
        if let Some(mcp) = &self.mcp_manager {
            tools.extend(self.get_mcp_tools(mcp).await);
        }

        ClaudeApiRequest {
            model: self.model.clone(),
            max_tokens: self.max_tokens,
            system: self.config.system_prompt.clone(),
            messages: self.convert_messages(messages),
            tools,
            stream: true,
        }
    }
}

Tool Executor (agent/tool_executor.rs)

Executes agent tools:

pub struct ToolExecutor {
    project_path: Option<String>,
    mcp_manager: Option<Arc<MCPManager>>,
}

impl ToolExecutor {
    pub async fn execute(&self, tool_use: &ToolUse) -> ToolResult {
        // Check for MCP tools
        if tool_use.name.starts_with("mcp_") {
            return self.execute_mcp_tool(tool_use).await;
        }

        // Execute built-in tools
        match tool_use.name.as_str() {
            "read_file" => tools::read_file(tool_use),
            "write_file" => tools::write_file(tool_use),
            "edit_file" => tools::edit_file(tool_use),
            "bash" => tools::bash(tool_use, &self.project_path).await,
            "glob" => tools::glob(tool_use, &self.project_path),
            "grep" => tools::grep(tool_use, &self.project_path),
            "list_dir" => tools::list_dir(tool_use),
            "docker_run" => tools::docker_run(tool_use, &self.project_path),
            _ => ToolResult::error(tool_use.id.clone(), "Unknown tool"),
        }
    }
}

Tool Implementations

File Operations

// tools/file_read.rs
pub fn read_file(tool_use: &ToolUse) -> ToolResult {
    let path = tool_use.input.get("path")
        .and_then(|v| v.as_str())
        .ok_or("Missing path")?;

    // Expand ~ to home directory
    let expanded = expand_tilde(path);

    let content = std::fs::read_to_string(&expanded)?;

    ToolResult::success(tool_use.id.clone(), content)
}

Docker Integration

// tools/docker.rs
pub async fn docker_run(
    tool_use: &ToolUse,
    project_path: &Option<String>,
) -> ToolResult {
    let docker = Docker::connect_with_local_defaults()?;

    let image = tool_use.input.get("image")
        .and_then(|v| v.as_str())
        .unwrap_or("python:3.11-alpine");

    let command = tool_use.input.get("command")
        .and_then(|v| v.as_str())
        .ok_or("Missing command")?;

    // Create container config
    let config = Config {
        image: Some(image),
        cmd: Some(vec!["/bin/sh", "-c", command]),
        host_config: Some(HostConfig {
            binds: Some(vec![
                format!("{}:/workspace", project_path),
                format!("{}:/skills:ro", skills_path),
            ]),
            ..Default::default()
        }),
        ..Default::default()
    };

    // Create and run container
    let container = docker.create_container(None, config).await?;
    docker.start_container(&container.id, None).await?;

    // Wait and get output
    let output = docker.wait_container(&container.id).await?;
    let logs = docker.logs(&container.id, options).await?;

    // Cleanup
    docker.remove_container(&container.id, None).await?;

    ToolResult::success(tool_use.id.clone(), logs)
}

MCP Integration

MCP Manager (mcp/client.rs)

pub struct MCPManager {
    servers: RwLock<HashMap<String, MCPServer>>,
    http_client: Client,
}

impl MCPManager {
    pub async fn add_server(&self, config: MCPServerConfig) -> Result<(), MCPError> {
        let server = MCPServer::connect(config).await?;
        self.servers.write().await.insert(server.id.clone(), server);
        Ok(())
    }

    pub async fn get_all_tools(&self) -> Vec<MCPTool> {
        let servers = self.servers.read().await;
        let mut tools = Vec::new();

        for server in servers.values() {
            if server.is_connected() {
                tools.extend(server.tools.clone());
            }
        }

        tools
    }

    pub async fn execute_tool(&self, call: &MCPToolCall) -> Result<String, MCPError> {
        let servers = self.servers.read().await;
        let server = servers.get(&call.server_id)
            .ok_or(MCPError::ServerNotFound)?;

        server.call_tool(&call.tool_name, &call.parameters).await
    }
}

Error Handling

Error Types

#[derive(Error, Debug)]
pub enum LLMError {
    #[error("HTTP error: {0}")]
    Http(#[from] reqwest::Error),

    #[error("API error: {0}")]
    Api(String),

    #[error("Parse error: {0}")]
    Parse(String),

    #[error("Unsupported provider: {0}")]
    UnsupportedProvider(String),
}

#[derive(Debug, Serialize)]
pub struct CommandError {
    pub message: String,
}

impl From<LLMError> for CommandError {
    fn from(err: LLMError) -> Self {
        CommandError {
            message: err.to_string(),
        }
    }
}

Async Architecture

Tokio Runtime

// main.rs
#[tokio::main]
async fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_fs::init())
        .invoke_handler(tauri::generate_handler![
            commands::get_settings,
            commands::save_settings,
            commands::send_chat_message,
            commands::run_task_agent,
            // ...
        ])
        .run(tauri::generate_context!())
        .expect("error running application");
}

Streaming with Channels

use tokio::sync::mpsc;

pub async fn run_agent_with_events(
    request: AgentRequest,
    window: Window,
) -> Result<String, CommandError> {
    let (tx, mut rx) = mpsc::channel(100);

    // Spawn event forwarder
    let event_window = window.clone();
    tokio::spawn(async move {
        while let Some(event) = rx.recv().await {
            let _ = event_window.emit("agent-event", event);
        }
    });

    // Run agent
    let result = agent_loop.run_with_history(messages, tx).await;

    Ok(result?)
}

Testing

Unit Tests

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_provider_detection() {
        assert_eq!(
            ProviderConfig::from_model("claude-3-sonnet").api_format,
            ApiFormat::Anthropic
        );
        assert_eq!(
            ProviderConfig::from_model("gpt-4o").api_format,
            ApiFormat::OpenAI
        );
    }

    #[tokio::test]
    async fn test_tool_execution() {
        let executor = ToolExecutor::new(None);
        let tool_use = ToolUse {
            id: "test".to_string(),
            name: "list_dir".to_string(),
            input: json!({"path": "."}),
        };

        let result = executor.execute(&tool_use).await;
        assert!(result.is_error.is_none());
    }
}

Integration Tests

#[cfg(test)]
mod integration_tests {
    #[tokio::test]
    async fn test_full_agent_flow() {
        // Create agent with mock LLM
        // Run a simple task
        // Verify tools are called
        // Check final output
    }
}

Performance Optimizations

Connection Pooling

let client = reqwest::Client::builder()
    .pool_max_idle_per_host(10)
    .timeout(Duration::from_secs(300))
    .build()?;

Parallel Tool Execution

// Future: Execute independent tools in parallel
let results = futures::future::join_all(
    tool_uses.iter().map(|tu| self.tool_executor.execute(tu))
).await;

Security Considerations

Input Validation

fn validate_path(path: &str) -> Result<PathBuf, ToolError> {
    let expanded = expand_tilde(path);
    let canonical = expanded.canonicalize()?;

    // Prevent path traversal
    if !canonical.starts_with(&project_root) {
        return Err(ToolError::AccessDenied);
    }

    Ok(canonical)
}

Command Sanitization

// Commands run in Docker are isolated
// But we still validate inputs
fn sanitize_command(cmd: &str) -> Result<String, ToolError> {
    if cmd.contains("rm -rf /") || cmd.contains(":(){ :|:& };:") {
        return Err(ToolError::DangerousCommand);
    }
    Ok(cmd.to_string())
}

Next Steps