A feature-rich yet lightweight terminal AI chat application designed for low resource consumption
Project description
TinyChat
TinyChat 是一款功能丰富且轻量的终端 AI 聊天应用,基于 Textual 框架构建,专为低资源消耗设计。支持 Ollama 本地模型和 OpenAI 兼容 API,内置插件式工具系统,提供流式响应、多会话管理、工作流引擎和中英文双语界面,满足从日常对话到 AI 辅助编程的多种场景。
特性
多后端支持
- Ollama — 本地 Ollama 服务器
- OpenAI 兼容 — 支持 vLLM、LM Studio、OpenRouter、Azure OpenAI 等所有 OpenAI 兼容 API
- 运行时热切换后端与模型,侧边栏一键操作(
Ctrl+B) - 自动验证并修正旧会话中失效的模型名称
- 非阻塞启动 — 后台异步获取模型列表,界面立即可用
现代化终端界面
- 基于 Textual 框架,响应式布局自适应终端尺寸
- 丰富的 Markdown 渲染和代码高亮,流式响应逐 token 实时显示
- 明/暗双主题,遵循 WCAG AA 无障碍对比度标准
- 原生鼠标支持(点击、滚动、右键菜单)
- 状态栏实时显示连接状态、模型名称、响应耗时和 tokens/s 吞吐量
ESC停止流式响应,输入历史导航(上下方向键)
多会话管理
- 标签式多会话,
Ctrl+T新建、Ctrl+L打开会话列表 - 会话持久化至
~/.tinychat/sessions/,每次对话自动保存(防抖 2 秒) - 会话列表对话框:模糊搜索、按日期分组、相对时间戳、消息预览、
j/k键盘导航 - 会话分叉(Fork) — 从任意助手消息创建新分支会话
- 内联重命名(
Ctrl+R)、两步删除确认(5 秒自动取消) - 会话导入/导出(Markdown / JSON),损坏文件自动备份恢复
- LRU 缓存策略,仅保留当前会话在内存中
消息操作
Alt+M消息操作菜单:分叉(Fork)、重新生成(Regenerate)、删除(Delete)- 删除消息时自动清理关联的工具调用和错误消息
- 工具执行结果可折叠卡片,超长内容自动收起,智能标题摘要(显示命令、文件名、行范围等)
工具系统(插件架构)
- 基于 Python entry points 的插件发现机制,第三方工具通过 pip 安装即可使用
- 智能工具选择 — 根据用户消息自动匹配文件路径、命令关键词、任务关键词,动态决定注入哪些工具
- 多语言触发词系统(
en.json/zh.json),按相关性百分比生成工具使用提示 - 三种工具调用适配器:
- NativeAdapter — 原生
tool_calls支持(Ollama 0.3+、OpenAI) - PromptAdapter — 无原生工具调用时的提示词降级方案
- DSMLParser — DeepSeek DSML 工具调用解析,支持 XML 和 JSON 参数格式,流式输出时自动屏蔽原始标记
- NativeAdapter — 原生
- 渐进信任机制 — 每次执行需确认,连续允许 3 次后提示"始终允许",偏好持久化到配置文件
- 重复调用检测,最大递归深度 50 层防止无限循环
内置工具(tinychat-builtin-tools)
read_file— 读取文件,支持偏移量、行数限制和尾部读取write_file— 写入文件,自动创建父目录edit_file— 查找替换编辑,支持全局替换list_directory— 列出目录内容glob— 按通配符模式搜索文件(**/*.py)grep— 正则搜索文件树,支持包含过滤、上下文行和最大匹配数exec_shell— Shell 命令执行,命令白名单、危险模式拦截、环境变量清理、超时控制no_action— 显式无操作工具,让 LLM 主动声明无需调用工具todo_list— 任务管理,支持传统待办模式和工作流模式
工作流引擎
- 多步骤工作流执行,支持步骤间依赖关系(DAG)
- 每步骤独立超时、重试次数和确认开关
- 工作流状态持久化,应用重启后自动恢复未完成的执行
- 状态追踪:pending → running → paused → completed / failed / cancelled
国际化
- 中文/英文双语界面,基于 gettext 运行时切换语言
- 所有 UI 文本均可翻译:绑定描述、状态消息、对话框标签、错误提示
- 翻译快捷命令:
翻译:内容/translate:content
跨平台
- 支持 Windows、macOS、Linux
- 跨平台剪贴板 — pyperclip 优先,OSC 52 降级(适配 SSH/远程终端)
快捷命令
翻译:内容— 自动改写为翻译提示(中文)translate:content— 自动改写为翻译提示(英文)
安装
系统要求
- Python 3.9+
- pip 或 uv 包管理器
从 PyPI 安装
pip install tinychat
从源码安装
git clone <repository-url>
cd tinychat
# 使用 pip
pip install -e ".[dev]"
# 或使用 uv
uv sync --extra dev
安装内置工具
内置工具提供文件读写、Shell 执行、搜索和工作流等功能,需单独安装:
pip install tinychat-builtin-tools
如从源码安装,可使用:
pip install -e "./packages/tinychat-builtin-tools"
使用
启动应用
tinychat
或直接运行模块:
python -m tinychat
基本操作
- 选择后端 - 在左侧边栏点击后端名称
- 选择模型 - 在边栏点击模型名称
- 发送消息 - 输入内容后按 Enter
- 换行 - 按 Ctrl+Enter 插入换行
- 滚动历史 - 使用鼠标滚轮或方向键
快捷键
| 按键 | 功能 |
|---|---|
| Enter | 发送消息 |
| Ctrl+J | 输入换行 |
| Ctrl+T | 新建会话 |
| Ctrl+L | 会话列表 |
| Ctrl+B | 后端/模型面板 |
| Ctrl+P | 命令面板 |
| Alt+M | 消息操作(分叉/重新生成/删除) |
| Ctrl+Q | 退出应用 |
| ESC | 停止流式响应 / 关闭面板 |
配置
配置文件位于 ~/.config/tinychat/config.toml(如不存在会自动创建)。
配置结构
[settings]
locale = "zh" # 语言: "en" (英语) 或 "zh" (中文)
[[backends]] # 可以配置多个后端
name = "backend-name" # 后端显示名称
type = "backend-type" # 后端类型
endpoint = "API地址" # API 端点
default_model = "模型名" # 默认模型
api_key = "密钥" # API 密钥(可选)
后端类型详解
| 类型 | 说明 | API 端点示例 |
|---|---|---|
ollama |
本地 Ollama 服务器 | http://localhost:11434 |
openai-compatible |
OpenAI 兼容的 API 服务 | https://api.example.com/v1 |
后端配置参数
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
name |
字符串 | 是 | 后端显示名称,用于 UI 标识 |
type |
字符串 | 是 | 后端类型:ollama 或 openai-compatible |
endpoint |
字符串 | 是 | API 地址,需包含完整路径(如 /v1) |
default_model |
字符串 | 是 | 默认使用的模型名称 |
api_key |
字符串 | 否 | API 密钥(Ollama 不需要) |
配置示例
Ollama 本地服务器:
[[backends]]
name = "ollama-local"
type = "ollama"
endpoint = "http://localhost:11434"
default_model = "llama3.2"
OpenAI 官方 API:
[[backends]]
name = "openai"
type = "openai-compatible"
endpoint = "https://api.openai.com/v1"
api_key = "sk-..."
default_model = "gpt-4o"
vLLM / LM Studio / Text Generation WebUI 等 OpenAI 兼容服务:
[[backends]]
name = "vllm-server"
type = "openai-compatible"
endpoint = "http://localhost:8000/v1"
api_key = "not-required" # 多数本地服务不需要密钥
default_model = "meta-llama/Llama-2-7b-chat-hf"
OpenRouter / Together AI 等云服务:
[[backends]]
name = "openrouter"
type = "openai-compatible"
endpoint = "https://openrouter.ai/api/v1"
api_key = "sk-or-..."
default_model = "openai/gpt-3.5-turbo"
Azure OpenAI Service:
[[backends]]
name = "azure-openai"
type = "openai-compatible"
endpoint = "https://your-resource.openai.azure.com/openai/deployments/your-deployment"
api_key = "your-azure-api-key"
default_model = "gpt-35-turbo"
多后端配置
可以同时配置多个后端,通过 name 字段区分:
[settings]
locale = "zh"
[[backends]]
name = "ollama-local"
type = "ollama"
endpoint = "http://localhost:11434"
default_model = "llama3.2"
[[backends]]
name = "openai-cloud"
type = "openai-compatible"
endpoint = "https://api.openai.com/v1"
api_key = "sk-..."
default_model = "gpt-4o"
[[backends]]
name = "vllm-server"
type = "openai-compatible"
endpoint = "http://localhost:8000/v1"
default_model = "meta-llama/Llama-2-7b-chat-hf"
启动后可在左侧边栏点击切换不同后端和模型。
开发
项目结构
tinychat/
├── src/tinychat/
│ ├── __main__.py # 入口
│ ├── app_textual.py # 主应用
│ ├── backends/ # 后端实现
│ │ ├── base.py # 抽象基类
│ │ ├── ollama.py # Ollama 后端
│ │ ├── openai.py # OpenAI 后端
│ │ └── dsml_parser.py # DSML 工具调用解析
│ ├── components/ # UI 组件
│ │ ├── chat_view.py # 聊天消息显示
│ │ ├── input_area.py # 用户输入区
│ │ ├── sidebar.py # 后端/模型侧边栏
│ │ ├── status_bar.py # 状态栏
│ │ ├── message_widgets.py # 消息渲染组件
│ │ ├── tool_result_card.py # 工具结果折叠卡片
│ │ ├── tool_confirm_screen.py # 工具执行确认
│ │ ├── session_list_dialog.py # 会话列表对话框
│ │ ├── rename_dialog.py # 会话重命名对话框
│ │ ├── message_action_screen.py # 消息操作菜单
│ │ └── left_panel.py # 左侧面板容器
│ ├── models/ # 数据模型
│ ├── tools/ # 工具系统
│ │ ├── base.py # 工具基类
│ │ ├── manager.py # 插件管理器
│ │ ├── executor.py # 工具执行器(信任机制)
│ │ ├── adapter.py # LLM 工具调用适配器
│ │ └── trigger_manager.py # 触发词管理器
│ ├── workflow/ # 工作流引擎
│ │ └── engine.py # 多步骤工作流执行
│ ├── utils/ # 工具函数
│ │ ├── config_manager.py # 统一 TOML 配置管理
│ │ ├── i18n.py # 国际化
│ │ ├── theme_manager.py # 主题管理
│ │ ├── session_persistence.py # 会话持久化
│ │ ├── session_manager.py # 会话状态管理
│ │ ├── metrics.py # 流式性能指标
│ │ ├── clipboard.py # 剪贴板(OSC 52 降级)
│ │ └── logging_config.py # 日志配置
│ ├── locales/ # 翻译文件
│ └── styles/ # CSS 样式
├── packages/
│ └── tinychat-builtin-tools/ # 内置工具插件
└── tests/ # 测试
运行测试
# 运行所有测试
pytest tests/ -v
# 带覆盖率报告
pytest tests/ --cov=src/tinychat --cov-report=html
# 运行单个测试
pytest tests/unit/test_app_textual.py -v
代码检查
ruff check src/ tests/
ruff format src/ tests/
打包发布
# 安装构建工具
pip install build
# 构建
python -m build
# 生成的文件在 dist/ 目录
致谢
许可证
MIT License
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tinychat_ai-0.1.6.tar.gz.
File metadata
- Download URL: tinychat_ai-0.1.6.tar.gz
- Upload date:
- Size: 88.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e1a6e560d84a0d59c97a2feec5ba8af0dbd0bcc5cf4b0a01f86ba567dc9bc6f
|
|
| MD5 |
68fa6337d63f297a757eb762dce8eabc
|
|
| BLAKE2b-256 |
e18c16de696a0c088623c96b951f37782df8dc4ae08a251556845c652f0a20b5
|
File details
Details for the file tinychat_ai-0.1.6-py3-none-any.whl.
File metadata
- Download URL: tinychat_ai-0.1.6-py3-none-any.whl
- Upload date:
- Size: 101.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1f485999f374ae28503bb476efaa626e36ef9fe6e0cd4491f4a30601280e788
|
|
| MD5 |
8beabbd6a1c46d14bf6a2fbd5bf8a22d
|
|
| BLAKE2b-256 |
3309c5116d13dbf37f75556c9a8abc77731868866e69da0b67d9e70acb694eca
|