1use std::sync::Arc;
21
22use anyhow::{Context, Result};
23use serde_json::json;
24
25use jev_bridge::server::{router, AppState, Bridge, BridgeConfig};
26
27const ADDRESS: &str = "127.0.0.1:8100";
28
29#[tokio::main]
30async fn main() -> Result<()> {
31 let openai_base = std::env::var("JEV_BRIDGE_UPSTREAM_URL")
32 .unwrap_or_else(|_| "http://127.0.0.1:8080/v1".to_string());
33 let native_base = std::env::var("JEV_BRIDGE_NATIVE_URL")
34 .unwrap_or_else(|_| openai_base.trim_end_matches("/v1").to_string());
35 let upstream_model =
36 std::env::var("JEV_BRIDGE_UPSTREAM_MODEL").unwrap_or_else(|_| "local-model".to_string());
37
38 let bridge = Bridge::connect(
39 reqwest::Client::new(),
40 BridgeConfig {
41 openai_base,
42 native_base,
43 upstream_model,
44 upstream_key: std::env::var("JEV_BRIDGE_UPSTREAM_KEY").ok(),
45 served_model: "example-bridge".to_string(),
46 description: "example bridge over a generic inference API".to_string(),
47 release_date: "2026-09-22".to_string(),
48 chat_template_kwargs: json!({"enable_thinking": false}),
49 max_input_tokens: None,
50 local: Default::default(),
51 },
52 )
53 .await
54 .context("connecting to the upstream service failed")?;
55
56 println!("transport: {} via {}", bridge.probe().name(), bridge.probe().endpoint());
57
58 let state = Arc::new(AppState {
59 bridge,
60 api_key: std::env::var("JEV_BRIDGE_API_KEY").ok(),
61 });
62 let listener = tokio::net::TcpListener::bind(ADDRESS)
63 .await
64 .with_context(|| format!("binding {ADDRESS} failed"))?;
65 println!("listening on http://{ADDRESS}");
66 axum::serve(listener, router(state))
67 .with_graceful_shutdown(async {
68 let _ = tokio::signal::ctrl_c().await;
69 })
70 .await
71 .context("the HTTP server stopped unexpectedly")
72}