seedframe 0.1.2

A clean, macro driven Rust library for building LLM apps
Documentation
# Seedframe 🌱

A clean, macro-driven Rust library for building LLM applications.

## Features

- **Declarative API** through straight forward proc-macros
- **Modular Architecture** with clearly defined components:
  - **Loaders**: Data ingestion from various sources (files, APIs, etc.)
  - **Vector Stores**: Embedding storage and retrieval (In-memory, Redis, etc.)
  - **Embedders**: Text embedding providers
  - **LLM Clients**: Unified interface for different LLM providers
  - **Tools**: Function calling abstractions with state management and automatic documentation
  - **Extractors**: Structured output generation from LLM responses

## Installation

Add to your `Cargo.toml`:
```toml
[dependencies]
seedframe = "0.1"
tokio = { version = "1.42", features = ["full"] }
async-trait = "0.1"
# If you'll be using Extractors or custom types as tool-call arguments
schemars = "0.8.22"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
dashmap = "6.1"
```
## Usage
This library is in early stages and its API  is subject to change.

Check out the [examples](https://github.com/Shifta-Robel/SeedFrame/tree/main/core/examples) directory for detailed usage demos.

### Tool calling and structured extraction

The `tool` proc-macro is responsible for declaring tool calls, and the `tools` attribute on the `client` proc-macro attaches them to the client.
The macro parses the descriptions for the function and it's arguments from the doc comments, its an error not to document the function or not to document every argument except the state arguments

You could also extract structured output from the llms, the target types need to implement the `Extractor`, `schemars::JsonSchema` and the `serde::Deserialize` traits.
Like the tools the description for the type and for it's fields will get extracted from the docs and get passed to the llm, but its not an error to leave them undocumented.

```rust
use seedframe::prelude::*;
use seedframe::providers::completions::OpenAI;

#[client(provider = "OpenAI", tools("analyze"))]
struct ToolClient;

/// Perform sentiment analysis on text
/// # Arguments
/// * `text`: Input text to analyze
/// * `language`: Language of the text (ISO 639-1)
#[tool]
fn analyze(text: String, language: String) -> String {
    todo!("implementation");
}

#[derive(Extractor)]
struct PersonData {
    /// Age in years
    age: u8,
    /// Email address
    email: String
}

#[tokio::main]
async fn main() -> Result<()> {
    let mut client = ToolClient::build("You're a data analyst".to_string())
        .await
        .with_state(AppState::new())?;

    // Tool call
    client.prompt("Analyze this: 'I love Rust!' (en)")
        .send()
        .await?;

    // Structured extraction
    let person = client.prompt("John is 30, email john@example.com")
        .extract::<PersonData>()
        .await?;
}
```

### Building a simple RAG
```rust
use seedframe::prelude::*;
use seedframe::providers::{completions::OpenAI, embeddings::OpenAIEmbedding};
use seedframe::vector_store::InMemoryVectorStore;

// Declare file loader that doesnt check for updates, loading files that match the glob pattern
#[loader(kind = "FileOnceLoader", path = "/tmp/data/**/*.txt")]
pub struct MyLoader;

#[vector_store(store = "InMemoryVectorStore")]
pub struct MyVectorStore;

#[embedder(provider = "OpenAIEmbedding")]
struct MyEmbedder {
    #[vector_store]
    my_vector_store: MyVectorStore,
    #[loader]
    my_loader: MyLoader,
}

#[client(provider = "OpenAI", config = r#"{"model": "gpt-4o-mini"}"#)]
struct MyClient {
    #[embedder]
    my_embedder: MyEmbedder,
}

#[tokio::main]
async fn main() {
    let mut client = MyClient::build(
        "You are a helpful assistant".to_string()
    ).await;
    
    tokio::time::sleep(Duration::from_secs(5)).await;
    let response = client.prompt("Explain quantum computing").send().await.unwrap();
}
```
## Built-in Components

**Loaders**
- [`FileOnceLoader`]https://github.com/Shifta-Robel/SeedFrame/blob/main/core/src/loader/builtins/file_loaders/file_once_loader.rs - Load files once using glob patterns
- [`FileUpdatingLoader`]https://github.com/Shifta-Robel/SeedFrame/blob/main/core/src/loader/builtins/file_loaders/file_updating_loader.rs  - Load files and watch for changes

**Vector Stores**
- [`InMemoryVectorStore`]https://github.com/Shifta-Robel/SeedFrame/blob/main/core/src/vector_store/in_memory_vec_store.rs  - Simple in-memory vector storage implementation

**Completion Providers**
- [`OpenAI`]https://github.com/Shifta-Robel/SeedFrame/blob/main/core/src/providers/completions/openai.rs - [OpenAI]https://openai.com API integration
- [`Deepseek`]https://github.com/Shifta-Robel/SeedFrame/blob/main/core/src/providers/completions/deepseek.rs  - [Deepseek]https://deepseek.com API integration
- [`Xai`]https://github.com/Shifta-Robel/SeedFrame/blob/main/core/src/providers/completions/xai.rs  - [Xai]https://x.ai's API integration

**Embeddings**
- [`OpenAI`]https://github.com/Shifta-Robel/SeedFrame/blob/main/core/src/providers/embeddings/openai.rs - [OpenAI]https://openai.com embeddings API integration

---

## Integrations

SeedFrame supports extending functionality through external crates. To create an integration all thats needed is to provide a type that implements the relevant trait from seedframe (`Loader`, `CompletionModel`, etc.). You can use the following crates as inspiration if you want to write an integration crate of your own.

**Completion Providers**
- [`seedframe_anthropic`]https://github.com/Shifta-Robel/SeedFrame/tree/main/integrations/completion_providers/seedframe_anthropic  - [Anthropic]https://anthropic.com API integration

**Embedding Providers**
- [`seedframe_voyageai`]https://github.com/Shifta-Robel/SeedFrame/tree/main/integrations/embedding_providers/seedframe_voyageai  - [VoyageAI]https://voyageai.com embeddings

**Vector Stores**
- [`seedframe_pinecone`]https://github.com/Shifta-Robel/SeedFrame/tree/main/integrations/vector_stores/seedframe_pinecone  - [Pinecone]https://pinecone.io vector database integration

**Loaders**
- [`seedframe_webscraper`]https://github.com/Shifta-Robel/SeedFrame/tree/main/integrations/seedframe_webscraper  - Web scraping using [scraper-rs]https://docs.rs/scraper

---

If you wrote an integration crate, please update this list and [submit a PR](https://github.com/Shifta-Robel/SeedFrame/compare).
## Contributing

All contributions as welcome! This library could use support for more loaders, vector stores, providers ... so don't shy away from helping!


#### ⭐ Leave a Star!

If you find seedframe helpful or interesting, please consider giving it a star so more people get to see it!