Nyzhi is a Rust workspace with six crates. Each crate has a single responsibility; dependencies flow downward from the binary to leaf crates with no cycles.
Crate Dependency Graph
The following diagram shows how the crates depend on each other. The CLI (nyz) sits at the top and depends on the TUI, core, and provider crates. Both TUI and provider depend on auth and config.
┌──────────────┐
│ nyzhi (cli) │
│ bin: nyz │
└──────┬───────┘
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌─────────────┐
│ nyzhi-tui │ │ nyzhi-core│ │nyzhi-provider│
└─────┬─────┘ └─────┬─────┘ └──────┬──────┘
│ │ │
│ ┌──────┴──────┐ │
│ │ │ │
▼ ▼ ▼ ▼
┌───────────┐ ┌─────────────┐ ┌───────────┐
│ nyzhi-auth│ │nyzhi-provider│ │ nyzhi-auth│
└─────┬─────┘ └──────┬──────┘ └─────┬─────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────┐
│ nyzhi-config │
└─────────────────────────────────────────────┘
Crate Summary
| Crate | Package | Role |
|---|---|---|
crates/cli | nyzhi | Binary entry point (nyz). CLI parsing via clap, command dispatch, MCP server setup, tool registry assembly. |
crates/core | nyzhi-core | Agent loop, 50+ tool implementations, session management, workspace detection, MCP client, planning, teams, hooks, skills, verification, analytics, and more. |
crates/provider | nyzhi-provider | LLM provider abstraction. Implements streaming chat completions for OpenAI, Anthropic, and Gemini with SSE, thinking/reasoning support, and a model registry. See Providers. |
crates/tui | nyzhi-tui | Terminal UI. ratatui-based app loop with theming, syntax highlighting, tab completion, input history, session export, and component rendering. See TUI. |
crates/auth | nyzhi-auth | Authentication. OAuth2 PKCE and device-code flows, API key resolution, token storage in auth.json, multi-account support with rate-limit rotation. |
crates/config | nyzhi-config | Configuration. TOML loading and merging across global, project, and local config files. Defines all config types and built-in provider definitions. See Configuration. |
nyzhi-core Module Map
The core crate contains 39 modules covering all agent logic. This section groups them by responsibility.
Agent Loop
The agent loop drives each turn: streaming from the LLM, executing tools, and handling approval and retries.
| Module | Purpose |
|---|---|
agent | Main agent turn loop. Streams LLM responses, executes tool calls, handles approval, retries, auto-compaction, and team context injection. |
agent_files | File context management for agent turns. |
agent_manager | Manages multiple concurrent agent instances (sub-agents, teammates). |
agent_roles | Role definitions for agent specialization (worker, explorer, planner, reviewer, etc.). |
Conversation and Sessions
| Module | Purpose |
|---|---|
conversation | Message sequence management (thread type). |
session | Session persistence: save, load, list, delete, rename, and search in JSON format. |
replay | Event-level session replay. |
streaming | Stream accumulation for SSE responses. |
Workspace and Context
| Module | Purpose |
|---|---|
workspace | Project root detection, project type classification (Rust/Node/Python/Go), rules loading (AGENTS.md, .nyzhi/rules.md, etc.), and .nyzhi/ scaffolding. |
worktree | Git worktree management for team isolation. |
context | Token estimation and context window management. |
context_files | File mention extraction and resolution (e.g., @file). |
prompt | System prompt construction with environment, tools, rules, skills, and MCP summaries. |
Tools
The tool system implements a registry with deferred loading and role-based filtering. See Tools for the full catalog.
| Module | Purpose |
|---|---|
tools | Tool trait, registry, context, and result types. Deferred tool loading and role-based filtering. |
tools/bash | Shell command execution with live output streaming. |
tools/read, write, edit | File read, write, and edit operations. |
tools/glob, grep | File pattern matching and content search. |
tools/git | Git status, diff, log, show, branch, commit, checkout. |
tools/filesystem | list_dir, directory_tree, file_info, delete, move, copy, create_dir. |
tools/verify | Build/test/lint execution with structured evidence. |
tools/lsp | LSP diagnostics, goto definition, find references, hover, AST search. |
tools/web | web_fetch and web_search. |
tools/browser | Browser automation (open, screenshot, evaluate). |
tools/pr | PR creation and review via gh. |
tools/task | Sub-agent delegation. |
tools/todo | Todo list management. |
tools/notepad | Notepad read/write. |
tools/memory | Persistent memory read/write. |
tools/team | Team creation, messaging, task management. See Teams. |
tools/semantic_search | Semantic code search. |
tools/fuzzy_find | Fuzzy file finder. |
tools/apply_patch, batch | Structured patch application and batch operations. |
tools/instrument | Debug instrumentation injection/removal. |
tools/think | Explicit thinking/reasoning tool. |
tools/update_plan | Plan update tool. |
tools/load_skill | Lazy skill loading. |
tools/tool_search | Deferred tool discovery. |
tools/tail_file | File tail for log monitoring. |
Features
| Module | Purpose |
|---|---|
mcp | MCP server management (stdio/HTTP), tool adaptation, hot-connect. See MCP. |
planning | Planner/critic loop with persistent plans in .nyzhi/plans/. |
autopilot | 5-phase autonomous execution (expansion, planning, execution, QA, validation). |
teams | Team configuration, task board with file-locking, mailbox messaging system. See Teams. |
commands | Custom slash command loading from .nyzhi/commands/ and config. |
hooks | After-edit, after-turn, pre/post-tool hook execution with pattern matching. See Hooks. |
skills | Skill persistence, templates, and lazy loading. |
verify | Auto-detection of build/test/lint checks per project type. |
routing | Prompt complexity classification and model tier selection. See Routing. |
analytics | Token usage and cost tracking in JSONL format. |
memory | Project-scoped and user-scoped persistent memory. |
notify | External notifications (webhook, Telegram, Discord, Slack). See Notifications. |
updater | Self-update with SHA256 verification, backup, rollback, integrity manifests. |
plugins | Plugin manifest and loader. |
deepinit | AGENTS.md generation from project analysis. |
diagnostics | System diagnostic info collection. |
sandbox | Sandboxed execution environment. |
index | Semantic indexing for code search. |
keywords | Keyword extraction from prompts. |
judging | Quality assessment. |
checkpoint | Checkpoint management. |
persistence | General persistence utilities. |
Data Flow
Interactive Mode (TUI)
The following diagram shows how user input flows through the system in interactive mode.
User Input
│
▼
nyzhi (cli) ── parse CLI args ── load config ── detect workspace
│
▼
nyzhi-tui::App::run()
│
├─ Build ToolRegistry (50+ tools + MCP tools)
├─ Create Provider (resolve credentials via nyzhi-auth)
├─ Start MCP servers (nyzhi-core::mcp)
│
▼
Event Loop
│
├─ User types message
│ │
│ ▼
│ nyzhi-core::agent::run_turn()
│ │
│ ├─ Build system prompt (workspace, rules, tools, skills)
│ ├─ Check context window, auto-compact if needed
│ ├─ Provider::chat_stream() ── HTTP/SSE to LLM API
│ │ │
│ │ ├─ ThinkingDelta events ── displayed in TUI
│ │ ├─ TextDelta events ── displayed in TUI
│ │ └─ ToolCall events ── execute tools
│ │ │
│ │ ├─ ReadOnly tools: execute in parallel
│ │ ├─ NeedsApproval tools: prompt user
│ │ └─ Results fed back for next LLM turn
│ │
│ ├─ Retry on 429/5xx (exponential backoff)
│ ├─ Run hooks (after_edit, after_turn)
│ └─ Log analytics (token counts, cost)
│
├─ Auto-save session
└─ Render updated UI
Non-Interactive Mode (nyz run)
The same flow applies, but the TUI event loop is skipped. Output streams directly to stdout. Trust mode defaults apply for tool approval. See Configuration for [agent.trust].
Tool Registry Design
The tool registry uses a deferred loading pattern to keep the initial prompt size small.
- Core tools are registered normally. Their full schemas are sent to the LLM in every request.
- Deferred tools are registered but only indexed (name and description). They are not included in the ChatRequest tool definitions.
- When the LLM needs a deferred tool, it calls
tool_searchto discover it by name or description. - On first use, the deferred tool is expanded — its full schema is included in subsequent requests.
This keeps the prompt under budget while making 50+ tools available. See Tools for the full list.
Permission Model
Each tool declares a permission level:
| Level | Behavior |
|---|---|
| ReadOnly | Always auto-approved. Can run in parallel with other read-only tools. |
| NeedsApproval | Requires user confirmation (or auto-approved in full trust mode, or if matching allow_tools/allow_paths in limited mode). See Configuration for trust settings. |
Agent Turn Lifecycle
A single agent turn (run_turn) follows this sequence:
- Push user message onto the conversation thread.
- Build tool definitions (filtered by role if applicable).
- For up to
max_stepsiterations:- Inject unread teammate messages (if in a team).
- Micro-compact the thread if any individual message is oversized.
- If context usage exceeds
auto_compact_threshold(default 85%), run full auto-compaction: summarize history, keep recent messages. - Build the chat request with thinking config.
- Stream response via the provider’s
chat_stream(). - On retryable error (429, 5xx): exponential backoff, try rate-limit account rotation.
- Execute tool calls: read-only in parallel, others sequentially.
- For NeedsApproval tools: emit an approval request, wait for user response.
- Offload large tool results to context files.
- Accumulate token usage, emit usage event.
- If the LLM stops calling tools (no tool_use in response), the turn is complete.
- Run after-turn hooks.
- Emit turn complete event.