# What Is the OpenLogi Agent Process? Core Architecture & Responsibilities

> Discover the OpenLogi agent process, the background service managing HID++ hardware. Learn its core architecture and responsibilities for seamless device control.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: architecture
- Published: 2026-09-09

---

**The OpenLogi agent process is the long-running background service that bridges Logitech HID++ hardware with the operating system, exposing device control via an IPC socket for the GUI, CLI, and overlay components.**

The agent is the central runtime of the [AprilNEA/OpenLogi](https://github.com/AprilNEA/OpenLogi) project, a local-first alternative to Logitech Options+. Written in Rust and organized under `crates/openlogi-agent`, this binary owns all low-level device interactions so that higher-level components remain hardware-agnostic.

## Core Responsibilities of the OpenLogi Agent Process

The agent consolidates seven critical subsystems into a single daemon. Each subsystem maps to specific source modules in the crate.

### HID Input Handling and Device I/O

The agent captures raw input events through platform-specific hooks and manages bidirectional communication using the **Hid++ protocol**.

On **macOS**, it utilizes `CGEventTap` to intercept system input events. The **Linux** implementation relies on `evdev` for capturing events and `uinput` for injecting modified inputs, while **Windows** employs the `WH_MOUSE_LL` low-level hook. All hardware reads and writes are funneled through the agent, ensuring no other process contends for device handles.

### Device Management and Pairing

Device enumeration, pairing, and feature discovery are handled in [`crates/openlogi-agent/src/pairing.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/pairing.rs). The agent maintains an internal registry of supported peripherals, handles battery queries, and negotiates protocol features during the handshake phase. Any configuration change—whether adjusting DPI, enabling SmartShift, or remapping buttons—flows through this module before reaching the hardware.

### State Orchestration and Profile Management

The agent maintains **per-application profiles** and **DPI cycles** in memory. When the active application changes or the user invokes a profile switch, the agent updates the hardware state immediately. This **single source of truth** pattern ensures that the mouse or keyboard always reflects the current configuration without requiring the GUI to remain open.

### IPC Server Architecture

At startup, the agent binds a **tarpc/bincode** IPC socket exposed as `openlogi-ipc`. This socket lives in [`crates/openlogi-agent/src/server.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/server.rs) and serves as the exclusive API surface for the rest of the ecosystem.

Components communicate via this socket:

- **openlogi-desktop** (GUI) queries device status and sends configuration commands.
- **openlogi-overlay** receives live DPI and profile updates for on-screen display.
- **openlogi-cli** issues commands like `list` or `set-dpi` by invoking RPC methods on the agent.

The RPC definitions reside in [`crates/openlogi-ipc/src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/ipc.rs), ensuring type safety across process boundaries.

### Lifecycle Management and System Integration

The agent handles its own binary updates and OS power events. [`crates/openlogi-agent/src/lifecycle.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/lifecycle.rs) manages graceful shutdowns and restarts during sleep/resume cycles, while [`crates/openlogi-agent/src/binary_watch.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/binary_watch.rs) monitors the agent executable for changes and triggers an in-place restart when a new version is detected.

On **Windows** and **macOS**, [`crates/openlogi-agent/src/tray.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/tray.rs) creates a system status item that reflects connection state and provides quick-access menu actions.

## Key Source Files and Architecture

Understanding the file layout clarifies how the agent process fulfills its role:

- [`crates/openlogi-agent/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/main.rs) – Entry point that initializes logging, spawns the IPC server, and starts the input hook loops.
- [`crates/openlogi-agent/src/server.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/server.rs) – Implements the tarpc server, deserializing bincode requests and dispatching to internal handlers.
- [`crates/openlogi-agent/src/pairing.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/pairing.rs) – Manages device discovery, pairing flows, and feature capability bits.
- [`crates/openlogi-agent/src/lifecycle.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/lifecycle.rs) – Handles Unix signals and Windows power events for clean shutdown and resume logic.
- [`crates/openlogi-agent/src/tray.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/tray.rs) – Platform-specific system tray integration using native APIs.
- [`crates/openlogi-agent/src/binary_watch.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/binary_watch.rs) – Filesystem watcher that triggers agent restarts after binary updates.
- [`crates/openlogi-agent/src/bin/mock_agent.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/bin/mock_agent.rs) – Standalone mock binary that simulates device inventories for UI development.

## Working with the OpenLogi Agent Process

### Running the Mock Agent for Development

You can test the UI and CLI without physical Logitech hardware by starting the mock agent:

```bash
cargo run -p openlogi-agent --bin mock_agent

```

This binary, defined in [`crates/openlogi-agent/src/bin/mock_agent.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/bin/mock_agent.rs), exposes the same IPC interface but returns scripted device data, allowing frontend development on machines without HID++ peripherals.

### Querying Device State via CLI

With the agent running, the CLI communicates over the IPC socket to enumerate devices:

```bash
openlogi list

```

The implementation in [`crates/openlogi-cli/src/commands/list.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-cli/src/commands/list.rs) constructs an `openlogi_ipc::Client`, calls the agent's list method, and renders the returned device structs.

### Programmatic Control via IPC

Third-party tools or custom scripts can link against `openlogi-ipc` to control devices directly. For example, changing the DPI of a specific device:

```rust
let client = openlogi_ipc::Client::new("/path/to/openlogi-ipc").await?;
client.set_dpi(device_id, new_dpi).await?;

```

This async call serializes the request using bincode, sends it over the local socket, and blocks until the agent confirms the hardware register has been updated.

## Summary

- The **OpenLogi agent process** is the mandatory background daemon that owns all hardware interaction for Logitech HID++ devices.
- It aggregates **platform-specific input hooks** (CGEventTap, evdev/uinput, WH_MOUSE_LL) into a unified event pipeline.
- The agent exposes a **tarpc/bincode IPC socket** (`openlogi-ipc`) that decouples the GUI, CLI, and overlay from device-specific logic.
- **Device pairing**, **profile orchestration**, and **state synchronization** all occur within the agent, ensuring consistent hardware configuration.
- A **mock agent** binary enables development and testing without requiring physical peripherals.

## Frequently Asked Questions

### What protocol does the OpenLogi agent use to communicate with devices?

The agent speaks the **Hid++ protocol**, Logitech's proprietary HID extension. It sends structured packets over USB or Bluetooth HID reports to read battery levels, set DPI registers, and configure button mappings. All protocol implementation details are encapsulated behind the agent's internal device abstraction layer.

### How does the OpenLogi agent handle application-specific profiles?

The agent maintains a **profile registry** in memory, mapping executable names or window classes to device configurations. When the active window changes (detected via OS-specific APIs), the agent cross-references the new application against its registry and pushes the associated DPI, button map, and lighting state to the hardware through the pairing module in [`src/pairing.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/pairing.rs).

### Can I run the OpenLogi agent without physical Logitech hardware?

Yes. The **mock agent** (`cargo run -p openlogi-agent --bin mock_agent`) simulates a populated device inventory and responds to IPC calls with dummy data. This allows you to develop the GUI or CLI on unsupported platforms or when hardware is unavailable, as the mock implements the same tarpc interface as the production agent.

### What is the relationship between the agent process and the OpenLogi GUI?

The **openlogi-desktop** GUI is a separate process that functions as an IPC client. It does not touch hardware directly; instead, it renders configuration UIs and forwards user actions to the agent via the `openlogi-ipc` socket. The GUI can exit or crash without affecting device operation, as the agent persists and continues enforcing the last active profile.