Skip to content

Commit

Permalink
feat: add help system command (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
reugn authored Dec 7, 2024
1 parent 1c6f426 commit 0dacfe2
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 11 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@ export GEMINI_API_KEY=<your_api_key>
The system chat message must begin with an exclamation mark and is used for internal operations.
A short list of supported system commands:

| Command | Description |
|---------|----------------------------------------------------|
| !q | Quit the application |
| !p | Select the system prompt for the chat <sup>1</sup> |
| !i | Toggle input mode (single-line <-> multi-line) |
| !m | Select a model operation <sup>2</sup> |
| !h | Select a history operation <sup>3</sup> |
| Command | Description |
|---------|----------------------------------------------------------------|
| !p | Select the generative model system prompt <sup>1</sup> |
| !m | Select from a list of generative model operations <sup>2</sup> |
| !h | Select from a list of chat history operations <sup>3</sup> |
| !i | Toggle the input mode (single-line <-> multi-line) |
| !q | Exit the application |
| !help | Show system command instructions |

<sup>1</sup> System instruction (also known as "system prompt") is a more forceful prompt to the model.
The model will follow instructions more closely than with a standard prompt.
Expand Down
7 changes: 5 additions & 2 deletions internal/chat/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ func New(
}

systemIO := handler.NewIO(terminalIO, terminalIO.Prompt.Cli)
systemHandler := handler.NewSystemCommand(systemIO, session, configuration,
opts.GenerativeModel)
systemHandler, err := handler.NewSystemCommand(systemIO, session, configuration,
opts.GenerativeModel, opts.rendererOptions())
if err != nil {
return nil, err
}

return &Chat{
io: terminalIO,
Expand Down
1 change: 1 addition & 0 deletions internal/cli/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cli

const (
SystemCmdPrefix = "!"
SystemCmdHelp = "help"
SystemCmdQuit = "q"
SystemCmdSelectPrompt = "p"
SystemCmdSelectInputMode = "i"
Expand Down
52 changes: 52 additions & 0 deletions internal/handler/help_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package handler

import (
"fmt"
"strings"

"github.com/charmbracelet/glamour"
"github.com/reugn/gemini-cli/internal/cli"
)

// HelpCommand handles the help system command request.
type HelpCommand struct {
*IO
renderer *glamour.TermRenderer
}

var _ MessageHandler = (*HelpCommand)(nil)

// NewHelpCommand returns a new HelpCommand.
func NewHelpCommand(io *IO, opts RendererOptions) (*HelpCommand, error) {
renderer, err := glamour.NewTermRenderer(
glamour.WithStylePath(opts.StylePath),
glamour.WithWordWrap(opts.WordWrap),
)
if err != nil {
return nil, fmt.Errorf("failed to instantiate terminal renderer: %w", err)
}

return &HelpCommand{
IO: io,
renderer: renderer,
}, nil
}

// Handle processes the help system command.
func (h *HelpCommand) Handle(_ string) (Response, bool) {
var b strings.Builder
b.WriteString("# System commands\n")
b.WriteString("Use a command prefixed with an exclamation mark (e.g., `!h`).\n")
fmt.Fprintf(&b, "* `%s` - Select the generative model system prompt.\n", cli.SystemCmdSelectPrompt)
fmt.Fprintf(&b, "* `%s` - Select from a list of generative model operations.\n", cli.SystemCmdModel)
fmt.Fprintf(&b, "* `%s` - Select from a list of chat history operations.\n", cli.SystemCmdHistory)
fmt.Fprintf(&b, "* `%s` - Toggle the input mode.\n", cli.SystemCmdSelectInputMode)
fmt.Fprintf(&b, "* `%s` - Exit the application.\n", cli.SystemCmdQuit)

rendered, err := h.renderer.Render(b.String())
if err != nil {
return newErrorResponse(fmt.Errorf("failed to format instructions: %w", err)), false
}

return dataResponse(rendered), false
}
10 changes: 8 additions & 2 deletions internal/handler/system_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ var _ MessageHandler = (*SystemCommand)(nil)

// NewSystemCommand returns a new SystemCommand.
func NewSystemCommand(io *IO, session *gemini.ChatSession, configuration *config.Configuration,
modelName string) *SystemCommand {
modelName string, rendererOptions RendererOptions) (*SystemCommand, error) {
helpCommandHandler, err := NewHelpCommand(io, rendererOptions)
if err != nil {
return nil, err
}

handlers := map[string]MessageHandler{
cli.SystemCmdHelp: helpCommandHandler,
cli.SystemCmdQuit: NewQuitCommand(io),
cli.SystemCmdSelectPrompt: NewSystemPromptCommand(io, session, configuration.Data),
cli.SystemCmdSelectInputMode: NewInputModeCommand(io),
Expand All @@ -37,7 +43,7 @@ func NewSystemCommand(io *IO, session *gemini.ChatSession, configuration *config
return &SystemCommand{
IO: io,
handlers: handlers,
}
}, nil
}

// Handle processes the chat system command.
Expand Down

0 comments on commit 0dacfe2

Please sign in to comment.