Add multi-line input, /model and /provider commands
ober
763ee587076be667f2fd24887c0b43b3af8ab2cf
--- a/lib/jcode/ui/cli.sls +++ b/lib/jcode/ui/cli.sls @@ -103,7 +103,7 @@ (def (repl-loop session-id) (display (make-prompt)) (flush-output-port (current-output-port)) - (let ([input (get-line (current-input-port))]) + (let ([input (read-multiline)]) (cond [(eof-object? input) (newline) (printf "Goodbye!~n")] [(equal? input "") (repl-loop session-id)] @@ -114,19 +114,75 @@ [else (handle-user-input input session-id) (repl-loop session-id)]))) + (def (read-multiline) + (let ([line (get-line (current-input-port))]) + (if (eof-object? line) + line + (let loop ([line line] [acc '()]) + (if (and (> (string-length line) 0) + (char=? + (string-ref line (- (string-length line) 1)) + #\\)) + (begin + (display " ... ") + (flush-output-port (current-output-port)) + (let ([next (get-line (current-input-port))]) + (if (eof-object? next) + (string-join + (reverse + (cons + (substring + line + 0 + (- (string-length line) 1)) + acc)) + "\n") + (loop + next + (cons + (string-append + (substring + line + 0 + (- (string-length line) 1)) + "\n") + acc))))) + (string-join (reverse (cons line acc)) "")))))) (def (handle-command input session-id) (let ([cmd (string-trim (substring input 1 (string-length input)))]) (cond [(equal? cmd "help") (display - "\nCommands:\n /help Show this help\n /model Show current model and provider\n /tools List available tools\n /clear Start a new session\n /sessions List saved sessions\n /compact Show message count\n /quit Exit\n\n")] + "\nCommands:\n /help Show this help\n /model [name] Show or set model\n /provider [name] Show or set provider\n /tools List available tools\n /clear Start a new session\n /sessions List saved sessions\n /compact Show message count\n /quit Exit\n\nMulti-line: end a line with \\ to continue on the next line.\n\n")] [(equal? cmd "model") - (printf "Provider: ~a~n" (config-provider)) - (printf "Model: ~a~n" (config-model)) + (printf + "Provider: ~a~n" + (or (current-provider-override) (config-provider))) + (printf + "Model: ~a~n" + (or (current-model-override) (config-model))) (printf "API Key: ~a~n" (if (config-api-key) "configured" "not set"))] + [(string-prefix? "model " cmd) + (let ([new-model (string-trim + (substring cmd 6 (string-length cmd)))]) + (current-model-override new-model) + (printf "Model set to: ~a~n" new-model))] + [(equal? cmd "provider") + (printf + "Provider: ~a~n" + (or (current-provider-override) (config-provider)))] + [(string-prefix? "provider " cmd) + (let ([new-provider (string-trim + (substring cmd 9 (string-length cmd)))]) + (current-provider-override new-provider) + (current-model-override (config-default-model new-provider)) + (printf + "Provider set to: ~a (model: ~a)~n" + new-provider + (current-model-override)))] [(equal? cmd "tools") (printf "Available tools: ~a~n" --- a/src/jcode/ui/cli.ss +++ b/src/jcode/ui/cli.ss @@ -121,7 +121,7 @@ EXAMPLES: (def (repl-loop session-id) (display (make-prompt)) (flush-output-port (current-output-port)) - (let ((input (get-line (current-input-port)))) + (let ((input (read-multiline))) (cond ((eof-object? input) (newline) @@ -135,15 +135,42 @@ EXAMPLES: (handle-user-input input session-id) (repl-loop session-id))))) +(def (read-multiline) + ;; Read input, continuing on lines ending with backslash + (let ((line (get-line (current-input-port)))) + (if (eof-object? line) line + (let loop ((line line) (acc '())) + (if (and (> (string-length line) 0) + (char=? (string-ref line (- (string-length line) 1)) #\\)) + (begin + (display " ... ") + (flush-output-port (current-output-port)) + (let ((next (get-line (current-input-port)))) + (if (eof-object? next) + (string-join (reverse (cons (substring line 0 (- (string-length line) 1)) acc)) "\n") + (loop next (cons (string-append (substring line 0 (- (string-length line) 1)) "\n") acc))))) + (string-join (reverse (cons line acc)) "")))))) + (def (handle-command input session-id) (let ((cmd (string-trim (substring input 1 (string-length input))))) (cond ((equal? cmd "help") - (display "\nCommands:\n /help Show this help\n /model Show current model and provider\n /tools List available tools\n /clear Start a new session\n /sessions List saved sessions\n /compact Show message count\n /quit Exit\n\n")) + (display "\nCommands:\n /help Show this help\n /model [name] Show or set model\n /provider [name] Show or set provider\n /tools List available tools\n /clear Start a new session\n /sessions List saved sessions\n /compact Show message count\n /quit Exit\n\nMulti-line: end a line with \\ to continue on the next line.\n\n")) ((equal? cmd "model") - (printf "Provider: ~a~n" (config-provider)) - (printf "Model: ~a~n" (config-model)) + (printf "Provider: ~a~n" (or (current-provider-override) (config-provider))) + (printf "Model: ~a~n" (or (current-model-override) (config-model))) (printf "API Key: ~a~n" (if (config-api-key) "configured" "not set"))) + ((string-prefix? "model " cmd) + (let ((new-model (string-trim (substring cmd 6 (string-length cmd))))) + (current-model-override new-model) + (printf "Model set to: ~a~n" new-model))) + ((equal? cmd "provider") + (printf "Provider: ~a~n" (or (current-provider-override) (config-provider)))) + ((string-prefix? "provider " cmd) + (let ((new-provider (string-trim (substring cmd 9 (string-length cmd))))) + (current-provider-override new-provider) + (current-model-override (config-default-model new-provider)) + (printf "Provider set to: ~a (model: ~a)~n" new-provider (current-model-override)))) ((equal? cmd "tools") (printf "Available tools: ~a~n" (string-join (list-tools) ", "))) ((equal? cmd "clear")