@@ -14,10 +14,13 @@ import (
1414 "github.com/replicate/cog/pkg/docker/command"
1515 "github.com/replicate/cog/pkg/dockercontext"
1616 "github.com/replicate/cog/pkg/registry"
17+ "github.com/replicate/cog/pkg/util"
1718 "github.com/replicate/cog/pkg/util/console"
1819 "github.com/replicate/cog/pkg/util/slices"
1920 "github.com/replicate/cog/pkg/util/version"
2021 "github.com/replicate/cog/pkg/weights"
22+ "golang.org/x/term"
23+ "gopkg.in/yaml.v2"
2124)
2225
2326const DockerignoreHeader = `# generated by replicate/cog
@@ -443,28 +446,17 @@ func (g *StandardGenerator) installCog() (string, error) {
443446 return "" , nil
444447 }
445448
446- if g .Config .Build .CogRuntime {
447- // We need fast-* compliant Python version to reconstruct coglet venv PYTHONPATH
448- if ! CheckMajorMinorOnly (g .Config .Build .PythonVersion ) {
449- return "" , fmt .Errorf ("Python version must be <major>.<minor>" )
450- }
451- m , err := NewMonobaseMatrix (http .DefaultClient )
452- if err != nil {
453- return "" , err
454- }
455- cmds := []string {
456- "ENV R8_COG_VERSION=coglet" ,
457- "ENV R8_PYTHON_VERSION=" + g .Config .Build .PythonVersion ,
458- "RUN pip install " + m .LatestCoglet .URL ,
459- }
460- return strings .Join (cmds , "\n " ), nil
449+ if g .Config .Build .CogRuntime != nil && * g .Config .Build .CogRuntime {
450+ return g .installCogRuntime ()
461451 }
462-
463- // cog-runtime does not support training yet
464- if g .Config .Train == "" {
465- console .Warnf ("Major Cog runtime upgrade available. Opt in now by setting build.cog_runtime: true in cog.yaml." )
466- console .Warnf ("More: https://replicate.com/changelog/2025-07-21-cog-runtime" )
452+ accepted , err := g .askAboutCogRuntime ()
453+ if err != nil {
454+ return "" , err
467455 }
456+ if accepted {
457+ return g .installCogRuntime ()
458+ }
459+
468460 data , filename , err := ReadWheelFile ()
469461 if err != nil {
470462 return "" , err
@@ -483,6 +475,75 @@ func (g *StandardGenerator) installCog() (string, error) {
483475 return strings .Join (lines , "\n " ), nil
484476}
485477
478+ func (g * StandardGenerator ) installCogRuntime () (string , error ) {
479+ // We need fast-* compliant Python version to reconstruct coglet venv PYTHONPATH
480+ if ! CheckMajorMinorOnly (g .Config .Build .PythonVersion ) {
481+ return "" , fmt .Errorf ("Python version must be <major>.<minor>" )
482+ }
483+ m , err := NewMonobaseMatrix (http .DefaultClient )
484+ if err != nil {
485+ return "" , err
486+ }
487+ cmds := []string {
488+ "ENV R8_COG_VERSION=coglet" ,
489+ "ENV R8_PYTHON_VERSION=" + g .Config .Build .PythonVersion ,
490+ "RUN pip install " + m .LatestCoglet .URL ,
491+ }
492+ return strings .Join (cmds , "\n " ), nil
493+ }
494+
495+ func (g * StandardGenerator ) askAboutCogRuntime () (bool , error ) {
496+ // Training is not supported
497+ if g .Config .Train != "" {
498+ return false , nil
499+ }
500+ // Only warn if cog_runtime is not explicitly set
501+ if g .Config .Build .CogRuntime != nil {
502+ return false , nil
503+ }
504+
505+ console .Warnf ("Major Cog runtime upgrade available. Opt in now by setting build.cog_runtime: true in cog.yaml." )
506+ console .Warnf ("More: https://replicate.com/changelog/2025-07-21-cog-runtime" )
507+
508+ // Skip question if not in an interactive shell
509+ if ! term .IsTerminal (int (os .Stdin .Fd ())) || ! term .IsTerminal (int (os .Stdout .Fd ())) || ! term .IsTerminal (int (os .Stderr .Fd ())) {
510+ return false , nil
511+ }
512+
513+ interactive := & console.InteractiveBool {
514+ Prompt : "Do you want to switch to the new Cog runtime?" ,
515+ Default : true ,
516+ // NonDefaultFlag is not applicable here
517+ }
518+ cogRuntime , err := interactive .Read ()
519+ if err != nil {
520+ return false , fmt .Errorf ("failed to read from stdin: %v" , err )
521+ }
522+ // Only add cog_runtime: true to cog.yaml if answer is yes
523+ // Otherwise leave it absent so we keep nagging
524+ if ! cogRuntime {
525+ console .Warnf ("Not switching. Add build.cog_runtime: false to disable this reminder." )
526+ return false , nil
527+ }
528+ g .Config .Build .CogRuntime = & cogRuntime
529+
530+ console .Infof ("Adding build.cog_runtime: true to %s" , g .Config .Filename ())
531+ newYaml , err := yaml .Marshal (g .Config )
532+ if err != nil {
533+ return false , err
534+ }
535+ path := filepath .Join (g .Dir , g .Config .Filename ())
536+ oldYaml , err := os .ReadFile (path )
537+ if err != nil {
538+ return false , err
539+ }
540+ merged , err := util .OverwriteYAML (newYaml , oldYaml )
541+ if err != nil {
542+ return false , err
543+ }
544+ return true , os .WriteFile (path , merged , 0o644 )
545+ }
546+
486547func (g * StandardGenerator ) pipInstalls () (string , error ) {
487548 var err error
488549 includePackages := []string {}
0 commit comments