# ContextProvider Trait
ARES provides a `ContextProvider` trait that lets extension crates inject external context into every agent call before LLM invocation.
## How It Works
Before every LLM call, ARES checks `state.context_provider.get_context(agent_name, tenant_id)`. If it returns `Some(context)`, the context is prepended to the agent's system prompt.
By default, ARES uses `NoOpContextProvider` which returns `None` — agents run with their configured system prompt only.
## Implementing Your Own
```rust
use ares::agents::context_provider::ContextProvider;
use async_trait::async_trait;
struct MyKnowledgeProvider {
api_url: String,
}
#[async_trait]
impl ContextProvider for MyKnowledgeProvider {
async fn get_context(
&self,
agent_name: &str,
tenant_id: &str,
) -> Option<String> {
// Fetch relevant context from your knowledge base
// Return None if no context available
let url = format!("{}/context/{}/{}", self.api_url, tenant_id, agent_name);
reqwest::get(&url).await.ok()?.text().await.ok()
}
}
```
## Wiring Into AppState
```rust
use std::sync::Arc;
let state = AppState {
context_provider: Arc::new(MyKnowledgeProvider {
api_url: "http://localhost:8081".to_string(),
}),
// ... other fields
};
```
## Use Cases
- **Knowledge base injection** — fetch relevant docs per agent and tenant
- **User preference injection** — personalize agent behavior based on user history
- **Compliance constraints** — inject regulatory rules into agent prompts
- **RAG augmentation** — supplement the built-in RAG with external retrieval