Metadata-Version: 2.5
Name: lcode-agent
Version: 0.1.0
Summary: 一个基于 Textual 的终端 TUI 编码 agent
License: MIT
Requires-Python: >=3.14
Requires-Dist: aiohttp>=3.11.0
Requires-Dist: textual>=8.2.8
Description-Content-Type: text/markdown

# Lcode-agent

一个基于 [Textual](https://textual.textualize.io/) 的终端 TUI 编码 agent。打字进去，它读你的项目、改文件、跑命令、联网查资料，全程在终端里完成。

## 特性

- **流式对话**：思考过程默认折叠、正文 Markdown 渲染；等待/思考/跑工具状态栏实时反馈，随时 Esc 打断
- **内置工具**：`read_file` / `write` / `search_replace`（带 diff 高亮）/ `list_dir` / `grep`（自动用 ripgrep 加速）/ `run_terminal_command`（输出实时刷进卡片）/ `todo_write`（待办面板）/ `web_search` / `web_fetch`
- **上下文管理**：达到模型窗口阈值自动把旧对话压成摘要（`/zip` 可手动触发），只读工具的大结果进上下文前自动截短，底部栏实时显示占用
- **会话管理**：多窗口会话、自动快照、`/history` 回退到任意一问之前的代码和对话
- **多模型**：`models` 列表 + `/model` 弹窗切换（Ctrl+M），推理模型还能选 `reasoning_effort`（default/low/medium/high），从 `/models` 元数据自动识别支持的等级
- **省 token 可见**：底部栏显示缓存命中百分比、估算费用（配置单价后）、上下文占用
- **稳定发送**：请求失败自动重试 10 次，输入框上方红字显示错误和 `重试 n/10`；服务端不认的参数（如 `reasoning_effort`）自动降级重发
- **多模态**：`/img` 附加图片随消息发送
- **数据安全**：改文件前自动快照，回退可还原；会话/检查点/快照全部落盘 SQLite

## 运行

需要 Python 3.14+ 和 [uv](https://docs.astral.sh/uv/)：

```bash
uv run lcode
```

等价方式：`uv run python -m lcode`。开发模式（带 dev console）：

```bash
uv run textual run
```

## 配置

所有配置集中在一个文件：`~/.lcode/config.json`（首次启动自动生成完整模板，缺的键自动补全）。

```jsonc
{
  // 接口地址（OpenAI 兼容，填到 /v1 为止）
  "url": "https://api.example.com/v1",
  // 协议类型："completions"（/chat/completions）或 "responses"（/responses），失败会自动互为备用
  "requestType": "responses",
  // 当前模型；models 是可切换列表（/model 弹窗里显示的就是它）
  "model": "deepseek-v4-pro-0813",
  "models": ["deepseek-v4-pro-0813", "deepseek-v4-flash"],
  // 密钥；也可以用环境变量 LCODE_API_KEY（优先级更高）
  "apiKey": "sk-xxx",
  // 单次回答输出上限 / 请求超时秒数
  "maxTokens": 4096,
  "timeoutSeconds": 180,
  // 上下文用到模型窗口的百分比时自动压缩
  "autoCompactPercent": 85,
  // 推理等级："" 为不发送参数；也可在应用里 /effort 切换
  "reasoningEffort": "",
  // 权限模式：ask 敏感操作先确认 / pass 全自动（Shift+Tab 可切换）
  "permissionMode": "ask",
  // 每百万 token 单价（美元），配了才会在底部栏显示估算费用
  "pricing": { "input": 0.3, "output": 1.2, "cacheRead": 0.03 }
}
```

不需要的键可以删掉，程序会按出厂默认（`src/lcode/default_config.json`）补全；模型相关的改动也可以不编辑文件，直接在应用里 `/model` 切换。

## 快捷键

| 按键 | 作用 |
| --- | --- |
| `Enter` | 发送消息 / 确认弹层选择 |
| `Esc` | 打断生成 / 关闭弹层 / 再按返回上级 |
| `Ctrl+C` | 生成中打断；空闲时退出 |
| `Ctrl+M` | 弹出模型选择器 |
| `Shift+Tab` | 切换 ask / pass 权限模式 |
| `Tab` | 补全命令 / `@` 文件路径 |
| `↑` / `↓` | 移动弹层选项、翻输入历史 |
| `Ctrl+Q` | 退出 |

输入 `@` 会弹出项目文件补全；点击头部灯笼有彩蛋。

## 斜杠命令

| 命令 | 作用 |
| --- | --- |
| `/new` | 新开一个对话窗口，当前会话收进栈 |
| `/changewin` | 切换历史窗口（可跟 id 前缀） |
| `/zip` | 手动压缩上下文，可加保留提示，如 `/zip 保留工具调用细节` |
| `/history` | 回退到某次提问前的代码和对话 |
| `/model` | 弹出模型列表切换；`/model 2` 按序号、`/model <id>` 直接切 |
| `/effort` | 推理等级；`/effort low\|medium\|high\|default` |
| `/rename` | 给当前窗口改名 |
| `/delwin` | 删除一个历史窗口 |
| `/export` | 当前窗口导出成 Markdown |
| `/img` | 附加图片随下一条消息发送，可多次叠加 |
| `/ask` `/pass` | 切换权限模式 |

## 数据存在哪

- `~/.lcode/config.json` —— 全部配置（模型、密钥、权限模式）
- `~/.lcode/lcode.db` —— 会话消息、压缩摘要、检查点与文件快照（SQLite，WAL 模式）
- 导出的 Markdown 和回退还原的项目文件在项目目录内

## 代码结构

标准 src 布局，发布到 PyPI 后用户 `uv tool install lcode-agent` 即得 `lcode` 命令。

```
src/lcode/
  app.py               TUI：气泡、工具卡片、弹层、底部栏、渲染与交互
  protocol.py          OpenAI 兼容协议：流式、工具调用、用量、重试降级
  tools.py             内置工具实现与参数解析
  store.py             SQLite 存储：消息、摘要、检查点、快照、用量
  compress.py          上下文自动压缩
  settings.py          配置读写与迁移（统一到 ~/.lcode/config.json）
  default_config.json  出厂默认配置（随包分发）
  __main__.py          python -m lcode 入口
```
