Metadata-Version: 2.4
Name: synapse-cli-agent
Version: 0.1.15
Summary: Local coding agent built on LangChain Deep Agents (LocalShell, no sandbox)
Project-URL: Homepage, https://github.com/alex8224/synapse-agent
Project-URL: Repository, https://github.com/alex8224/synapse-agent
Project-URL: Issues, https://github.com/alex8224/synapse-agent/issues
Project-URL: Changelog, https://github.com/alex8224/synapse-agent/blob/main/CHANGELOG.md
Author-email: alex8224 <alex8224@gmail.com>
Requires-Python: >=3.12
Requires-Dist: aiosqlite>=0.20.0
Requires-Dist: deepagents>=0.6.12
Requires-Dist: langchain-anthropic>=1.4.8
Requires-Dist: langchain-openai>=1.3.5
Requires-Dist: langchain>=1.3.14
Requires-Dist: langgraph-checkpoint-sqlite>=3.1.0
Requires-Dist: langgraph>=1.2.9
Requires-Dist: mcp>=1.28.0
Requires-Dist: pydantic-settings>=2.14.2
Requires-Dist: python-dotenv>=1.2.2
Requires-Dist: rich>=15.0.0
Requires-Dist: termaid>=0.7.1
Requires-Dist: texicode>=1.0.3
Requires-Dist: textual-diff-view>=0.1.5
Requires-Dist: textual>=1.0.0
Requires-Dist: typer>=0.27.0
Requires-Dist: websockets<16,>=13
Requires-Dist: zstandard>=0.23.0
Provides-Extra: dev
Requires-Dist: mkdocs-material>=9.7.7; extra == 'dev'
Requires-Dist: mkdocs>=1.6.1; extra == 'dev'
Requires-Dist: pytest>=9.1.1; extra == 'dev'
Requires-Dist: ruff>=0.15.22; extra == 'dev'
Description-Content-Type: text/markdown

# Synapse

基于 **LangChain Deep Agents** 的本地 Synapse。

- Harness: `deepagents.create_deep_agent`
- Backend: `LocalShellBackend`（**无 sandbox**）
- 默认审批: **关闭 / 自动通过**
- 依赖管理: `uv`

## 功能

| 能力 | 说明 |
|---|---|
| 读改代码 | `read/write/edit/glob`；目录和搜索通过 `execute` 调用项目命令 |
| 执行命令 | `execute` 本地 shell |
| 规划 | `write_todos` |
| 子代理 | 默认 `researcher` / `tester` / `reviewer`（`task` 委派） |
| 自定义工具 | 会话查阅工具；git/测试/搜索等通过 `execute` 调用项目命令 |
| 记忆 | `AGENTS.md` |
| Skills | `skills/**`（Agent Skills frontmatter） |
| 会话 | sqlite checkpointer + 会话元数据管理 |
| 多模型 | `ModelRegistry`（单模型兼容 / JSON 多 profile） |
| MCP | 配置 MCP Server 后注入为 tools |
| 权限/只读 | `FilesystemPermission` + `HarnessProfile.excluded_tools` |
| CLI | `run` / `chat` / `tui` / `sessions` / `models` / `mcp` / `version` |
| 可选 HITL | `--require-approval`（默认关） |

## 安装

### 前置要求

- [uv](https://docs.astral.sh/uv/getting-started/installation/)（会自动安装和管理所需的 Python >= 3.12）

### 方法一：从 PyPI 安装为系统 CLI 工具（推荐）

无需克隆仓库或预装 Python：

```powershell
uv tool install synapse-cli-agent
```

开发者如需从本地源码可编辑安装：

```powershell
powershell -ExecutionPolicy Bypass -File scripts/install.ps1 -Force
# 或：uv tool install --editable --force .
```

安装后任意目录直接使用：

```bash
synapse tui -w .
synapse run "查看当前仓库结构并总结" -w .
```

仓库根目录还提供 `synapse.cmd` 薄启动器（优先 PATH 上的入口，其次 `.venv\Scripts`，最后回退 `uv run`）。

### 方法二：本地 venv 开发

```bash
# 同步依赖
uv sync

# 使用 venv 入口（Windows）
.\.venv\Scripts\synapse.exe tui -w .

# 或模块入口
uv run python -m synapse tui -w .

# 兼容旧写法
uv run synapse chat -w .
```

### 卸载

```powershell
uv tool uninstall synapse-cli-agent
# 或
powershell -ExecutionPolicy Bypass -File scripts/install.ps1 -Uninstall
```

## 快速开始

安装并配置完成后，即可运行：

```bash
# TUI 交互界面（推荐）
synapse tui -w .

# 单次执行
synapse run "总结当前项目结构" -w .

# CLI 对话
synapse chat -w .
```

### 会话管理

```bash
synapse sessions list
synapse sessions export <thread_id> -f md
# 默认写入 .coding-agent/exports/<thread_id>.md；打印到终端加 --stdout
```

### 模型与 MCP 管理

```bash
synapse models list
synapse mcp list
```

## 配置

Synapse 采用**分层配置**策略：用户全局配置（`~/.synapse/`）与项目本地配置（`<workspace>/.synapse/`）合并，项目层覆盖用户层。

```
~/.synapse/              # 用户全局层（优先级低）
  models.json            # 模型 profiles + api_key（推荐方式）
  mcp.json               # MCP Server 定义
  settings.json          # 非敏感 Settings 覆盖
  themes.json            # 自定义 UI 主题

<workspace>/.synapse/    # 项目层（优先级高，覆盖用户层）
  models.json
  mcp.json
  settings.json
  themes.json
  system_prompt.md       # 自定义系统提示
  sessions.sqlite
  checkpoints.sqlite
```

### 方式一：环境变量（.env 快速入门）

从模板创建，填入密钥即可：

```bash
cp .env.example .env
```

核心变量：

| 变量 | 必填 | 说明 |
|---|---|---|
| `MODEL` | 是 | 模型标识，如 `openai:gpt-4.1`、`openai:deepseek-chat` |
| `OPENAI_API_KEY` | 是* | OpenAI 兼容 API 密钥 |
| `OPENAI_BASE_URL` | 否 | 自定义 API 端点（中转/本地服务需填） |
| `OPENAI_WEBSOCKET` | 否 | 普通 Responses API 使用 WebSocket；默认 `false`（HTTP/SSE）。瞬时断流按模型 `max_retries` 重连，耗尽后在尚未输出内容时回退 HTTP/SSE |
| `ANTHROPIC_API_KEY` | 否 | Anthropic 原生 API 密钥 |
| `WORKSPACE` | 否 | 工作区路径，默认 `.` |
| `SHELL_EXECUTABLE` | 否 | Shell 类型，默认 `pwsh`（可选 `cmd`/`bash`） |
| `SHELL_TIMEOUT` | 否 | 命令超时秒数，默认 120 |
| `TOKEN_STREAM` | 否 | token 级流式输出，默认 `true` |
| `PARALLEL_TOOL_CALLS` | 否 | 并发工具调用，默认 `true` |

完整变量列表见 `.env.example`。

### OpenAI Codex OAuth（ChatGPT Plus/Pro）

除普通 API Key 外，Synapse 可使用 Codex 的 ChatGPT OAuth 登录。凭据仅保存到用户目录
`~/.synapse/openai_oauth.json`，不会写入项目配置或显示在终端中。

```bash
# 浏览器登录；也可加 --no-browser 手动打开终端打印的链接
synapse auth openai login

# 若本机已通过 Codex CLI 登录，安全导入其现有登录态
synapse auth openai login --import-codex

synapse auth openai status
synapse auth openai logout
```

然后在 `~/.synapse/models.json` 或 `<workspace>/.synapse/models.json` 配置模型：

```json
{
  "default": "codex",
  "models": {
    "codex": {
      "model": "openai:gpt-5",
      "auth": "openai_oauth"
    }
  }
}
```

OAuth profile 强制使用 Codex backend，不能通过 `base_url` 覆盖。该登录方式不能用于第三方
OpenAI 兼容网关，也不需要设置 `OPENAI_API_KEY`。浏览器授权回调固定使用
`http://localhost:1455/auth/callback`；若端口被占用，请关闭占用进程后重试。Synapse 会自动将
Agent 的 OpenAI `system` 消息转换为 Codex backend 接受的 `developer` 消息，并移除 DeepSeek
兼容的 `extra_body.thinking` 字段，只发送 Codex 支持的 reasoning 参数，并强制设置 `store: false`。

### 方式二：models.json（多模型 profiles，推荐）

在 `~/.synapse/` 或 `<workspace>/.synapse/` 下创建 `models.json`。支持多 profile、自定义模型参数（temperature、max_tokens、thinking 等）。

参考示例：`examples/models.example.json`

```json
{
  "default": "primary",
  "models": {
    "primary": {
      "model": "openai:gpt-4.1",
      "api_key": "sk-REPLACE_ME",
      "websocket": false,
      "context_window": 128000,
      "temperature": 0.2,
      "max_tokens": 8192
    },
    "deepseek": {
      "model": "openai:deepseek-v4-pro",
      "api_key": "sk-REPLACE_ME",
      "base_url": "http://127.0.0.1:3000/v1",
      "context_window": 128000,
      "thinking": "high",
      "temperature": 0.2
    }
  }
}
```

OpenAI Responses API 同时支持 HTTP/SSE 与普通 LLM WebSocket。profile 中设置
`"websocket": true` 后，Synapse 使用持久 `/v1/responses` WebSocket；省略或设为
`false` 时保持现有 HTTP/SSE。自定义 OpenAI-compatible 网关必须实现该 WebSocket
端点，否则请保持关闭。WebSocket 模式会自动启用 `use_responses_api`。

通过 `AGENT_ACTIVE_MODEL` 环境变量或 CLI 参数切换 profile。

#### 非多模态模型的图片识别

主模型与识图模型独立配置。主模型 profile 不写 `image_input` 时，Synapse 会按常见模型名推断；未知的 OpenAI-compatible 模型默认按纯文本模型处理。需要覆盖推断时，在 profile 中写 `"image_input": true/false`。

识图模型放在同一层 `models.json` 顶层的 `vision_model` 配置中（也支持 `settings.json`），可以自由更换任意兼容 OpenAI Chat Completions 图片输入的服务：

```json
{
  "vision_model": {
    "model": "qwen-vl-max",
    "base_url": "https://your-vision-gateway.example/v1",
    "api_key_env": "VISION_API_KEY",
    "timeout_secs": 45,
    "max_input_bytes": 10485760,
    "max_retries": 2,
    "fallback_model": "qwen-vl-plus",
    "allow_remote_urls": false,
    "think": true,
    "prompt": "Describe the image for a text-only coding assistant. Extract visible text and errors."
  }
}
```

`vision_model.model`、`base_url`、`api_key_env` 均可更换；`api_key` 也支持，但建议使用环境变量。`think` 是识图模型独立的思考开关，开启后发送 `thinking: {"type": "enabled"}`；它不影响主模型。默认只处理本地/内存图片；将 `allow_remote_urls` 设为 `true` 才会把消息中的 HTTP(S) 图片 URL 转发给识图服务。该服务只用于把图片转换成文字，配置后图片内容会发送到指定服务。多模态主模型会跳过该 middleware，不调用识图服务。

### MCP 服务器配置

在 `~/.synapse/` 或 `<workspace>/.synapse/` 下创建 `mcp.json`。

参考示例：`examples/mcp.example.json`

```json
{
  "servers": [
    {
      "name": "filesystem",
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
      "enabled": false
    },
    {
      "name": "anysearch",
      "transport": "streamable_http",
      "url": "https://api.anysearch.com/mcp",
      "headers": {
        "Authorization": "Bearer ${ANYSEARCH_API_KEY}"
      },
      "enabled": false,
      "tool_prefix": "anysearch__"
    }
  ]
}
```

配置后通过 `synapse mcp list` 查看状态，可在 TUI 中动态启用/禁用。

### Settings 覆盖

在 `~/.synapse/settings.json` 或 `<workspace>/.synapse/settings.json` 中写入非敏感配置，与 `.env` 环境变量作用相同但优先级更高（项目层 > 用户层 > 环境变量）。

## 使用技巧

### TUI 快捷键

| 快捷键 | 功能 |
|--------|------|
| `Ctrl+T` | 折叠/展开最近工具组 |
| `Ctrl+E` | 展开/收起最近 Thought 摘要 |
| `Ctrl+L` | 清空 transcript |
| `Alt+C` | 复制当前划选（无选区时复制最近答案） |
| `Ctrl+Shift+Y` | 复制最近一条助手答案 |
| `Ctrl+C` / `Ctrl+Q` | 退出 |

文本选择：transcript 中答案/Thought/工具组/用户条支持鼠标拖选（有高亮），划选后用 `Alt+C` 复制。

### 斜杠命令（chat / TUI）

- `/help` `/thread` `/new` `/sessions` `/session ...` `/switch <id>`
- `/rename` `/export [md\|json] [path]`
- `/model` `/model <alias>`
- `/mcp list|tools|test|reload|enable|disable|config`
- `/clear` `/exit`

补全：TUI 输入 `/` 后有 ghost 建议（`Tab`/`→` 接受，`Shift+Tab` 上一项，`Ctrl+Space` 列出候选）；chat 模式下 `Tab` 补全。

### MCP transports

| transport | 用途 | 关键字段 |
|-----------|------|----------|
| `stdio` | 本地 MCP 进程 | `command` / `args` / `env` |
| `sse` | 远程 SSE | `url` / `headers` |
| `streamable_http` / `http` | 远程 Streamable HTTP | `url` / `headers` |

连接在后台事件循环中保持复用；`/mcp reload` 重建 agent 与连接池。

### models.json 字段说明

| 字段 | 含义 |
|---|---|
| `api_key` | **推荐**：密钥直接写在 models.json |
| `api_key_env` | 旧方式：从环境变量读密钥 |
| `auth` | 认证方式；设为 `openai_oauth` 时使用 `synapse auth openai login` 保存的 Codex OAuth 登录态 |
| `headers` | 模型级 HTTP 请求头对象；同名头覆盖顶层 `headers`，适用于自定义 `User-Agent` 等请求指纹 |
| `thinking` / `thinking_level` / `reasoning_effort` | 思考级别：`off\|minimal\|low\|medium\|high\|max` |
| `enable_thinking` | 兼容旧字段 bool |
| `temperature` / `max_tokens` / `timeout` 等 | 直接传给 ChatModel |
| `stream_chunk_timeout` | 流式相邻 chunk 静默超时（秒）；默认关闭，避免长思考被 langchain-openai 120s 掐断 |
| `model_kwargs` | 请求体 kwargs |
| `extra_body` | 厂商扩展体（与 thinking 合并） |

### 自定义请求头与请求指纹

参考 `cmd-agent` 的配置方式，`models.json` 顶层 `headers` 会应用到全部 OpenAI 兼容模型；
模型内 `headers` 按 HTTP 头名称（不区分大小写）覆盖全局值。分层配置的优先级为：
项目模型 > 用户模型 > 项目全局 > 用户全局。可用于设置 `User-Agent`、客户端标识等请求指纹。

```json
{
  "headers": {
    "User-Agent": "synapse-global/1.0",
    "X-Client-Channel": "desktop"
  },
  "models": {
    "codex": {
      "model": "openai:gpt-5",
      "auth": "openai_oauth",
      "headers": {
        "User-Agent": "synapse-codex/1.0"
      }
    }
  }
}
```

OAuth 模式中 `ChatGPT-Account-Id`、`originator` 等协议认证头由运行时强制设置，不能被配置覆盖。
请求头值支持 `${ENV_NAME}` / `$ENV_NAME` 环境变量展开；不要将私密 token 写入项目级配置。

`.env` 仍可读，仅作迁移/CI 兼容，**不推荐**作为常规分发方式。

## 示例：修复 sample_repo

`tests/fixtures/sample_repo` 中 `sub()` 有意写错，可用于验证 agent 闭环：

```bash
# 先确认测试失败
uv run pytest tests/fixtures/sample_repo -q

# 让 agent 修复（需要有效模型密钥）
uv run synapse run "修复 calculator.sub 的 bug，使 tests 全部通过" -w tests/fixtures/sample_repo
```

## 环境变量参考

关键 Agent 行为变量：

| 变量 | 默认 | 含义 |
|---|---|---|
| `MODEL` | `openai:gpt-4.1` | `provider:model` 或 profile 名 |
| `AGENT_MODELS_CONFIG` | - | 多模型 JSON 路径 |
| `AGENT_ACTIVE_MODEL` | - | 当前 profile 别名 |
| `WORKSPACE` | `.` | 工作区 |
| `AGENT_REQUIRE_APPROVAL` | `false` | 是否启用 HITL |
| `AGENT_ENABLE_SUBAGENTS` | `true` | 默认子代理 |
| `AGENT_READONLY` | `false` | 排除写/执行工具 |
| `AGENT_ENABLE_FS_PERMISSIONS` | `false` | 文件系统权限规则 |
| `AGENT_ENABLE_MCP` | `true` | 启用 MCP 注入 |
| `AGENT_MCP_EAGER` | `false` | 启动时立刻连 MCP（默认延迟到 TUI 后台二阶段） |
| `AGENT_TUI_DEFER_AGENT` | `true` | TUI 先起 UI，后台 build agent |
| `AGENT_MCP_CONFIG` | - | MCP servers JSON |
| `CHECKPOINT_BACKEND` | `sqlite` | `sqlite` 或 `memory` |
| `INHERIT_ENV` | `true` | shell 继承主机环境 |
| `VIRTUAL_MODE` | `true` | 文件路径虚拟根 |

## 安全说明

- **不使用 sandbox**：命令在宿主机执行。
- 默认**不审批**；仅建议在受信开发机使用。
- 可用 `--require-approval` 临时打开 HITL。
- `safety.py` 提供危险命令黑名单（警告/检测用）；默认不拦截 agent 内置 `execute`。
- `--readonly` / `AGENT_READONLY=true` 通过 harness 排除 `execute/write_file/edit_file`。

## 开发

```bash
uv run pytest
uv run ruff check src tests
```

## 项目结构

```text
src/synapse/
  agent.py           # create_deep_agent 装配
  backends.py        # LocalShellBackend
  cli.py             # typer CLI
  config.py          # pydantic-settings
  models_registry.py # 多模型目录
  mcp_client.py      # MCP → tools
  sessions.py        # 会话元数据
  subagents.py       # 默认子代理
  harness.py         # excluded_tools
  fs_permissions.py  # FilesystemPermission
  prompts.py
  safety.py
  tools/             # session tools
  ui/                # stream + TUI
docs/design.md
skills/              # agent skills
examples/            # models/mcp 配置样例
AGENTS.md
```

## 设计文档

更完整的架构与分期说明见 [`docs/design.md`](docs/design.md)。
