mod.rs 4.85 KB
Newer Older
1
2
3
//! Router implementations

use async_trait::async_trait;
4
5
6
7
8
9
use axum::{
    body::Body,
    extract::Request,
    http::{HeaderMap, StatusCode},
    response::{IntoResponse, Response},
};
10
11
use std::fmt::Debug;

12
use crate::protocols::spec::{
13
14
    ChatCompletionRequest, CompletionRequest, EmbeddingRequest, GenerateRequest, RerankRequest,
    ResponsesRequest,
15
};
16

17
pub mod factory;
18
pub mod grpc;
19
pub mod header_utils;
20
pub mod http;
21
pub mod router_manager;
22
pub mod worker_initializer;
23
24

pub use factory::RouterFactory;
25
pub use worker_initializer::WorkerInitializer;
26
27
// Re-export HTTP routers for convenience (keeps routers::openai_router path working)
pub use http::{openai_router, pd_router, pd_types, router};
28
29
30
31
32
33
34
35

/// Worker management trait for administrative operations
///
/// This trait is separate from RouterTrait to allow Send futures
/// for use in service discovery and other background tasks
#[async_trait]
pub trait WorkerManagement: Send + Sync {
    /// Add a worker to the router
36
37
38
39
40
    async fn add_worker(
        &self,
        worker_url: &str,
        api_key: &Option<String>,
    ) -> Result<String, String>;
41
42
43
44
45
46
47
48
49
50
51
52

    /// Remove a worker from the router
    fn remove_worker(&self, worker_url: &str);

    /// Get all worker URLs
    fn get_worker_urls(&self) -> Vec<String>;
}

/// Core trait for all router implementations
///
/// This trait provides a unified interface for routing requests,
/// regardless of whether it's a regular router or PD router.
53
#[async_trait]
54
55
56
pub trait RouterTrait: Send + Sync + Debug + WorkerManagement {
    /// Get a reference to self as Any for downcasting
    fn as_any(&self) -> &dyn std::any::Any;
57

58
    /// Route a health check request
59
    async fn health(&self, req: Request<Body>) -> Response;
60
61

    /// Route a health generate request
62
    async fn health_generate(&self, req: Request<Body>) -> Response;
63
64

    /// Get server information
65
    async fn get_server_info(&self, req: Request<Body>) -> Response;
66
67

    /// Get available models
68
    async fn get_models(&self, req: Request<Body>) -> Response;
69
70

    /// Get model information
71
    async fn get_model_info(&self, req: Request<Body>) -> Response;
72
73

    /// Route a generate request
74
75
76
77
78
79
    async fn route_generate(
        &self,
        headers: Option<&HeaderMap>,
        body: &GenerateRequest,
        model_id: Option<&str>,
    ) -> Response;
80
81
82
83

    /// Route a chat completion request
    async fn route_chat(
        &self,
84
85
        headers: Option<&HeaderMap>,
        body: &ChatCompletionRequest,
86
        model_id: Option<&str>,
87
    ) -> Response;
88
89
90
91

    /// Route a completion request
    async fn route_completion(
        &self,
92
93
        headers: Option<&HeaderMap>,
        body: &CompletionRequest,
94
        model_id: Option<&str>,
95
    ) -> Response;
96

97
98
99
100
101
    /// Route a responses request
    async fn route_responses(
        &self,
        headers: Option<&HeaderMap>,
        body: &ResponsesRequest,
102
        model_id: Option<&str>,
103
104
    ) -> Response;

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    /// Retrieve a stored/background response by id
    async fn get_response(&self, headers: Option<&HeaderMap>, response_id: &str) -> Response;

    /// Cancel a background response by id
    async fn cancel_response(&self, headers: Option<&HeaderMap>, response_id: &str) -> Response;

    /// Delete a response by id
    async fn delete_response(&self, _headers: Option<&HeaderMap>, _response_id: &str) -> Response {
        (
            StatusCode::NOT_IMPLEMENTED,
            "Responses delete endpoint not implemented",
        )
            .into_response()
    }

    /// List input items of a response by id
    async fn list_response_input_items(
        &self,
        _headers: Option<&HeaderMap>,
        _response_id: &str,
    ) -> Response {
        (
            StatusCode::NOT_IMPLEMENTED,
            "Responses list input items endpoint not implemented",
        )
            .into_response()
    }

133
134
135
136
137
138
139
    /// Route embedding requests (OpenAI-compatible /v1/embeddings)
    async fn route_embeddings(
        &self,
        headers: Option<&HeaderMap>,
        body: &EmbeddingRequest,
        model_id: Option<&str>,
    ) -> Response;
140

141
142
143
144
145
146
    async fn route_rerank(
        &self,
        headers: Option<&HeaderMap>,
        body: &RerankRequest,
        model_id: Option<&str>,
    ) -> Response;
147

148
    /// Flush cache on all workers
149
    async fn flush_cache(&self) -> Response;
150
151

    /// Get worker loads (for monitoring)
152
    async fn get_worker_loads(&self) -> Response;
153
154
155
156
157
158
159
160
161
162

    /// Get router type name
    fn router_type(&self) -> &'static str;

    /// Check if this is a PD router
    fn is_pd_mode(&self) -> bool {
        self.router_type() == "pd"
    }

    /// Server liveness check - is the server process running
163
    fn liveness(&self) -> Response {
164
        // Simple liveness check - if we can respond, we're alive
165
        (StatusCode::OK, "OK").into_response()
166
167
168
    }

    /// Server readiness check - is the server ready to handle requests
169
    fn readiness(&self) -> Response;
170
}