
# Cyrene-Agent
**English** | [δΈζ](./README.md)
**Primary repo**: [GitHub](https://github.com/Playa-0v0/Cyrene-Agent) γ» **Mirror for China**: [Gitee](https://gitee.com/playa0/cyrene-agent)
**Cyrene-Agent is a Windows Live2D AI desktop companion centered around Cyrene from _Honkai: Star Rail_.**
> A desktop Live2D conversational Agent built with Electron and TypeScript.
> Centered around Cyrene's character design and powered by the self-developed Cyrene_Harness&DMAE memory engine,
> it brings character-driven conversation, personalized memory, voice interaction, tool use, and multi-platform access into a single desktop Agent,
> supporting four conversation modes: Chat, Work, Code, and Learn.
---
## β¨ At a Glance
- πΈ **Playful Desktop Companion** β A persistent Live2D character with expressions, actions, status, mood, speech bubbles, and intelligent stickers
- π¬ **Casual Conversation (Chat)** β Focused on character-driven interaction, with responses shaped by conversation history, user style, and long-term memory
- π οΈ **Assisted Work (Work)** β General-purpose task session that chains together web search, file processing, document generation, and lifestyle tools through the [CyreneHarness](./src/main/orchestrator/harness/cyrene-harness.ts) main loop
- π» **Code Collaboration (Code)** β Binds a trusted code directory, provides LSP semantic queries (definitions / references / hover / symbols / diagnostics) plus restricted read/write/exec commands; safety is enforced by Harness's permission approval (Permission Policy) and Execution Policy
- π **Learning Companion (Learn)** β Binds an Obsidian Vault, accompanies users in understanding materials, organizing notes, generating exercises, and tracking progress
- π§ **Personalized Memory** β L0 / L1 / L2 layered memory combined with the self-developed DMAE Worldbook for long-term interaction continuity
- π **Voice Interaction** β Integrated TTS, ASR, and voice calls so Cyrene can listen and respond
- π§° **Rich Tool Ecosystem** β Web search, file processing, document generation, everyday services, music, and MCP extensions
- π **Multi-Provider Model Support** β Tiered Structured Output and Function Calling compatibility profiles for different model providers
- π¨ **Customizable Appearance** β Multiple interface styles, themes, and chat font options
- π± **Multi-Platform Access** β Desktop, Feishu/Lark, WeChat iLink, and QQ through NapCat/OneBot 11
- π **Proactive Chat** β Starts conversations according to time, status, and user preferences, with targeted multi-channel delivery
---
## βοΈ CyreneHarness Core Engine
> `Work / Code / Learn` and any session mode that requires tool invocation runs on top of **CyreneHarness**.
> Source: [`src/main/orchestrator/harness/cyrene-harness.ts`](./src/main/orchestrator/harness/cyrene-harness.ts)
CyreneHarness is the core Agent Loop of Cyrene Agent. It chains **model decisions, tool execution, side-effect accounting, and state recovery** into a continuous loop that is interruptible, recoverable, and replayable.
**Key design points:**
- **Continuous while + Function Calling loop** β Each round calls the LLM, dispatches the returned `toolCalls`, and lets the model end the turn when it returns no tool calls.
- **assistantMessage must be written back** β Every assistant message is pushed into `messages` unconditionally after each LLM response. Skipping this step breaks the loop on the next round.
- **Exclusive Ask path** β `ask_user` / `confirm_uncertain_effect` are user-waiting built-in tools that monopolize the round: other co-round tools return `not_executed`, and the progress buffer is discarded before continuing.
- **Four-state outcome with uncertainEffect interception** β Tool results fall into `success / failure / unknown / not_executed`. When `unknown` is paired with `sideEffect === non_idempotent`, the side effect is recorded into `state.uncertainEffects` and `halted = true` blocks further automatic replays of the same dangerous call within the round.
- **Failure retry** β Failed tools decide whether to retry based on `classifyToolResultError` + `resolveSideEffect`; the `sleepWithJitter` backoff is interruptible via `AbortSignal`.
- **Conservative parallel scheduling** β Serial by default; only explicitly concurrency-safe read-only tools run in parallel (default limit 4). Results are always committed in the original tool-call order; on halt / error / cancel, already-executed results are never dropped, and failed slots are closed with synthetic failure results so the transcript stays consistent.
- **Dual-clock timeout** β Execution time and user-wait time are tracked separately: while `ask_user` is waiting for the user, the execution clock is paused, so user thinking time never consumes the task timeout budget.
- **Mid-loop Compaction** β Each round checks the token budget and triggers an LLM-driven summary when over the threshold, preserving todos and confirmed results; if the post-compaction checkpoint fails, the run aborts immediately without issuing another model request.
- **Prefix-cache discipline** β Stable prefix layering (stablePrefix / sessionPrefix / mode); volatile state such as Todos is kept out of the prefix; the tool list is frozen for the whole run; dynamic facts are materialized into the transcript once instead of being re-appended every round; `cacheEpoch` advances across compaction / recovery; vendor cache hints such as Kimi's `prompt_cache_key` are injected uniformly at the request layer.
- **Two-tier tool output truncation** β Large outputs are persisted to disk (`ToolOutputRef`) while model messages only keep a preview; the model can call the built-in `read_tool_result` tool to read the full output on demand, drastically reducing context usage.
- **Context-usage snapshots** β A `context_usage` snapshot event is emitted before each model request and at terminal settlement, powering the live context-ring UI.
- **Truncation made visible** β When the output hits the model's length limit (`finishReason = length`), a notice is appended to the reply instead of failing silently.
- **Stream-first with fallback** β Falls back to non-streaming only when zero deltas were received and the vendor explicitly rejects stream + tools; a half-replayed stream never happens; token accounting distinguishes cache hits.
- **Signal-aware throughout** β Almost every `await` is wrapped with `raceWithSignal`; `signal.aborted` returns `cancelled()` (with `finalAnswer = ''` and **no `final_answer` event emitted**).
- **Per-round checkpoint** β `onCheckpoint` persists `messages + state + rounds` so execution can resume after a cross-process crash.
**Four terminal states:**
| Status | `terminated` | `terminateReason` | Trigger |
| :---: | :---: | :---: | --- |
| β
success | `false` | `undefined` | Model ends the turn without invoking any tool |
| βͺ cancelled | `true` | `cancelled` | `AbortSignal` fires (`finalAnswer = ''`) |
| π₯ error | `true` | `error` | LLM throws or checkpoint fails |
| π¨ timeout | `true` | `timeout` | `config.totalTimeoutMs` exceeded |
**Main flow:**

*(β Init β β‘ Main loop β β’ LLM β β£ Tool dispatch β β€ State ledger β β₯ Terminal settlement)*
---
## π Quick Start
### Prerequisites
- **Windows 10 / 11 64-bit**
- **Node.js 24 LTS**
- **npm 10+** (npm 11 recommended)
- **[Rust stable](https://www.rust-lang.org/tools/install)** (required for building the screenshot helper from source)
- **[Visual Studio 2022 Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/)**
When installing Visual Studio Build Tools, select:
- **Desktop development with C++**
- **MSVC v143**
- **Windows 10 / 11 SDK**
After installing Rust, it is recommended to confirm the MSVC toolchain:
```powershell
rustup default stable-x86_64-pc-windows-msvc
```
> Feishu, WeChat iLink, `nut-js` keyboard/mouse automation, and the native screenshot feature depend on the Windows environment.
>
> If you install a packaged release directly, you do not need to install Rust or Visual Studio Build Tools.
### 1. Clone the Project
```bash
# GitHub (primary repo)
git clone https://github.com/Playa-0v0/Cyrene-Agent.git
# Or via the Gitee mirror (China)
git clone https://gitee.com/playa0/cyrene-agent.git
cd Cyrene-Agent
```
### 2. Install Dependencies
```bash
npm install
```
The first installation downloads Electron, Pixi.js, Live2D, and related dependencies. The time required depends on your network connection.
### 3. Command-line Entry
The project ships a `cyrene` command-line entry point for the first-time greeting, version checks, and launching the desktop app. From the project root:
```bash
npm run build:cli
npm link
```
You can then use `cyrene` from any directory:
```bash
cyrene # First run shows the welcome banner; later runs stay quiet
cyrene hello # Show the full welcome banner again
cyrene about # Banner plus project metadata
cyrene version # Print the version
cyrene --help # List all subcommands
cyrene run # Launch the desktop app from a project root (dev mode)
```
> The first-time greeting appears only once; the state is recorded in `~/.cyrene/state.json`. Subsequent default invocations print only `Cyrene Agent