Skip to content

Commit c7f81e3

Browse files
authored
Merge pull request #989 from zhouyou9505/migrate/apix-v1alpha2-pkg-generator
migrate: sigs.k8s.io/gateway-api-inference-extension @ ed1af5d8
2 parents cb2e8fb + d205388 commit c7f81e3

78 files changed

Lines changed: 4448 additions & 38 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apix/v1alpha2/doc.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package v1alpha2 contains API Schema definitions for the
18+
// inference.networking.x-k8s.io API group.
19+
//
20+
// +k8s:openapi-gen=true
21+
// +kubebuilder:object:generate=true
22+
// +groupName=inference.networking.x-k8s.io
23+
// +groupGoName=XInference
24+
package v1alpha2
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha2
18+
19+
import (
20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
)
22+
23+
// InferenceModelRewrite is the Schema for the InferenceModelRewrite API.
24+
// +kubebuilder:object:root=true
25+
// +kubebuilder:subresource:status
26+
// +kubebuilder:printcolumn:name="Inference Pool",type=string,JSONPath=`.spec.poolRef.name`
27+
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
28+
// +genclient
29+
type InferenceModelRewrite struct {
30+
metav1.TypeMeta `json:",inline"`
31+
metav1.ObjectMeta `json:"metadata,omitempty"`
32+
33+
Spec InferenceModelRewriteSpec `json:"spec,omitempty"`
34+
Status InferenceModelRewriteStatus `json:"status,omitempty"`
35+
}
36+
37+
// InferenceModelRewriteList contains a list of InferenceModelRewrite.
38+
//
39+
// +kubebuilder:object:root=true
40+
type InferenceModelRewriteList struct {
41+
metav1.TypeMeta `json:",inline"`
42+
metav1.ListMeta `json:"metadata,omitempty"`
43+
Items []InferenceModelRewrite `json:"items"`
44+
}
45+
46+
// InferenceModelRewriteSpec defines the desired state of InferenceModelRewrite.
47+
type InferenceModelRewriteSpec struct {
48+
// PoolRef is a reference to the inference pool.
49+
// +kubebuilder:validation:Required
50+
PoolRef *PoolObjectReference `json:"poolRef"`
51+
52+
// Rules are the ordered set of rules for rewriting inference requests.
53+
// The first rule to match a request will be used.
54+
55+
//
56+
// --- Precedence and Conflict Resolution ---
57+
// If multiple InferenceModelRewrite resources target the same
58+
// InferencePool, the controller will merge them based on precedence.
59+
//
60+
// Across all rules specified on applicable rewrites, precedence MUST be
61+
// given to the match having an "Exact" model match over a generic match
62+
// (a rule with an empty `matches` array).
63+
//
64+
// If ties still exist across multiple InferenceModelRewrite resources (e.g.
65+
// two rewrites both have an exact match for the same model), matching
66+
// precedence MUST be determined by the oldest resource based on
67+
// creation timestamp.
68+
//
69+
// If ties still exist within a single InferenceModelRewrite resource, the
70+
// FIRST matching rule (in list order) is used.
71+
// +required
72+
Rules []InferenceModelRewriteRule `json:"rules"`
73+
}
74+
75+
// InferenceModelRewriteRule defines the match criteria and corresponding action.
76+
// For details on how precedence is determined across multiple rules and
77+
// InferenceModelRewrite resources, see the "Precedence and Conflict Resolution"
78+
// section in InferenceModelRewriteSpec.
79+
type InferenceModelRewriteRule struct {
80+
// Matches defines the criteria for matching a request.
81+
// If multiple match criteria are specified, a request matches if
82+
// ANY of the criteria are satisfied (logical OR).
83+
// If empty, the rule matches all requests.
84+
85+
// +optional
86+
Matches []Match `json:"matches,omitempty"`
87+
88+
// --- Actions ---
89+
// Targets defines how to distribute traffic across a set of
90+
// weighted model targets. This is used for traffic splitting, A/B tests,
91+
// or canary rollouts.
92+
// +optional
93+
// +kubebuilder:validation:MinItems=1
94+
//
95+
Targets []TargetModel `json:"targets,omitempty"`
96+
}
97+
98+
// TargetModel defines a weighted model destination for traffic distribution.
99+
type TargetModel struct {
100+
// (The following comment is copied from the original targetModel)
101+
// Weight is used to determine the proportion of traffic that should be
102+
// sent to this model when multiple target models are specified.
103+
//
104+
// Weight defines the proportion of requests forwarded to the specified
105+
// model. This is computed as weight/(sum of all weights in this
106+
// TargetModels list). For non-zero values, there may be some epsilon from
107+
// the exact proportion defined here depending on the precision an
108+
// implementation supports. Weight is not a percentage and the sum of
109+
// weights does not need to equal 100.
110+
//
111+
// If a weight is set for any targetModel, it must be set for all targetModels.
112+
// Conversely weights are optional, so long as ALL targetModels do not specify a weight.
113+
//
114+
// +optional
115+
// +kubebuilder:validation:Minimum=1
116+
// +kubebuilder:validation:Maximum=1000000
117+
Weight int32 `json:"weight"`
118+
119+
// --- Destination Types ---
120+
// ModelRewrite specifies a static model name destination.
121+
// +required
122+
ModelRewrite string `json:"modelRewrite"`
123+
}
124+
125+
// Match defines the criteria for matching the LLM requests.
126+
type Match struct {
127+
// Model specifies the criteria for matching the 'model' field
128+
// within the JSON request body.
129+
// +required
130+
Model *ModelMatch `json:"model,omitempty"`
131+
}
132+
133+
// ModelMatch defines how to match against the model name in the request body.
134+
type ModelMatch struct {
135+
// Type specifies the kind of string matching to use.
136+
// Supported value is "Exact". Defaults to "Exact".
137+
// +optional
138+
// +kubebuilder:default=Exact
139+
Type *MatchValidationType `json:"type,omitempty"`
140+
141+
// Value is the model name string to match against.
142+
// +required
143+
// +kubebuilder:validation:MinLength=1
144+
Value string `json:"value"`
145+
}
146+
147+
// MatchValidationType specifies the type of string matching to use.
148+
// +kubebuilder:validation:Enum=Exact
149+
type MatchValidationType string
150+
151+
const (
152+
// MatchExact indicates that the model name must match exactly.
153+
MatchExact MatchValidationType = "Exact"
154+
)
155+
156+
// InferenceModelRewriteStatus defines the observed state of InferenceModelRewrite.
157+
type InferenceModelRewriteStatus struct {
158+
// Conditions track the state of the InferenceModelRewrite.
159+
//
160+
// Known condition types are:
161+
//
162+
// * "Accepted"
163+
//
164+
// +optional
165+
// +listType=map
166+
// +listMapKey=type
167+
// +kubebuilder:validation:MaxItems=8
168+
// +kubebuilder:default={{type: "Accepted", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}
169+
Conditions []metav1.Condition `json:"conditions,omitempty"`
170+
}
171+
172+
// InferenceModelRewriteConditionType is a type of condition for the InferenceModelRewrite.
173+
type InferenceModelRewriteConditionType string
174+
175+
// InferenceModelRewriteConditionReason is the reason for a given InferenceModelRewriteConditionType.
176+
type InferenceModelRewriteConditionReason string
177+
178+
const (
179+
// RewriteConditionAccepted indicates if the rewrite is accepted, and if not, why.
180+
// This is the primary condition for this resource.
181+
//
182+
// Possible reasons for this condition to be True are:
183+
//
184+
// * "Accepted"
185+
//
186+
// Possible reasons for this condition to be Unknown are:
187+
//
188+
// * "Pending"
189+
//
190+
RewriteConditionAccepted InferenceModelRewriteConditionType = "Accepted"
191+
192+
// RewriteReasonAccepted indicates the rewrite is valid, non-conflicting,
193+
// and has been successfully applied to the inference pool.
194+
RewriteReasonAccepted InferenceModelRewriteConditionReason = "Accepted"
195+
196+
// RewriteReasonPending is the initial state, and indicates that the
197+
// controller has not yet reconciled the InferenceModelRewrite.
198+
RewriteReasonPending InferenceModelRewriteConditionReason = "Pending"
199+
)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha2
18+
19+
import (
20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
)
22+
23+
// InferenceObjective is the Schema for the InferenceObjectives API.
24+
//
25+
// +kubebuilder:object:root=true
26+
// +kubebuilder:subresource:status
27+
// +kubebuilder:storageversion
28+
// +kubebuilder:printcolumn:name="Inference Pool",type=string,JSONPath=`.spec.poolRef.name`
29+
// +kubebuilder:printcolumn:name="Priority",type=string,JSONPath=`.spec.priority`
30+
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
31+
// +genclient
32+
type InferenceObjective struct {
33+
metav1.TypeMeta `json:",inline"`
34+
metav1.ObjectMeta `json:"metadata,omitempty"`
35+
36+
Spec InferenceObjectiveSpec `json:"spec,omitempty"`
37+
Status InferenceObjectiveStatus `json:"status,omitempty"`
38+
}
39+
40+
// InferenceObjectiveList contains a list of InferenceObjective.
41+
//
42+
// +kubebuilder:object:root=true
43+
type InferenceObjectiveList struct {
44+
metav1.TypeMeta `json:",inline"`
45+
metav1.ListMeta `json:"metadata,omitempty"`
46+
Items []InferenceObjective `json:"items"`
47+
}
48+
49+
// InferenceObjectiveSpec represents the desired state of a specific model use case. This resource is
50+
// managed by the "Inference Workload Owner" persona.
51+
//
52+
// The Inference Workload Owner persona is someone that trains, verifies, and
53+
// leverages a large language model from a model frontend, drives the lifecycle
54+
// and rollout of new versions of those models, and defines the specific
55+
// performance and latency goals for the model. These workloads are
56+
// expected to operate within an InferencePool sharing compute capacity with other
57+
// InferenceObjectives, defined by the Inference Platform Admin.
58+
type InferenceObjectiveSpec struct {
59+
60+
// Priority defines how important it is to serve the request compared to other requests in the same pool.
61+
// Priority is an integer value that defines the priority of the request.
62+
// The higher the value, the more critical the request is; negative values _are_ allowed.
63+
// No default value is set for this field, allowing for future additions of new fields that may 'one of' with this field.
64+
// However, implementations that consume this field (such as the Endpoint Picker) will treat an unset value as '0'.
65+
// Priority is used in flow control, primarily in the event of resource scarcity(requests need to be queued).
66+
// All requests will be queued, and flow control will _always_ allow requests of higher priority to be served first.
67+
// Fairness is only enforced and tracked between requests of the same priority.
68+
//
69+
// Example: requests with Priority 10 will always be served before
70+
// requests with Priority of 0 (the value used if Priority is unset or no InferenceObjective is specified).
71+
// Similarly requests with a Priority of -10 will always be served after requests with Priority of 0.
72+
// +optional
73+
Priority *int `json:"priority,omitempty"`
74+
75+
// PoolRef is a reference to the inference pool, the pool must exist in the same namespace.
76+
//
77+
// +kubebuilder:validation:Required
78+
PoolRef PoolObjectReference `json:"poolRef"`
79+
}
80+
81+
// InferenceObjectiveStatus defines the observed state of InferenceObjective
82+
type InferenceObjectiveStatus struct {
83+
// Conditions track the state of the InferenceObjective.
84+
//
85+
// Known condition types are:
86+
//
87+
// * "Accepted"
88+
//
89+
// +optional
90+
// +listType=map
91+
// +listMapKey=type
92+
// +kubebuilder:validation:MaxItems=8
93+
// +kubebuilder:default={{type: "Ready", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}
94+
Conditions []metav1.Condition `json:"conditions,omitempty"`
95+
}
96+
97+
// InferenceObjectiveConditionType is a type of condition for the InferenceObjective.
98+
type InferenceObjectiveConditionType string
99+
100+
// InferenceObjectiveConditionReason is the reason for a given InferenceObjectiveConditionType.
101+
type InferenceObjectiveConditionReason string
102+
103+
const (
104+
// ObjectiveConditionAccepted indicates if the objective config is accepted, and if not, why.
105+
//
106+
// Possible reasons for this condition to be True are:
107+
//
108+
// * "Accepted"
109+
//
110+
// Possible reasons for this condition to be Unknown are:
111+
//
112+
// * "Pending"
113+
//
114+
ObjectiveConditionAccepted InferenceObjectiveConditionType = "Accepted"
115+
116+
// ObjectiveReasonAccepted is the desired state. Model conforms to the state of the pool.
117+
ObjectiveReasonAccepted InferenceObjectiveConditionReason = "Accepted"
118+
119+
// ObjectiveReasonPending is the initial state, and indicates that the controller has not yet reconciled the InferenceObjective.
120+
ObjectiveReasonPending InferenceObjectiveConditionReason = "Pending"
121+
)

0 commit comments

Comments
 (0)