Skip to main content

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

Project description

minicode

Terminal-native AI coding assistant, implemented in Python.

当前状态:已完成 v0(工具层)、v1(模型层)、v2(ReAct 循环 + 记忆系统 + 权限 + Hook + Goal + Chat Bridge + 斜杠命令补全 + 自定义命令 + 代码简化)。 下一版(v3)会接 Google provider、plugin system、远程 skill/agent 拉取。

Quick start

# 1. install
pip install -e .

# 2. 跑起来(首次会自动建 .minicode/)
minicode

# 一次性命令
minicode --init              # 初始化项目.minicode
minicode --version
minicode --paths
minicode --print-tools       # 列工具
minicode --check-config      # 校验配置

Layout

minicode/
├── pyproject.toml
├── README.md
├── .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
│   ├── commands/                    # custom slash commands
│   │   ├── review.md
│   │   └── fix.md
│   ├── hooks/                       # python/shell hooks
│   ├── mcp.json                     # MCP server config (stdio / http)
│   └── 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 (tools/models/skills/agents/hooks)
│   ├── 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 抽象基类 + ModelResponse/Event
│   │   ├── 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            # 分级裁剪(soft/hard trim + 滑动窗口)
│   │   ├── 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/                  # 工具调用权限
│   │   ├── service.py               # PermissionService
│   │   └── types.py                 # PermissionRequest/Result
│   ├── hooks/                       # Hook 系统
│   │   ├── dispatcher.py            # HookDispatcher
│   │   ├── types.py                 # EventName / Action / HookResponse
│   │   ├── python.py                # PythonHook
│   │   └── shell.py                 # ShellHook
│   ├── goal/                        # 停止条件 + judge
│   │   ├── service.py               # GoalService
│   │   ├── types.py                 # Goal / Verdict
│   │   └── judge.py                 # judge 独立 LLM 调用
│   ├── display/                     # 结构化渲染
│   │   └── formatter.py             # thinking / tool-call / code-change
│   ├── chatbridge/                  # 多端聊天桥接
│   │   ├── adapter.py               # ChatAdapter
│   │   ├── adapters/                # stdio / webhook
│   │   └── manager.py               # ChatBridgeManager
│   └── cli/
│       ├── app.py                   # REPL + 命令处理
│       └── input.py                 # 斜杠命令补全
└── tests/                           # 单测 + 端到端冒烟
    ├── test_base.py
    ├── test_skill_loader.py
    ├── test_registry.py
    ├── test_config.py
    ├── test_model_registry.py
    ├── test_openai_compat.py
    ├── test_anthropic.py
    ├── test_demo.py
    ├── test_agent_runtime.py
    ├── test_memory_budget.py
    ├── test_memory_truncation.py
    ├── test_memory_compact.py
    ├── test_permission.py
    ├── test_hooks.py
    ├── test_goal.py
    ├── test_command.py
    ├── demo_mcp_server.py
    └── test_e2e_mcp.py

config.yaml 格式

.minicode/config.yaml

# 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 的额外参数(可选)
extra:
  temperature: 0.7
  max_tokens: 8K

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 命令

命令 作用
/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 退出

工具协议

所有工具实现同一接口(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 — hook 触发
  • bus — 事件总线
  • model_registry — 模型切换
  • config — 当前配置
  • history — 对话历史
  • context_budget — token 预算

ToolResult

  • title — 短标题
  • output — 内容(str | list[Part])
  • metadata — dict(error / file_path / tool_name 等)

记忆系统

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

Hook 系统(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 → 串联合并。

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)。

Subagent(agent/)

.minicode/agents/<name>.md 定义独立 LLM 上下文:

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

你是 code reviewer...

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

Chat Bridge(chatbridge/)

多端聊天桥接,支持 stdio / webhook adapter:

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

自定义命令(command.py)

.minicode/commands/<name>.md

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

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

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

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

TTY 环境下输入 / 时显示命令列表,继续输入实时过滤,Tab 补全到最长公共前缀。非 TTY 降级为 input()

架构图

┌──────────────────────────────────────────────────────────────────────┐
│                           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  │
   └──────────────────────────────────────────────────┘

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.3.0.tar.gz (53.9 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.3.0-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for pyminicode-0.3.0.tar.gz
Algorithm Hash digest
SHA256 6ece2ab0a350aff43be9c4ac71422e75a7a6b2b61d1dc85e68972a555836f364
MD5 21a6ac64f0ea60dff9b9a8c14801e706
BLAKE2b-256 18a74419662373f802a14caf0fe3613f38c8e778a22021211f33668a1a8b11c6

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyminicode-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 7.5 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2e9238670cc4c3b21fd2ebd1b1c57ad488d39fe20b55e1d00354971326e87c21
MD5 6cc61f4b2e7d604912a816c363166d17
BLAKE2b-256 f2f3ef1e1684a69f6c760c919983ad4cf384f093febe24d66429bbeaa2874ab8

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