fleet-memory/hindsight-clients/rust/INTEGRATION.md
2025-11-27 16:22:16 +01:00

3.2 KiB

CLI Integration Guide

This guide shows how to integrate the auto-generated Rust client into the CLI.

Approach

The generated client is async (uses tokio), while the CLI currently uses blocking code. There are two integration strategies:

Option 1: Minimal Wrapper (Current Approach)

Create a thin api.rs wrapper that uses tokio::runtime::Runtime to bridge sync→async:

pub struct ApiClient {
    client: hindsight_client::Client,
    runtime: tokio::runtime::Runtime,
}

impl ApiClient {
    pub fn new(base_url: String) -> Result<Self> {
        let runtime = tokio::runtime::Runtime::new()?;
        let client = hindsight_client::Client::new(&base_url);
        Ok(ApiClient { client, runtime })
    }

    pub fn list_agents(&self) -> Result<Vec<hindsight_client::types::AgentListItem>> {
        self.runtime.block_on(async {
            self.client.list_agents().await
        })
    }
    // ... other methods
}

Make the CLI fully async using #[tokio::main]:

#[tokio::main]
async fn main() -> Result<()> {
    let cli = Cli::parse();
    let client = hindsight_client::Client::new(&config.api_url);

    match cli.command {
        Commands::Agent(AgentCommands::List) => {
            let agents = client.list_agents().await?;
            for agent in agents {
                println!("  - {}", agent.agent_id);
            }
        }
        // ... other commands
    }

    Ok(())
}

Type Mapping

The generated types are in hindsight_client::types::*. Here's the mapping:

CLI Expected Generated Type
Agent AgentListItem
AgentProfile AgentProfileResponse
AgentStats From /stats endpoint
BatchMemoryRequest BatchPutRequest
BatchMemoryResponse BatchPutResponse
DocumentsResponse ListDocumentsResponse
Document Item in ListDocumentsResponse
DocumentDetails DocumentResponse
OperationsResponse From /operations endpoint

Example: List Agents Command

Before (Manual API Code):

pub fn list_agents(&self, verbose: bool) -> Result<Vec<Agent>> {
    let url = format!("{}/api/v1/agents", self.base_url);
    let response = self.client.get(&url).send()?;
    // ... manual parsing
}

After (Generated Client):

pub fn list_agents(&self) -> Result<Vec<AgentListItem>> {
    self.runtime.block_on(async {
        self.client.list_agents().await
    })
}

Benefits

No manual maintenance - API client updates automatically with OpenAPI spec Type safe - Compiler catches API changes Full coverage - All endpoints generated Better errors - Typed error responses Async ready - Built for modern Rust

Next Steps for Full Integration

  1. Update Type Imports - Fix type names in main.rs to use generated types
  2. Test Each Command - Verify each CLI command works with new client
  3. Remove Old Code - Delete api.rs.old once migration complete
  4. Optional: Make CLI fully async for better UX with long operations

Quick Test

Test the client library directly:

cd hindsight-clients/rust
cargo test

Build CLI with new client:

cd ../../hindsight-cli
cargo build