Metadata-Version: 2.4
Name: chattool
Version: 7.1.1
Summary: Toolkit for Chat API
Author-email: Rex Wang <1073853456@qq.com>
License: MIT license
Project-URL: Homepage, https://github.com/cubenlp/chattool
Project-URL: Repository, https://github.com/cubenlp/chattool
Keywords: chattool
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Click>=7.0
Requires-Dist: chatstyle<0.2.0,>=0.1.0
Requires-Dist: chatenv<0.3.0,>=0.2.0
Requires-Dist: requests>=2.20
Requires-Dist: python-dotenv>=0.17.0
Requires-Dist: colorama
Requires-Dist: httpx
Requires-Dist: tomli; python_version < "3.11"
Provides-Extra: arch
Requires-Dist: ChatGH<0.3.0,>=0.2.6; extra == "arch"
Requires-Dist: ChatUp<0.3.0,>=0.2.0; extra == "arch"
Requires-Dist: ChatPyPI<0.3.0,>=0.2.3; extra == "arch"
Requires-Dist: ChatNet<0.3.0,>=0.2.0; extra == "arch"
Requires-Dist: ChatLark<0.2.0,>=0.1.1; extra == "arch"
Provides-Extra: interactive
Requires-Dist: questionary>=2.1.0; extra == "interactive"
Requires-Dist: prompt_toolkit; extra == "interactive"
Provides-Extra: batch
Requires-Dist: batch_executor>=0.3.0; extra == "batch"
Requires-Dist: filelock; extra == "batch"
Provides-Extra: dns
Requires-Dist: ChatDNS<0.2.0,>=0.1.1; extra == "dns"
Provides-Extra: lark
Requires-Dist: ChatLark<0.2.0,>=0.1.1; extra == "lark"
Provides-Extra: images
Requires-Dist: dashscope; extra == "images"
Provides-Extra: screenshot
Requires-Dist: selenium; extra == "screenshot"
Requires-Dist: pillow; extra == "screenshot"
Requires-Dist: imageio; extra == "screenshot"
Provides-Extra: browser
Requires-Dist: selenium; extra == "browser"
Requires-Dist: pillow; extra == "browser"
Requires-Dist: imageio; extra == "browser"
Requires-Dist: playwright; extra == "browser"
Provides-Extra: serve
Requires-Dist: fastapi; extra == "serve"
Requires-Dist: uvicorn; extra == "serve"
Requires-Dist: pydantic>=2.0.0; extra == "serve"
Requires-Dist: ChatDNS<0.2.0,>=0.1.1; extra == "serve"
Provides-Extra: mcp
Requires-Dist: fastmcp; python_version >= "3.10" and extra == "mcp"
Provides-Extra: client
Requires-Dist: gitpython; extra == "client"
Requires-Dist: rich; extra == "client"
Provides-Extra: pypi
Requires-Dist: ChatPyPI<0.3.0,>=0.2.3; extra == "pypi"
Provides-Extra: setup
Requires-Dist: chatup<0.3.0,>=0.2.0; extra == "setup"
Provides-Extra: tools
Requires-Dist: chattool[batch,browser,client,dns,images,interactive,lark,mcp,screenshot,serve]; extra == "tools"
Provides-Extra: tests
Requires-Dist: coverage; extra == "tests"
Requires-Dist: pytest>=3; extra == "tests"
Requires-Dist: pytest-asyncio; extra == "tests"
Requires-Dist: pytest-mock; extra == "tests"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.4.0; extra == "docs"
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
Requires-Dist: mkdocs-minify-plugin>=0.6.0; extra == "docs"
Requires-Dist: mkdocs-static-i18n>=0.53; extra == "docs"
Requires-Dist: mkdocs-awesome-pages-plugin>=2.8.0; extra == "docs"
Requires-Dist: mkdocs-redirects>=1.2.0; extra == "docs"
Requires-Dist: mike>=1.1.2; extra == "docs"
Requires-Dist: pyparsing>=3.0; extra == "docs"
Provides-Extra: dev
Requires-Dist: wheel; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: chattool[arch,docs,setup,tests,tools]; extra == "dev"
Dynamic: license-file

<div align="center">
    <a href="https://pypi.python.org/pypi/chattool">
        <img src="https://img.shields.io/pypi/v/chattool.svg" alt="PyPI version" />
    </a>
    <a href="https://github.com/cubenlp/chattool/actions/workflows/ci.yml">
        <img src="https://github.com/cubenlp/chattool/actions/workflows/ci.yml/badge.svg" alt="Tests" />
    </a>
    <a href="https://chattool.wzhecnu.cn">
        <img src="https://img.shields.io/badge/docs-github_pages-blue.svg" alt="Documentation Status" />
    </a>
    <a href="https://codecov.io/gh/cubenlp/chattool">
        <img src="https://codecov.io/gh/cubenlp/chattool/branch/master/graph/badge.svg" alt="Coverage" />
    </a>
</div>

<div align="center">
    <img src="https://qiniu.wzhecnu.cn/PicBed6/picgo/chattool.jpeg" alt="ChatAPI Toolkit" width="360" style="border-radius: 20px;">

[English](README_en.md) | [简体中文](README.md)
</div>

以 CLI 为核心的 Python 开发套件，集成 LLM 对话、工具箱（DNS、飞书、绘图等）、MCP 服务和环境管理。

支持 Python `>=3.9`。

## 安装

默认安装只包含核心聊天能力和基础 CLI。DNS、MCP、Serve、交互式 TUI 等较重依赖已拆到 extras。

```bash
pip install chattool --upgrade
pip install "chattool[tools]"        # 常用工具全集
pip install "chattool[mcp]"          # legacy MCP 服务（DNS MCP 本轮不维护）
pip install "chattool[images]"       # 含图像工具
pip install "chattool[pypi]"         # 安装独立 ChatPyPI，用 chatpypi 管理 Python 包创建/构建/发布
pip install "chattool[lark]"         # 安装独立 ChatLark，用 chatlark 管理飞书/Lark bot helper
pip install "chattool[setup]"        # 安装独立 ChatUp，用 chatup workspace/hermes/cc-connect 等命令做环境初始化
pip install "chattool[arch]"         # 一次性安装 ChatGH / ChatUp / ChatPyPI / ChatNet / ChatLark 这些平行 ChatArch 工具
pip install "chattool[dev]"          # 仓库开发依赖
```

## 功能概览

### 环境变量管理 (`chatenv`)

ChatTool 7.0.0 起，typed env/profile 默认存放到 `~/.chatarch/envs`，可用 `CHATARCH_HOME` 改根目录；不再读取旧 `~/.config/chattool/envs`。

如需从旧目录手动迁移，可在仓库根目录运行：

```bash
python scripts/migrate_chattool_envs_to_chatarch.py --dry-run
python scripts/migrate_chattool_envs_to_chatarch.py
```

```bash
chatenv init -i                  # 交互式初始化（敏感字段自动隐藏）
chatenv init -i -t openai        # 仅初始化指定服务
chatenv cat                      # 查看配置（敏感值打码）
chatenv cat -t feishu           # 查看飞书配置，供 chattool cc init 默认候选值参考
chatenv cat -t openai --no-mask | chatenv paste --stdin --yes  # 跨设备复制/导入配置
chatenv set OPENAI_API_KEY=sk-xxx
chatenv new mini -t feishu      # 从当前激活配置复制一份新的 Feishu profile
chatenv new -t openai           # 交互式创建 OpenAI profile：先问名称，再补齐字段，不改 active .env
chatenv save work -t openai && chatenv use work -t openai   # 按类型管理 profile
chatlark info -e work          # 显式使用 Feishu profile，优先级高于当前 shell 环境变量
chattool cc init -i --quiet      # 生成默认 quiet 的 cc-connect 项目配置
```

### LLM 对话 (`chattool.Chat`)

```python
from chattool import Chat

# 多轮对话
chat = Chat("Hello!")
chat.get_response()
chat.user("How are you?").get_response()

# 异步并发
import asyncio
base = Chat().system("你是助手")
tasks = [base.copy().user(f"主题 {i}").async_get_response() for i in range(5)]
responses = asyncio.run(asyncio.gather(*tasks))

# 流式输出
async for chunk in Chat().user("写一首诗").async_get_response_stream():
    if chunk.delta_content:
        print(chunk.delta_content, end="", flush=True)
```

### 飞书/Lark Bot（已迁移到 ChatLark）

飞书/Lark bot helper 已从 ChatTool 分离到独立包 `ChatLark`，请使用一等 CLI `chatlark`。模型调用相关入口暂不接回 ChatTool。

```bash
pip install "chattool[lark]"
chatlark send USER_ID "Hello"
chatlark send "Hello"                  # 使用 FEISHU_DEFAULT_RECEIVER_ID
chatlark send -t chat_id "Hello team" # 使用 FEISHU_DEFAULT_CHAT_ID
chatlark info
chatlark serve echo
chatlark serve webhook
```

```python
from chatlark import LarkBot, ChatSession

bot = LarkBot()
session = ChatSession(chat_factory=my_chat_factory)

@bot.on_message
def chat(ctx):
    ctx.reply(session.chat(ctx.sender_id, ctx.text))

bot.start()
```

### DNS 管理（已迁移到 ChatDNS）

DNS 记录管理、DDNS、IP 探测和 DNS-01 证书自动化已经从 ChatTool 分离到独立包 `ChatDNS`，请使用一等 CLI `chatdns`：

```bash
chatdns --help
chatdns list
chatdns records home.example.com
chatdns set home.example.com -v 1.2.3.4
chatdns delete home.example.com -t A --yes
chatdns ip
chatdns ddns home.example.com --monitor
chatdns cert apply -d example.com -e admin@example.com --provider aliyun --staging
chatdns cert check -d example.com
```

在 ChatTool 中可通过可选依赖安装：`pip install "chattool[dns]"`。旧的 nested `chattool dns` 命令已移除，避免 ChatTool 继续持有重复 DNS/证书业务实现。

### Nginx 配置生成 (`chattool nginx`)

```bash
chattool nginx --list
chattool nginx proxy-pass --set SERVER_NAME=app.example.com --set PROXY_PASS=http://127.0.0.1:8080
chattool nginx websocket-proxy ./websocket.conf --set SERVER_NAME=ws.example.com --set PROXY_PASS=http://127.0.0.1:3000
chattool nginx static-root ./nas.conf --set SERVER_NAME=share.example.com --set ROOT_DIR=/storage/nas
chattool nginx -i  # 交互式选择模板并逐项填写
```

### AI 绘图 (`chattool image`)

```bash
chattool image pollinations generate "a cat in space" -o cat.png
chattool image siliconflow generate "a cute dog" -o dog.png
chattool image codex generate "a watercolor fox"
chattool image huggingface generate
```

交互终端里，各家 `generate` 命令缺少 `prompt` 时会自动补问；`huggingface generate` 与 `codex generate` 未传 `-o` 时会默认写到当前目录下的 `generated/image_<provider>_<model>_<timestamp>.png`。显式传 `-I` 时保持直接报错。

### 数据探索 (`chattool explore`)

```bash
chattool explore arxiv search -p ai4math -n 10
chattool explore arxiv daily -p math-formalization --days 3
chattool explore arxiv daily -p math-formalization-weekly --days 7 -v
chattool explore arxiv get 1706.03762 -v
chattool explore arxiv get
```

交互终端里，`chattool explore arxiv get` 缺少 arXiv ID 时会自动补问。

### 本地服务 (`chattool serve`)

```bash
chattool serve local ./cli-tree.html --host 127.0.0.1 --port 8765
chattool serve local ./reports --html cli-tree.html --port 8765
chattool serve local . --html index.html --dry-run
```

`serve local` 可用本地端口打开 HTML 文件或目录；省略目标时默认使用当前目录，`-i` 会进入统一交互补问。

### 其他工具

| 工具 | 命令 | 说明 |
|------|------|------|
| Nginx 配置 | `chattool nginx` | 按模板生成常见的反向代理、路径转发和静态目录配置 |
| PyPI 工具 | `chatpypi`（来自 `chattool[pypi]` / `chattool[arch]` / `ChatPyPI`） | 创建、构建、校验、上传与探测 Python 包；ChatTool 不再内置 `chattool pypi` |
| MCP 服务 | `chattool mcp start` | 标准 MCP Server，供 Claude/Cursor 调用 |
| 环境安装 | `chatup zsh/codex/claude/opencode/hermes/lark-cli/docker` | ChatTool 的 setup 能力已迁移到独立 ChatUp；安装 `chattool[setup]` 或 `chatup` 后使用 `chatup ...` 一级命令配置常用 Agent CLI / WebUI / Docker 环境 |
| Workspace | `chatup workspace` | 初始化围绕核心项目的人类-AI 协作工作区骨架；当前默认使用 `projects/` 作为实际工作的执行容器，workspace 根目录则保留 general-use 协议与上下文；可选 `--with-chattool`、`--with-chatblog`、`--with-memory` 分别挂载 ChatTool、ChatBlog、ChatMemory |
| Skills | `chattool skill install` | 安装 ChatTool skills 到 Codex / Claude / OpenCode |
| CC-Connect | `chattool cc` | cc-connect 快速配置与启动 |
| CRS 查询 | `chattool crs` | 查询 Claude Relay Service API key 用量、模型统计和只读 admin 信息 |

## 文档

完整文档见 [chattool.wzhecnu.cn](https://chattool.wzhecnu.cn)
仓库结构设计草案见 `docs/design/python-library-repo-structure.md`
PyPI 包管理能力已迁移到独立 `ChatPyPI` / `chatpypi` 包。

## 测试约定

- `tests/cli-tests/`：真实 CLI 链路与真实环境验收，采用 doc-first。
- `tests/mock-cli-tests/`：所有基于 `mock`、`patch`、`monkeypatch`、fake client / API 的 CLI 测试，统一集中到这里。
- `tests/code-tests/`：非 CLI 的代码测试与历史测试迁移落点。

快速建包请安装并使用独立 `chatpypi`：

```bash
pip install "chattool[pypi]"
chatpypi init mychat
chatpypi init mycli -t chatarch
chatpypi init -i                  # 交互式选择模板、mkdocs/workflow 等选项
chatpypi probe mychat
```

也可以通过 `pip install "chattool[arch]"` 一次性安装 ChatGH、ChatUp、ChatPyPI、ChatNet。

`ChatPyPI` / `chatpypi` 是 Python 包创建、构建、校验、上传与探测能力的 canonical owner；ChatTool 不再内置 `chattool pypi` 或 `chatpypi` wrapper。

默认模板生成的 `pyproject.toml` 会写入 `requires-python = ">=3.9"`；`chatarch` 模板默认写入 `requires-python = ">=3.10"`，并依赖 `chatstyle>=0.1.0,<0.2.0` 与 `chatenv>=0.2.0,<0.3.0`。

`chatarch` 模板会额外生成 `DEVELOP.md`、`CHANGELOG.md`、`AGENTS.md`、`README.en.md`、`mkdocs.yml`、`docs/`、`tests/cli-tests/`、`tests/mock-cli-tests/`、`tests/code-tests/` 与 `.github/workflows/` 骨架；发布 workflow 由显式 `v*` tag 或 `workflow_dispatch` 触发，校验 tag 与包内 `__version__` 一致，并通过 PyPI Trusted Publishing 发布。默认不写 `environment: pypi`，除非 PyPI Trusted Publisher 明确配置了同名 environment。

如只想生成代码与测试骨架，可以用 `--without-mkdocs` 跳过 mkdocs/docs，用 `--without-workflows` 跳过 `.github/workflows/`。

## 开源协议

MIT License
