Documentation
¶
Overview ¶
Copyright 2023-2025 Hanzo AI Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Copyright 2023-2025 Hanzo AI Inc. All Rights Reserved. Portions Copyright 2025 The OpenAgent Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Copyright 2023-2025 Hanzo AI Inc. All Rights Reserved. Portions Copyright 2025 The OpenAgent Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Copyright 2023-2025 Hanzo AI Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Copyright 2023-2025 Hanzo AI Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Copyright 2023-2025 Hanzo AI Inc. All Rights Reserved. Portions Copyright 2025 The OpenAgent Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Copyright 2023-2025 Hanzo AI Inc. All Rights Reserved. Portions Copyright 2025 The OpenAgent Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Copyright 2023-2025 Hanzo AI Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Copyright 2023-2025 Hanzo AI Inc. All Rights Reserved. Portions Copyright 2025 The OpenAgent Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Index ¶
- Variables
- func DeleteTrainJob(job *object.FinetuneJob, lang string) error
- func Deploy(application *object.Application, lang string) (bool, error)
- func DeploySync(application *object.Application, lang string) (bool, error)
- func Describe(apps []*object.Application, lang string)
- func FailureReason(namespace string, lang string) (string, error)
- func FinetuneNamespace(owner string) string
- func Manifest(application *object.Application, lang string) (string, error)
- func Phase(owner, name, namespace string, lang string) (string, error)
- func RegisterK8sClientFactory(f func(kubeconfig string) (K8sClient, error))
- func Status(lang string) (string, error)
- func SubmitTrainJob(job *object.FinetuneJob, hp object.Hyperparams, token, lang string) error
- func URL(namespace string, lang string) (string, error)
- func Undeploy(owner, name, namespace string, lang string) (bool, error)
- func UndeployFinetune(job *object.FinetuneJob, lang string) error
- func UndeploySync(owner, name, namespace string, lang string) (bool, error)
- func View(namespace string, lang string) (*object.ApplicationView, error)
- type K8sClient
- type Serving
- type TrainJob
Constants ¶
This section is empty.
Variables ¶
var ( ErrK8sNotFound = errors.New("k8s: resource not found") ErrK8sAlreadyExists = errors.New("k8s: resource already exists") ErrK8sForbidden = errors.New("k8s: forbidden (RBAC)") )
The cluster-error sentinels. They stand in for apierrors.IsNotFound and friends so no caller needs the k8s error package. An implementation MUST wrap the underlying error (%w) rather than replacing it: callers print the original text into failure reasons, and losing it would turn a precise RBAC message into a shrug.
Functions ¶
func DeleteTrainJob ¶
func DeleteTrainJob(job *object.FinetuneJob, lang string) error
DeleteTrainJob deletes the TrainJob CR (used for cancel). NotFound is not an error — the desired end state (gone) is already met.
func DeploySync ¶
func DeploySync(application *object.Application, lang string) (bool, error)
func Describe ¶
func Describe(apps []*object.Application, lang string)
func FailureReason ¶
FailureReason returns the failure reason for an application deployment
func FinetuneNamespace ¶
FinetuneNamespace is the per-org namespace TrainJobs (and their HF-token Secret) live in, isolating one tenant's runs from another's.
func Manifest ¶
func Manifest(application *object.Application, lang string) (string, error)
Manifest renders an application's deployment manifest from its template and parameters. Callers set it on the record before saving; nothing here touches a cluster. This is the only kustomize caller in the tree.
func RegisterK8sClientFactory ¶ added in v1.832.31
RegisterK8sClientFactory installs the cluster implementation. The kubeconfig is the ConfigText of the tenant's Kubernetes provider, so one process can serve many clusters. Called from the build that has a cluster to talk to; this service never calls it and therefore never links a Kubernetes client.
func SubmitTrainJob ¶
func SubmitTrainJob(job *object.FinetuneJob, hp object.Hyperparams, token, lang string) error
SubmitTrainJob provisions the namespace + HF-token Secret and applies the TrainJob CR. token may be "" (public repos only). Returns the namespace + CR name it used (already set on job before the call).
func UndeployFinetune ¶
func UndeployFinetune(job *object.FinetuneJob, lang string) error
UndeployFinetune deletes the InferenceService and the model registration.
func UndeploySync ¶
UndeploySync undeploys application and waits for it to be completely removed
Types ¶
type K8sClient ¶ added in v1.832.31
type K8sClient interface {
// Get returns one object. Missing objects yield ErrK8sNotFound.
Get(ctx context.Context, group, version, resource, namespace, name string) (map[string]any, error)
// List returns the objects in a namespace ("" for cluster-scoped). A missing
// CRD, API group, or namespace yields ErrK8sNotFound — callers rely on being
// able to tell "no cluster state yet" from "the request failed".
List(ctx context.Context, group, version, resource, namespace string) ([]map[string]any, error)
// Create creates one object. A losing race yields ErrK8sAlreadyExists, which
// callers treat as success.
Create(ctx context.Context, group, version, resource, namespace string, obj map[string]any) error
// Delete removes one object. A missing object yields ErrK8sNotFound, which
// callers treat as success (teardown is idempotent).
Delete(ctx context.Context, group, version, resource, namespace, name string) error
// Apply upserts ONE arbitrary object, resolving its apiVersion+kind to a
// resource through the cluster's own discovery and defaulting a namespaced
// object into namespace. This is the seam for rendered manifests: only
// something holding a cluster connection can map a Kind to a resource, so
// asking the caller to do it would drag discovery back across the boundary.
Apply(ctx context.Context, namespace string, obj map[string]any) error
// Host is the cluster API server's hostname, used to build the externally
// reachable URL for a NodePort/ClusterIP service. Empty when unknown.
Host() string
// Ready reports cluster reachability and, when false, WHY. The reason is
// surfaced verbatim to operators, so "unavailable" is never silent — the
// whole point of failing closed is that somebody can find out what is missing.
Ready() (ok bool, reason string)
}
K8sClient is the cluster seam.
func BuildK8sClient ¶ added in v1.832.31
BuildK8sClient returns the registered implementation for a kubeconfig, or the unavailable default. It never returns nil: a nil client would push a nil-check to every call site, and the one that got forgotten would panic in a request handler instead of returning an error that names what is missing.
type Serving ¶
type Serving struct {
ModelId string `json:"modelId"` // public model id (use in /v1/chat/completions)
Provider string `json:"provider"` // the registered provider name
Service string `json:"service"` // InferenceService name
Namespace string `json:"namespace"` // its namespace
Url string `json:"url"` // status.url, when already available
}
Serving is what a deploy returns to the controller.
func DeployFinetune ¶
func DeployFinetune(job *object.FinetuneJob, lang string) (*Serving, error)
DeployFinetune serves a completed job's checkpoints and registers the result as a routable model. Requires a succeeded job with an OutputUri. Idempotent: re-deploying updates the InferenceService + model records in place.
type TrainJob ¶
type TrainJob struct {
Status string // pending|queued|running|succeeded|failed|cancelled
Progress int // 0..100 (best-effort)
Message string
Started string // RFC3339, when the run entered Running (best-effort)
Finished string // RFC3339, when it reached a terminal state (best-effort)
Found bool // false when the CR no longer exists in the cluster
}
TrainJob is the live status read back from a TrainJob CR.
func TrainJobStatus ¶
func TrainJobStatus(job *object.FinetuneJob, lang string) (*TrainJob, error)
TrainJobStatus reads the TrainJob CR and maps its conditions to a object.FinetuneJob status. Found=false (no error) when the CR is gone.