A Windows-first, CLI-first coding agent you can actually study, run locally, and extend.
It shows plans before execution, asks before risky actions, and can rewind both repository state and conversation history.
Plan before act | Approve risky actions | Explicit @subagent handoff | Rewind code + conversation safely | CLI + TUI
pp-Echo is both a practical local coding agent and a learn-by-reading reference project for agent engineering. If you are new to agents, this repo gives you something many projects do not: a real runtime, visible planning, approval gates, memory, session recovery, and a codebase you can follow without needing a giant platform behind it.
pp-Echo 既是一个可实际运行的本地 coding agent,也是一个适合边读边学的 agent engineering 参考项目。如果你是 agent 初学者,这个仓库提供了很多项目没有的东西:真实可运行的 runtime、可见的 planning、审批门控、memory、session 恢复能力,以及一套不依赖庞大平台、可以真正顺着读懂的代码结构。
pp-Echo should currently be understood as a Windows-first project.
- Windows is the main supported and most tested path today.
- The helper scripts and the quickest onboarding path are Windows-oriented.
- Linux and macOS should not be assumed to have equal support yet.
- The runtime, approvals, rewind, session tree, and storage model are real and useful today.
- Subagent support exists, but it is still MVP-level rather than a finished agent-team system.
In other words: this repo already contains real architecture worth studying, but it is still evolving and should not be described as a fully mature multi-agent platform.
The project is intentionally described as Windows-first to avoid confusion.
- Use Windows for the clearest supported experience.
- Treat Linux/macOS compatibility as future work rather than current parity.
- Read the
.batscripts as the primary convenience entrypoints, not as optional historical leftovers.
The @subagent path is real, but narrow by design today.
What exists now:
- explicit user-triggered
@subagenthandoff - a built-in
spawn_subagenttool - two built-in child specs:
repo-researcherandchange-reviewer - child execution that forks a session, narrows tools, runs a constrained prompt, and returns a summary
What does not exist yet:
- full agent-team orchestration
- rich long-running multi-agent coordination
- a broad child-role ecosystem
The honest description is: subagent support exists, but it is currently an MVP child-handoff workflow rather than a finished agent-team system.
- It is not just a toy chatbot. It contains a real runtime loop, tool registry, session host, memory layer, approvals, rewind, and multiple user interfaces.
- It is beginner-friendly. The repo includes Chinese and English learning guides plus a source map for reading the code in a sensible order.
- It is practical. You can run it locally, inspect its behavior, and use it as a reference when building your own agent system.
- It is opinionated in the right places. Planning is visible, risky actions are reviewable, and the system is designed around repo work instead of generic chat.
- It is a good bridge project. Beginners can learn architecture here, and experienced builders can borrow patterns for runtime orchestration, tool calling, and safety boundaries.
- Beginners who want to understand how an agent project is organized end to end.
- Developers who want a local coding agent with visible planning and approval flow.
- Builders who want to learn how runtime, tools, memory, sessions, CLI, and TUI fit together.
- People comparing agent repos and looking for one that is easier to read, extend, and trust.
- How an agent runtime manages turns, planning, tools, and execution.
- How tool registration and dispatch work in a repo-aware coding assistant.
- How session hosting, rewind, and checkpoint ideas can improve agent usability.
- How memory and vector retrieval integrate into an agent workflow.
- How one backend can drive both a CLI chat experience and a richer TUI.
- How to structure a project so it is usable as both product and learning material.
pp-Echo targets Python 3.9+ and is easiest to try on Windows first.
Before you start:
- Set
PP_AGENT_API_KEYin your environment. - Use
start-agent.batfor the fastest first run. - If you run from source, set
PYTHONPATH=src.
set PP_AGENT_API_KEY=your_api_key
.\start-agent.batThis is the shortest path from clone to first conversation.
set PP_AGENT_API_KEY=your_api_key
.\echo-cli.batUse this when you want the richer terminal UI instead of plain chat output.
git clone https://github.com/CHEN2003-CHIP/pp-Echo.git
cd pp-Echo
set PP_AGENT_API_KEY=your_api_key
set PYTHONPATH=src
python -m pp_agent.cli.main chatMinimal non-interactive demo:
set PP_AGENT_API_KEY=your_api_key
set PYTHONPATH=src
python -m pp_agent.cli.main run "Give me a quick overview of this repo"python -m pip install --upgrade pip setuptools wheel
python -m pip install -e .
pp-agent chatIf pip install -e . fails on an older environment, use the source-run path first.
If you are new to this repo, read in this order:
- Start with the learning docs: docs/agent-learning-zh.md, docs/agent-learning-en.md, docs/source-map.md
- Then read the three core backend files: src/pp_agent/runtime/runtime.py, src/pp_agent/tools/registry.py, src/pp_agent/runtime/session_host.py
- Then move to the product layers: src/pp_agent/cli/chat.py, src/pp_agent/tui/app.py, src/pp_agent/app/bootstrap.py
flowchart TD
A["Start Here"] --> B["Learning Guides"]
B --> B1["docs/agent-learning-zh.md"]
B --> B2["docs/agent-learning-en.md"]
B --> B3["docs/source-map.md"]
B3 --> C["Core Runtime Path"]
C --> C1["runtime/runtime.py"]
C1 --> C2["tools/registry.py"]
C2 --> C3["runtime/session_host.py"]
C3 --> D["System Assembly"]
D --> D1["app/bootstrap.py"]
D1 --> D2["storage/settings.py"]
C1 --> E["Capability Layers"]
E --> E1["memory/*"]
E --> E2["skills/*"]
E --> E3["extensions/*"]
E --> E4["mcp/*"]
C1 --> F["Product Layers"]
F --> F1["cli/chat.py"]
F --> F2["tui/app.py"]
F --> F3["cli/render/*"]
- Launch with
start-agent.batfor chat orecho-cli.batfor the TUI. - Ask the agent to inspect a repo task and preview risky work before execution.
- Review approvals, create checkpoints, and use safe rewind to recover both code and conversation state.
| Interactive chat | Checkpoint + rewind |
|---|---|
![]() |
![]() |
Most coding agents are good at producing output. Fewer are good at making their behavior visible, reviewable, and reversible once a real repository gets messy. pp-Echo is built for that gap.
- Planning stays visible before execution, so you can supervise direction instead of reacting after changes land.
- High-risk operations can pause behind approvals instead of mutating the workspace immediately.
- Sessions are stored as a tree, making branch, resume, compare, and rewind workflows easier to reason about.
- Safe rewind is git-backed, so you can restore the conversation, the workspace, or both together.
- Skills, extensions, and MCP-backed capabilities fit into the same repo-aware runtime rather than feeling bolted on.
- Subagent delegation is explicit: users can require a child handoff with
@subagentinstead of guessing when the agent will delegate on its own.
If this repo helps you learn agents faster or gives you a useful starting point for your own system, a Star helps more people discover it.
Phase 1 now uses a mandatory policy gate for sensitive execution. This gate is checked at execution time, not only at planner time.
- The policy gate returns
allow,ask, ordeny. askmeans the model can stage a proposed effect, but only the host/user side may approve it.- Protected paths are enforced through path protection and policy gating.
- This phase is not a true shell sandbox. The existing shell runner remains in place behind the policy gate and host approval flow.
Protected paths in Phase 1:
.pp-agent/**.git/**.env.env.**.pem*.key
Important Phase 1 limit:
.pp-agent/**is logically isolated from model-facing tools, but it is not physically separated from the repository yet.
Phase 2A upgrades sensitive approval binding so host approval applies to an exact staged effect, not just a token.
- Sensitive file and shell proposals now produce an effect record before execution.
payload_digestis the primary approval binding.- Human-readable summaries are review output and a secondary consistency check, not the primary security anchor.
- File effects distinguish whether the target was absent or present at staging time.
- Shell effects use narrow normalization: whitespace-only differences normalize, but command content, separators, redirection, quotes, parameter order, and timeout changes remain material.
- Planner approval is still not execution approval.
Phase 2B keeps exact-effect approval binding, but makes staged shell effects easier to review and reason about.
- Shell effects now include structured fields such as
normalized_command,command_head,risk_class,writes_workspace_files,touches_external_paths,requests_network, anddestructive_hint. - Current shell classes are
inspect,workspace_mutation,external_mutation,networked, anddestructive. - Human-readable shell summaries are stable review output such as
Inspect repository status with git statusorFetch remote content with curl. - Classification enriches policy decisions and previews, but it does not bypass host-side approval and it is not a shell sandbox.
- Normalization remains intentionally narrow: whitespace-only differences normalize to the same effect, while command, parameter, separator, redirection, quote, and timeout changes remain material.
Current Phase 2B limits:
- Shell classification is still conservative heuristic matching, not a full shell parser or AST.
- The existing shell runner is still used; this phase does not add sandbox infrastructure.
- Policy still keeps shell execution behind host-side approval even for
inspectcommands.
Planned Phase 2C direction:
- Finer-grained shell semantics and better effect summaries.
- Broader effect classification across more tool families.
- Stronger policy differentiation once classification confidence is high enough.
Phase 2C generalizes effect semantics across built-in file tools, shell tools, and dynamic extension or MCP tools.
- Shared analysis records now expose
family,risk_class,summary,confidence_band,touches_workspace,touches_external,requests_network,destructive_hint, andprotected_path_hint. - Policy uses stable confidence bands such as
high,medium,low, andunknowninstead of relying on raw float thresholds in behavior rules. - Built-in file reads can still be allowed when the target is a normal workspace path and analysis is high confidence.
- Shell policy differentiation stays narrow: only a known-safe inspect subset such as
git status,git diff,rg,grep,ls,dir, andGet-ChildItemmay be allowed automatically. - Extension and MCP tools now receive shared analysis too, but this does not mean they have shared exact-effect approvals. Without staged exact-effect support, they remain policy-level
askordeny.
Current Phase 2C limits:
- Shared analysis is still heuristic and conservative.
- Unknown or weakly understood extension or MCP semantics fail closed.
- Only security-relevant, stably recomputable analysis fields are included in effect identity.
Phase 4A completes the public cutover: explicit declarations are now the only author-facing semantics contract for dynamic extension and MCP tools.
- Dynamic tools declare
exact_effect_modeasnone,auto, orrequired. exact_effect_modeis the primary exact-effect capability declaration. Authors do not set a freesupports_exact_effect_stagingboolean directly.- Registration acceptance is intentionally looser than execution eligibility: weakly declared tools may still register, but they fail closed at policy or execution time.
requirednever falls back to direct execution. If a call cannot be represented stably enough for exact approval, it fails closed withapproval_unavailable.known_safe_inspectonly makes a tool eligible for safe-inspect policy consideration. It never impliesallowby itself.- Runtime/shared analysis now tightens fields conservatively instead of replacing declared semantics wholesale.
- Author-facing
analysis_hintsare no longer accepted by public registration APIs. - A private runtime-internal override path remains available only for conservative risk tightening inside framework code.
Primary declarations:
exact_effect_modenon_side_effectfulknown_safe_inspectrequests_network_hinttouches_external_hint
Private runtime-only risk overrides may only tighten risk with these keys:
requests_networktouches_externaldestructive_hintprotected_path_hinttouches_workspace
Only the tightening-direction value True is accepted for these internal overrides. Safe or widening values such as False, safe, allow, read_only, or inspect_only are rejected.
Disallowed legacy keys:
risk_classsummaryconfidence_scoreconfidence_bandknown_safe_inspectexact_effect_modesupports_exact_effect_staging
Representative alias examples that are also rejected as primary-semantics hints:
safeallowread_onlyinspect_onlystageableapproval_supportedexact_effect_supportedconfidencesafety_scoredisplay_summary
Author guidance:
- Prefer
exact_effect_mode="auto"when unsure. - Use
requiredonly for tools that should enter exact-effect approval whenever the call is policy-sensitive and stably representable. - Leave
known_safe_inspect=Falseunless the tool is clearly read-only and non-side-effectful. - Runtime risk signals win conservatively on a field-by-field basis. A declared safe inspect tool can still be tightened back to
ask,approval_unavailable, ordeny. - See
docs/dynamic-tool-declarations.mdfor the versioned deprecation timeline, an old-to-new migration table, and examples of a safe inspect tool, a staged side-effectful tool, an unstable fail-closed tool, and an MCP registration.
The legacy-hints doctor now doubles as a release gate for the public cutover.
- Use
pp-agent capabilities legacy-hints --workspace <path>for a human-readable report. - Use
pp-agent capabilities legacy-hints --json --workspace <path>for machine-readable output. - Use
pp-agent capabilities legacy-hints --strict --workspace <path>to fail the command when author-facing legacy usage remains. - Runtime metadata is the authoritative readiness source.
- Static source scanning is advisory only and does not decide readiness by itself.
- Author-facing legacy
analysis_hintscount as removal blockers. Runtime-internal risk overrides are reported separately. - Removal readiness for
v0.4.0requires zero author-facing legacyanalysis_hintsin runtime metadata.
Current limits:
- Dynamic tool defaults remain tighter than built-in file and shell flows.
- Direct execution on policy
allowstays limited to a narrow high-confidence, non-side-effectful inspect subset. - Unknown, weakly understood, networked, destructive, or externally touching dynamic calls still fail closed to
askordeny. - This phase still does not add sandboxing, a grant history ledger, or physical control-plane separation.
set PYTHONPATH=src
python -m pp_agent.cli.main chat
python -m pp_agent.cli.main run "Audit this repo and summarize risky commands"Use @subagent when you want the runtime to force a child handoff before the main agent touches other tools.
This is currently an MVP child workflow, not a full agent-team planner. Treat it as explicit delegated inspection with a constrained child, not as mature multi-agent orchestration.
@subagent Read README.md and summarize the project
@subagent Review the current diff and call out the biggest risks
Current built-in subagent specs:
repo-researcher: read-only repository inspection withread_file,list_files,search_text, andgrep_codechange-reviewer: change-review flow withgit_statusandgit_diff_worktreeadded to the read-only tool set
Behavior notes:
@subagentis required beforespawn_subagentcan run.- If the model invents an unknown child name, runtime normalizes it back to a valid built-in subagent spec.
- In chat mode,
@subagentrequests are forced throughspawn_subagentinstead of silently falling back to direct main-agent file reads. - Current child execution is intentionally narrow: fork session, restrict tools, run a constrained prompt, return summary output.
set PYTHONPATH=src
python -m pp_agent.cli.main sessions list
python -m pp_agent.cli.main sessions treeset PYTHONPATH=src
python -m pp_agent.cli.main approvals list
python -m pp_agent.cli.main approvals summaryset PYTHONPATH=src
python -m pp_agent.cli.main checkpoint list
python -m pp_agent.cli.main rewind-safe --session <session_id> --turns 2set PYTHONPATH=src
python -m pp_agent.cli.main capabilities list
python -m pp_agent.cli.main skills listflowchart LR
U["User Prompt"] --> CLI["CLI / BAT entry"]
CLI --> RT["Agent runtime"]
RT --> PLAN["Planner"]
PLAN --> GATE{"Approval needed?"}
GATE -->|"Yes"| AQ["Approval queue"]
GATE -->|"No"| EXEC["Executor"]
AQ --> EXEC
EXEC --> TOOLS["Repo / file / shell / search / MCP tools"]
TOOLS --> CKPT["Git-backed checkpoint + safe rewind"]
CKPT --> SESS["Session tree + workspace state"]
SESS --> CLI
If you are new to agent engineering or want a guided tour of this codebase:
- Chinese learning guide: docs/agent-learning-zh.md
- English learning guide: docs/agent-learning-en.md
- Source map / module call graph: docs/source-map.md
PP_AGENT_API_KEYPP_AGENT_BASE_URLPP_AGENT_MODELPP_AGENT_ENABLE_THINKINGPP_AGENT_HOME
Create .pp-agent/config.json for per-project overrides:
{
"model": "qwen3.5-plus",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"enable_thinking": false,
"shell_timeout_seconds": 30,
"capabilities": {
"builtin_tools": { "enable": true },
"skills": {
"enable_project": true,
"enable_user": true,
"enable_builtin": true,
"custom_directories": [],
"ignored": [],
"include": []
},
"extensions": {
"enable_project": true,
"enable_user": true,
"enable_builtin": false,
"custom_directories": [],
"ignored": [],
"include": []
},
"mcp": {
"enable": false,
"config_paths": [],
"server_filters": []
}
},
"tool_confirmation": {
"write_file": true,
"edit_file": true,
"run_shell": true,
"high_risk_plan": true
}
}tool_confirmation still exists for planner-era compatibility, but it is no longer the complete safety model on its own. Sensitive execution now also passes through a mandatory execution-time policy gate.
Project resources can be declared in .pp-agent/resources.json or .pp-agent/package.json. If no manifest is present, pp-Echo falls back to conventional directories like .pp-agent/skills and .pp-agent/extensions, and also supports pi-compatible discovery from .pi/skills and .agents/skills.
- Release notes for the first formal release live in releases/v0.2.0.md.
- A reusable template for future releases lives in .github/release-template.md.
- GitHub Releases page: github.com/CHEN2003-CHIP/pp-Echo/releases
- Latest benchmark report: docs/benchmarks/latest.md
- Generated benchmark artifacts: artifacts/benchmarks
- The suite is deterministic, offline, and focuses on planner gating, safe rewind, MCP lazy activation, session branching, and long-context compaction.
Contributions are welcome across CLI behavior, docs polish, demo assets, tests, extensions, and release packaging.
Start here:
- Read CONTRIBUTING.md
- Run tests with
python -m pytest - Keep documentation and demo assets in sync when user-facing behavior changes
This project is licensed under the MIT License. See LICENSE.


