Files
goaichat/dev-plan.md

175 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Goaichat Development Plan
## Overview
- **Goal** Build a terminal-based AI chat client in Go that interacts with an OpenAI-compatible API using settings provided via `config.yaml`.
- **Primary outcomes** Provide an interactive chat session with conversational history, robust config handling, and a clean developer experience.
- **Assumptions** Users run the app locally inside a terminal emulator with network access to the configured API endpoint.
## Functional Requirements
- **Interactive chat loop** Allow continuous message exchange with the AI until the user exits.
- **Config-driven startup** Parse `config.yaml` for `api.url`, `api.key`, model defaults, and future options (e.g., system prompts, temperature, streaming flag).
- **Persistent history** Store chats in a SQLite database located at `$HOME/.local/share/goaichat/goaichat.db` (configurable), capturing session metadata and full message transcripts.
- **History commands** Provide `/list` to enumerate saved chats and allow selecting or reopening them within the session.
- **Model management** Support `/models` command to display configured/available models, persist the users choice, and use it for subsequent requests.
- **Graceful exit controls** Support commands like `/exit`, `/reset`, `/help`.
- **Error feedback** Surface authentication and network issues with actionable terminal messages.
## Non-Functional Requirements
- **Portability** Pure Go solution compatible with Linux/macOS/Windows terminals.
- **Security** Keep API key out of logs; support environment variable overrides for secrets; ensure persisted data has restrictive filesystem permissions.
- **Resilience** Retry transient HTTP failures, validate config on load, handle streaming interruptions.
- **Observability** Include structured logging with verbosity toggle.
## Architecture
### High-Level Components
- **CLI entrypoint** `cmd/goaichat/main.go` handles argument parsing and bootstraps the app.
- **Configuration layer** `internal/config` loads, validates, merges `config.yaml` with environment overrides.
- **Application core** `internal/app` wires config, client, history, and UI controller.
- **Chat service** `internal/chat` manages conversation state, prompt assembly, tool commands, and transcripts.
- **Storage layer** `internal/storage` handles SQLite connections, schema migrations, and CRUD helpers for sessions, messages, and model preferences.
- **OpenAI client** `internal/openai` wraps REST calls (Chat Completions or Responses API) with streaming support.
- **Terminal UI** `internal/ui` renders chat in the terminal; leverages `github.com/charmbracelet/bubbletea` + `lipgloss` for layout.
- **Logging/metrics** `internal/telemetry` centralizes loggers and future metrics hooks.
### Data Flow
```mermaid
dflow LR
UserInput[(User input)] --> UI[Terminal UI]
UI -->|Submit| ChatCore[Chat service]
ChatCore -->|Build request| OpenAIClient[OpenAI client]
OpenAIClient -->|HTTP call| API[(OpenAI-compatible API)]
API -->|Response/stream| OpenAIClient
OpenAIClient --> ChatCore
ChatCore -->|Update state| Storage[(SQLite history store)]
Storage --> ChatCore
ChatCore --> UI
Config[(config.yaml + env)] --> ConfigPkg[Configuration]
ConfigPkg --> AppCore[Application core]
AppCore --> ChatCore
AppCore --> OpenAIClient
AppCore --> Storage
##- **Persistence & Data Storage (`internal/storage`)
- **Data directory** Resolve user-specific path `$HOME/.local/share/goaichat/` (configurable override) and ensure directories exist with secure permissions.
- **Database** SQLite file `goaichat.db` managed via `modernc.org/sqlite` (pure Go) for portability; allow build tag to switch to `mattn/go-sqlite3` if desired.
- **Schema**
- **`sessions`** (`id`, `name`, `created_at`, `updated_at`, `model_name`, `summary`).
- **`messages`** (`id`, `session_id`, `role`, `content`, `token_count`, `created_at`).
- **`models`** (`id`, `name`, `display_name`, `provider`, `is_default`, `last_used_at`).
{{ ... }}
- **Data access** Provide repository interfaces for chat service to create sessions, append messages, list chats, update selected model, and fetch transcripts.
- **Performance** Enable write-ahead logging, tune connection settings, and guard concurrent access with a request queue or mutex.
## Configuration Handling (`internal/config`)
- **Load order** Default values → `config.yaml` → environment overrides (`GOAICHAT_API_KEY`, etc.) → CLI flags.
- **Parsing** Use `gopkg.in/yaml.v3` with a typed struct, e.g., `Config{ API struct{ URL string; Key string }; Model struct{ Name string; Temperature float64; Stream bool }; Logging struct{ Level string } }`.
- **Validation** Ensure non-empty `API.URL`, `API.Key`; validate URL format and ranges (temperature 0-2); provide default fallbacks.
- **Hot reload (future)** Structure API to support reloading without restart.
- **Sample `config.yaml`**
```yaml
api:
url: "https://api.openai.com/v1"
key: "${OPENAI_API_KEY}"
model:
name: "gpt-4o-mini"
temperature: 0.7
stream: true
ui:
show_timestamps: true
logging:
level: "info"
```
## Terminal UI (`internal/ui`)
- **Framework** Adopt Bubble Tea for TUI state management; use `textinput` component for prompt entry and a scrolling viewport for conversation.
- **Features**
- **Message formatting** Differentiate user/assistant/system with colors via `lipgloss`.
- **Streaming display** Render tokens incrementally if streaming enabled.
- **Shortcut commands** `/reset`, `/config`, `/copy-last`, `/save`, `/list`, `/models`.
- **Status bar** Show model name, latency, active session, and config hints.
- **Accessibility** Support basic ANSI-only fallback.
## Chat Service (`internal/chat`)
- **State** Maintain slice of `Message{Role, Content, Timestamp}` plus metadata (tokens, response duration).
- **Prompt assembly** Prepend system prompt from config; limit history by token budget using approximate counts and hydrate from stored transcripts when reopening a session.
- **Commands** Parse `/` prefixed input before sending to API, including `/reset`, `/help`, `/exit`, `/list`, `/models`, `/config`, `/copy-last`, `/save`.
- **Persistence integration** Manage session lifecycle, store messages, list sessions, and update preferred model through `internal/storage`.
## OpenAI Client (`internal/openai`)
- **HTTP layer** Use net/http with context cancellation, timeout, retry (exponential backoff) on 5xx.
- **Endpoints** Start with Chat Completions `POST /chat/completions`; optionally add Responses API abstraction.
- **Streaming** Handle Server-Sent Events (SSE) or chunked responses; emit channel of tokens consumed by UI.
- **Auth** Inject `Authorization: Bearer` header from config/environment.
- **Telemetry hooks** Log request duration; hide sensitive payloads in debug output.
- **Testing** Mock transport implementation for deterministic tests.
## Application Core (`internal/app`)
- **Lifecycle** Initialize logger → load config → instantiate client and chat service → start UI program.
- **Dependency injection** Pass config structs or interfaces to decouple packages for testing.
- **Shutdown** Capture signals (Ctrl+C) to flush logs, close session transcripts.
## Implementation Roadmap
- **Milestone 1: Project bootstrap**
- **Create module** `go mod init github.com/<user>/goaichat`.
- **Set up CI** (GitHub Actions) running `go test` and lint.
- **Add basic logging** using `log/slog` or `zerolog`.
- **Milestone 2: Config foundation**
- **Implement** `internal/config` loader with validation and tests.
- **Support** environment overrides and `--config` CLI flag.
- **Milestone 3: API integration**
- **Build** `internal/openai` client with non-streaming support first.
- **Add** response parsing, error handling, retries.
- **Write** integration tests against mock server.
- **Milestone 4: Persistence foundation**
- **Design** SQLite schema and migrations within `internal/storage`.
- **Implement** repositories for sessions, messages, and models.
- **Ensure** path resolution to `$HOME/.local/share/goaichat/` with permission checks and tests.
- **Milestone 5: Chat loop MVP**
- **Implement** CLI loop that reads user input, calls chat client, prints responses.
- **Integrate** persistence for session creation, message storage, `/list`, and `/models` commands.
- **Instrument** logging and simple metrics.
- **Milestone 6: Terminal UI**
- **Integrate** Bubble Tea UI replacing basic loop.
- **Add** viewport rendering, streaming display, command palette.
- **Polish** keyboard shortcuts and layout.
- **Milestone 7: Enhancements & polish**
- **Implement** transcript saving, timestamp display, configurable prompts.
- **Add** optional plugins (command to open last response in $EDITOR).
- **Harden** error messages and retries; tune tests and docs.
## Testing & Quality Strategy
- **Unit tests** Cover config parsing, validation, command parsing, token budgeting.
- **Integration tests** Use httptest server to simulate OpenAI API scenarios (success, auth error, rate limit, streaming).
- **UI tests** Leverage Bubble Tea test helpers to simulate model update cycles.
- **Static analysis** `golangci-lint` for vet, errcheck, gofmt.
- **Load testing (future)** Add simple script to replay prompts for latency measurement.
## Developer Tooling & DX
- **Makefile** Targets: `make build`, `make test`, `make lint`, `make run`.
- **Task runner** Optionally use `taskfile` or `mage`.
- **Documentation** Maintain `README.md`, `docs/configuration.md`, `docs/development.md`.
- **Sample configs** Provide `config.example.yaml` without secrets.
- **Issue templates** For bug reports and feature requests once repo public.
## Deployment & Distribution
- **Binary releases** Cross-compile via `goreleaser` for Linux/macOS/Windows; ensure `CGO_ENABLED=0` for static binaries.
- **Packaging** Offer Homebrew tap or `go install` instructions.
- **Versioning** Semantic versioning with tagged releases; changelog via `git-chglog`.
## Future Extensions
- **Plugin commands** Shell hooks, sending to external tools, code interpreter.
- **Multi-provider support** Add adapters for Anthropic, local LLMs via OpenAI-compatible bridges.
- **Conversation persistence** SQLite-backed history with search.
- **Team collaboration** Shared sessions via websockets or tmux integration.
- **Telemetry dashboard** Optional Prometheus exporter for usage stats.
## Risks & Mitigations
- **API drift** Mitigate with client abstraction and compatibility tests.
- **Rate limits** Implement exponential backoff, expose retry counters in UI.
- **Secret leakage** Ensure config accepts env vars, redact logs, document best practices.
- **Terminal portability** Provide fallback non-TUI mode for minimal terminals.