1use super::sequence_checkpoint::{SequenceCheckpointLayout, SequenceCheckpointLayoutData};
2use super::{
3 AttributeId, BTreeMap, BTreeSet, CapabilityId, ContractVersion, Deserialize, Deserializer,
4 ExecutionWeightPlan, MemoryPlan, ModelFamilyId, NodeId, NodeWorkContract, OperationId,
5 OperationRegistryAuthority, PlanExactAlias, PlanHash, PlanId, PlanNode,
6 PlanProviderRejectReason, PlanSchemaVersion, PlanStateEffect, ProviderId, ProviderResourcePlan,
7 ProviderSelection, ProviderWorkspaceRequirement, QuantizationFormatId, ResolvedValueBinding,
8 ResourceId, RetainedCompletionValue, SemanticValue, Serialize, WeightFormatId,
9};
10use crate::vnext::ProviderExecutionSemantics;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct PlanNodeResolution {
17 pub(super) operation_registry_authority: OperationRegistryAuthority,
18 pub(super) node_id: NodeId,
19 pub(super) values: Vec<ResolvedValueBinding>,
20 pub(super) required_capabilities: BTreeSet<CapabilityId>,
21 pub(super) preferred_provider: Option<ProviderId>,
22 pub(super) provider_resource_candidates: Vec<ProviderResourcePlan>,
23 pub(super) provider_resolution_rejections: BTreeMap<ProviderId, PlanProviderRejectReason>,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
27#[serde(deny_unknown_fields)]
28pub struct ExecutionPlanPayload {
29 pub(super) schema: PlanSchemaVersion,
30 pub(super) plan_id: PlanId,
31 pub(super) family_id: ModelFamilyId,
32 pub(super) device_id: super::DeviceId,
33 pub(super) device_runtime_implementation_fingerprint: String,
34 pub(super) prepared_family_fingerprint: String,
35 pub(super) program_fingerprint: String,
36 pub(super) capability_catalog_fingerprint: String,
37 pub(super) policy_version: ContractVersion,
38 pub(super) policy_fingerprint: String,
39 pub(super) maximum_scheduled_tokens: u64,
40 pub(super) execution_weights: ExecutionWeightPlan,
41 pub(super) weight_format: WeightFormatId,
42 pub(super) quantization_formats: BTreeSet<QuantizationFormatId>,
43 pub(super) retained_completion_values: Vec<RetainedCompletionValue>,
44 pub(super) terminal_output_resources: Vec<ResourceId>,
45 pub(super) nodes: Vec<PlanNode>,
46 pub(super) memory: MemoryPlan,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub(super) sequence_checkpoint_layout: Option<SequenceCheckpointLayout>,
49}
50
51impl ExecutionPlanPayload {
52 pub const fn schema(&self) -> PlanSchemaVersion {
53 self.schema
54 }
55
56 pub fn plan_id(&self) -> &PlanId {
57 &self.plan_id
58 }
59
60 pub fn family_id(&self) -> &ModelFamilyId {
61 &self.family_id
62 }
63
64 pub fn device_id(&self) -> &super::DeviceId {
65 &self.device_id
66 }
67
68 pub fn device_runtime_implementation_fingerprint(&self) -> &str {
69 &self.device_runtime_implementation_fingerprint
70 }
71
72 pub fn prepared_family_fingerprint(&self) -> &str {
73 &self.prepared_family_fingerprint
74 }
75
76 pub fn program_fingerprint(&self) -> &str {
77 &self.program_fingerprint
78 }
79
80 pub fn capability_catalog_fingerprint(&self) -> &str {
81 &self.capability_catalog_fingerprint
82 }
83
84 pub const fn policy_version(&self) -> ContractVersion {
85 self.policy_version
86 }
87
88 pub fn policy_fingerprint(&self) -> &str {
89 &self.policy_fingerprint
90 }
91
92 pub const fn maximum_scheduled_tokens(&self) -> u64 {
93 self.maximum_scheduled_tokens
94 }
95
96 pub fn execution_weights(&self) -> &ExecutionWeightPlan {
97 &self.execution_weights
98 }
99
100 pub fn weight_format(&self) -> &WeightFormatId {
101 &self.weight_format
102 }
103
104 pub fn quantization_formats(&self) -> &BTreeSet<QuantizationFormatId> {
105 &self.quantization_formats
106 }
107
108 pub fn retained_completion_values(&self) -> &[RetainedCompletionValue] {
109 &self.retained_completion_values
110 }
111
112 pub fn terminal_output_resources(&self) -> &[ResourceId] {
113 &self.terminal_output_resources
114 }
115
116 pub fn nodes(&self) -> &[PlanNode] {
117 &self.nodes
118 }
119
120 pub fn memory(&self) -> &MemoryPlan {
121 &self.memory
122 }
123}
124
125#[derive(Serialize)]
126pub(super) struct PlanHashMaterial<'a> {
127 pub(super) schema: PlanSchemaVersion,
128 pub(super) family_id: &'a ModelFamilyId,
129 pub(super) device_id: &'a super::DeviceId,
130 pub(super) device_runtime_implementation_fingerprint: &'a str,
131 pub(super) prepared_family_fingerprint: &'a str,
132 pub(super) program_fingerprint: &'a str,
133 pub(super) capability_catalog_fingerprint: &'a str,
134 pub(super) policy_version: ContractVersion,
135 pub(super) policy_fingerprint: &'a str,
136 pub(super) maximum_scheduled_tokens: u64,
137 pub(super) execution_weights: &'a ExecutionWeightPlan,
138 pub(super) weight_format: &'a WeightFormatId,
139 pub(super) quantization_formats: &'a BTreeSet<QuantizationFormatId>,
140 pub(super) retained_completion_values: &'a [RetainedCompletionValue],
141 pub(super) terminal_output_resources: &'a [ResourceId],
142 pub(super) nodes: &'a [PlanNode],
143 pub(super) memory: &'a MemoryPlan,
144 #[serde(skip_serializing_if = "Option::is_none")]
145 pub(super) sequence_checkpoint_layout: Option<&'a SequenceCheckpointLayout>,
146}
147
148impl<'a> From<&'a ExecutionPlanPayload> for PlanHashMaterial<'a> {
149 fn from(payload: &'a ExecutionPlanPayload) -> Self {
150 Self {
151 schema: payload.schema,
152 family_id: &payload.family_id,
153 device_id: &payload.device_id,
154 device_runtime_implementation_fingerprint: &payload
155 .device_runtime_implementation_fingerprint,
156 prepared_family_fingerprint: &payload.prepared_family_fingerprint,
157 program_fingerprint: &payload.program_fingerprint,
158 capability_catalog_fingerprint: &payload.capability_catalog_fingerprint,
159 policy_version: payload.policy_version,
160 policy_fingerprint: &payload.policy_fingerprint,
161 maximum_scheduled_tokens: payload.maximum_scheduled_tokens,
162 execution_weights: &payload.execution_weights,
163 weight_format: &payload.weight_format,
164 quantization_formats: &payload.quantization_formats,
165 retained_completion_values: &payload.retained_completion_values,
166 terminal_output_resources: &payload.terminal_output_resources,
167 nodes: &payload.nodes,
168 memory: &payload.memory,
169 sequence_checkpoint_layout: payload.sequence_checkpoint_layout.as_ref(),
170 }
171 }
172}
173
174#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
177#[serde(deny_unknown_fields)]
178pub struct UnvalidatedProviderResourcePlan {
179 pub(super) provider_id: ProviderId,
180 pub(super) estimator_id: String,
181 pub(super) estimator_version: ContractVersion,
182 pub(super) estimator_implementation_fingerprint: String,
183 pub(super) estimator_input_fingerprint: String,
184 pub(super) estimate_fingerprint: String,
185 pub(super) value_alignment_bytes: u64,
186 pub(super) scratch: Option<ProviderWorkspaceRequirement>,
187 pub(super) binding: Option<ProviderWorkspaceRequirement>,
188 pub(super) persistent: Option<ProviderWorkspaceRequirement>,
189}
190
191#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
192#[serde(deny_unknown_fields)]
193pub struct UnvalidatedPlanNode {
194 pub(super) id: NodeId,
195 pub(super) dependencies: Vec<NodeId>,
196 pub(super) operation_id: OperationId,
197 pub(super) operation_version: ContractVersion,
198 pub(super) operation_fingerprint: String,
199 pub(super) provider_implementation_fingerprint: String,
200 pub(super) provider_execution_semantics: ProviderExecutionSemantics,
201 pub(super) required_capabilities: BTreeSet<CapabilityId>,
202 pub(super) attributes: BTreeMap<AttributeId, SemanticValue>,
203 pub(super) work: NodeWorkContract,
204 pub(super) selection: ProviderSelection,
205 pub(super) provider_resources: UnvalidatedProviderResourcePlan,
206 pub(super) values: Vec<ResolvedValueBinding>,
207 pub(super) exact_aliases: Vec<PlanExactAlias>,
208 pub(super) state_effects: Vec<PlanStateEffect>,
209 pub(super) scratch_resource: Option<ResourceId>,
210 pub(super) binding_resource: Option<ResourceId>,
211 pub(super) persistent_resource: Option<ResourceId>,
212 pub(super) resources: Vec<ResourceId>,
213}
214
215#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
216#[serde(deny_unknown_fields)]
217pub(super) struct UnvalidatedExecutionPlanPayload {
218 pub(super) schema: PlanSchemaVersion,
219 pub(super) plan_id: PlanId,
220 pub(super) family_id: ModelFamilyId,
221 pub(super) device_id: super::DeviceId,
222 pub(super) device_runtime_implementation_fingerprint: String,
223 pub(super) prepared_family_fingerprint: String,
224 pub(super) program_fingerprint: String,
225 pub(super) capability_catalog_fingerprint: String,
226 pub(super) policy_version: ContractVersion,
227 pub(super) policy_fingerprint: String,
228 pub(super) maximum_scheduled_tokens: u64,
229 pub(super) execution_weights: ExecutionWeightPlan,
230 pub(super) weight_format: WeightFormatId,
231 pub(super) quantization_formats: BTreeSet<QuantizationFormatId>,
232 pub(super) retained_completion_values: Vec<RetainedCompletionValue>,
233 pub(super) terminal_output_resources: Vec<ResourceId>,
234 pub(super) nodes: Vec<UnvalidatedPlanNode>,
235 pub(super) memory: MemoryPlan,
236 #[serde(default, skip_serializing_if = "Option::is_none")]
237 pub(super) sequence_checkpoint_layout: Option<SequenceCheckpointLayoutData>,
238}
239
240#[derive(Debug, Clone, PartialEq, Eq)]
241pub struct UnvalidatedExecutionPlan {
242 pub(super) payload: UnvalidatedExecutionPlanPayload,
243 pub(super) plan_hash: PlanHash,
244}
245
246#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
247pub(crate) struct UnvalidatedExecutionPlanWire {
248 pub(super) payload: UnvalidatedExecutionPlanPayload,
249 pub(super) plan_hash: PlanHash,
250}
251
252#[derive(Deserialize, Serialize)]
253#[serde(deny_unknown_fields)]
254pub(super) struct UnvalidatedExecutionPlanWireFields {
255 pub(super) payload: UnvalidatedExecutionPlanPayload,
256 pub(super) plan_hash: PlanHash,
257}
258
259impl<'de> Deserialize<'de> for UnvalidatedExecutionPlanWire {
260 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
261 where
262 D: Deserializer<'de>,
263 {
264 let raw = serde_json::Value::deserialize(deserializer)?;
265 let fields = UnvalidatedExecutionPlanWireFields::deserialize(&raw)
266 .map_err(serde::de::Error::custom)?;
267 if let Some(layout) = &fields.payload.sequence_checkpoint_layout {
268 layout
269 .validate_version()
270 .map_err(serde::de::Error::custom)?;
271 }
272 let canonical = serde_json::to_value(&fields).map_err(serde::de::Error::custom)?;
273 if canonical != raw {
274 return Err(serde::de::Error::custom(
275 "execution plan wire contains unknown or non-canonical nested fields",
276 ));
277 }
278 Ok(Self {
279 payload: fields.payload,
280 plan_hash: fields.plan_hash,
281 })
282 }
283}
284
285impl From<UnvalidatedExecutionPlanWire> for UnvalidatedExecutionPlan {
286 fn from(wire: UnvalidatedExecutionPlanWire) -> Self {
287 Self {
288 payload: wire.payload,
289 plan_hash: wire.plan_hash,
290 }
291 }
292}