Skip to content

Commit 40aa227

Browse files
committed
refactor: replace deprecated WithConfigMediaType with WithManifestOptions and clean up related code
1 parent 699ef41 commit 40aa227

9 files changed

Lines changed: 63 additions & 158 deletions

File tree

pkg/distribution/builder/builder.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ import (
77
"io"
88
"time"
99

10-
"github.com/opencontainers/go-digest"
11-
1210
"github.com/docker/model-runner/pkg/distribution/format"
1311
"github.com/docker/model-runner/pkg/distribution/internal/mutate"
1412
"github.com/docker/model-runner/pkg/distribution/internal/partial"
1513
"github.com/docker/model-runner/pkg/distribution/modelpack"
1614
"github.com/docker/model-runner/pkg/distribution/oci"
1715
"github.com/docker/model-runner/pkg/distribution/types"
16+
"github.com/opencontainers/go-digest"
1817
)
1918

2019
// BuildFormat specifies the output artifact format.

pkg/distribution/builder/from_directory.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ import (
88
"strings"
99
"time"
1010

11-
"github.com/opencontainers/go-digest"
12-
1311
"github.com/docker/model-runner/pkg/distribution/files"
1412
"github.com/docker/model-runner/pkg/distribution/format"
1513
"github.com/docker/model-runner/pkg/distribution/internal/mutate"
1614
"github.com/docker/model-runner/pkg/distribution/internal/partial"
1715
"github.com/docker/model-runner/pkg/distribution/modelpack"
1816
"github.com/docker/model-runner/pkg/distribution/oci"
1917
"github.com/docker/model-runner/pkg/distribution/types"
18+
"github.com/opencontainers/go-digest"
2019
)
2120

2221
const rootFSType = "rootfs"

pkg/distribution/internal/mutate/model.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ func (m *model) GetManifestOptions() partial.ManifestOptions {
109109
var opts partial.ManifestOptions
110110
if base, ok := m.base.(partial.WithManifestOptions); ok {
111111
opts = base.GetManifestOptions()
112-
} else if cmt, ok := m.base.(partial.WithConfigMediaType); ok {
113-
opts.ConfigMediaType = cmt.GetConfigMediaType()
114112
}
115113
// Apply overrides set on this wrapper.
116114
if m.configMediaType != "" {

pkg/distribution/internal/partial/cncf_model.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ func (m *CNCFModel) GetManifestOptions() ManifestOptions {
3131
}
3232
}
3333

34-
// GetConfigMediaType implements WithConfigMediaType for backward compatibility.
35-
func (m *CNCFModel) GetConfigMediaType() oci.MediaType {
36-
return modelpack.MediaTypeModelConfigV1
37-
}
38-
3934
func (m *CNCFModel) Layers() ([]oci.Layer, error) {
4035
return m.LayerList, nil
4136
}

pkg/distribution/internal/partial/model.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,11 @@ func (m *BaseModel) Descriptor() (types.Descriptor, error) {
130130
return Descriptor(m)
131131
}
132132

133-
// GetConfigMediaType returns the config media type for the model.
134-
// If not set, returns empty string and ManifestForLayers will default to V0.1.
135-
func (m *BaseModel) GetConfigMediaType() oci.MediaType {
136-
return m.ConfigMediaType
133+
// GetManifestOptions implements WithManifestOptions, providing the config
134+
// media type for Docker-format models. If ConfigMediaType is not set,
135+
// ManifestForLayers will default to V0.1.
136+
func (m *BaseModel) GetManifestOptions() ManifestOptions {
137+
return ManifestOptions{
138+
ConfigMediaType: m.ConfigMediaType,
139+
}
137140
}

pkg/distribution/internal/partial/partial.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -301,12 +301,6 @@ func matchesMediaType(layerMT, targetMT oci.MediaType, modelFormat string) bool
301301
return false
302302
}
303303

304-
// WithConfigMediaType provides access to the config media type version.
305-
// Deprecated: prefer WithManifestOptions which also carries the artifact type.
306-
type WithConfigMediaType interface {
307-
GetConfigMediaType() oci.MediaType
308-
}
309-
310304
// ManifestOptions holds the manifest-level metadata for an artifact.
311305
type ManifestOptions struct {
312306
// ConfigMediaType is the media type of the config blob.
@@ -317,29 +311,23 @@ type ManifestOptions struct {
317311
ArtifactType string
318312
}
319313

320-
// WithManifestOptions provides manifest assembly options. It takes precedence
321-
// over WithConfigMediaType when both are implemented.
314+
// WithManifestOptions provides manifest assembly options.
322315
type WithManifestOptions interface {
323316
GetManifestOptions() ManifestOptions
324317
}
325318

326-
// resolveManifestOptions extracts manifest options from the given object,
327-
// checking WithManifestOptions first and falling back to WithConfigMediaType.
319+
// resolveManifestOptions extracts manifest options from the given object
320+
// via the WithManifestOptions interface.
328321
func resolveManifestOptions(i interface{}) ManifestOptions {
329322
if mof, ok := i.(WithManifestOptions); ok {
330323
return mof.GetManifestOptions()
331324
}
332-
if cmt, ok := i.(WithConfigMediaType); ok {
333-
if mt := cmt.GetConfigMediaType(); mt != "" {
334-
return ManifestOptions{ConfigMediaType: mt}
335-
}
336-
}
337325
return ManifestOptions{}
338326
}
339327

340328
// ManifestForLayers assembles an OCI manifest for the given model. The
341329
// config media type and optional artifact type are read from the model via
342-
// the WithManifestOptions interface (or the legacy WithConfigMediaType).
330+
// the WithManifestOptions interface.
343331
func ManifestForLayers(i WithLayers) (*oci.Manifest, error) {
344332
raw, err := i.RawConfigFile()
345333
if err != nil {

pkg/distribution/internal/testutil/model.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,13 @@ func NewModelPackArtifact(t *testing.T, model modelpack.Model, layers ...LayerSp
143143
return NewArtifact(rawConfig, modelpack.MediaTypeModelConfigV1, builtLayers...)
144144
}
145145

146-
// GetConfigMediaType implements partial.WithConfigMediaType so that ManifestForLayers
147-
// uses the correct config media type when building the OCI manifest.
148-
func (a *Artifact) GetConfigMediaType() oci.MediaType {
149-
return a.configMediaType
146+
// GetManifestOptions implements partial.WithManifestOptions so that
147+
// ManifestForLayers uses the correct config media type when building the
148+
// OCI manifest.
149+
func (a *Artifact) GetManifestOptions() partial.ManifestOptions {
150+
return partial.ManifestOptions{
151+
ConfigMediaType: a.configMediaType,
152+
}
150153
}
151154

152155
// ID implements types.ModelArtifact.

pkg/distribution/modelpack/convert.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const (
3232
// 2. Filepath/annotation heuristics for ambiguous media types.
3333
// 3. Docker media type fallback.
3434
func ClassifyLayer(dockerMT oci.MediaType, path string) LayerKind {
35-
switch dockerMT {
35+
switch dockerMT { //nolint:exhaustive // Only Docker semantic media types are classified; OCI standard types fall through to filepath heuristics.
3636
case types.MediaTypeLicense:
3737
return KindDoc
3838
case types.MediaTypeChatTemplate, types.MediaTypeVLLMConfigArchive, types.MediaTypeModelFile:
@@ -62,6 +62,8 @@ func classifyByPath(path string) LayerKind {
6262
return KindDoc
6363
case files.FileTypeChatTemplate:
6464
return KindWeightConfig
65+
case files.FileTypeUnknown:
66+
return KindWeightConfig
6567
case files.FileTypeConfig:
6668
// .md files are documentation, not weight config.
6769
if strings.ToLower(filepath.Ext(path)) == ".md" {
@@ -80,9 +82,10 @@ func LayerKindToMediaType(kind LayerKind) oci.MediaType {
8082
return MediaTypeWeightRaw
8183
case KindDoc:
8284
return MediaTypeDocRaw
83-
default:
85+
case KindWeightConfig:
8486
return MediaTypeWeightConfigRaw
8587
}
88+
return MediaTypeWeightConfigRaw
8689
}
8790

8891
// MapLayerMediaType returns the CNCF model-spec media type for the given

pkg/distribution/modelpack/types.go

Lines changed: 38 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,20 @@
33
// without conversion. Both Docker and ModelPack formats are supported natively through
44
// the types.ModelConfig interface.
55
//
6-
// Note: JSON tags in this package use camelCase (e.g., "createdAt", "paramSize") to match
7-
// the CNCF ModelPack spec, which differs from Docker model-spec's snake_case convention
8-
// (e.g., "context_size").
6+
// The struct types (ModelDescriptor, ModelConfig, ModelFS, ModelCapabilities) are
7+
// re-exported directly from the official CNCF model-spec Go module so that
8+
// serialization tags and field definitions stay in sync with the specification.
99
//
1010
// See: https://github.com/modelpack/model-spec
1111
package modelpack
1212

1313
import (
1414
"encoding/json"
1515
"strings"
16-
"time"
1716

1817
"github.com/docker/model-runner/pkg/distribution/types"
19-
"github.com/opencontainers/go-digest"
20-
2118
specv1 "github.com/modelpack/model-spec/specs-go/v1"
19+
"github.com/opencontainers/go-digest"
2220
)
2321

2422
const (
@@ -60,6 +58,40 @@ const (
6058
MediaTypeWeightSafetensors = "application/vnd.cncf.model.weight.v1.safetensors"
6159
)
6260

61+
// Type aliases re-export the canonical CNCF model-spec struct types so that
62+
// callers use the upstream definitions (and their JSON tags) by default.
63+
// This eliminates local struct duplication while keeping the modelpack
64+
// package as the single import for DMR code.
65+
type (
66+
// ModelDescriptor defines the general information of a model.
67+
ModelDescriptor = specv1.ModelDescriptor
68+
69+
// ModelConfig defines the execution parameters for an inference engine.
70+
ModelConfig = specv1.ModelConfig
71+
72+
// ModelFS describes the layer content addresses.
73+
ModelFS = specv1.ModelFS
74+
75+
// ModelCapabilities defines the special capabilities that the model supports.
76+
ModelCapabilities = specv1.ModelCapabilities
77+
)
78+
79+
// Model represents the CNCF ModelPack config structure.
80+
// It provides the `application/vnd.cncf.model.config.v1+json` mediatype when marshalled to JSON.
81+
//
82+
// The struct mirrors specv1.Model but is declared as its own named type so
83+
// that it can implement the types.ModelConfig interface required by DMR.
84+
type Model struct {
85+
// Descriptor provides metadata about the model provenance and identity.
86+
Descriptor ModelDescriptor `json:"descriptor"`
87+
88+
// ModelFS describes the layer content addresses.
89+
ModelFS ModelFS `json:"modelfs"`
90+
91+
// Config defines the execution parameters for the model.
92+
Config ModelConfig `json:"config,omitempty"`
93+
}
94+
6395
// IsModelPackWeightMediaType checks if the given media type is a CNCF ModelPack weight layer type.
6496
// This includes both format-specific types (e.g., .gguf, .safetensors) and
6597
// format-agnostic types from the official model-spec (e.g., .raw, .tar).
@@ -126,121 +158,6 @@ func IsModelPackConfig(raw []byte) bool {
126158
return false
127159
}
128160

129-
// Model represents the CNCF ModelPack config structure.
130-
// It provides the `application/vnd.cncf.model.config.v1+json` mediatype when marshalled to JSON.
131-
type Model struct {
132-
// Descriptor provides metadata about the model provenance and identity.
133-
Descriptor ModelDescriptor `json:"descriptor"`
134-
135-
// ModelFS describes the layer content addresses.
136-
ModelFS ModelFS `json:"modelfs"`
137-
138-
// Config defines the execution parameters for the model.
139-
Config ModelConfig `json:"config,omitempty"`
140-
}
141-
142-
// ModelDescriptor defines the general information of a model.
143-
type ModelDescriptor struct {
144-
// CreatedAt is the date and time on which the model was built.
145-
CreatedAt *time.Time `json:"createdAt,omitempty"`
146-
147-
// Authors contains the contact details of the people or organization responsible for the model.
148-
Authors []string `json:"authors,omitempty"`
149-
150-
// Family is the model family, such as llama3, gpt2, qwen2, etc.
151-
Family string `json:"family,omitempty"`
152-
153-
// Name is the model name, such as llama3-8b-instruct, gpt2-xl, etc.
154-
Name string `json:"name,omitempty"`
155-
156-
// DocURL is the URL to get documentation on the model.
157-
DocURL string `json:"docURL,omitempty"`
158-
159-
// SourceURL is the URL to get source code for building the model.
160-
SourceURL string `json:"sourceURL,omitempty"`
161-
162-
// DatasetsURL contains URLs referencing datasets that the model was trained upon.
163-
DatasetsURL []string `json:"datasetsURL,omitempty"`
164-
165-
// Version is the version of the packaged software.
166-
Version string `json:"version,omitempty"`
167-
168-
// Revision is the source control revision identifier for the packaged software.
169-
Revision string `json:"revision,omitempty"`
170-
171-
// Vendor is the name of the distributing entity, organization or individual.
172-
Vendor string `json:"vendor,omitempty"`
173-
174-
// Licenses contains the license(s) under which contained software is distributed
175-
// as an SPDX License Expression.
176-
Licenses []string `json:"licenses,omitempty"`
177-
178-
// Title is the human-readable title of the model.
179-
Title string `json:"title,omitempty"`
180-
181-
// Description is the human-readable description of the software packaged in the model.
182-
Description string `json:"description,omitempty"`
183-
}
184-
185-
// ModelConfig defines the execution parameters which should be used as a base
186-
// when running a model using an inference engine.
187-
type ModelConfig struct {
188-
// Architecture is the model architecture, such as transformer, cnn, rnn, etc.
189-
Architecture string `json:"architecture,omitempty"`
190-
191-
// Format is the model format, such as gguf, safetensors, onnx, etc.
192-
Format string `json:"format,omitempty"`
193-
194-
// ParamSize is the size of the model parameters, such as "8b", "16b", "32b", etc.
195-
ParamSize string `json:"paramSize,omitempty"`
196-
197-
// Precision is the model precision, such as bf16, fp16, int8, mixed etc.
198-
Precision string `json:"precision,omitempty"`
199-
200-
// Quantization is the model quantization method, such as awq, gptq, etc.
201-
Quantization string `json:"quantization,omitempty"`
202-
203-
// Capabilities defines special capabilities that the model supports.
204-
Capabilities *ModelCapabilities `json:"capabilities,omitempty"`
205-
}
206-
207-
// ModelCapabilities defines the special capabilities that the model supports.
208-
type ModelCapabilities struct {
209-
// InputTypes specifies what input modalities the model can process.
210-
// Values can be: "text", "image", "audio", "video", "embedding", "other".
211-
InputTypes []string `json:"inputTypes,omitempty"`
212-
213-
// OutputTypes specifies what output modalities the model can produce.
214-
// Values can be: "text", "image", "audio", "video", "embedding", "other".
215-
OutputTypes []string `json:"outputTypes,omitempty"`
216-
217-
// KnowledgeCutoff is the date of the datasets that the model was trained on.
218-
KnowledgeCutoff *time.Time `json:"knowledgeCutoff,omitempty"`
219-
220-
// Reasoning indicates whether the model can perform reasoning tasks.
221-
Reasoning *bool `json:"reasoning,omitempty"`
222-
223-
// ToolUsage indicates whether the model can use external tools.
224-
ToolUsage *bool `json:"toolUsage,omitempty"`
225-
226-
// Reward indicates whether the model is a reward model.
227-
Reward *bool `json:"reward,omitempty"`
228-
229-
// Languages indicates the languages that the model can speak.
230-
// Encoded as ISO 639 two letter codes. For example, ["en", "fr", "zh"].
231-
Languages []string `json:"languages,omitempty"`
232-
}
233-
234-
// ModelFS describes the layer content addresses.
235-
type ModelFS struct {
236-
// Type is the type of the rootfs. MUST be set to "layers".
237-
Type string `json:"type"`
238-
239-
// DiffIDs is an array of layer content hashes (DiffIDs),
240-
// in order from bottom-most to top-most.
241-
DiffIDs []digest.Digest `json:"diffIds"`
242-
}
243-
244161
// Ensure Model implements types.ModelConfig
245162
var _ types.ModelConfig = (*Model)(nil)
246163

0 commit comments

Comments
 (0)