fix: support v0.2

<optional footer>

Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
This commit is contained in:
Christopher Phillips 2026-05-27 10:45:37 -04:00
parent 1f035bc369
commit 58b6f5807e
No known key found for this signature in database
3 changed files with 38 additions and 6 deletions

View File

@ -29,12 +29,12 @@ func NewGGUFCataloger() pkg.Cataloger {
// covering three discovery paths: // covering three discovery paths:
// - **/*.safetensors files (single-file models; header-only parse) // - **/*.safetensors files (single-file models; header-only parse)
// - **/model.safetensors.index.json files (sharded models) // - **/model.safetensors.index.json files (sharded models)
// - application/vnd.docker.ai.model.config.v0.1+json OCI layers (Docker Model // - application/vnd.docker.ai.model.config.v0.1+json / v0.2+json OCI layers
// Runner artifacts whose config advertises format=="safetensors") // (Docker Model Runner artifacts whose config advertises format=="safetensors")
func NewSafeTensorsCataloger() pkg.Cataloger { func NewSafeTensorsCataloger() pkg.Cataloger {
return generic.NewCataloger(safeTensorsCatalogerName). return generic.NewCataloger(safeTensorsCatalogerName).
WithParserByGlobs(parseSafeTensorsFile, "**/*.safetensors"). WithParserByGlobs(parseSafeTensorsFile, "**/*.safetensors").
WithParserByGlobs(parseSafeTensorsIndex, "**/*.safetensors.index.json"). WithParserByGlobs(parseSafeTensorsIndex, "**/*.safetensors.index.json").
WithParserByMediaType(parseSafeTensorsOCIConfig, dockerAIModelConfigMediaType). WithParserByMediaType(parseSafeTensorsOCIConfig, dockerAIModelConfigMediaTypes...).
WithProcessors(safeTensorsMergeProcessor) WithProcessors(safeTensorsMergeProcessor)
} }

View File

@ -18,11 +18,20 @@ import (
// Docker AI OCI media types used by Docker Model Runner artifacts. // Docker AI OCI media types used by Docker Model Runner artifacts.
const ( const (
dockerAIModelConfigMediaType = "application/vnd.docker.ai.model.config.v0.1+json" dockerAIModelFileMediaType = "application/vnd.docker.ai.model.file"
dockerAIModelFileMediaType = "application/vnd.docker.ai.model.file" dockerAILicenseMediaType = "application/vnd.docker.ai.license"
dockerAILicenseMediaType = "application/vnd.docker.ai.license"
) )
// dockerAIModelConfigMediaTypes are the model-config schema versions this
// cataloger understands. Versions are enumerated explicitly rather than matched
// with a wildcard so that a future, potentially breaking, config schema is not
// silently consumed; add a new version here only after confirming the fields we
// parse still apply.
var dockerAIModelConfigMediaTypes = []string{
"application/vnd.docker.ai.model.config.v0.1+json",
"application/vnd.docker.ai.model.config.v0.2+json",
}
// dockerAIModelConfig mirrors the JSON shape of the vnd.docker.ai.model.config // dockerAIModelConfig mirrors the JSON shape of the vnd.docker.ai.model.config
// blob written by Docker Model Runner for AI artifacts. Only fields we use are // blob written by Docker Model Runner for AI artifacts. Only fields we use are
// declared; unknown fields are ignored. // declared; unknown fields are ignored.

View File

@ -410,3 +410,26 @@ func TestModelNameFromPath(t *testing.T) {
assert.Equal(t, "my-model", modelNameFromIndexPath("/models/my-model/model.safetensors.index.json")) assert.Equal(t, "my-model", modelNameFromIndexPath("/models/my-model/model.safetensors.index.json"))
assert.Equal(t, "safetensors-model", modelNameFromIndexPath("model.safetensors.index.json")) assert.Equal(t, "safetensors-model", modelNameFromIndexPath("model.safetensors.index.json"))
} }
func TestDockerAIModelConfigMediaTypes(t *testing.T) {
// supported mirrors how the resolver matches: filepath.Match each registered
// media type against a layer's media type.
supported := func(mt string) bool {
for _, p := range dockerAIModelConfigMediaTypes {
if ok, err := filepath.Match(p, mt); err == nil && ok {
return true
}
}
return false
}
// the known, verified schema versions are consumed
assert.True(t, supported("application/vnd.docker.ai.model.config.v0.1+json"))
assert.True(t, supported("application/vnd.docker.ai.model.config.v0.2+json"))
// unknown/future schema versions are intentionally NOT consumed, to avoid
// silently ingesting a potentially breaking config change
assert.False(t, supported("application/vnd.docker.ai.model.config.v0.3+json"))
assert.False(t, supported("application/vnd.docker.ai.model.config.v9.9+json"))
// sibling layer media types are not matched either
assert.False(t, supported("application/vnd.docker.ai.model.file"))
assert.False(t, supported("application/vnd.docker.ai.gguf.v3"))
}