Not a copilot. A crew of autonomous agents that understand, navigate, and evolve your codebase β together.

English: README.md Β· δΈζοΌREADME_zh.md
Most AI coding tools share a fundamental flaw: they treat code as text, not structure β and they treat context as infinite, when it is the scarcest thing you have.
| Traditional Tools | Yagent |
|---|---|
| Flat text pattern matching | π§ Structural code understanding β AST + call graphs + hybrid retrieval |
| Single agent, working alone | π€ Hub-and-Spoke multi-agent: Director orchestrates, six specialists execute |
| Static capabilities | 𧬠Meta-Agent: designs & registers new agents at runtime β the system evolves |
| Keyword-only search | π Natural-language semantic search β "find where auth logic is implemented" |
| Every tool schema sent on every step | ποΈ Deferred tool schemas: cold tools ship as name + one-line brief; the model fetches the schema when it actually needs it |
| Long sessions silently degrade | ποΈ Three-tier context compression + a cross-agent note board, so conclusions stay addressable instead of being re-derived |
| One model for everything | π― Benchmark-scored auto-routing: fast / balanced / high, picked per sub-task |
| "Trust me, it compiles" | β
Forced delegation, design gate, git checkpoints, activity-aware timeouts, and /resume from durable rollout logs |
| Agent | Role | Permissions | Default Max Steps |
|---|---|---|---|
| πΌ Director | Orchestrator β the only agent that talks to you. Decomposes, delegates, reviews | Read-only + delegation | 100 |
| π¬ Repo-Agent | Code archaeologist / auditor β AST, semantic search, call graphs, impact analysis | Read-only, may delegate DevOps | 50 |
| βοΈ Coding-Agent | Staff engineer β edits, shell, design & reflection tools, self-correction | Full read/write + shell | 150 |
| π Browser-Agent | Drives real Chrome for docs, issues, Stack Overflow, and live web verification | 14 browser tools + its own workspace (no shell, no file writes) | 200 |
| π§ DevOps-Agent | SRE β shell execution, environment diagnostics, process management | Read-only + shell | 50 |
| π¬ Chat-Agent | Technical advisor β Q&A and explanations with no filesystem access at all | None | 50 |
| 𧬠Meta-Agent | Agent factory β designs a new agent as JSON, it is registered and runs immediately | Single-shot, tool-less | 50 |
| ποΈ Custom Agents | Runtime products of the Meta-Agent (e.g. delegate_security_auditor) |
Capability subset chosen by the LLM | 15 |
Authority is not a suggestion in a prompt β it is derived. Each agent declares a capability profile (a bitmask of allowed effects), and its tool surface is computed from the central registry. Add a tool and it appears wherever its capability is granted; forget one and startup validation fails loudly instead of the tool silently vanishing.
TUI (Bubble Tea v2) Β· HTTP + WebSocket Β· --prompt
β
ββββββββββββ΄βββββββββββ
β πΌ Director β Planner Β· Thought & Plan journal
β (orchestrator) β Β· circuit breaker Β· review
ββββββββββββ¬βββββββββββ
ββββββββββ¬βββββββββ¬βββββββ΄βββββββ¬ββββββββββ¬ββββββββββ
π¬ Repo βοΈ Coding π¬ Chat π§ DevOps π Browser 𧬠Meta
read-only write+ no fs read+ real designs β
+ graph shell access shell Chrome registers
ββββββββββ΄βββββββββ΄βββββββ¬βββββββ΄ββββββββββ΄ββββββββββ
β
every result becomes β€ π a Blackboard note (structured handoff,
β derived index) Β· πͺ¨ an offloaded artifact
ββββββββββββ΄βββββββββββ
β ENGINE LAYER β π§© Tool Registry β 50 tools, capability
β β profiles, deferred schemas (load_tool)
β β π― Model Router β fast / balanced / high,
β β scored from a 478-model benchmark catalog
β β ποΈ Three-Tier Compression β π§ Thinklink
β β πΌ Rollout JSONL β /resume
ββββββββββββ¬βββββββββββ
β MCP stdio (6 tools)
π¦ codeseek β Tree-sitter AST Β· Petgraph call graph
Β· LanceDB dense Β· Tantivy BM25 Β· RRF Β· cross-encoder
The Repo-Agent is backed by codeseek β a Rust engine (git submodule, shipped inside the Go binary, called over MCP stdio) that understands code like a senior engineer.
- 25 Tree-sitter language IDs, with function/class extraction and call-graph edges verified for Rust Β· Python Β· JS Β· TS Β· Go Β· C/C++ Β· Java
- Call graph analysis via Petgraph: who calls this, what breaks if I change this, depth-limited graph traversal, and code skeletons β so an agent reads a module's shape instead of opening every file
- Six tools bridged over MCP:
semantic_search,query_code_skeleton,query_code_snippet,find_function_caller,find_function_callee,query_call_graph - Auto-indexing: file watcher with 2s debounce keeps the model in sync while you edit
- Graceful degradation: no embedding API, no reranker, or index still building β the engine falls back to graph-based name search and the agents fall back to file tools. Never a hard failure.
User Query
βββ Stage 1 Β· Hybrid Search (dual-channel recall)
β βββ π§ Dense : LanceDB ANN (default Qwen3-Embedding-4B, 2560-dim, configurable)
β βββ π€ Sparse: Tantivy BM25 with a custom CodeTokenizer (snake_case / CamelCase)
β βββ π RRF : Reciprocal Rank Fusion merges both channels
βββ Stage 2 Β· Code Graph Expansion
β βββ PetCodeGraph BFS from seed symbols β callers/callees, restoring architectural position
βββ Stage 3 Β· Cross-Encoder Rerank
βββ Optional Qwen3-Reranker scoring of each (query, code) pair
| Pure Vector Search | Yagent Hybrid + Graph Expansion | |
|---|---|---|
| Recall | β Semantic matches with different wording β missed | β BM25 + dense dual channel |
| Precision | β Short noisy snippets rank high | β RRF + short-code penalty + cross-encoder |
| Context | β Isolated snippets, no call relationships | β Call chains expanded automatically |
| Code-aware | β Generic tokenizers | β CodeTokenizer for code naming |
| Robustness | β Single point of failure | β Three independent degradation paths |
Declaring all fifty tools in full costs the model several thousand tokens of boilerplate on every single step β and the agent needs maybe a dozen of them per task. Yagent tiers every tool as Hot / Warm / Cold:
- Hot tools carry their full JSON Schema every step (flow control and the tools an agent uses constantly).
- Cold tools appear only in a Deferred tools catalog in the system prompt β
name: one-line brief. - When the model wants one, it calls
load_toolwith up to 8 names batched, gets the real parameter schema, and proceeds. Skip that step and the system doesn't reject it as hallucination β it hands back the schema once, as a teaching fallback. - A per-step declaration budget (default 2500 tokens,
[tools.deferred.budget_tokens]) demotes oversized tools to Cold automatically, and[tools.deferred.hot] / [cold]let you retune tiers by name without recompiling. /resumerestores which schemas were already materialized, so a recovered session doesn't pay the round-trip again.- One switch (
disable = true) returns to the old all-schemas-always behavior β kept honest for A/B debugging.
Every step is checked against a budget derived from an embedded catalog of 478 models (context Γ 0.75; no catalog hit falls back to your configured threshold).
- Tier 1 β Rule: truncate tool results by value priority (cognitive results like
deepthinking/designare protected), keeping the most recent ones intact. - Tier 2 β Emergency: extract Thought & Plan blocks into the thinklink journal, keep the last 3 verbatim, LLM-summarize the rest, and rewrite memory as
[system, one user]. - Tier 3 β Ultimate: rebuild the working context from the thinking journal, keep the most recent plans, then hard-truncate to budget.
All three emit events and rollout records, and the TUI shows exactly what each tier bought you: per-tier saved tokens, percentage, a context trend sparkline, and a leaderboard of which tools got cut. One renderer, one accounting rule β so the sidebar, the bottom bar, and the collapsed row can never disagree.
When a sub-agent finishes, its result is written as a note with a structured handoff β conclusion, verifiable facts[] (each with a where: file:line, symbol, URL), open_questions, status β and large deliverables are offloaded to disk as artifacts, leaving a summary plus an ID in context.
An index of every note is injected into each Director turn and each delegation prefix, and context_refs lets the Director say "build on what Repo already found":
delegate_coding(task = "implement the fix",
context_refs = ["agent:repo", "artifact:20261014-093012-a1b2c3d4"])
The index is derived state, rebuilt from disk and never persisted into session memory β which is precisely why compression can't evaporate it. Read-back is three tools: read_note (handoff + paged body), read_artifact (paged full text), list_notes (board directory). Boards are session-scoped, so a /resume picks up the same notes instead of re-exploring the repo from zero.
Point Yagent at several providers and it sorts them for you. The embedded model catalog carries benchmark results; routing scores each candidate (ai_score over the strict benchmark intersection, weighting DeepSWE / SWE-Bench Pro / GPQA Diamond at 1.5Γ) and picks three tiers from your own pool β highest, median, lowest. If fewer than three configured models share benchmark data, routing disables itself with the reason printed instead of guessing.
Then a fast model classifies every sub-task as fast / balanced / high: run a command and read a log β fast; ordinary coding and retrieval β balanced; architecture, planning, subtle debugging β high. Per-agent baselines override the default tier ([routing.baselines] coding = "high"), a failed classification falls back to the baseline rather than blocking the task, and alt+r / :route flips modes live with the chosen model and score shown in the TUI.
Provider selection is three-level β tool β agent β global β so micro_agent can run locally while the Director runs your frontier model. Both wire formats are first-class: api_format = "openai" and "anthropic" (native Messages, Extended Thinking with budget mapping, streaming tool_use reassembly), plus weighted fallback providers and a circuit breaker on top.
When a task falls outside the built-in crew, the Director asks the Meta-Agent, which designs β executes β registers:
- π¨ One LLM call produces a new agent's system prompt, toolset, and goal as JSON
- β‘ It runs immediately (15 steps) to finish the current sub-task
- π§ It stays registered as
delegate_<name>for the rest of the task, listed in the Director's prompt
Auto-creates
delegate_security_auditorfor a full-repo audit, ordelegate_performance_profilerfor bottleneck hunting.
Its tool palette is capped by the registry the same way every other agent's is β a generated agent cannot invent permissions.
Rebuilt on an external browser-control CLI driving an actual Chrome instance β 14 tools (open / inspect / snapshot / click / fill / type / select / tabs / wait / screenshot / eval β¦) so the agent can read rendered DOM, not just fetched HTML.
mode = "attach": connect to your existing browser over CDP and use a session you are already logged into- Isolated per-delegation workspace β screenshots, traces and upstream state land in
~/.yagent/data/browser/<delegation>/, never in your repository - URL policy (
allowed_domains/denied_domains), dialog policy, and an output cap so a giant page can't flood context - Authorization for sensitive JS β cookie/storage/network access and form submission require approval; screenshots are path-converged into the session workspace
- Honest capability degradation: no binary or no Chrome β
delegate_browser's own description becomes "unavailable + why + how to fix it", so the model stops trying
designβ a pre-coding gate. For complex tasks the Coding-Agent's prompt requires a design pass before implementation: goal & scope, affected files, ordered steps, risks, verification criteria. Mid-implementation scope change means re-run it.deepthinking(reactive, for when conventional attempts failed) Β·micro_agent(isolated sub-LLM reasoning, own provider slot) Β·thinking(cheap self-reflection) β each with its own tool-level provider.- Structured Thought & Plan blocks β
goal / step / reason / planwith machine validation, parsed into a rolling journal that drives Tier-3 compression, feeds the TUI timeline, and survives context resets. - Parallel read-only execution β consecutive read-only calls (file reads, searches, call-graph queries, note reads, read-only delegations) are batched and run concurrently (default 4, ceiling 8). Concurrency is derived from tool effects, not a name list, and a contract test guards every widening of that surface.
- Git checkpoints β snapshot and roll back per coding sub-task.
- Forced delegation β the Director cannot write files, and repository exploration goes through the Repo-Agent. Replying without delegating triggers a reminder, up to three times.
| Concern | How Yagent Handles It |
|---|---|
| Blast radius | WorkspaceGuard: writing tools and run_bash must land inside the workspace; anything reaching outside needs authorization (persisted per session/project). run_bash carries no command blacklist β it combines the model's own is_dangerous flag with a check that any absolute path token pointing outside the workspace asks first. |
| Human in the loop | ask_user_for_help with confirm / select / input β blocking authorization travels on a critical bypass queue that is never dropped, matched by request_id. |
| Escalation for autonomy | -y / --yolo approves in-workspace operations; -Y / --full-yolo also removes ask_user_for_help entirely for unattended runs. |
| LLM flakiness | Exponential retry (β€30s) per step β weighted provider fallback β circuit breaker with reset timeout. |
| Stalled work | Activity-aware timeouts instead of a fixed deadline: heartbeats from each running tool distinguish an idle agent from a slow one (delegate_idle_timeout / delegate_total_timeout), and cancellation propagates into sub-agents. |
| Lost session | Synchronous rollout JSONL is the source of truth: /resume rebuilds conversation memory (repairing tool-call pairing), thinklink entries, per-agent token totals, compression history, model & context window, and re-adopts the blackboard. Interrupted runs raise a dialog listing unfinished plan items and dangling tool calls, and offer to continue. |
| Size bombs | 10MB edit/read caps, 1000 lines per read, soft warning at 2MB, tool-result budgets, artifact offloading for oversized deliverables. |
Built on Bubble Tea v2, with a single hand-drawn panel language (rounded borders, embedded mode labels, keycap hints) and a responsive layout engine down to narrow terminals.
- Up to 10 parallel session tabs (
ctrl+t,alt+1..9,alt+w), each snapshotting its own conversation, task, timeline, token counters and compression stats, keyed by its own session ID - Real vim modal editing β
EscβNORMAL,iβINSERT, count prefixes (10j),/in-buffer search withn/N, and a:command line (:q :h :mode :language :route :model :timeout :clear :hist :resume) /skill-nameautocompletion from aSKILL.mdregistry, and@to pick a file through the embedded fzf- Token dashboard, one renderer: Ξ£ totals, per-agent breakdown,
βprompt-cache hit rate (normalized across OpenAI and Anthropic accounting),βcontext-vs-window meter with green/yellow/red gradient, plus theβ§compression block showing per-tier savings (alt+tcollapses it to one line) alt+mmodel selector β rebind the global default, any of the 7 agents,deepthinking/design, or the LLM timeout at runtime;spacealso persists the choicectrl+gthinklink fullscreen with a per-agent filter (f),ctrl+ltimeline fullscreen, and a resume/history browser grouped by project and datectrl+zsuspends to your shell, and:languagetoggles the whole interface between Chinese β English
Grab the latest all-in-one release for your platform from GitHub Releases. The binary embeds the codeseek intelligence engine (Rust), fzf and ripgrep β extract, and run ./yagent. Zero dependencies.
- Go 1.25+
ripgreponPATH(used bysearch_by_regex; the release binary bundles it)- Rust + Cargo only if you want to rebuild codeseek from the submodule
git clone --recurse-submodules https://github.com/iohub/yagent.git
cd yagent
./build.sh # Rust (codeseek) + Go β dist/bin/codeseek and ./yagent
go build -o yagent . # Go only, reusing the prebuilt dist/bin~/.yagent/config/config.toml is generated from an embedded template on first run (or point at your own with -c):
[global.llm]
use_provider = "siliconflow"
[global.llm.providers.siliconflow]
model = "deepseek-ai/DeepSeek-V3.2"
api_base_url = "https://api.siliconflow.cn/v1"
api_key = "your-api-key"
temperature = 0.0
max_tokens = 23000
# context_window = 262144 # TUI context meter only (compression uses the model catalog)
# api_format = "anthropic" # native Messages + Extended Thinking
# reasoning_effort = "high" # openai: passthrough Β· anthropic: thinking budget
# fallback_providers = ["mimo", { provider = "local", weight = 2 }]
[agents.llm.coding] # per-agent and per-tool provider overrides
use_provider = "local"
[tools.llm.micro_agent]
use_provider = "local"
[routing]
mode = "auto" # benchmark-scored fast/balanced/high
[routing.baselines]
coding = "high"
repo = "balanced"
[codeseek] # Rust code intelligence over MCP
binary_path = "" # empty β extracted from the embedded binary
[browser] # Browser-Agent (needs browser-control + Chrome)
enabled = true
mode = "headless" # headless | headful | attach./yagent # TUI (default)
./yagent tui --taskfile TASK.md
./yagent -p "explain the build system" # non-interactive single shot
./yagent http --port 0 # HTTP + WebSocket, port auto-detected from 9800Flags: -d/--disable-agents Β· -c/--config Β· -y/--yolo Β· -Y/--full-yolo Β· -Q/--force-quit.
The working directory is the project root. Drop reusable prompts as *.md in .yagent/skills/ (or ~/.yagent/skills/) and they show up as /slash commands.
bash scripts/check_all.sh # the one-command local gate: build + vet + 5 guards + full suite
RACE=true bash scripts/check_all.sh # plus -race on the concurrent packages
go test ./internal/... -count=1 # ~970 tests across 129 files, seconds not minutes- End-to-end chains run against real components. Authorization round-trip, cross-delegation handoff (notes + artifacts + deferred-schema retry), delegation lifecycle (idle/total timeout & cancellation), and
/resumeall execute with the real dispatcher, realWorkspaceGuard, real note store and real rollout files β only the LLM is scripted, and it is scripted per agent identity, not by global call index. - Protocol layer pinned by shape.
httptestfakes assert the exact JSON going out and the exact usage accounting coming back (the two providers' cache-token conventions are opposite, and that is asserted). - Tests must be able to fail. A hygiene ratchet rejects assertion-less tests, unconditional skips, and duplicate helpers; a fixture that never triggers the branch under test is treated as a bug. Timing tests use seams, never
sleepβ the suite stays fast enough to actually run. - Architecture ratchets:
director/may not importagents/(no cycles),toolspecstays a leaf, no hand-written tool lookup tables, and the file-size gate reports when it drifts out of sync instead of crying wolf. - Events have one source of truth:
protocol/agent-events.yamlgenerates the Go / TS / JSON-Schema.
| Document | Description |
|---|---|
| ARCHITECTURE.md Β· ARCHITECTURE.en.md | System architecture, modules, data flow |
| AGENTS.md | The knowledge base agents themselves read before contributing β module map, invariants, known pitfalls |
| tool-registry-design.md | Capability registry, profiles, and deferred tool schemas |
| blackboard-handoff-design.md | Cross-agent notes, structured handoff, derived index |
| browser-agent-design.md | Browser-Agent on the browser-control CLI |
| token-dashboard-design.md Β· token-compress-panel-design.md | Token accounting and compression telemetry |
| config-guide.md | Configuration guide |
| anthropic-config.md | Anthropic provider configuration |
| llm-fallback-config.md | Fallback and circuit-breaker configuration |
Known gap, stated plainly: the long-term knowledge retrieval injector (
internal/knowledge/injector.go) is temporarily gated off β the write path (consolidate_knowledge, repo-level memory consolidation) is live, but historical knowledge is not auto-injected into context yet.
We welcome all contributions β bug reports, feature requests, docs, and code.
- π Open an Issue
- π Submit a PR
- π¬ Join the Discussion