Skip to content
This repository was archived by the owner on Oct 6, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
48 changes: 48 additions & 0 deletions commands/configure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package commands

import (
"fmt"

"github.com/docker/model-cli/commands/completion"
"github.com/docker/model-runner/pkg/inference/scheduling"
"github.com/spf13/cobra"
)

func newConfigureCmd() *cobra.Command {
var opts scheduling.ConfigureRequest

c := &cobra.Command{
Use: "configure [--context-size=<n>] MODEL [-- <runtime-flags...>]",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need -- here? As model is a required argument, everything after could be considered runtime flags (comparable to docker run IMAGE <command...>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need it so we can pass runtime flags that start with -- so they're not treated as flags for the configure command itself.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. docker run doesn't require this and I can't see any magic code for this purpose on https://github.com/docker/cli/blob/master/cli/command/container/run.go#L36

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but the command doesn't usually contain "--" so it's parsed as a flag.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not:

$ docker run alpine/curl --help
Usage: curl [options...] <url>
 -d, --data <data>           HTTP POST data
...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, nice! Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the -- terminator is a de facto standard (in GNU getopt, Cobra, Argparse, etc.) indicating the end of flag parsing, let's go with it for now and then we can potentially make it optional in the future (see, e.g., git help log, where -- is recommended but optional in certain cases).

This will give us the most flexibility later to evolve the command (e.g. supporting multiple model specifications), because honestly this command is being added with a little less design time than we'd ideally like.

For now though, it's the most unambiguous option and doesn't risk breaking in the future since it's a multi-decade convention.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you declare this command with this syntax this will have to stay forever, otherwise Compose integration will be broken

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm okay with it staying forever, it's been in use as a parsing convention for several decades now and it's baked into the APIs and CLIs of many libraries and tools. In git for example, anything taking arbitrary pathspecs uses a -- convention (because that's the GNU convention for arbitrary args). It doesn't cost anything to support it and there's no risk of support for it being removed from argument parsing libraries.

If we didn't use it though, we wouldn't have any way to (in the future) support an arbitrary number of model specs (because we'd have no way of knowing when the model specs ended and the runtime flags began). So I think leaning into the standard here gives us more flexibility with the command design. Doing a clever parsing heuristic now would give us far less flexibility in the other direction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok makes sense

Short: "Configure runtime options for a model",
Args: func(cmd *cobra.Command, args []string) error {
argsBeforeDash := cmd.ArgsLenAtDash()
if argsBeforeDash == -1 {
// No "--" used, so we need exactly 1 total argument.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flags are not included, they're not counted.

if len(args) != 1 {
return fmt.Errorf(
"Exactly one model must be specified, got %d: %v\n\n"+
"See 'docker model configure --help' for more information",
len(args), args)
}
} else {
// Has "--", so we need exactly 1 argument before it.
if argsBeforeDash != 1 {
return fmt.Errorf(
"Exactly one model must be specified before --, got %d\n\n"+
"See 'docker model configure --help' for more information",
argsBeforeDash)
}
}
opts.Model = args[0]
opts.RuntimeFlags = args[1:]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-- will be part of the sub-slice

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It won't, it's parsed and excluded automatically by cobra.

return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return desktopClient.ConfigureBackend(opts)
},
ValidArgsFunction: completion.ModelNames(getDesktopClient, -1),
}

c.Flags().Int64Var(&opts.ContextSize, "context-size", -1, "context size (in tokens)")
return c
}
1 change: 1 addition & 0 deletions commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ func NewRootCmd(cli *command.DockerCli) *cobra.Command {
newTagCmd(),
newInstallRunner(),
newUninstallRunner(),
newConfigureCmd(),
newPSCmd(),
newDFCmd(),
newUnloadCmd(),
Expand Down
2 changes: 2 additions & 0 deletions docs/reference/docker_model.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ long: |-
pname: docker
plink: docker.yaml
cname:
- docker model configure
- docker model df
- docker model inspect
- docker model install-runner
Expand All @@ -23,6 +24,7 @@ cname:
- docker model unload
- docker model version
clink:
- docker_model_configure.yaml
- docker_model_df.yaml
- docker_model_inspect.yaml
- docker_model_install-runner.yaml
Expand Down
24 changes: 24 additions & 0 deletions docs/reference/docker_model_configure.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
command: docker model configure
short: Configure runtime options for a model
long: Configure runtime options for a model
usage: docker model configure [--context-size=<n>] MODEL [-- <runtime-flags...>]
pname: docker model
plink: docker_model.yaml
options:
- option: context-size
value_type: int64
default_value: "-1"
description: context size (in tokens)
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
experimentalcli: true
kubernetes: false
swarm: false

1 change: 1 addition & 0 deletions docs/reference/model.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Docker Model Runner (EXPERIMENTAL)

| Name | Description |
|:------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------|
| [`configure`](model_configure.md) | Configure runtime options for a model |
| [`df`](model_df.md) | Show Docker Model Runner disk usage |
| [`inspect`](model_inspect.md) | Display detailed information on one model |
| [`install-runner`](model_install-runner.md) | Install Docker Model Runner (Docker Engine only) |
Expand Down
14 changes: 14 additions & 0 deletions docs/reference/model_configure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# docker model configure

<!---MARKER_GEN_START-->
Configure runtime options for a model

### Options

| Name | Type | Default | Description |
|:-----------------|:--------|:--------|:-------------------------|
| `--context-size` | `int64` | `-1` | context size (in tokens) |


<!---MARKER_GEN_END-->

74 changes: 39 additions & 35 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,60 +1,62 @@
module github.com/docker/model-cli

go 1.23.7
go 1.24

toolchain go1.24.4

require (
github.com/docker/cli v28.2.2+incompatible
github.com/docker/cli v28.3.0+incompatible
github.com/docker/cli-docs-tool v0.10.0
github.com/docker/docker v28.2.2+incompatible
github.com/docker/go-connections v0.5.0
github.com/docker/go-units v0.5.0
github.com/docker/model-distribution v0.0.0-20250512190053-b3792c042d57
github.com/docker/model-runner v0.0.0-20250613083629-6b8c3b816f00
github.com/google/go-containerregistry v0.20.3
github.com/docker/model-distribution v0.0.0-20250620111407-b631ab263648
github.com/docker/model-runner v0.0.0-20250626211904-cce6a71cc9d6
github.com/google/go-containerregistry v0.20.6
github.com/mattn/go-isatty v0.0.17
github.com/nxadm/tail v1.4.8
github.com/olekukonko/tablewriter v0.0.5
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0
go.opentelemetry.io/otel v1.35.0
go.opentelemetry.io/otel v1.37.0
go.uber.org/mock v0.5.0
golang.org/x/sync v0.12.0
golang.org/x/sync v0.15.0
)

require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/containerd/containerd/v2 v2.0.4 // indirect
github.com/containerd/containerd/v2 v2.1.3 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/platforms v1.0.0-rc.1 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/creack/pty v1.1.24 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.9.3 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gpustack/gguf-parser-go v0.14.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
github.com/henvic/httpretty v0.1.4 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jaypipes/ghw v0.16.0 // indirect
github.com/jaypipes/ghw v0.17.0 // indirect
github.com/jaypipes/pcidb v1.0.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect
Expand All @@ -69,42 +71,44 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/common v0.60.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smallnest/ringbuffer v0.0.0-20241116012123-461381446e3d // indirect
github.com/theupdateframework/notary v0.7.1-0.20210315103452-bf96a202a09a // indirect
github.com/vbatts/tar-split v0.11.6 // indirect
github.com/vbatts/tar-split v0.12.1 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
golang.org/x/crypto v0.35.0 // indirect
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.36.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/crypto v0.39.0 // indirect
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/time v0.9.0 // indirect
golang.org/x/tools v0.29.0 // indirect
golang.org/x/tools v0.34.0 // indirect
gonum.org/v1/gonum v0.15.1 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250219182151-9fdb1cabc7b2 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2 // indirect
google.golang.org/grpc v1.70.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e // indirect
google.golang.org/grpc v1.72.2 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.2 // indirect
howett.net/plist v1.0.0 // indirect
howett.net/plist v1.0.1 // indirect
)
Loading
Loading