chat

package
v0.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 31, 2024 License: MIT Imports: 24 Imported by: 4

README

Bobatea Chat UI

Bobatea Chat UI is a Go library for building interactive terminal-based chat interfaces that communicate with language model (LLM) stream completion endpoints.

Features

  • Real-time streaming responses from AI assistants
  • Rich conversation navigation and history
  • Extensive keyboard shortcuts
  • Code block and message copying
  • Conversation import/export
  • Customizable styling

Installation

go get github.com/go-go-golems/bobatea/pkg/chat

Using the Chat Interface

UI Modes

The chat interface has three main modes:

  1. User Input Mode (Default)

    • Type your message and submit it to the AI
    • See real-time streaming responses
    • Copy the last response or code blocks
  2. Navigation Mode

    • Browse through conversation history
    • Select and copy previous messages
    • Return to input mode to continue the conversation
  3. Stream Mode

    • Shows real-time AI responses
    • Displays progress indicators
    • Can be cancelled if needed
Keyboard Controls
General
  • ctrl-? - Show help dialog
  • alt+q - Quit application
  • ctrl+s, alt+s - Save conversation to file
Message Input
  • tab - Submit your message
  • esc or ctrl+g - Cancel current operation, unfocus message, or dismiss error
  • alt+l - Copy last AI response
  • alt+k - Copy code blocks from last response
Navigation
  • shift+pgup - Scroll conversation up
  • shift+pgdown - Scroll conversation down
  • shift+up - Select previous message
  • shift+down - Select next message
  • enter - Focus selected message
  • alt+c - Copy selected message
  • alt+d - Copy code blocks from selected message
  • left - Previous conversation thread
  • right - Next conversation thread
Coming Soon
  • Message regeneration
  • Conversation branching
  • Message editing
  • Thread navigation

For Developers

See TUTORIAL.md for implementation details and backend integration guide.

Example

Check out cmd/chat/main.go for a complete working example.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultKeyMap = KeyMap{
	SelectPrevMessage: key.NewBinding(
		key.WithKeys("shift+up"),
		key.WithHelp("shift+↑", "move up")),
	SelectNextMessage: key.NewBinding(
		key.WithKeys("shift+down"),
		key.WithHelp("shift+↓", "move down"),
	),

	UnfocusMessage: key.NewBinding(
		key.WithKeys("esc", "ctrl+g"),
		key.WithHelp("esc", "unfocus message"),
	),
	FocusMessage: key.NewBinding(
		key.WithKeys("enter"),
		key.WithHelp("enter", "focus message"),
	),

	SubmitMessage: key.NewBinding(
		key.WithKeys("tab"),
		key.WithHelp("tab", "submit message"),
	),
	CancelCompletion: key.NewBinding(
		key.WithKeys("esc", "ctrl+g"),
		key.WithHelp("esc", "cancel completion"),
	),

	DismissError: key.NewBinding(
		key.WithKeys("esc", "ctrl+g"),
		key.WithHelp("esc", "dismiss error"),
	),

	SaveToFile: key.NewBinding(
		key.WithKeys("ctrl+s", "alt+s"),
		key.WithHelp("ctrl+s", "save to file"),
	),

	CopyToClipboard: key.NewBinding(
		key.WithKeys("alt+c"),
		key.WithHelp("alt+c", "copy selected"),
	),
	CopyLastResponseToClipboard: key.NewBinding(
		key.WithKeys("alt+l"),
		key.WithHelp("alt+l", "copy response"),
	),
	CopySourceBlocksToClipboard: key.NewBinding(
		key.WithKeys("alt+d"),
		key.WithHelp("alt+d", "copy selected source"),
	),
	CopyLastSourceBlocksToClipboard: key.NewBinding(
		key.WithKeys("alt+k"),
		key.WithHelp("alt+k", "copy source"),
	),

	ScrollUp: key.NewBinding(
		key.WithKeys("shift+pgup"),
		key.WithHelp("shift+pgup", "scroll up"),
	),
	ScrollDown: key.NewBinding(
		key.WithKeys("shift+pgdown"),
		key.WithHelp("shift+pgdown", "scroll down"),
	),

	Quit: key.NewBinding(
		key.WithKeys("alt+q"),
		key.WithHelp("alt+q", "quit"),
	),

	Help: key.NewBinding(
		key.WithKeys("ctrl-?"),
		key.WithHelp("ctrl-?", "help")),

	PreviousConversationThread: key.NewBinding(
		key.WithKeys("left"),
		key.WithHelp("left", "previous conversation thread"),
	),

	NextConversationThread: key.NewBinding(
		key.WithKeys("right"),
		key.WithHelp("right", "next conversation thread"),
	),
}

Functions

func InitialModel

func InitialModel(manager geppetto_conversation.Manager, backend Backend, options ...ModelOption) model

func OpenTTY

func OpenTTY() (io.ReadWriteCloser, error)

Types

type AppendInputTextMsg added in v0.0.11

type AppendInputTextMsg struct {
	Text string
}

type Backend

type Backend interface {
	// Start begins the backend process with the provided context and conversation messages.
	Start(ctx context.Context, msgs []*conversation.Message) (tea.Cmd, error)

	// Interrupt signals the backend process to gracefully stop its current operation.
	Interrupt()

	// Kill forces the backend process to terminate immediately. This is used in
	// situations where an immediate halt of the backend process is required, such as
	// when the application is closing or an unrecoverable error has occurred.
	Kill()

	// IsFinished checks if the backend process has completed its tasks. It returns
	// true if the backend has finished processing and no further Stream*Msg messages
	// will be sent to the UI.
	IsFinished() bool
}

Backend abstracts initiating and stopping the backend process that is responsible for streaming and processing chat messages.

Communication between the backend and the chat UI is facilitated through a series of Stream*Msg messages that the backend sends to the UI.

The typical flow of communication is as follows:

  1. The UI invokes the Start method, providing a context and the current conversation messages, to begin the backend streaming process.
  2. As the backend processes the stream, it sends Stream*Msg messages to the UI: - StreamStartMsg: Indicates the streaming process has started. - StreamStatusMsg: Provides updates on the status of the streaming process. - StreamCompletionMsg: Contains new data from the backend, such as a new message. - StreamDoneMsg: Signals the successful completion of the streaming process. - StreamErrorMsg: Communicates errors that occurred during streaming.
  3. The UI's Update method receives these messages and updates the chat model and view.
  4. The Backend interface provides Interrupt and Kill methods to allow the UI to request the backend to gracefully stop or forcefully terminate the streaming process.
  5. Upon completion of its tasks, the backend sends a BackendFinishedMsg to indicate that it has finished processing and will not send any further messages.

The backend is expected to maintain the context of the conversation, ensuring that new messages sent as completion events are correctly associated with the last message in the conversation to maintain the chat's continuity.

type BackendFinishedMsg added in v0.0.4

type BackendFinishedMsg struct{}

BackendFinishedMsg is a message sent when the backend process has finished its operation.

type CancelCompletionMsg added in v0.0.11

type CancelCompletionMsg struct{}

type CopyLastResponseToClipboardMsg added in v0.0.11

type CopyLastResponseToClipboardMsg struct{}

type CopyLastSourceBlocksToClipboardMsg added in v0.0.11

type CopyLastSourceBlocksToClipboardMsg struct{}

type CopySourceBlocksToClipboardMsg added in v0.0.11

type CopySourceBlocksToClipboardMsg struct{}

type CopyToClipboardMsg added in v0.0.11

type CopyToClipboardMsg struct{}

type DismissErrorMsg added in v0.0.11

type DismissErrorMsg struct{}

type FocusMessageMsg added in v0.0.11

type FocusMessageMsg struct{}

type GetInputTextMsg added in v0.0.11

type GetInputTextMsg struct{}

type InputTextMsg added in v0.0.11

type InputTextMsg struct {
	Text string
}

type KeyMap

type KeyMap struct {
	SelectPrevMessage key.Binding `keymap-mode:"moving-around"`
	SelectNextMessage key.Binding `keymap-mode:"moving-around"`
	UnfocusMessage    key.Binding `keymap-mode:"user-input"`
	FocusMessage      key.Binding `keymap-mode:"moving-around"`

	SubmitMessage key.Binding `keymap-mode:"user-input"`
	ScrollUp      key.Binding
	ScrollDown    key.Binding

	CancelCompletion key.Binding `keymap-mode:"stream-completion"`
	DismissError     key.Binding `keymap-mode:"error"`

	LoadFromFile key.Binding

	Regenerate         key.Binding `keymap-mode:"user-input"`
	RegenerateFromHere key.Binding `keymap-mode:"moving-around"`
	EditMessage        key.Binding `keymap-mode:"moving-around"`

	PreviousConversationThread key.Binding `keymap-mode:"moving-around"`
	NextConversationThread     key.Binding `keymap-mode:"moving-around"`

	SaveToFile             key.Binding `keymap-mode:"*"`
	SaveSourceBlocksToFile key.Binding `keymap-mode:"*"`

	CopyToClipboard                 key.Binding `keymap-mode:"moving-around"`
	CopyLastResponseToClipboard     key.Binding `keymap-mode:"user-input"`
	CopyLastSourceBlocksToClipboard key.Binding `keymap-mode:"user-input"`
	CopySourceBlocksToClipboard     key.Binding `keymap-mode:"moving-around"`

	Help key.Binding `keymap-mode:"*"`
	Quit key.Binding `keymap-mode:"*"`
}

func (KeyMap) FullHelp

func (k KeyMap) FullHelp() [][]key.Binding

func (KeyMap) ShortHelp

func (k KeyMap) ShortHelp() []key.Binding

type ModelOption added in v0.0.4

type ModelOption func(*model)

func WithAutoStartBackend added in v0.0.13

func WithAutoStartBackend(autoStartBackend bool) ModelOption

func WithStatus added in v0.0.11

func WithStatus(status *Status) ModelOption

func WithTitle added in v0.0.4

func WithTitle(title string) ModelOption

type PrependInputTextMsg added in v0.0.11

type PrependInputTextMsg struct {
	Text string
}

type QuitMsg added in v0.0.11

type QuitMsg struct{}

type ReplaceInputTextMsg added in v0.0.11

type ReplaceInputTextMsg struct {
	Text string
}

Add these new message types

type SaveToFileMsg added in v0.0.11

type SaveToFileMsg struct{}

type SelectNextMessageMsg added in v0.0.11

type SelectNextMessageMsg struct{}

type SelectPrevMessageMsg added in v0.0.11

type SelectPrevMessageMsg struct{}

type StartBackendMsg added in v0.0.13

type StartBackendMsg struct{}

type State

type State string
const (
	StateUserInput        State = "user-input"
	StateMovingAround     State = "moving-around"
	StateStreamCompletion State = "stream-completion"
	StateSavingToFile     State = "saving-to-file"

	StateError State = "error"
)

type Status added in v0.0.11

type Status struct {
	State        State  `json:"state"`
	InputText    string `json:"inputText"`
	SelectedIdx  int    `json:"selectedIdx"`
	MessageCount int    `json:"messageCount"`
	Error        error  `json:"error,omitempty"`
}

type SubmitMessageMsg added in v0.0.11

type SubmitMessageMsg struct{}

type ToggleHelpMsg added in v0.0.11

type ToggleHelpMsg struct{}

type UnfocusMessageMsg added in v0.0.11

type UnfocusMessageMsg struct{}

type UserActionMsg added in v0.0.11

type UserActionMsg interface {
	// contains filtered or unexported methods
}

New message types for user actions

type UserBackend added in v0.0.11

type UserBackend struct {
	// contains filtered or unexported fields
}

func NewUserBackend added in v0.0.11

func NewUserBackend(status *Status, options ...UserBackendOption) *UserBackend

func (*UserBackend) Router added in v0.0.11

func (u *UserBackend) Router() *mux.Router

func (*UserBackend) SetProgram added in v0.0.11

func (u *UserBackend) SetProgram(p *tea.Program)

type UserBackendOption added in v0.0.11

type UserBackendOption func(*UserBackend)

func WithLogFile added in v0.0.11

func WithLogFile(path string) UserBackendOption

func WithLogger added in v0.0.11

func WithLogger(logger zerolog.Logger) UserBackendOption

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL