- Include detailed architecture overview in `docs/architecture.md`. - Add `docs/configuration.md`, detailing configuration file structure and settings. - Provide a step-by-step provider implementation guide in `docs/provider-implementation.md`. - Add frequently asked questions (FAQ) document in `docs/faq.md`. - Create `docs/migration-guide.md` for future breaking changes and version upgrades. - Introduce new examples in `examples/` showcasing basic chat, custom providers, and theming. - Add a changelog (`CHANGELOG.md`) for tracking significant changes. - Provide contribution guidelines (`CONTRIBUTING.md`) and a Code of Conduct (`CODE_OF_CONDUCT.md`).
72 lines
5.0 KiB
Markdown
72 lines
5.0 KiB
Markdown
# Owlen Architecture
|
|
|
|
This document provides a high-level overview of the Owlen architecture. Its purpose is to help developers understand how the different parts of the application fit together.
|
|
|
|
## Core Concepts
|
|
|
|
The architecture is designed to be modular and extensible, centered around a few key concepts:
|
|
|
|
- **Providers**: Connect to various LLM APIs (Ollama, OpenAI, etc.).
|
|
- **Session**: Manages the conversation history and state.
|
|
- **TUI**: The terminal user interface, built with `ratatui`.
|
|
- **Events**: A system for handling user input and other events.
|
|
|
|
## Component Interaction
|
|
|
|
A simplified diagram of how components interact:
|
|
|
|
```
|
|
[User Input] -> [Event Loop] -> [Session Controller] -> [Provider]
|
|
^ |
|
|
| v
|
|
[TUI Renderer] <------------------------------------ [API Response]
|
|
```
|
|
|
|
1. **User Input**: The user interacts with the TUI, generating events (e.g., key presses).
|
|
2. **Event Loop**: The main event loop in `owlen-tui` captures these events.
|
|
3. **Session Controller**: The event is processed, and if it's a prompt, the session controller sends a request to the current provider.
|
|
4. **Provider**: The provider formats the request for the specific LLM API and sends it.
|
|
5. **API Response**: The LLM API returns a response.
|
|
6. **TUI Renderer**: The response is processed, the session state is updated, and the TUI is re-rendered to display the new information.
|
|
|
|
## Crate Breakdown
|
|
|
|
- `owlen-core`: Defines the core traits and data structures, like `Provider` and `Session`.
|
|
- `owlen-tui`: Contains all the logic for the terminal user interface, including event handling and rendering.
|
|
- `owlen-cli`: The command-line entry point, responsible for parsing arguments and starting the TUI.
|
|
- `owlen-ollama` / `owlen-openai` / etc.: Implementations of the `Provider` trait for specific services.
|
|
|
|
## Session Management
|
|
|
|
The session management system is responsible for tracking the state of a conversation. The two main structs are:
|
|
|
|
- **`Conversation`**: Found in `owlen-core`, this struct holds the messages of a single conversation, the model being used, and other metadata. It is a simple data container.
|
|
- **`SessionController`**: This is the high-level controller that manages the active conversation. It handles:
|
|
- Storing and retrieving conversation history via the `ConversationManager`.
|
|
- Managing the context that is sent to the LLM provider.
|
|
- Switching between different models.
|
|
- Sending requests to the provider and handling the responses (both streaming and complete).
|
|
|
|
When a user sends a message, the `SessionController` adds the message to the current `Conversation`, sends the updated message list to the `Provider`, and then adds the provider's response to the `Conversation`.
|
|
|
|
## Event Flow
|
|
|
|
The event flow is managed by the `EventHandler` in `owlen-tui`. It operates in a loop, waiting for events and dispatching them to the active application (`ChatApp` or `CodeApp`).
|
|
|
|
1. **Event Source**: Events are primarily generated by `crossterm` from user keyboard input. Asynchronous events, like responses from a `Provider`, are also fed into the event system via a `tokio::mpsc` channel.
|
|
2. **`EventHandler::next()`**: The main application loop calls this method to wait for the next event.
|
|
3. **Event Enum**: Events are defined in the `owlen_tui::events::Event` enum. This includes `Key` events, `Tick` events (for UI updates), and `Message` events (for async provider data).
|
|
4. **Dispatch**: The application's `run` method matches on the `Event` type and calls the appropriate handler function (e.g., `dispatch_key_event`).
|
|
5. **State Update**: The handler function updates the application state based on the event. For example, a key press might change the `InputMode` or modify the text in the input buffer.
|
|
6. **Re-render**: After the state is updated, the UI is re-rendered to reflect the changes.
|
|
|
|
## TUI Rendering Pipeline
|
|
|
|
The TUI is rendered on each iteration of the main application loop in `owlen-tui`. The process is as follows:
|
|
|
|
1. **`tui.draw()`**: The main loop calls this method, passing the current application state.
|
|
2. **`Terminal::draw()`**: This method, from `ratatui`, takes a closure that receives a `Frame`.
|
|
3. **UI Composition**: Inside the closure, the UI is built by composing `ratatui` widgets. The root UI is defined in `owlen_tui::ui::render`, which builds the main layout and calls other functions to render specific components (like the chat panel, input box, etc.).
|
|
4. **State-Driven Rendering**: Each rendering function takes the current application state as an argument. It uses this state to decide what and how to render. For example, the border color of a panel might change if it is focused.
|
|
5. **Buffer and Diff**: `ratatui` does not draw directly to the terminal. Instead, it renders the widgets to an in-memory buffer. It then compares this buffer to the previous buffer and only sends the necessary changes to the terminal. This is highly efficient and prevents flickering.
|