- 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`).
5.0 KiB
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]
- User Input: The user interacts with the TUI, generating events (e.g., key presses).
- Event Loop: The main event loop in
owlen-tuicaptures these events. - Session Controller: The event is processed, and if it's a prompt, the session controller sends a request to the current provider.
- Provider: The provider formats the request for the specific LLM API and sends it.
- API Response: The LLM API returns a response.
- 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, likeProviderandSession.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 theProvidertrait 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 inowlen-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).
- Storing and retrieving conversation history via the
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).
- Event Source: Events are primarily generated by
crosstermfrom user keyboard input. Asynchronous events, like responses from aProvider, are also fed into the event system via atokio::mpscchannel. EventHandler::next(): The main application loop calls this method to wait for the next event.- Event Enum: Events are defined in the
owlen_tui::events::Eventenum. This includesKeyevents,Tickevents (for UI updates), andMessageevents (for async provider data). - Dispatch: The application's
runmethod matches on theEventtype and calls the appropriate handler function (e.g.,dispatch_key_event). - State Update: The handler function updates the application state based on the event. For example, a key press might change the
InputModeor modify the text in the input buffer. - 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:
tui.draw(): The main loop calls this method, passing the current application state.Terminal::draw(): This method, fromratatui, takes a closure that receives aFrame.- UI Composition: Inside the closure, the UI is built by composing
ratatuiwidgets. The root UI is defined inowlen_tui::ui::render, which builds the main layout and calls other functions to render specific components (like the chat panel, input box, etc.). - 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.
- Buffer and Diff:
ratatuidoes 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.