@@ -8,13 +8,16 @@ import (
88 "io"
99 "os"
1010 "os/signal"
11+ "strconv"
1112 "strings"
1213 "syscall"
1314
1415 "github.com/charmbracelet/glamour"
1516 "github.com/docker/model-runner/cmd/cli/commands/completion"
1617 "github.com/docker/model-runner/cmd/cli/desktop"
1718 "github.com/docker/model-runner/cmd/cli/readline"
19+ "github.com/docker/model-runner/pkg/inference"
20+ "github.com/docker/model-runner/pkg/inference/scheduling"
1821 "github.com/fatih/color"
1922 "github.com/muesli/termenv"
2023 "github.com/spf13/cobra"
@@ -90,11 +93,12 @@ func readMultilineInput(cmd *cobra.Command, scanner *bufio.Scanner) (string, err
9093func generateInteractiveWithReadline (cmd * cobra.Command , desktopClient * desktop.Client , model string ) error {
9194 usage := func () {
9295 fmt .Fprintln (os .Stderr , "Available Commands:" )
93- fmt .Fprintln (os .Stderr , " /set system Set or update the system message" )
9496 fmt .Fprintln (os .Stderr , " /bye Exit" )
97+ fmt .Fprintln (os .Stderr , " /set Set a session variable" )
9598 fmt .Fprintln (os .Stderr , " /?, /help Help for a command" )
9699 fmt .Fprintln (os .Stderr , " /? shortcuts Help for keyboard shortcuts" )
97100 fmt .Fprintln (os .Stderr , " /? files Help for file inclusion with @ symbol" )
101+ fmt .Fprintln (os .Stderr , " /? set Help for /set command" )
98102 fmt .Fprintln (os .Stderr , "" )
99103 fmt .Fprintln (os .Stderr , `Use """ to begin a multi-line message.` )
100104 fmt .Fprintln (os .Stderr , "" )
@@ -134,6 +138,14 @@ func generateInteractiveWithReadline(cmd *cobra.Command, desktopClient *desktop.
134138 fmt .Fprintln (os .Stderr , "" )
135139 }
136140
141+ usageSet := func () {
142+ fmt .Fprintln (os .Stderr , "Available /set commands:" )
143+ fmt .Fprintln (os .Stderr , " /set system <message> Set system message for the conversation" )
144+ fmt .Fprintln (os .Stderr , " /set num_ctx <n> Set context window size (in tokens)" )
145+ fmt .Fprintln (os .Stderr , " /set parameter num_ctx <n> Set context window size (in tokens) [deprecated]" )
146+ fmt .Fprintln (os .Stderr , "" )
147+ }
148+
137149 scanner , err := readline .New (readline.Prompt {
138150 Prompt : "> " ,
139151 AltPrompt : ". " ,
@@ -204,36 +216,103 @@ func generateInteractiveWithReadline(cmd *cobra.Command, desktopClient *desktop.
204216 case scanner .Pasting :
205217 fmt .Fprintln (& sb , line )
206218 continue
207- case strings .HasPrefix (line , "/help" ), strings . HasPrefix ( line , "/? " ):
219+ case strings .HasPrefix (line , "/" ):
208220 args := strings .Fields (line )
209- if len (args ) > 1 {
221+ switch args [0 ] {
222+ case "/help" , "/?" :
223+ if len (args ) > 1 {
224+ switch args [1 ] {
225+ case "shortcut" , "shortcuts" :
226+ usageShortcuts ()
227+ case "file" , "files" :
228+ usageFiles ()
229+ case "set" :
230+ usageSet ()
231+ default :
232+ usage ()
233+ }
234+ } else {
235+ usage ()
236+ }
237+ case "/exit" , "/bye" :
238+ return nil
239+ case "/set" :
240+ if len (args ) < 2 {
241+ usageSet ()
242+ continue
243+ }
210244 switch args [1 ] {
211- case "shortcut" , "shortcuts" :
212- usageShortcuts ()
213- case "file" , "files" :
214- usageFiles ()
245+ case "system" :
246+ // Extract the system prompt text after "/set system"
247+ if len (args ) > 2 {
248+ systemPrompt = strings .Join (args [2 :], " " )
249+ } else {
250+ systemPrompt = ""
251+ }
252+ if systemPrompt == "" {
253+ fmt .Fprintln (os .Stderr , "Cleared system message." )
254+ } else {
255+ fmt .Fprintln (os .Stderr , "Set system message." )
256+ }
257+ case "num_ctx" :
258+ // Handle /set num_ctx <value> syntax
259+ if len (args ) < 3 {
260+ fmt .Fprintln (os .Stderr , "Usage: /set num_ctx <value>" )
261+ continue
262+ }
263+ paramValue := args [2 ]
264+ if val , err := strconv .ParseInt (paramValue , 10 , 32 ); err == nil && val > 0 {
265+ ctx := int32 (val )
266+ if err := desktopClient .ConfigureBackend (scheduling.ConfigureRequest {
267+ Model : model ,
268+ BackendConfiguration : inference.BackendConfiguration {
269+ ContextSize : & ctx ,
270+ },
271+ }); err != nil {
272+ fmt .Fprintf (os .Stderr , "Failed to set num_ctx: %v\n " , err )
273+ } else {
274+ fmt .Fprintf (os .Stderr , "Set num_ctx to %d\n " , val )
275+ }
276+ } else {
277+ fmt .Fprintf (os .Stderr , "Invalid value for num_ctx: %s (must be a positive integer)\n " , paramValue )
278+ }
279+ case "parameter" :
280+ // Handle legacy /set parameter <name> <value> syntax for backward compatibility
281+ if len (args ) < 4 {
282+ fmt .Fprintln (os .Stderr , "Usage: /set parameter <name> <value>" )
283+ fmt .Fprintln (os .Stderr , "Available parameters: num_ctx" )
284+ continue
285+ }
286+ paramName , paramValue := args [2 ], args [3 ]
287+ switch paramName {
288+ case "num_ctx" :
289+ if val , err := strconv .ParseInt (paramValue , 10 , 32 ); err == nil && val > 0 {
290+ ctx := int32 (val )
291+ if err := desktopClient .ConfigureBackend (scheduling.ConfigureRequest {
292+ Model : model ,
293+ BackendConfiguration : inference.BackendConfiguration {
294+ ContextSize : & ctx ,
295+ },
296+ }); err != nil {
297+ fmt .Fprintf (os .Stderr , "Failed to set num_ctx: %v\n " , err )
298+ } else {
299+ fmt .Fprintf (os .Stderr , "Set num_ctx to %d\n " , val )
300+ }
301+ } else {
302+ fmt .Fprintf (os .Stderr , "Invalid value for num_ctx: %s (must be a positive integer)\n " , paramValue )
303+ }
304+ default :
305+ fmt .Fprintf (os .Stderr , "Unknown parameter: %s\n " , paramName )
306+ fmt .Fprintln (os .Stderr , "Available parameters: num_ctx" )
307+ }
215308 default :
216- usage ()
309+ fmt .Fprintf (os .Stderr , "Unknown /set option: %s\n " , args [1 ])
310+ usageSet ()
217311 }
218- } else {
219- usage ()
220- }
221- continue
222- case strings .HasPrefix (line , "/set system " ) || line == "/set system" :
223- // Extract the system prompt text after "/set system "
224- systemPrompt = strings .TrimPrefix (line , "/set system " )
225- systemPrompt = strings .TrimSpace (systemPrompt )
226- if systemPrompt == "" {
227- fmt .Fprintln (os .Stderr , "Cleared system message." )
228- } else {
229- fmt .Fprintln (os .Stderr , "Set system message." )
312+ default :
313+ fmt .Printf ("Unknown command '%s'. Type /? for help\n " , args [0 ])
230314 }
231315 continue
232- case strings .HasPrefix (line , "/exit" ), strings .HasPrefix (line , "/bye" ):
233- return nil
234- case strings .HasPrefix (line , "/" ):
235- fmt .Printf ("Unknown command '%s'. Type /? for help\n " , strings .Fields (line )[0 ])
236- continue
237316 default :
238317 sb .WriteString (line )
239318 }
0 commit comments