1use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use std::collections::BTreeMap;
10use std::path::PathBuf;
11
12#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
16pub enum ProtocolVersion {
17 #[serde(rename = "7")]
19 V7,
20}
21
22#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
25#[serde(tag = "operation", rename_all = "snake_case", deny_unknown_fields)]
26pub enum AdapterRequest {
27 PlanServe {
30 protocol_version: ProtocolVersion,
31 input: PlanServeInput,
32 },
33 RenderServe {
36 protocol_version: ProtocolVersion,
37 input: RenderServeInput,
38 },
39}
40
41impl AdapterRequest {
42 #[must_use]
44 pub const fn protocol_version(&self) -> ProtocolVersion {
45 match self {
46 Self::PlanServe {
47 protocol_version, ..
48 }
49 | Self::RenderServe {
50 protocol_version, ..
51 } => *protocol_version,
52 }
53 }
54}
55
56#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
58#[serde(deny_unknown_fields)]
59pub struct PlanServeInput {
60 pub model: ServeModelInput,
61 pub topology: ServeTopology,
62 #[serde(default, skip_serializing_if = "Option::is_none")]
63 pub gateway_backend: Option<String>,
64 #[serde(default, skip_serializing_if = "Option::is_none")]
65 pub pd_router_backend: Option<String>,
66 #[serde(default, skip_serializing_if = "Option::is_none")]
67 pub kv_transfer: Option<KvTransferMechanism>,
68 pub roles: Vec<ServeRoleInput>,
69 #[serde(default)]
70 pub profiling: bool,
71}
72
73#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
76#[serde(deny_unknown_fields)]
77pub struct RenderServeInput {
78 pub model: ServeModelInput,
79 pub topology: ServeTopology,
80 #[serde(default, skip_serializing_if = "Option::is_none")]
81 pub gateway_backend: Option<String>,
82 #[serde(default, skip_serializing_if = "Option::is_none")]
83 pub pd_router_backend: Option<String>,
84 #[serde(default, skip_serializing_if = "Option::is_none")]
85 pub kv_transfer: Option<KvTransferMechanism>,
86 pub allocations: Vec<ServeProcessAllocation>,
87 #[serde(default)]
88 pub profiling: bool,
89}
90
91#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
93#[serde(rename_all = "snake_case")]
94pub enum ServeTopology {
95 Single,
97 PrefillDecode,
99}
100
101#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
103#[serde(rename_all = "snake_case")]
104pub enum ServeRoleKind {
105 Serve,
107 Prefill,
109 Decode,
111}
112
113#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
115#[serde(rename_all = "snake_case")]
116pub enum KvTransferMechanism {
117 Mooncake,
119 Nixl,
121}
122
123#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
126#[serde(deny_unknown_fields)]
127pub struct ServeRoleInput {
128 pub id: String,
129 pub kind: ServeRoleKind,
130 pub replica_count: u32,
131 pub parallelism: Parallelism,
132 pub settings: BTreeMap<String, SettingValue>,
133}
134
135#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
138#[serde(deny_unknown_fields)]
139pub struct ServeRoleResult {
140 pub id: String,
141 pub kind: ServeRoleKind,
142 pub declared_replica_count: u32,
143 pub effective_replica_count: u32,
144 pub effective_settings: BTreeMap<String, SettingValue>,
145 pub effective_parallelism: Parallelism,
146 #[serde(default, skip_serializing_if = "Option::is_none")]
149 pub public_endpoint: Option<EndpointRequirement>,
150 #[serde(default)]
151 pub render_inputs: Vec<RenderInputDeclaration>,
152}
153
154#[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
159#[serde(default, deny_unknown_fields)]
160pub struct Parallelism {
161 #[serde(skip_serializing_if = "Option::is_none")]
163 pub outer: Option<ParallelismOuter>,
164 #[serde(skip_serializing_if = "Option::is_none")]
166 pub attention: Option<ParallelismAttention>,
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub experts: Option<ParallelismExperts>,
170}
171
172impl Parallelism {
173 pub fn merge_from(&mut self, other: &Self) {
176 if let Some(other) = &other.outer {
177 self.outer.get_or_insert_default().merge_from(other);
178 }
179 if let Some(other) = &other.attention {
180 self.attention.get_or_insert_default().merge_from(other);
181 }
182 if let Some(other) = &other.experts {
183 self.experts.get_or_insert_default().merge_from(other);
184 }
185 }
186}
187
188#[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
190#[serde(default, deny_unknown_fields)]
191pub struct ParallelismOuter {
192 #[schemars(range(min = 1))]
193 #[serde(skip_serializing_if = "Option::is_none")]
194 pub tensor_parallel_size: Option<u32>,
195 #[schemars(range(min = 1))]
196 #[serde(skip_serializing_if = "Option::is_none")]
197 pub pipeline_parallel_size: Option<u32>,
198}
199
200impl ParallelismOuter {
201 fn merge_from(&mut self, other: &Self) {
202 if other.tensor_parallel_size.is_some() {
203 self.tensor_parallel_size = other.tensor_parallel_size;
204 }
205 if other.pipeline_parallel_size.is_some() {
206 self.pipeline_parallel_size = other.pipeline_parallel_size;
207 }
208 }
209}
210
211#[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
213#[serde(default, deny_unknown_fields)]
214pub struct ParallelismAttention {
215 #[schemars(range(min = 1))]
216 #[serde(skip_serializing_if = "Option::is_none")]
217 pub tensor_parallel_size: Option<u32>,
218 #[schemars(range(min = 1))]
219 #[serde(skip_serializing_if = "Option::is_none")]
220 pub data_parallel_size: Option<u32>,
221 #[schemars(range(min = 1))]
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub context_parallel_size: Option<u32>,
224}
225
226impl ParallelismAttention {
227 fn merge_from(&mut self, other: &Self) {
228 if other.tensor_parallel_size.is_some() {
229 self.tensor_parallel_size = other.tensor_parallel_size;
230 }
231 if other.data_parallel_size.is_some() {
232 self.data_parallel_size = other.data_parallel_size;
233 }
234 if other.context_parallel_size.is_some() {
235 self.context_parallel_size = other.context_parallel_size;
236 }
237 }
238}
239
240#[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
242#[serde(default, deny_unknown_fields)]
243pub struct ParallelismExperts {
244 #[schemars(range(min = 1))]
245 #[serde(skip_serializing_if = "Option::is_none")]
246 pub tensor_parallel_size: Option<u32>,
247 #[schemars(range(min = 1))]
248 #[serde(skip_serializing_if = "Option::is_none")]
249 pub data_parallel_size: Option<u32>,
250 #[schemars(range(min = 1))]
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub expert_parallel_size: Option<u32>,
253 #[schemars(range(min = 1))]
254 #[serde(skip_serializing_if = "Option::is_none")]
255 pub dense_tensor_parallel_size: Option<u32>,
256}
257
258impl ParallelismExperts {
259 fn merge_from(&mut self, other: &Self) {
260 if other.tensor_parallel_size.is_some() {
261 self.tensor_parallel_size = other.tensor_parallel_size;
262 }
263 if other.data_parallel_size.is_some() {
264 self.data_parallel_size = other.data_parallel_size;
265 }
266 if other.expert_parallel_size.is_some() {
267 self.expert_parallel_size = other.expert_parallel_size;
268 }
269 if other.dense_tensor_parallel_size.is_some() {
270 self.dense_tensor_parallel_size = other.dense_tensor_parallel_size;
271 }
272 }
273}
274
275#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
277#[serde(deny_unknown_fields)]
278pub struct ServeModelInput {
279 pub id: String,
280 pub served_name: String,
281}
282
283#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
287#[serde(deny_unknown_fields)]
288pub struct MeasurementModelInput {
289 pub locator: String,
290 pub served_name: String,
291}
292
293#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
295#[serde(deny_unknown_fields)]
296pub struct EndpointAssignment {
297 pub host: String,
298 pub port: u16,
299}
300
301#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
303#[serde(deny_unknown_fields)]
304pub struct ClientEndpointInput {
305 pub protocol: EndpointProtocol,
306 pub host: String,
307 pub port: u16,
308 pub completions_path: String,
309 pub chat_completions_path: String,
310}
311
312#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
314#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
315pub enum EvalDefinitionInput {
316 #[serde(rename = "openai_smoke")]
318 OpenAiSmoke {
319 prompt: String,
320 max_tokens: u32,
321 timeout_seconds: u64,
322 },
323 LmEval {
325 task: Box<EvalTaskSourceInput>,
326 #[serde(default)]
327 request_body: BTreeMap<String, SettingValue>,
328 limit: Option<u32>,
329 few_shot: Option<u32>,
330 seed: Option<u64>,
331 trials: u32,
332 max_tokens: Option<u32>,
333 concurrency: Option<u32>,
334 metric: String,
335 #[serde(default)]
336 metric_filter: Option<String>,
337 threshold: f64,
338 timeout_seconds: u64,
339 },
340}
341
342#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
344#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
345pub enum EvalTaskSourceInput {
346 BuiltIn { name: String },
348 Bundled {
350 name: String,
351 task_identity: String,
352 path: PathBuf,
353 task_closure_sha256: String,
354 task_definition_sha256: String,
355 prompt_asset_sha256: String,
356 dataset_asset_sha256: String,
357 scorer_sha256: String,
358 },
359 WorkspaceYaml { path: PathBuf },
361}
362
363#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
365#[serde(deny_unknown_fields)]
366pub struct BenchDefinitionInput {
367 pub request_source: BenchRequestSourceInput,
368 pub seed: u64,
369 #[serde(default)]
370 pub request_body: BTreeMap<String, SettingValue>,
371 #[serde(default)]
372 pub request_slo: Option<BenchRequestSloInput>,
373 pub timeout_seconds: u64,
374 #[serde(default)]
375 pub reset_prefix_cache: bool,
376}
377
378#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
380#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
381pub enum BenchRequestSourceInput {
382 Random {
385 input_tokens: u32,
386 output_tokens: u32,
387 #[serde(default)]
388 prefix_sharing: Option<BenchPrefixSharingInput>,
389 },
390 RandomMixture {
393 shapes: Vec<BenchRandomShapeInput>,
394 total_weight: u64,
395 },
396 Dataset {
399 dataset: BenchDatasetInput,
400 max_input_tokens: u32,
401 output_tokens: Option<u32>,
402 catalog: BenchDatasetCatalogInput,
403 },
404}
405
406#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
409#[serde(deny_unknown_fields)]
410pub struct BenchPrefixSharingInput {
411 pub shared_prefix_ratio: f64,
412 pub shared_prefix_tokens: u32,
413 pub unique_suffix_tokens: u32,
414}
415
416#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
418#[serde(deny_unknown_fields)]
419pub struct BenchRandomShapeInput {
420 pub input_tokens: u32,
421 pub output_tokens: u32,
422 pub weight: u32,
423}
424
425#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
427#[serde(rename_all = "snake_case")]
428pub enum BenchDatasetInput {
429 Sharegpt,
430}
431
432#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
434#[serde(deny_unknown_fields)]
435pub struct BenchDatasetCatalogInput {
436 pub upstream_identity: String,
437 pub url: String,
438 pub sha256: String,
439 pub source_format: String,
440 pub license: String,
441 pub cache_path: PathBuf,
442 pub cache_state: BenchDatasetCacheState,
443 pub materialization_identity: String,
444}
445
446#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
448#[serde(rename_all = "snake_case")]
449pub enum BenchDatasetCacheState {
450 Missing,
451 Present,
452}
453
454#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
456#[serde(deny_unknown_fields)]
457pub struct BenchPopulationInput {
458 pub path: PathBuf,
459 pub sha256: String,
460 pub entries: u32,
461 pub tpot_applicable: bool,
462}
463
464#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
467#[serde(deny_unknown_fields)]
468pub struct BenchDatasetPreparationRequest {
469 pub protocol_version: ProtocolVersion,
470 pub model: MeasurementModelInput,
471 pub request_source: BenchRequestSourceInput,
472 pub source_path: PathBuf,
473 pub required_entries: u32,
474 pub seed: u64,
475 #[serde(default)]
476 pub request_body: BTreeMap<String, SettingValue>,
477 pub artifact_dir: PathBuf,
478}
479
480#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
483#[serde(deny_unknown_fields)]
484pub struct BenchTokenCountSummary {
485 pub minimum: u32,
486 pub maximum: u32,
487 pub mean: f64,
488}
489
490#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
492#[serde(deny_unknown_fields)]
493pub struct BenchDatasetPreparationResult {
494 pub schema_version: u32,
495 pub status: ClientStatus,
496 pub materialization_identity: String,
497 pub requested_entries: u32,
498 pub candidate_entries: u64,
499 pub admitted_entries: u64,
500 pub ineligible_entries: u64,
501 #[serde(default)]
502 pub ineligible_reasons: BTreeMap<String, u64>,
503 pub population: Option<BenchPopulationInput>,
504 pub input_tokens: Option<BenchTokenCountSummary>,
505 pub output_tokens: Option<BenchTokenCountSummary>,
506 pub evidence_path: Option<PathBuf>,
507 pub error: Option<String>,
508}
509
510#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
512#[serde(deny_unknown_fields)]
513pub struct BenchRequestSloInput {
514 #[serde(default)]
515 pub request_latency_ms: Option<f64>,
516 #[serde(default)]
517 pub ttft_ms: Option<f64>,
518 #[serde(default)]
519 pub tpot_ms: Option<f64>,
520 pub minimum_good_request_ratio: f64,
521}
522
523#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
526#[serde(untagged)]
527pub enum SettingValue {
528 Bool(bool),
530 Integer(i64),
532 Float(f64),
534 String(String),
536 Array(Vec<SettingValue>),
538 Object(BTreeMap<String, SettingValue>),
540}
541
542#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
544#[serde(tag = "status", rename_all = "snake_case", deny_unknown_fields)]
545pub enum AdapterResponse {
546 Ok {
548 protocol_version: ProtocolVersion,
549 result: Box<AdapterResult>,
550 },
551 Error {
553 protocol_version: ProtocolVersion,
554 error: AdapterError,
555 },
556}
557
558impl AdapterResponse {
559 #[must_use]
561 pub const fn protocol_version(&self) -> ProtocolVersion {
562 match self {
563 Self::Ok {
564 protocol_version, ..
565 }
566 | Self::Error {
567 protocol_version, ..
568 } => *protocol_version,
569 }
570 }
571}
572
573#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
576#[serde(tag = "operation", rename_all = "snake_case", deny_unknown_fields)]
577pub enum AdapterResult {
578 PlanServe { output: Box<PlanServeResult> },
580 RenderServe { output: Box<RenderServeResult> },
582}
583
584#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
588#[serde(deny_unknown_fields)]
589pub struct PlanServeResult {
590 pub integration: IntegrationIdentity,
591 pub roles: Vec<ServeRoleResult>,
592 pub replicas: Vec<ServeReplicaRequirement>,
593 pub links: Vec<ServeRoleLink>,
594 #[serde(default, skip_serializing_if = "Option::is_none")]
595 pub gateway: Option<GatewayPlan>,
596 #[serde(default, skip_serializing_if = "Option::is_none")]
597 pub pd_router: Option<PdRouterPlan>,
598}
599
600#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
604#[serde(rename_all = "snake_case")]
605pub enum RenderSource {
606 ControlPlane,
607 Integration,
608}
609
610#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
612#[serde(rename_all = "snake_case")]
613pub enum FrontendProcessRole {
614 Gateway,
615}
616
617#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
619#[serde(deny_unknown_fields)]
620pub struct FrontendCoRendering {
621 pub process_role: FrontendProcessRole,
622}
623
624#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
626#[serde(rename_all = "snake_case")]
627pub enum FrontendGatewayComponent {
628 Gateway,
629}
630
631#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
633#[serde(rename_all = "snake_case")]
634pub enum FrontendPdRouterComponent {
635 PdRouter,
636}
637
638#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
640#[serde(transparent)]
641pub struct GatewayFrontendBinding(pub [FrontendGatewayComponent; 1]);
642
643#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
645#[serde(transparent)]
646pub struct GatewayPdRouterFrontendBinding(
647 pub (FrontendGatewayComponent, FrontendPdRouterComponent),
648);
649
650#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
654#[serde(untagged)]
655pub enum FrontendComponents {
656 Gateway(GatewayFrontendBinding),
657 GatewayPdRouter(GatewayPdRouterFrontendBinding),
658}
659
660impl FrontendComponents {
661 #[must_use]
662 pub const fn gateway() -> Self {
663 Self::Gateway(GatewayFrontendBinding([FrontendGatewayComponent::Gateway]))
664 }
665
666 #[must_use]
667 pub const fn gateway_pd_router() -> Self {
668 Self::GatewayPdRouter(GatewayPdRouterFrontendBinding((
669 FrontendGatewayComponent::Gateway,
670 FrontendPdRouterComponent::PdRouter,
671 )))
672 }
673
674 #[must_use]
675 pub const fn includes_pd_router(&self) -> bool {
676 matches!(self, Self::GatewayPdRouter(_))
677 }
678}
679
680#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
682#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
683pub enum GatewayTarget {
684 Engine { role: String },
686 PdRouter,
688}
689
690#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
693#[serde(deny_unknown_fields)]
694pub struct GatewayPlan {
695 pub backend: String,
696 pub implementation: String,
697 pub implementation_version: String,
698 pub effective_settings: BTreeMap<String, SettingValue>,
699 pub endpoint: EndpointRequirement,
700 pub readiness: ReadinessProbe,
701 #[serde(default)]
702 pub ports: Vec<String>,
703 pub targets: Vec<GatewayTarget>,
704 #[serde(default)]
705 pub render_inputs: Vec<RenderInputDeclaration>,
706 pub render_source: RenderSource,
707 pub co_rendering: FrontendCoRendering,
708}
709
710#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
712#[serde(deny_unknown_fields)]
713pub struct PdRoutingPolicies {
714 pub prefill: String,
715 pub decode: String,
716}
717
718#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
721#[serde(rename_all = "snake_case")]
722pub enum FrontendHandoff {
723 InProcess,
724}
725
726#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
729#[serde(deny_unknown_fields)]
730pub struct PdRouterPlan {
731 pub backend: String,
732 pub implementation: String,
733 pub implementation_version: String,
734 pub effective_settings: BTreeMap<String, SettingValue>,
735 pub policies: PdRoutingPolicies,
736 pub prefill_role: String,
737 pub decode_role: String,
738 pub target_scheme: TargetEndpointScheme,
739 #[serde(default)]
740 pub ports: Vec<String>,
741 pub readiness: ReadinessProbe,
742 pub handoff: FrontendHandoff,
743 #[serde(default)]
744 pub render_inputs: Vec<RenderInputDeclaration>,
745 pub render_source: RenderSource,
746 pub co_rendering: FrontendCoRendering,
747}
748
749#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
752#[serde(deny_unknown_fields)]
753pub struct RenderInputDeclaration {
754 pub source_path: String,
755}
756
757#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
760#[serde(deny_unknown_fields)]
761pub struct SuppliedRenderInput {
762 pub source_path: String,
763 pub text: String,
764 pub sha256: String,
765}
766
767#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
770#[serde(deny_unknown_fields)]
771pub struct ServeReplicaRequirement {
772 pub id: String,
773 pub role_id: String,
774 pub replica_index: u32,
775 pub device_count: u32,
776 pub ports: Vec<String>,
777 pub primary_ports: Vec<String>,
778 pub primary_readiness: ReadinessProbe,
779 pub worker_readiness: ReadinessProbe,
780 #[serde(default, skip_serializing_if = "Option::is_none")]
781 pub capture_target: Option<CaptureTargetRequirement>,
782}
783
784#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
788#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
789pub enum ServeProcessAllocation {
790 ModelRank {
791 process: String,
792 role: String,
793 role_kind: ServeRoleKind,
794 replica: u32,
795 rank: u32,
796 rank_count: u32,
797 machine: String,
798 devices: Vec<u32>,
799 model_locator: String,
800 #[serde(default, skip_serializing_if = "Option::is_none")]
801 endpoint: Option<EndpointAssignment>,
802 ports: BTreeMap<String, EndpointAssignment>,
803 cache: String,
804 launch: AllocationLaunch,
805 effective_settings: BTreeMap<String, SettingValue>,
806 effective_parallelism: Parallelism,
807 #[serde(default)]
808 links: Vec<ServeRoleLink>,
809 #[serde(default)]
810 dependencies: Vec<String>,
811 #[serde(default)]
812 render_inputs: Vec<SuppliedRenderInput>,
813 },
814 Frontend {
815 process: String,
816 process_role: FrontendProcessRole,
817 components: FrontendComponents,
818 machine: String,
819 devices: Vec<u32>,
820 endpoint: EndpointAssignment,
821 ports: BTreeMap<String, EndpointAssignment>,
822 cache: String,
823 launch: AllocationLaunch,
824 gateway: Box<GatewayPlan>,
825 #[serde(default, skip_serializing_if = "Option::is_none")]
826 pd_router: Option<Box<PdRouterPlan>>,
827 #[serde(default)]
828 links: Vec<ServeRoleLink>,
829 #[serde(default)]
830 dependencies: Vec<String>,
831 #[serde(default)]
832 render_inputs: Vec<SuppliedRenderInput>,
833 },
834}
835
836#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
838#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
839pub enum AllocationLaunch {
840 Local,
841 Ssh { target: String },
842}
843
844#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
847#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
848pub enum ServeRoleLink {
849 RequestRouting {
851 source: String,
852 targets: Vec<String>,
853 },
854 KvTransfer {
856 source: String,
857 target: String,
858 mechanism: KvTransferMechanism,
859 },
860 Bootstrap {
862 source: String,
863 target: String,
864 port: String,
865 },
866 SideChannel {
868 source: String,
869 target: String,
870 port: String,
871 },
872}
873
874#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
877#[serde(deny_unknown_fields)]
878pub struct CaptureTargetRequirement {
879 pub window_control: CaptureWindowControlRequirement,
880}
881
882#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
885#[serde(deny_unknown_fields)]
886pub struct CaptureWindowControlRequirement {
887 pub endpoint: CaptureWindowControlEndpoint,
888 pub start: HttpActionSpec,
889 pub stop: HttpActionSpec,
890}
891
892#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
895#[serde(rename_all = "snake_case")]
896pub enum CaptureWindowControlEndpoint {
897 ReplicaEntry,
899 Gateway,
901}
902
903#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
906#[serde(deny_unknown_fields)]
907pub struct RenderServeResult {
908 pub integration: IntegrationIdentity,
909 pub processes: Vec<RenderedServeProcess>,
910}
911
912#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
915#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
916pub enum RenderedServeProcess {
917 ModelRank {
918 process: String,
919 role: String,
920 replica: u32,
921 rank: u32,
922 rank_count: u32,
923 launch_files: Vec<LaunchFileDeclaration>,
924 command: ProcessSpec,
925 },
926 Frontend {
927 process: String,
928 process_role: FrontendProcessRole,
929 components: FrontendComponents,
930 launch_files: Vec<LaunchFileDeclaration>,
931 command: ProcessSpec,
932 },
933}
934
935#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
937#[serde(deny_unknown_fields)]
938pub struct LaunchFileDeclaration {
939 pub relative_path: String,
940 pub text: String,
941 pub sha256: String,
942}
943
944#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
946#[serde(deny_unknown_fields)]
947pub struct HttpActionSpec {
948 pub method: HttpMethod,
949 pub path: String,
950}
951
952#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
954#[serde(rename_all = "snake_case")]
955pub enum HttpMethod {
956 Post,
958}
959
960#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
963#[serde(deny_unknown_fields)]
964pub struct IntegrationIdentity {
965 pub adapter_id: String,
966 pub adapter_version: String,
967 pub framework: String,
968 pub framework_version: String,
969}
970
971#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
973#[serde(deny_unknown_fields)]
974pub struct ProcessSpec {
975 pub argv: Vec<String>,
976 pub env: BTreeMap<String, String>,
977}
978
979#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
981#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
982pub enum ReadinessProbe {
983 Http { path: String },
985 HttpTargetRegistry(Box<HttpTargetRegistryReadiness>),
988 ProcessAlive,
990}
991
992#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
994#[serde(deny_unknown_fields)]
995pub struct HttpTargetRegistryReadiness {
996 pub target_scheme: TargetEndpointScheme,
997 pub readiness_path: String,
998 pub registry_path: String,
999 pub targets_field: String,
1000 pub target_url_field: String,
1001 pub target_role_field: String,
1002 pub target_healthy_field: String,
1003 pub target_bootstrap_port_field: String,
1004 pub prefill_role_value: String,
1005 pub decode_role_value: String,
1006 pub prefill_bootstrap_port: String,
1007}
1008
1009#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1011#[serde(rename_all = "snake_case")]
1012pub enum TargetEndpointScheme {
1013 Http,
1015 Grpc,
1017}
1018
1019#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1022#[serde(deny_unknown_fields)]
1023pub struct EndpointRequirement {
1024 pub protocol: EndpointProtocol,
1025 pub completions_path: String,
1026 pub chat_completions_path: String,
1027 #[serde(default, skip_serializing_if = "Option::is_none")]
1028 pub prefix_cache_reset: Option<HttpActionSpec>,
1029}
1030
1031#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1033#[serde(rename_all = "snake_case")]
1034pub enum EndpointProtocol {
1035 Http,
1037}
1038
1039#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1041#[serde(deny_unknown_fields)]
1042pub struct AdapterError {
1043 pub code: AdapterErrorCode,
1044 pub message: String,
1045}
1046
1047#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1049#[serde(rename_all = "snake_case")]
1050pub enum AdapterErrorCode {
1051 InvalidRequest,
1053 UnsupportedProtocolVersion,
1055 InvalidSettings,
1057 Internal,
1059 UnsupportedOperation,
1061}
1062
1063#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1066#[serde(deny_unknown_fields)]
1067pub struct EvalClientRequest {
1068 pub protocol_version: ProtocolVersion,
1069 pub workspace_root: PathBuf,
1070 pub workspace_source_exclusions: Vec<PathBuf>,
1071 pub endpoint: ClientEndpointInput,
1072 pub model: MeasurementModelInput,
1073 pub definition: EvalDefinitionInput,
1074 pub case_budget_seconds: f64,
1076 pub artifact_dir: PathBuf,
1077}
1078
1079#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1083#[serde(deny_unknown_fields)]
1084pub struct BenchClientRequest {
1085 pub protocol_version: ProtocolVersion,
1086 pub endpoint: ClientEndpointInput,
1087 pub model: MeasurementModelInput,
1088 pub definition: BenchDefinitionInput,
1089 #[serde(default)]
1090 pub population: Option<BenchPopulationInput>,
1091 pub case: BenchCaseInput,
1092 pub case_budget_seconds: f64,
1094 pub artifact_dir: PathBuf,
1095}
1096
1097#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1099#[serde(deny_unknown_fields)]
1100pub struct BenchCaseInput {
1101 pub load_shape: BenchLoadInput,
1102 pub request_count: u32,
1103 #[serde(default)]
1104 pub warmup_request_count: u32,
1105}
1106
1107#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1109#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
1110pub enum BenchLoadInput {
1111 ConcurrencyLimited { concurrency: u32 },
1113 RequestRateLimited {
1115 request_rate: f64,
1116 burstiness: Option<f64>,
1117 },
1118 UnboundedRequestRate,
1120}
1121
1122#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1124#[serde(rename_all = "snake_case")]
1125pub enum ClientStatus {
1126 Succeeded,
1128 Failed,
1130}
1131
1132#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1134#[serde(rename_all = "snake_case")]
1135pub enum EvalFailureKind {
1136 TaskResolution,
1137 ProbeTokenizer,
1138 ProbeTransport,
1139 ProbeHttp,
1140 ProbeMalformedResponse,
1141 ProbeGeneratedOnlyLogprobs,
1142 ProbeTokenizerAlignment,
1143 MetricNormalization,
1144}
1145
1146#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1148#[serde(rename_all = "snake_case")]
1149pub enum EvalMetricComparison {
1150 AtLeast,
1151 AtMost,
1152}
1153
1154#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1156#[serde(rename_all = "snake_case")]
1157pub enum EvalMetricGateConclusion {
1158 Passed,
1159 Failed,
1160}
1161
1162#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1164#[serde(deny_unknown_fields)]
1165pub struct EvalNormalizedMetric {
1166 pub source_identity: String,
1167 pub metric: String,
1168 pub filter: Option<String>,
1169 pub native_metric_key: String,
1170 pub value: f64,
1171 pub higher_is_better: bool,
1172}
1173
1174#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1176#[serde(deny_unknown_fields)]
1177pub struct EvalMetricGate {
1178 pub metric: EvalNormalizedMetric,
1179 pub threshold: f64,
1180 pub comparison: EvalMetricComparison,
1181 pub conclusion: EvalMetricGateConclusion,
1182}
1183
1184#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1186#[serde(deny_unknown_fields)]
1187pub struct EvalTrialSummary {
1188 pub requested_trials: u32,
1189 pub issued_trials: u32,
1190 pub unissued_trials: u32,
1191 pub completed_trials: u32,
1192 pub request_failure_trials: u32,
1193 pub passed_trials: u32,
1194 pub pass_rate: Option<f64>,
1195 pub per_trial_metric: String,
1196 pub per_trial_filter: Option<String>,
1197 pub higher_is_better: bool,
1198}
1199
1200#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1202#[serde(deny_unknown_fields)]
1203pub struct EvalClientResult {
1204 pub schema_version: u32,
1207 pub status: ClientStatus,
1208 pub metrics: BTreeMap<String, f64>,
1209 #[serde(default)]
1210 pub normalized_metrics: BTreeMap<String, EvalNormalizedMetric>,
1211 #[serde(default)]
1212 pub gate: Option<EvalMetricGate>,
1213 #[serde(default)]
1214 pub trial_summary: Option<EvalTrialSummary>,
1215 pub native_command: Vec<String>,
1216 #[serde(default)]
1217 pub native_exit_code: Option<i32>,
1218 #[serde(default)]
1219 pub native_timed_out: bool,
1220 pub raw_artifacts: Vec<RawArtifact>,
1221 pub failure_kind: Option<EvalFailureKind>,
1222 pub error: Option<String>,
1223}
1224
1225#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1227#[serde(deny_unknown_fields)]
1228pub struct BenchClientResult {
1229 pub schema_version: u32,
1232 pub status: ClientStatus,
1233 pub completed_requests: u64,
1234 pub failed_requests: u64,
1235 pub normalization_schema: String,
1236 pub metrics: BTreeMap<String, f64>,
1237 #[serde(default)]
1238 pub request_slo: Option<BenchRequestSloResult>,
1239 pub native_command: Vec<String>,
1240 pub native_exit_code: Option<i32>,
1241 pub raw_artifacts: Vec<RawArtifact>,
1242 pub error: Option<String>,
1243}
1244
1245#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1247#[serde(deny_unknown_fields)]
1248pub struct BenchRequestSloResult {
1249 pub good_requests: u64,
1250 pub good_request_ratio: f64,
1251 pub goodput: f64,
1252 pub profiling_duration_seconds: f64,
1253 pub profiling_duration_source: String,
1254 pub request_count_reconciled: bool,
1255 #[serde(default)]
1256 pub native_aggregate_good_request_count: Option<u64>,
1257 #[serde(default)]
1258 pub native_aggregate_good_request_count_consistent: Option<bool>,
1259}
1260
1261#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
1263#[serde(deny_unknown_fields)]
1264pub struct RawArtifact {
1265 pub name: String,
1266 pub kind: String,
1267 pub path: PathBuf,
1268}
1269
1270#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1272#[serde(deny_unknown_fields)]
1273pub struct AdapterProtocol {
1274 pub request: AdapterRequest,
1275 pub response: AdapterResponse,
1276}
1277
1278#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
1282#[serde(deny_unknown_fields)]
1283pub struct MeasurementProtocol {
1284 #[serde(default, skip_serializing_if = "Option::is_none")]
1285 pub eval_client_request: Option<EvalClientRequest>,
1286 #[serde(default, skip_serializing_if = "Option::is_none")]
1287 pub eval_client_result: Option<EvalClientResult>,
1288 #[serde(default, skip_serializing_if = "Option::is_none")]
1289 pub bench_client_request: Option<BenchClientRequest>,
1290 #[serde(default, skip_serializing_if = "Option::is_none")]
1291 pub bench_client_result: Option<BenchClientResult>,
1292 #[serde(default, skip_serializing_if = "Option::is_none")]
1293 pub bench_dataset_preparation_request: Option<BenchDatasetPreparationRequest>,
1294 #[serde(default, skip_serializing_if = "Option::is_none")]
1295 pub bench_dataset_preparation_result: Option<BenchDatasetPreparationResult>,
1296}