Skip to main content

Terminal-native AI coding assistant (Python) with ReAct loop, memory system, and extensible tool/skill/hook architecture

Project description

minicode

终端原生的 AI 编程助手 · Terminal-native AI coding assistant (Python)

PyPI Python License: MIT Status

minicode 是一个用 Python 实现的终端原生 AI 编程助手,仿照 ClaudeCode 的设计思路,自研了一套完整的 Agent 内核:ReAct 循环分级记忆管理可插拔工具 / Skill / Hook / Subagent斜杠命令补全。最大的特点是完整展示 Agent 内部每一步的运行状态——每一次输入提示词的构成、每一次工具调用的参数、中间思考过程,全部可见,非常适合用来学习代码 Agent 的内部机制。


📑 目录


特性

  • 🤖 完整的 ReAct 循环 — user → LLM → tool_call → execute → result → LLM,标准 Agent 模式
  • 🧠 三级预算管理 — 软裁剪 → 硬裁剪 → 自动 compact,按压力等级自动保护上下文
  • 🔧 可插拔工具系统 — 8 个内置工具 + Skill + MCP + Subagent,统一接口
  • 💬 斜杠命令补全 — TTY 环境下输入 / 自动提示,Tab 补全到最长公共前缀
  • 🪝 双类型 Hook — 支持 Python 和 Shell 两种 hook,事件粒度细化到 tool_call
  • 🎯 Goal + Judge — 设置停止条件,judge LLM 独立评估任务完成度
  • 🔐 细粒度权限 — per-session always-allow / always-deny + 阻塞式询问
  • 🌐 多端 Chat Bridge — stdio / webhook adapter,让外部聊天工具接入 agent
  • 📝 自定义命令.minicode/commands/*.md 文件即命令,支持 $ARGUMENTS 占位
  • 🪟 上下文可视化/context 命令打印 system / tools / history 的占比
  • 🧪 442 个测试用例 — 单元测试 + 端到端测试,全量通过

快速开始

从 PyPI 安装(推荐)

  • PyPI 包名(pip 用的名字):pyminicode
  • Python 导入名(import 用的名字):minicode
  • 命令行入口(安装后多出来的命令):minicode
pip install pyminicode

升级到最新版:

pip install --upgrade pyminicode

指定版本:

pip install pyminicode==0.2.0

带开发依赖安装(如果要参与开发或跑测试):

pip install "pyminicode[dev]"

从 GitHub 源码安装

git clone https://github.com/<your-username>/minicode.git
cd minicode
pip install -e .

或使用 pip 直接装 GitHub 仓库:

pip install git+https://github.com/<your-username>/minicode.git

首次运行

安装完成后:

# 1. 在当前项目目录初始化 .minicode/(含 config.yaml 模板 + skills/agents/hooks/commands 子目录)
minicode --init

# 2. 编辑 .minicode/config.yaml,填入你的 API Key
#    (推荐用环境变量:${OPENAI_API_KEY})

# 3. 启动 REPL
minicode

环境变量模板:

# OpenAI / OpenAI 兼容服务
export OPENAI_API_KEY=sk-...

# Anthropic
export ANTHROPIC_API_KEY=sk-ant-...

第一次启动会自动加载 .minicode/config.yaml、构建 tool registry、加载 memory/hooks/agents/skills,然后进入 REPL。

如果你想在 Python 代码里调用(不是通过 REPL):

import minicode
print(minicode.__version__)        # '0.2.0'
from minicode.cli.app import main  # 等价于命令行 `minicode`
from minicode.model import ModelRegistry
from minicode.tool.registry import ToolRegistry

一次性命令

minicode --version          # 打印版本
minicode --paths            # 打印 .minicode 路径解析结果
minicode --init             # 在当前目录创建 .minicode/ + config.yaml 模板
minicode --check-config     # 校验配置文件
minicode --print-tools      # 列出所有工具
minicode --print-memory     # 打印加载的 AGENTS.md + rules

项目状态

版本 内容
v0 工具层(Tool / Registry / 8 个内置工具 + Skill + MCP)
v1 模型层(OpenAI 兼容 / Anthropic / Demo provider)
v2 ✅ 当前 ReAct 循环 + 记忆系统(预算/裁剪/压缩/持久化/可视化)+ 权限 + Hook + Goal + Chat Bridge + 斜杠命令补全 + 自定义命令 + 代码简化

下一版(v3)计划:

  • Google Gemini provider
  • 远程 skill / agent 拉取(从 git / URL)
  • 超过阈值的输出自动转临时文件 + 占位符
  • chatbridge 多 session 隔离

架构总览

┌──────────────────────────────────────────────────────────────────────┐
│                           CLI (cli/app.py)                           │
│  REPL / 命令处理 / 斜杠补全 / 状态栏 / 渲染                           │
└──────────────────────────┬───────────────────────────────────────────┘
                           │
          ┌────────────────┼────────────────┐
          │                │                │
          ▼                ▼                ▼
   ┌────────────┐  ┌────────────┐  ┌────────────────┐
   │  ToolRegistry│  │ModelRegistry│  │ CommandLoader  │
   │  (all tools) │  │ (providers) │  │ (custom cmds)  │
   └──────┬─────┘  └──────┬─────┘  └────────────────┘
          │                │
          │                │
          ▼                ▼
   ┌──────────────────────────────────────────┐
   │              ReAct 循环 (agent/runtime.py) │
   │  user → LLM → tool_call → execute → result │
   │       ↑                          │        │
   │       └──────────────────────────┘        │
   │                                          │
   │  预算管理:soft/hard trim → compact       │
   │  doom loop 检测                           │
   │  tool 输出截断(错误感知 head+tail)       │
   └──────────────────────────────────────────┘
          │
          ├──────────────┬──────────────┬──────────────┐
          ▼              ▼              ▼              ▼
   ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐
   │  builtin │  │  skill   │  │   mcp    │  │subagent  │
   │  tools   │  │  tools   │  │  tools   │  │ (nested) │
   └──────────┘  └──────────┘  └──────────┘  └──────────┘

   ┌──────────────────────────────────────────────────┐
   │              记忆系统 (memory/)                    │
   │  budget → truncation → compact → context_view     │
   │  history (持久化) / status (输入框前)             │
   └──────────────────────────────────────────────────┘

   ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
   │  permission  │  │    hooks     │  │    goal      │
   │  (per-session)│  │ (python/shell)│  │  + judge    │
   └──────────────┘  └──────────────┘  └──────────────┘

   ┌──────────────────────────────────────────────────┐
   │              chatbridge (多端桥接)                  │
   │  stdio / webhook adapter → bus → model → history  │
   └──────────────────────────────────────────────────┘

目录结构

minicode/
├── pyproject.toml
├── README.md
├── LICENSE                             # MIT
├── .gitignore
├── .minicode/                          # per-project config dir
│   ├── skills/                         # skill files
│   │   ├── code-review/SKILL.md
│   │   ├── refactor/SKILL.md
│   │   └── test-gen/SKILL.md
│   ├── agents/                         # subagent definitions
│   │   ├── code-reviewer.md
│   │   ├── explorer.md
│   │   └── test-writer.md
│   ├── commands/                       # custom slash commands
│   │   ├── review.md
│   │   └── fix.md
│   ├── hooks/                          # python/shell hooks
│   ├── rules/                          # memory rules
│   ├── mcp.json                        # MCP server config (stdio / http)
│   ├── AGENTS.md                       # agent memory root
│   └── config.yaml                     # LLM provider 配置
├── minicode/                           # source
│   ├── __init__.py
│   ├── __main__.py
│   ├── _ansi.py                        # ANSI 颜色常量 + TTY 探测(公共模块)
│   ├── paths.py                        # .minicode 路径解析
│   ├── config.py                       # config.yaml 加载
│   ├── command.py                      # custom command loader
│   ├── registry.py                     # 全局 registry
│   ├── tool/                           # 工具层
│   │   ├── base.py                     # Tool 抽象基类 + ToolContext + ToolResult
│   │   ├── registry.py                 # ToolRegistry
│   │   ├── skill.py                    # SkillLoader
│   │   ├── mcp.py                      # McpClient + McpToolAdapter
│   │   └── builtin/                    # 8 个内置工具
│   │       ├── bash.py
│   │       ├── edit.py
│   │       ├── glob_tool.py
│   │       ├── grep_tool.py
│   │       ├── read.py
│   │       ├── write.py
│   │       ├── skill.py
│   │       └── subagent.py             # delegate_to_subagent
│   ├── model/                          # 模型层
│   │   ├── base.py                     # Model 抽象基类
│   │   ├── message.py                  # Message / Part / ToolSchema
│   │   ├── openai_compat.py            # OpenAI Chat Completions
│   │   ├── anthropic.py                # Anthropic Messages API
│   │   ├── demo.py                     # 假 provider(echo)
│   │   └── registry.py                 # ModelRegistry
│   ├── agent/                          # ReAct 循环 + subagent
│   │   ├── loader.py                   # SubagentLoader
│   │   └── runtime.py                  # run_agent / run_subagent + 预算管理
│   ├── memory/                         # 记忆系统
│   │   ├── budget.py                   # ContextBudget + token 估算
│   │   ├── truncation.py               # 分级裁剪
│   │   ├── compact.py                  # /compact 手动压缩
│   │   ├── context.py                  # AGENTS.md + rules → system prompt
│   │   ├── context_view.py             # /context 可视化
│   │   ├── history.py                  # 会话历史持久化
│   │   ├── loaders.py                  # AGENTS.md / rules 加载
│   │   └── status.py                   # 输入框前 ctx 状态栏
│   ├── permission/                     # 工具调用权限
│   ├── hooks/                          # Hook 系统
│   ├── goal/                           # 停止条件 + judge
│   ├── display/                        # 结构化渲染
│   ├── chatbridge/                     # 多端聊天桥接
│   └── cli/
│       ├── app.py                      # REPL + 命令处理
│       └── input.py                    # 斜杠命令补全
└── tests/                              # 442 个测试用例
    └── ...

配置说明

.minicode/config.yaml(由 minicode --init 自动生成):

# LLM provider:当前支持 openai / anthropic / demo
provider: openai

# API Key。推荐用环境变量:${OPENAI_API_KEY}
api_key: ${OPENAI_API_KEY}

# API base URL
base_url: https://api.openai.com/v1

# 模型名称
model: gpt-4o

# 上下文窗口大小(可选)。支持 128K / 1M / 128000 等写法
context_window: 128K

# 透传给 provider 的额外参数(可选)。
# 整数字段(如 max_tokens)也支持 K/M 后缀,会自动展开成整数。
extra:
  temperature: 0.7
  max_tokens: 8000

provider 可选值:

说明
openai 任何实现 OpenAI Chat Completions 的服务(OpenAI / DeepSeek / Moonshot / ollama / vllm / ...)
anthropic Anthropic Messages API
demo 进程内回显,无需网络(开箱即用)

extra 字段透传给 provider 实现(OpenAI:temperature / top_p / presence_penalty;Anthropic:max_tokens 必填 / temperature / top_k)。


CLI 命令

在 REPL 中输入 / 触发自动补全(Tab 键补全到最长公共前缀)。

命令 作用
/tools 列出所有工具(builtin + skill + mcp)
/skills 列出 skill
/agents 列出 subagent
/hooks 列出已加载的 hook
/mcp 列出 MCP 服务和状态
/model 显示当前 model 详情
/model test 流式发 "ping" 测试当前 model 的连通性
/memory 显示 AGENTS.md + rules
/context 显示上下文窗口占用(进度条 + 分项明细)
/history 列出历史会话
/compact 手动压缩历史对话(调 LLM 摘要)
/goal 设置/查看停止条件
/goal judge 调 judge 评估是否完成
/chat chat bridge 管理
/permission 权限管理(always allow/deny/clear)
/display 渲染 demo(thinking / tool-call / code-change)
/paths 打印路径解析结果
/call <id> [json] 手动调用一个工具
/reload 重新 build registry
/commands 列出自定义命令
/help 打印帮助
/exit / /quit 退出

工具 / Skill / Hook / Subagent

工具协议

所有工具实现同一接口(minicode/tool/base.py):

class Tool(ABC):
    kind: ToolKind = ToolKind.BUILTIN

    @property
    def id(self) -> str: ...

    @property
    def description(self) -> str: ...

    @property
    def parameters(self) -> type[BaseModel]: ...

    async def execute(self, args: Parameters, ctx: ToolContext) -> ToolResult: ...

ToolContext 携带:session_id / cwd / project_root / tool_registry / permission_service / hook_dispatcher / bus / model_registry / config / history / context_budget

ToolResult 字段:title(短标题)/ output(内容,str 或 list[Part])/ metadata(dict)。

Skill(.minicode/skills/<name>/SKILL.md

---
name: code-review
description: 严格审查代码改动并给出改进建议
---

你是 code reviewer ...

通过内置的 skill 工具动态加载。

Hook(.minicode/hooks/

支持 Python 和 Shell 两种 hook:

# .minicode/hooks/my_hook.py
def run(event, context):
    if event.event == "tool_call_before":
        if event.data["tool"] == "bash":
            return HookResponse.deny("no bash allowed")
    return HookResponse.allow()
# .minicode/hooks/my_hook.sh
#!/bin/bash
EVENT=$(cat)
if echo "$EVENT" | jq -e '.event == "tool_call_before" and .data.tool == "bash"' > /dev/null; then
    echo '{"action":"deny","reason":"no bash"}'
    exit 0
fi
echo '{"action":"allow"}'

事件:session_start, session_end, user_prompt_submit, assistant_message, tool_call_before, tool_call_after, error, stop, compact

聚合规则:并行执行,任一 deny → 整体 deny,多个 modify → 串联合并。

Subagent(.minicode/agents/<name>.md

---
name: code-reviewer
description: 严格审查代码改动并给出改进建议
---

你是 code reviewer ...

delegate_to_subagent 工具让父 LLM 把任务委派给 subagent,防递归(subagent 看不到此工具)。

自定义命令(.minicode/commands/<name>.md

---
description: 代码审查命令
---

请审查以下代码改动,给出改进建议。
用户输入:$ARGUMENTS

运行时 $ARGUMENTS 替换为用户输入。

Chat Bridge(chatbridge/)

> /chat
> /chat register webhook https://example.com/webhook
> /chat status

支持 stdio / webhook adapter,让外部聊天工具接入 agent。


记忆系统

Token 预算(memory/budget.py)

不引入 tiktoken,用 chars / 3 粗估。ContextBudget 跟踪 system + history 的 token,按压力等级分级:

等级 阈值 动作
0 < 50%
1 50-70% 软裁剪旧 tool result(head+tail)
2 70-85% 硬裁剪旧 tool result(清空内容)
3 ≥ 85% 自动 compact(调 LLM 压缩历史)

分级裁剪(memory/truncation.py)

  • soft_trim_tool_results — 旧 tool result → head+tail(保留结构,压缩体积)
  • hard_trim_tool_results — 旧 tool result → 清空标记(保留 tool_call 配对)
  • truncate_messages — 丢弃整轮旧消息(最后的兜底)

保护最近 N 轮不动(避免裁到当前上下文)。

/compact 手动压缩(memory/compact.py)

把旧消息喂给 LLM 生成摘要,替换成一条 assistant summary message。

上下文可视化(memory/context_view.py)

/context 命令展示:

┌──────────────────────────────────────────┐
│ context window  6500/8000  81.3%          │
│ [████████░░]                              │
│                                          │
│ breakdown                                │
│   system prompt   1200 (15.0%)           │
│   tools schema     800 (10.0%)           │
│   history         4500 (56.3%)           │
│     user text     1200                   │
│     assistant     1500                   │
│     tool calls     800                   │
│     tool results  1000                   │
│                                          │
│   output reserve  4000 (50.0%)           │
│   remaining       1500 (18.8%)           │
│                                          │
│   pressure: high (level 3)               │
└──────────────────────────────────────────┘

状态栏(memory/status.py)

输入框前显示:minicode> [ctx 6500/8000 ████████░░] $_

颜色:绿 (< 60%) / 黄 (60-85%) / 红 (> 85%)。

历史持久化(memory/history.py)

会话退出时保存到 .minicode/history/{session_id}.json,支持 /history 列出和恢复。


权限系统(permission/)

工具调用前询问用户:

[permission] tool 'bash' wants to run
            args: {"command": "ls -la"}
            [1] Yes
            [2] Yes, and always (allow this tool for the rest of the session)
            [3] No  [default: 1]
  • always_allow / always_deny — per-session 状态
  • /permission 管理:allow <tool> / deny <tool> / clear

Goal + Judge(goal/)

设置停止条件,让 judge 独立 LLM 调用评估是否完成:

> /goal tests pass
Goal set: "tests pass"

> /goal judge
[judge] evaluating...
[goal not yet] test suite has 3 failures

Verdict:ok(满足)、impossible(不可达)、error(judge 失败,fail-open)。


斜杠命令补全(cli/input.py)

TTY 环境下输入 / 时在下方显示命令列表,继续输入实时过滤,Tab 补全到最长公共前缀,Enter 确认,Ctrl+C / Ctrl+D 中断。非 TTY 降级为 input()

跨平台实现:Windows 用 msvcrt.getwch() 逐字符读取,POSIX 用 termios + sys.stdin.read(1),不依赖 prompt_toolkit / rich。


与 ClaudeCode / mimo-code 的差异

维度 mimo-code (TS) minicode (Py)
语言 TypeScript + Effect Python 3.10+ + Pydantic
异步模型 Effect.gen async/await
工具 schema zod Pydantic BaseModel
MCP SDK 官方 @modelcontextprotocol/sdk 自研最小 JSON-RPC over stdio/http
内置工具数 21 8(保留核心 + subagent 委派)
Skill 协议 完整(嵌套 + 外部目录 + 远程拉取) 简化(<name>/SKILL.md + frontmatter)
Model 协议 Vercel AI SDK 自研(stream() + complete()
provider 11 种 3 种(openai-compat + anthropic + demo)
LLM 循环 接好 已接(v2,ReAct + 预算管理)
记忆系统 完整(预算/裁剪/压缩/持久化/可视化)
权限 per-session always + 阻塞 prompt
Hook python/shell 双类型
Goal/Judge 独立 LLM 调用评估
Chat Bridge stdio/webhook adapter
自定义命令 .minicode/commands/*.md
斜杠补全 TTY 逐字符读取 + 实时过滤
可观测性 一般 突出 — 完整展示每一步 Agent 运行状态、提示词构成、tool_call 参数

核心特色:本项目的最大亮点是完整可观测性——适合想要学习代码 Agent 内部运行机制的开发者。


开发与测试

克隆后开发模式安装:

git clone https://github.com/<your-username>/minicode.git
cd minicode
pip install -e ".[dev]"

跑测试:

pytest tests/ -v

代码风格检查(可选):

ruff check minicode/

路线图

  1. Google provider(v3)— Gemini generateContent
  2. 远程 skill/agent 拉取 — 从 git repo / URL 拉取
  3. truncate 服务 — 超过阈值的输出写入临时文件,原始位置放占位
  4. 多 session 隔离 — chatbridge 的 thread_key → session_id 映射
  5. 测试覆盖 — 当前 442 个测试,目标 500+

已知问题

  • judge 依赖 LLM 的 JSON 输出能力,弱模型可能解析失败(fail-open 处理)。
  • chatbridge 的 webhook adapter 需要外部服务配合测试。

许可证

本项目使用 MIT 许可证 开源。

MIT License

Copyright (c) 2026 minicode authors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the above copyright notice and this permission
notice appearing in the Software.

Star History

如果这个项目对你有帮助,欢迎在 GitHub 上点 ⭐ Star!

贡献

欢迎 PR / Issue。在提交 PR 前请:

  1. 跑通 pytest tests/ -v
  2. 保持 ruff check 通过
  3. 保持现有功能不变

用 Python 重新实现的代码 Agent · Made for learning how agents work

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyminicode-0.5.0.tar.gz (172.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyminicode-0.5.0-py3-none-any.whl (147.9 kB view details)

Uploaded Python 3

File details

Details for the file pyminicode-0.5.0.tar.gz.

File metadata

  • Download URL: pyminicode-0.5.0.tar.gz
  • Upload date:
  • Size: 172.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for pyminicode-0.5.0.tar.gz
Algorithm Hash digest
SHA256 0e704086d24ea412e6b72592163f7857219690666e242530ab75bc71b884a0fd
MD5 842b280aac7f7cbd58011178aef6f21f
BLAKE2b-256 67e832f46b5bc60ee767e29c331ef6e278fb1273c71e524f404904ea1dd7a5f1

See more details on using hashes here.

File details

Details for the file pyminicode-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: pyminicode-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 147.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for pyminicode-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b31321b6cec09ca2500d01f738579cb40168736db6249ec395e0a4af48b2885e
MD5 59bc2c7a8e79a7b719c0a399167aa0b9
BLAKE2b-256 9b5095740430fe6e993e039b6994d81f3d1ce6af1054abf9288282dd51bbc7a7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page