# abdullah61305/bruno architecture

> Architecture diagram of the GitHub repository abdullah61305/bruno, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-06). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/abdullah61305/bruno
- Repository: https://github.com/abdullah61305/bruno

## Overview

#### Purpose and Entry Points
Bruno is a Windows tray-resident voice companion: push-to-talk or hands-free speech is transcribed locally, sent to an LLM, optionally augmented with screen/browser tools, then spoken as streamed sentences. Runtime entry is `bruno/__main__.py`, which delegates application composition and CLI behavior to `bruno/app.py`; the packaged Windows build is produced by `scripts/build.py`.

#### Application Composition and Lifecycle
`bruno/app.py` is the composition root: it selects concrete implementations for protocol-defined stages, initializes UI and persistent services, and coordinates startup/shutdown. `bruno/pipeline.py` owns the request lifecycle across capture, transcription, model response, tool execution, and speech. Shared lifecycle/state contracts live in `bruno/core/protocols.py` and `bruno/core/state.py`. A single-instance guard prevents competing tray processes in `bruno/core/single_instance.py`.

#### User Interaction and UI State
Global keyboard capture turns `Alt+Space` into press-to-record/release-to-send and interruption behavior through `bruno/input/hotkey.py` and Windows bindings in `bruno/input/win32.py`. Hands-free mode is coordinated in `bruno/hands_free.py`, using speech endpointing rather than key release. The tray UI and visual state indicators are implemented by `bruno/ui/tray.py`, `bruno/ui/orb/window.py`, and the embedded WebGL orb at `bruno/ui/orb/index.html`.

#### Audio and Local Speech Runtime
The microphone remains open and records with pre-roll buffering via `bruno/audio/recorder.py`; device discovery is in `bruno/audio/devices.py`. Hands-free end-of-speech detection uses Silero VAD in `bruno/audio/endpointing.py`. Local STT is encapsulated by `bruno/stt/runtime.py` and `bruno/stt/whisper.py` (faster-whisper). Responses are segmented for low time-to-first-word in `bruno/tts/chunker.py`, synthesized by Piper in `bruno/tts/piper.py`, and output through `bruno/audio/player.py`.

#### LLM Conversation and Provider Failover
Conversation history, prompts, and streaming/tool-call orchestration are centered in `bruno/llm/conversation.py`, `bruno/llm/prompt.py`, and `bruno/llm/chain.py`. `bruno/llm/factory.py` instantiates configured backends; `bruno/llm/providers.py`, `bruno/llm/groq.py`, and `bruno/llm/openai_compatible.py` support multiple hosted providers and failover when quota or provider failures occur. Text—and screenshots only when requested—crosses this external-service boundary; audio transcription stays local.

#### Explicit Capabilities: Screen and Browser
LLM tool calls are registered and dispatched through `bruno/tools/registry.py`. Screen capture is an on-demand tool in `bruno/tools/screen.py`; browser control of the user’s existing browser is in `bruno/tools/browser.py`. This isolates privileged desktop actions from the audio/LLM pipeline and makes tools the extension boundary for new actions.

#### Persistence, Onboarding, and Runtime Infrastructure
First-run setup and provider/key collection are handled by `bruno/onboarding.py`. Configuration and user profile persist under `%LOCALAPPDATA%\Bruno` through `bruno/core/config.py`, `bruno/core/profile.py`, and `bruno/core/paths.py`; API credentials are encrypted with the Windows account via `bruno/core/credentials.py` and `bruno/core/secrets.py`. Logging—including screen-capture records—uses `bruno/core/logging.py`. Runtime assets such as Whisper/Piper models are managed by `bruno/core/assets.py`.

Main entry points: [`bruno/app.py`](https://github.com/abdullah61305/bruno/blob/main/bruno/app.py) (App composition), [`bruno/pipeline.py`](https://github.com/abdullah61305/bruno/blob/main/bruno/pipeline.py) (Request pipeline), [`bruno/llm/conversation.py`](https://github.com/abdullah61305/bruno/blob/main/bruno/llm/conversation.py) (Conversation orchestration), [`bruno/stt/runtime.py`](https://github.com/abdullah61305/bruno/blob/main/bruno/stt/runtime.py) (Local transcription)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Application"]
  node_entry["Runtime entry<br/>Python entrypoint<br/>[__main__.py]"]
  node_app_root["App composition<br/>composition root<br/>[app.py]"]
  node_pipeline["Request pipeline<br/>orchestrator<br/>[pipeline.py]"]
  node_contracts["Lifecycle contracts<br/>protocols and state<br/>[protocols.py]"]
  node_instance_guard["Single-instance guard<br/>process guard<br/>[single_instance.py]"]
end

subgraph group_interaction["Interaction &amp; Audio"]
  node_input_modes["Hotkey &amp; hands-free<br/>input control<br/>[hotkey.py]"]
  node_tray_orb["Tray and orb UI<br/>Windows UI<br/>[tray.py]"]
  node_recorder["Microphone recorder<br/>audio capture<br/>[recorder.py]"]
  node_endpointing["Speech endpointing<br/>Silero VAD<br/>[endpointing.py]"]
  node_player["Audio player<br/>audio output<br/>[player.py]"]
end

subgraph group_intelligence["Speech &amp; LLM"]
  node_stt["Local transcription<br/>faster-whisper runtime<br/>[runtime.py]"]
  node_conversation["Conversation orchestration<br/>streaming LLM flow<br/>[conversation.py]"]
  node_provider_factory["Provider factory &amp; failover<br/>LLM backend selection<br/>[factory.py]"]
  node_external_llm{{"Hosted LLM providers<br/>external service boundary<br/>[providers.py]"}}
  node_chunker["Response chunker<br/>sentence streaming<br/>[chunker.py]"]
  node_tts["Local speech synthesis<br/>Piper TTS<br/>[piper.py]"]
end

subgraph group_tools["Privileged Tools"]
  node_tool_registry["Tool registry<br/>tool dispatch<br/>[registry.py]"]
  node_screen_tool["Screen capture<br/>on-demand desktop tool<br/>[screen.py]"]
  node_browser_tool["Browser control<br/>desktop tool<br/>[browser.py]"]
end

subgraph group_runtime["Persistence &amp; Runtime"]
  node_onboarding["Onboarding<br/>first-run setup<br/>[onboarding.py]"]
  node_profile_store[("Profile &amp; config store<br/>local persistence<br/>[config.py]")]
  node_credentials["Encrypted credentials<br/>Windows-account secrets<br/>[credentials.py]"]
  node_assets["Speech model assets<br/>runtime asset manager<br/>[assets.py]"]
end

node_entry -->|"starts"| node_app_root
node_app_root -->|"enforces"| node_instance_guard
node_app_root -->|"composes"| node_pipeline
node_app_root -->|"initializes"| node_tray_orb
node_app_root -->|"runs first-run"| node_onboarding
node_app_root -.->|"uses"| node_contracts
node_input_modes -->|"record/send control"| node_pipeline
node_input_modes -->|"hands-free endpointing"| node_endpointing
node_recorder -->|"captured audio"| node_pipeline
node_endpointing -->|"speech end"| node_pipeline
node_pipeline -->|"audio"| node_stt
node_stt -->|"transcript"| node_conversation
node_conversation -->|"model request"| node_provider_factory
node_provider_factory -->|"text / requested screenshot"| node_external_llm
node_conversation -->|"tool calls"| node_tool_registry
node_tool_registry -->|"dispatches"| node_screen_tool
node_tool_registry -->|"dispatches"| node_browser_tool
node_conversation -->|"streamed response"| node_chunker
node_chunker -->|"sentences"| node_tts
node_tts -->|"speech audio"| node_player
node_pipeline -->|"state updates"| node_tray_orb
node_onboarding -->|"writes setup"| node_profile_store
node_app_root -->|"loads settings"| node_profile_store
node_profile_store -.->|"references secrets"| node_credentials
node_stt -->|"loads models"| node_assets
node_tts -->|"loads voice model"| node_assets

click node_entry "https://github.com/abdullah61305/bruno/blob/main/bruno/__main__.py"
click node_app_root "https://github.com/abdullah61305/bruno/blob/main/bruno/app.py"
click node_pipeline "https://github.com/abdullah61305/bruno/blob/main/bruno/pipeline.py"
click node_contracts "https://github.com/abdullah61305/bruno/blob/main/bruno/core/protocols.py"
click node_instance_guard "https://github.com/abdullah61305/bruno/blob/main/bruno/core/single_instance.py"
click node_input_modes "https://github.com/abdullah61305/bruno/blob/main/bruno/input/hotkey.py"
click node_tray_orb "https://github.com/abdullah61305/bruno/blob/main/bruno/ui/tray.py"
click node_recorder "https://github.com/abdullah61305/bruno/blob/main/bruno/audio/recorder.py"
click node_endpointing "https://github.com/abdullah61305/bruno/blob/main/bruno/audio/endpointing.py"
click node_player "https://github.com/abdullah61305/bruno/blob/main/bruno/audio/player.py"
click node_stt "https://github.com/abdullah61305/bruno/blob/main/bruno/stt/runtime.py"
click node_conversation "https://github.com/abdullah61305/bruno/blob/main/bruno/llm/conversation.py"
click node_provider_factory "https://github.com/abdullah61305/bruno/blob/main/bruno/llm/factory.py"
click node_external_llm "https://github.com/abdullah61305/bruno/blob/main/bruno/llm/providers.py"
click node_chunker "https://github.com/abdullah61305/bruno/blob/main/bruno/tts/chunker.py"
click node_tts "https://github.com/abdullah61305/bruno/blob/main/bruno/tts/piper.py"
click node_tool_registry "https://github.com/abdullah61305/bruno/blob/main/bruno/tools/registry.py"
click node_screen_tool "https://github.com/abdullah61305/bruno/blob/main/bruno/tools/screen.py"
click node_browser_tool "https://github.com/abdullah61305/bruno/blob/main/bruno/tools/browser.py"
click node_onboarding "https://github.com/abdullah61305/bruno/blob/main/bruno/onboarding.py"
click node_profile_store "https://github.com/abdullah61305/bruno/blob/main/bruno/core/config.py"
click node_credentials "https://github.com/abdullah61305/bruno/blob/main/bruno/core/credentials.py"
click node_assets "https://github.com/abdullah61305/bruno/blob/main/bruno/core/assets.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry,node_app_root,node_pipeline,node_contracts,node_instance_guard toneBlue
class node_input_modes,node_tray_orb,node_recorder,node_endpointing,node_player toneAmber
class node_stt,node_conversation,node_provider_factory,node_external_llm,node_chunker,node_tts toneMint
class node_tool_registry,node_screen_tool,node_browser_tool toneRose
class node_onboarding,node_profile_store,node_credentials,node_assets toneIndigo
```

## Components

### Application

- [Runtime entry](https://github.com/abdullah61305/bruno/blob/main/bruno/__main__.py): Python entrypoint · `bruno/__main__.py`
- [App composition](https://github.com/abdullah61305/bruno/blob/main/bruno/app.py): composition root · Selects implementations and coordinates lifecycle. · `bruno/app.py`
- [Request pipeline](https://github.com/abdullah61305/bruno/blob/main/bruno/pipeline.py): orchestrator · Coordinates capture, STT, LLM/tools, and speech. · `bruno/pipeline.py`
- [Lifecycle contracts](https://github.com/abdullah61305/bruno/blob/main/bruno/core/protocols.py): protocols and state · `bruno/core/protocols.py`
- [Single-instance guard](https://github.com/abdullah61305/bruno/blob/main/bruno/core/single_instance.py): process guard · `bruno/core/single_instance.py`

### Interaction & Audio

- [Hotkey & hands-free](https://github.com/abdullah61305/bruno/blob/main/bruno/input/hotkey.py): input control · Alt+Space recording and VAD-driven hands-free control. · `bruno/input/hotkey.py`
- [Tray and orb UI](https://github.com/abdullah61305/bruno/blob/main/bruno/ui/tray.py): Windows UI · Shows tray controls and visual voice state. · `bruno/ui/tray.py`
- [Microphone recorder](https://github.com/abdullah61305/bruno/blob/main/bruno/audio/recorder.py): audio capture · Keeps microphone open with pre-roll buffering. · `bruno/audio/recorder.py`
- [Speech endpointing](https://github.com/abdullah61305/bruno/blob/main/bruno/audio/endpointing.py): Silero VAD · `bruno/audio/endpointing.py`
- [Audio player](https://github.com/abdullah61305/bruno/blob/main/bruno/audio/player.py): audio output · `bruno/audio/player.py`

### Speech & LLM

- [Local transcription](https://github.com/abdullah61305/bruno/blob/main/bruno/stt/runtime.py): faster-whisper runtime · Audio remains local for transcription. · `bruno/stt/runtime.py`
- [Conversation orchestration](https://github.com/abdullah61305/bruno/blob/main/bruno/llm/conversation.py): streaming LLM flow · Manages history, prompts, streaming, and tool calls. · `bruno/llm/conversation.py`
- [Provider factory & failover](https://github.com/abdullah61305/bruno/blob/main/bruno/llm/factory.py): LLM backend selection · Selects hosted providers and handles provider/quota failures. · `bruno/llm/factory.py`
- [Hosted LLM providers](https://github.com/abdullah61305/bruno/blob/main/bruno/llm/providers.py): external service boundary · Receives text and requested screenshots only. · `bruno/llm/providers.py`
- [Response chunker](https://github.com/abdullah61305/bruno/blob/main/bruno/tts/chunker.py): sentence streaming · Segments responses for low time-to-first-word. · `bruno/tts/chunker.py`
- [Local speech synthesis](https://github.com/abdullah61305/bruno/blob/main/bruno/tts/piper.py): Piper TTS · `bruno/tts/piper.py`

### Privileged Tools

- [Tool registry](https://github.com/abdullah61305/bruno/blob/main/bruno/tools/registry.py): tool dispatch · Extension boundary for LLM-invoked actions. · `bruno/tools/registry.py`
- [Screen capture](https://github.com/abdullah61305/bruno/blob/main/bruno/tools/screen.py): on-demand desktop tool · `bruno/tools/screen.py`
- [Browser control](https://github.com/abdullah61305/bruno/blob/main/bruno/tools/browser.py): desktop tool · Controls the user's existing browser. · `bruno/tools/browser.py`

### Persistence & Runtime

- [Onboarding](https://github.com/abdullah61305/bruno/blob/main/bruno/onboarding.py): first-run setup · Collects provider and key configuration. · `bruno/onboarding.py`
- [Profile & config store](https://github.com/abdullah61305/bruno/blob/main/bruno/core/config.py): local persistence · Persists configuration and user profile under %LOCALAPPDATA%\Bruno. · `bruno/core/config.py`
- [Encrypted credentials](https://github.com/abdullah61305/bruno/blob/main/bruno/core/credentials.py): Windows-account secrets · `bruno/core/credentials.py`
- [Speech model assets](https://github.com/abdullah61305/bruno/blob/main/bruno/core/assets.py): runtime asset manager · Manages Whisper and Piper models. · `bruno/core/assets.py`

## Connections

- Runtime entry → App composition: starts
- App composition → Single-instance guard: enforces
- App composition → Request pipeline: composes
- App composition → Tray and orb UI: initializes
- App composition → Onboarding: runs first-run
- App composition → Lifecycle contracts: uses
- Hotkey & hands-free → Request pipeline: record/send control
- Hotkey & hands-free → Speech endpointing: hands-free endpointing
- Microphone recorder → Request pipeline: captured audio
- Speech endpointing → Request pipeline: speech end
- Request pipeline → Local transcription: audio
- Local transcription → Conversation orchestration: transcript
- Conversation orchestration → Provider factory & failover: model request
- Provider factory & failover → Hosted LLM providers: text / requested screenshot
- Conversation orchestration → Tool registry: tool calls
- Tool registry → Screen capture: dispatches
- Tool registry → Browser control: dispatches
- Conversation orchestration → Response chunker: streamed response
- Response chunker → Local speech synthesis: sentences
- Local speech synthesis → Audio player: speech audio
- Request pipeline → Tray and orb UI: state updates
- Onboarding → Profile & config store: writes setup
- App composition → Profile & config store: loads settings
- Profile & config store → Encrypted credentials: references secrets
- Local transcription → Speech model assets: loads models
- Local speech synthesis → Speech model assets: loads voice model
