Files
cortiq-gateway/src/model.rs
T
infosave2007andClaude Opus 4.8 51487e6329 feat: universal LLM gateway with embedded multilingual admin console
- OpenAI-compatible gateway with intelligent routing via cortiq-router (allaigate)
- Embedded build-free admin SPA at /admin: 7 languages (en/ru/de/fr/es/zh/tr),
  light/dark themes, hot config reload (no restart)
- Admin API, per-request statistics + Prometheus /metrics, secret store, playground
- English documentation (primary) with Russian translations (*.ru.md)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 10:51:37 +03:00

103 lines
3.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Canonical (protocol-neutral) request/response model.
//!
//! All incoming protocols are translated into these types, and providers translate
//! from them. This way N protocols × M providers do not become N×M translations:
//! each adapter only knows its own protocol ↔ canonical mapping. See docs/ARCHITECTURE.md §3.
use serde::{Deserialize, Serialize};
/// How to handle routing for a specific request.
#[derive(Clone, Debug)]
pub enum RoutingDirective {
/// `model = "cortiq-auto"` — ask cortiq-router and pick a model from the pool.
Auto { profile: Option<String> },
/// `model = "<real id>"` — call a specific model directly, bypassing routing.
Pinned { model_id: String },
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Message {
pub role: String, // system | user | assistant | tool
#[serde(default)]
pub content: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tool_calls: Vec<serde_json::Value>,
}
#[derive(Clone, Debug, Default)]
pub struct GenParams {
pub temperature: Option<f32>,
pub max_tokens: Option<u32>,
pub top_p: Option<f32>,
pub stop: Vec<String>,
/// Fields we do not interpret but must proxy through to the provider.
pub passthrough: serde_json::Map<String, serde_json::Value>,
}
#[derive(Clone, Debug, Default)]
pub struct RequestMeta {
pub account: String,
pub protocol: String,
pub idempotency_key: Option<String>,
pub traceparent: Option<String>,
}
/// Canonical form of a generation request.
#[derive(Clone, Debug)]
pub struct ChatRequest {
pub routing: RoutingDirective,
pub messages: Vec<Message>,
pub tools: Vec<serde_json::Value>,
pub params: GenParams,
pub stream: bool,
pub meta: RequestMeta,
}
#[derive(Clone, Debug, Serialize)]
pub struct Usage {
pub prompt_tokens: u32,
pub completion_tokens: u32,
pub total_tokens: u32,
}
/// Routing metadata attached to the response (X-Cortiq-* headers and the `cortiq` field).
#[derive(Clone, Debug, Serialize)]
pub struct RouteInfo {
pub task_label: String,
pub complexity_score: f32,
pub complexity_tier: String,
pub selected_model: String,
pub route_source: String, // router | cache | fallback | pinned
pub router_request_id: Option<String>,
pub cost_usd: f64,
#[serde(default)]
pub failover: bool,
}
#[derive(Clone, Debug, Serialize)]
pub struct Choice {
pub index: u32,
pub message: Message,
pub finish_reason: String,
}
/// Canonical form of a response.
#[derive(Clone, Debug)]
pub struct ChatResponse {
pub id: String,
pub model_used: String,
pub choices: Vec<Choice>,
pub usage: Usage,
pub cortiq: RouteInfo,
}
/// Decision from cortiq-router (the subset of its contract needed by the gateway).
#[derive(Clone, Debug)]
pub struct RouteDecision {
pub task_label: String,
pub complexity_score: f32,
pub complexity_tier: String,
pub router_request_id: Option<String>,
pub source: String, // router | cache | fallback
}