Skip to content

Latest commit

 

History

63 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mycode - 编程智能体

⚠️ 警告:本项目正在开发中,不建议在非测试环境使用。

功能特性

  • 智能对话:基于 OpenAI 兼容 API 的交互式编程助手
  • 工具调用:支持自定义工具注册系统(ToolsRegistry
  • 命令执行:内置 bash 工具,直接执行 shell 命令
  • 文件检索:内置 lsglobgrep,按行号/KiB 截断输出
  • 文件读写:内置 readwriteeditpatch,统一走路径安全检查
  • 任务跟踪:内置 todo_write,搭配陈旧度自动提醒与重放同步
  • 模式权限:询问/自动/全权三种模式 + 确认界面(同意/编辑/拒绝),按操作分类决定是否需人工确认
  • 双渲染风格:default(emoji 标题 + 灰色输入区 + rich 语法高亮代码块, 并对 bash/write/patch/edit 工具调用做特化展示)/ classic(无 emoji + myc[模式] > 提示符,保持完整 YAML 参数围栏)
  • 会话管理:完整的对话上下文管理,支持多轮交互与断点续接
  • 命令历史:持久化保存输入历史,支持上下键翻阅
  • 自动补全:内置命令补全功能

项目结构

myc/
├── pyproject.toml          # uv 项目配置(依赖、入口、构建)
├── uv.lock                 # 依赖锁文件(由 uv 自动生成)
├── .python-version         # Python 版本(uv 自动读取)
├── .env.example            # 环境变量模板
├── src/mycode/             # 主包
│   ├── __init__.py
│   ├── __main__.py         # 支持 `python -m mycode`
│   ├── ask_ui.py           # 通用询问界面(单选/多选/自定义输入,供 confirm 等复用)
│   ├── cli.py              # CLI 入口逻辑
│   ├── confirm.py          # 确认交互(基于 ask_ui:同意/编辑/拒绝)
│   ├── mode.py             # 模式与权限系统
│   ├── renderer.py         # 渲染器(default/classic 风格)
│   ├── session.py          # 会话管理与 ADT 事件类型
│   ├── tools_registry.py   # 工具注册表(ToolsRegistry)
│   ├── tools/
│   │   ├── __init__.py     # 导入以触发工具注册
│   │   ├── _safe_path.py    # 路径安全检查(CWD 内 + 保护正则)
│   │   ├── _truncate.py     # KiB 输出截断
│   │   ├── bash.py          # bash 命令执行
│   │   ├── ls.py            # ls -la
│   │   ├── glob.py          # fd / find glob
│   │   ├── grep.py          # rg / grep 搜索
│   │   ├── read.py          # 带行号读文件
│   │   ├── write.py         # 写文件
│   │   ├── edit.py          # 字符串替换编辑
│   │   ├── patch.py         # 应用 unified diff
│   │   └── todo_write.py    # 内存待办事项列表
│   └── py.typed            # PEP 561 类型标记
├── tests/                  # 测试(pytest)
│   ├── _helpers.py         # 测试辅助工具
│   ├── conftest.py         # pytest 共享 fixtures
│   ├── test_ask_ui.py
│   ├── test_cli.py
│   ├── test_confirm.py
│   ├── test_mode.py
│   ├── test_renderer.py
│   ├── test_safe_path.py
│   ├── test_session.py
│   ├── test_tools.py
│   ├── test_tools_registry.py
│   └── test_truncate.py
├── docs/dev/
│   ├── ask_ui_design.md           # ask_ui 通用询问界面设计
│   ├── event_design.md            # 事件架构设计
│   ├── mode_permission_design.md  # 模式与权限系统设计
│   ├── tools_registry_design.md   # 工具注册系统设计
│   └── cli_render_design.md       # CLI 渲染设计
├── LICENSE
└── README.md

快速开始

前置要求

  • uv(推荐,>= 0.4)
  • Python 3.10+(uv 会根据 .python-version 自动管理)
  • OpenAI API 密钥(或兼容的 API 服务)
  • 可选外部命令:fdfind(用于 glob)、rggrep(用于 grep)、 patch(用于 patch)。mycode 会按 fd → findrg → grep 顺序回退。

安装与同步依赖

uv sync

uv sync 会自动创建 .venv/ 虚拟环境并安装所有依赖(含 dev 依赖)。 rich(默认风格语法高亮)与 pyyaml 同为主运行时依赖。

配置环境变量

复制模板并填写真实值:

cp .env.example .env
# 编辑 .env 填入 API_KEY 等

.env 文件位于 git 忽略列表,请勿提交。

.env.example 中可配置的关键项:

变量 说明 默认值
API_KEY OpenAI 兼容 API 的密钥 (必填)
BASE_URL OpenAI 兼容 API 的 Base URL OpenAI 官方
MODEL_NAME 默认模型名 (必填)
ADDITIONAL_SYSTEM_PROMPT 附加系统提示词,拼接在内置提示词之后(用换行分隔);留空表示无追加 (空)
BASH_TIMEOUT bash 工具的超时(秒) 60
BASH_DANGEROUS 逗号分隔的危险命令正则(re.search 命中即拒) (空)
BASH_CAUTION 逗号分隔的注意命令正则(命中时视模式需确认) (空)
MYCODE_HOME_DIR mycode 的应用目录(存放会话与历史) ~/.mycode
MYCODE_PROTECTED_PATH_PATTERN 逗号分隔的受保护路径正则;路径命中任一条则 ls/glob/grep/read/write/edit/patch 拒绝访问 (空)
MYCODE_TODO_STALE_THRESHOLD todo_write 陈旧度阈值(连续 N 轮未更新且有未完成项则注入提醒) 5
MYCODE_TODO_MAX_IN_PROGRESS todo_write 同时处于进行中的待办项数上限 3
E429_WAIT_SECONDS 逗号分隔的正整数秒列表(如 1,2,5,10),429 限流自动重试的等待档位;默认不配置则不开启,解析失败或连续 429 次数超出列表长度时同样向上抛出 (空)

运行

任选其一:

# 通过 uv 管理的脚本入口(myc / mycode 均可)
uv run myc

# 等价于
.venv/bin/myc

# 别名入口
uv run mycode

# 也可以作为模块调用
uv run python -m mycode

续接上次的会话

uv run myc -r <session_uuid>
#
uv run myc -c   # 恢复当前目录的最新会话

渲染风格

uv run myc -s classic      # 经典风格(myc[模式] > 提示符 + 复选框待办)
uv run myc -s default      # 默认风格(emoji 标题 + 灰色输入区 + rich 语法高亮)

默认 defaultclassic 提供无 emoji 的标题与 myc[模式] > 提示符。 default 风格下,assistant 正文经 richMarkdown 渲染(标题/列表/表格/ 引用与内联样式等富文本着色),正文中的代码块与工具调用 YAML 参数、工具输出、 异常 traceback、read 返回等代码块统一经 rich语法高亮read 返回 带行号展示(按文件路径/内容自动识别语言),bash 工具输出也按内容猜测语法; 其余工具(write/edit/glob/grep/ls/patch 等)输出保持纯文本展示;classic 风格保持纯代码围栏、assistant 正文原样输出。 工具调用 YAML 参数在 default 风格下另对 bash/write/patch/edit 四个 工具做特化展示:YAML 中去掉大字段(command/content/diff/old_text、new_text), 添加一个空行后在新代码块中再次展示——bash 用 bash 语法带行号展示命令文本、 writefile_path 推断语言带行号展示 content、patch 用 diff 语法不带 行号展示 diff、edit 用 diff 语法不带行号展示 old_text/new_text 的 unified diff(文件可读时基于文件真实内容展示整文件 diff,行号为原始文件行号); read/ls/glob/grep/todo_write 等工具仍保持完整 YAML 参数块。 语法高亮主题默认 nord(低饱和柔和),可用环境变量 MYCODE_SYNTAX_THEME 覆盖(如 gruvbox-darkzenburn);工具输出与 assistant 正文自带 ANSI 控制码时原样输出、不二次高亮/解析。 模式切换(shift-tab 或 /ask /auto /yolo)与确认界面在两种风格下均可用。

内置工具一览

所有工具均在 ToolsRegistry 中注册,启动后即可被智能体调用。除 bash 外 的文件类工具均受 MYCODE_PROTECTED_PATH_PATTERN 保护,并使用统一的 行数 + KiB 联合截断:任一上限触发即在行内不被切断的前提下追加 "\n... 已截断" 标记。

工具 用途
bash 执行 shell 命令;按 BASH_TIMEOUT 超时,命中 BASH_DANGEROUS 拒绝
ls 类似 ls -laF:权限、大小、ISO-8601 日期、类型后缀(/ * @ `
glob 按 glob 模式匹配路径(fd --glob -C <wksp> 优先,回退 find -name
grep 在文件/目录中按正则/字面量搜索(rg 优先,回退 grep
read cat -n 风格读文件,支持 offset/limit/truncate
write 覆盖写入文件,自动创建父目录
edit old_text/new_text 替换;replace_all 控制全部替换
patch 应用 unified diff(自动检测 -p0/-p1,先 dry-run 再正式应用)
todo_write 整体替换内存待办事项列表;最多 3 项进行中(可用 MYCODE_TODO_MAX_IN_PROGRESS 调整)

路径安全:所有文件类工具在处理前都会通过 safe_path(),拒绝超出 CWD 的路径(含跟随软链接后越界)以及命中 MYCODE_PROTECTED_PATH_PATTERN 的路径。越界时返回 Error: 路径 '...' 超出当前工作目录safe_path() 返回 SafePath{ wksp, abs, rel }wksp 是工作区绝对路径 (交给子进程做输出基准),abs 是请求路径的绝对路径(实际读写磁盘用), rel 是相对工作区的规范化路径;glob/grepwksp + rel 让输出 前缀保持简短。

模式与权限系统

mycode 提供三种工作模式,控制工具调用是否需要人工确认。模式作为 会话公共字段记录,切换后随会话持久化。

模式

模式 说明 提示符(classic / default)
询问(ask) 写 / 未知 / 注意操作需确认 myc[询问] > / │? (蓝)
自动(auto) 仅注意操作需确认(默认) myc[自动] > / (绿)
全权(yolo) 除危险外均无需确认 myc[全权] > / │! (橙)

切换方式:

  • shift-tab:循环切换(自动 → 全权 → 询问 → 自动)。
  • 命令/ask/auto/yolo 手动切换。

模式切换作为一个事件(ModeChangeEvent)分发并持久化到会话历史; 恢复会话时自动恢复上次模式。

操作分类

类别 工具
危险 bash 且命中 BASH_DANGEROUS 正则(所有模式一律拒绝)
注意 bash 且命中 BASH_CAUTION 正则
未知 bash 且未命中以上两类
write / edit / patch
ls / glob / grep / read
内部 todo_write

各模式确认规则

类别 询问 自动 全权
危险 拒绝 拒绝 拒绝
注意 确认 确认 直接执行
未知 确认 直接执行 直接执行
确认 直接执行 直接执行
直接执行 直接执行 直接执行
内部 直接执行 直接执行 直接执行

确认界面基于通用询问界面 ask_ui(仅 bash 工具需确认时含【编辑】), default 风格示例:

❯ 🟢 同意
  ⚪ 编辑 >>
  ⚪ 拒绝:__理由__
  • 【编辑】进入命令行编辑界面,Alt+Enter 提交、ESC 返回菜单、Ctrl-C 取消。编辑后命令有变化时,派发 NoticeEvent(终端黄色高亮显示、写入 会话历史,并经 to_user_msg() 注入一条 <notice> 文本给模型);命令 无变化时直接执行。
  • 选【拒绝】时可直接输入拒绝理由,Enter 确认。
  • 无理由拒绝 → 跳出 Agent 循环。

todo_write 与陈旧度提醒

  • todo_write(items) 整体替换当前待办事项列表;空列表表示清空。
  • 每产生一个 assistant 消息时自增一次陈旧度计数;
    • 超过 MYCODE_TODO_STALE_THRESHOLD 且存在未完成项时,往 messages 注入一条 <reminder> 文本(模型下次 API 调用可见),同时派发 NoticeEvent 在终端以黄色高亮显示并写入会话历史;
    • 调用 todo_write 成功后陈旧度计数自动清零。
  • 重放历史时,replay_history 会在派发 todo_writeToolCallEvent 之后把 _todo_state 同步成调用时刻的列表,让对应的 ToolResultEvent 渲染能看到当时的进度。

使用方法

启动后会进入交互式命令行界面,直接输入你的需求即可。例如:

  • 创建一个 Python 项目结构
  • 在当前目录列出所有文件
  • 帮我写一个 Flask Web 应用
  • 给 README.md 加一段工具介绍
  • 把当前进度用 todo_write 记一下

开发

运行测试

uv run pytest

测试覆盖:

  • 工具注册表(test_tools_registry.py
  • 各内置工具的注册、参数、基础与边界行为(test_tools.py
  • 路径安全检查(test_safe_path.py
  • 行数/KiB 联合截断(test_truncate.py
  • 会话历史与 ADT 序列化往返(test_session.py
  • 渲染器 default/classic 风格输出(含 bash/write/patch/edit 工具调用特化渲染,test_renderer.py
  • 通用询问界面 ask_ui:选项数据/单选多选/自定义输入/状态持久化/布局/前缀展示(test_ask_ui.py
  • 确认交互:confirm_tool 动作映射与多行编辑视图(test_confirm.py
  • 模式与权限:工具分类、决策矩阵、模式切换与持久化(test_mode.py
  • CLI 输入、agent_loop 消息补齐、replay 同步、陈旧提醒等集成行为(test_cli.py

类型检查

uv run mypy src

添加新工具

  1. src/mycode/tools/ 下新建模块,例如 mycode/tools/echo.py

    from typing import Annotated
    from mycode.tools_registry import ToolsRegistry
    
    @ToolsRegistry.tool(description="回显文本")
    def echo(text: Annotated[str, "要回显的内容"]) -> str:
        return text

    若工具需要读写文件,建议复用 safe_path() 做路径安全检查,并用 cap_lines() 处理大输出。

  2. src/mycode/tools/__init__.py 中导入该模块以触发装饰器注册:

    from mycode.tools import bash, echo  # noqa: F401
  3. 编写测试到 tests/,运行 uv run pytest

License

MIT License. 详见 LICENSE 文件。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages