Skip to content

Commit b4b8755

Browse files
Add AnyLLM auto provider example
Co-authored-by: anode-agent[bot] <283895490+anode-agent[bot]@users.noreply.github.com>
1 parent 3a6638a commit b4b8755

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use std::env;
2+
use std::sync::Arc;
3+
4+
use openai_agents::extensions::{AnyLLMApi, AnyLLMProvider};
5+
use openai_agents::{
6+
Agent, AgentOutputSchema, AgentsError, Model, ModelProvider, ModelRequest, ModelSettings,
7+
MultiProvider, MultiProviderMap, OpenAIProvider, OutputSchemaDefinition, Runner, function_tool,
8+
set_tracing_disabled,
9+
};
10+
use schemars::JsonSchema;
11+
use serde::{Deserialize, Serialize};
12+
13+
const MODEL: &str = "any-llm/openrouter/openai/gpt-5.4-mini";
14+
const OPENROUTER_BASE_URL: &str = "https://openrouter.ai/api/v1";
15+
16+
#[derive(Debug, Deserialize, JsonSchema)]
17+
struct WeatherArgs {
18+
city: String,
19+
}
20+
21+
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
22+
struct ResultOutput {
23+
output_text: String,
24+
tool_results: Vec<String>,
25+
}
26+
27+
fn openrouter_model_id(model: &str) -> &str {
28+
model.strip_prefix("openrouter/").unwrap_or(model)
29+
}
30+
31+
#[derive(Clone)]
32+
struct OpenRouterAnyLLMProvider {
33+
inner: AnyLLMProvider,
34+
}
35+
36+
impl ModelProvider for OpenRouterAnyLLMProvider {
37+
fn resolve(&self, model: Option<&str>) -> Arc<dyn Model> {
38+
self.inner.resolve(model.map(openrouter_model_id))
39+
}
40+
41+
fn prepare_request(&self, mut request: ModelRequest) -> ModelRequest {
42+
request.model = request
43+
.model
44+
.map(|model| openrouter_model_id(&model).to_owned());
45+
self.inner.prepare_request(request)
46+
}
47+
}
48+
49+
#[tokio::main]
50+
async fn main() -> Result<(), AgentsError> {
51+
set_tracing_disabled(true);
52+
53+
let api_key = env::var("OPENROUTER_API_KEY").unwrap_or_else(|_| "dummy".to_owned());
54+
if api_key == "dummy" {
55+
println!("Skipping run because OPENROUTER_API_KEY is not set.");
56+
return Ok(());
57+
}
58+
59+
let base_url =
60+
env::var("OPENROUTER_BASE_URL").unwrap_or_else(|_| OPENROUTER_BASE_URL.to_owned());
61+
let get_weather = function_tool(
62+
"get_weather",
63+
"Get the weather for a city.",
64+
|_ctx, args: WeatherArgs| async move {
65+
println!("[debug] getting weather for {}", args.city);
66+
Ok::<_, AgentsError>(format!("The weather in {} is sunny.", args.city))
67+
},
68+
)?;
69+
70+
let output_schema = AgentOutputSchema::<ResultOutput>::new(true);
71+
let agent = Agent::builder("Assistant")
72+
.instructions("You only respond in haikus.")
73+
.model(MODEL)
74+
.model_settings(ModelSettings {
75+
tool_choice: Some("required".to_owned()),
76+
..ModelSettings::default()
77+
})
78+
.output_schema(OutputSchemaDefinition::from_agent_output_schema(
79+
"Result",
80+
&output_schema,
81+
)?)
82+
.function_tool(get_weather)
83+
.build();
84+
85+
let mut provider_map = MultiProviderMap::default();
86+
provider_map.add_provider(
87+
"any-llm",
88+
Arc::new(OpenRouterAnyLLMProvider {
89+
inner: AnyLLMProvider::new()
90+
.with_api_key(api_key)
91+
.with_base_url(base_url)
92+
.with_api(AnyLLMApi::ChatCompletions),
93+
}),
94+
);
95+
let provider =
96+
MultiProvider::new(Arc::new(OpenAIProvider::new())).with_provider_map(provider_map);
97+
let runner = Runner::new().with_model_provider(Arc::new(provider));
98+
let result = runner.run(&agent, "What's the weather in Tokyo?").await?;
99+
100+
println!("{}", result.final_output.unwrap_or_default());
101+
Ok(())
102+
}

0 commit comments

Comments
 (0)