Metadata-Version: 2.4
Name: txcode-sdk
Version: 1.5.0
Summary: AI Agent SDK with built-in tools for Python projects
Author: homecommunity
License: MIT
Project-URL: Repository, https://github.com/homecommunity/txcode-sdk
Keywords: ai,agent,openai,tools,react
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file
Dynamic: requires-python

# txcode-sdk

AI Agent SDK with built-in tools for Python projects.

## Installation

- 要求：**Python >= 3.6**（含 3.6/3.7/3.8/3.9/3.10/3.11/3.12）
- **零第三方运行时依赖**（仅标准库，适合门禁设备等离线环境）

```bash
pip install txcode-sdk
```

## Quick Start

```python
import asyncio
from txcode_sdk import TxCodeClient

async def main():
    client = TxCodeClient(
        api_key="sk-xxx",
        base_url="https://api.openai.com/v1",
        model="gpt-4",
    )
    result = await client.chat("Hello!")
    print(result.answer)

asyncio.get_event_loop().run_until_complete(main())
```

## Features

- ReAct Agent loop with tool calling
- Multiple agent types: code, chat, common, task, plan, shell, skill, test, design, discuss, dream, name
- 10 built-in tools: read_file, write_file, edit_file, glob, grep, bash, memory, web_shell_exec, todo_read, todo_write
- Session management with JSON file persistence
- Context compression for long conversations
- Multimodal input support (images)
- Extensible custom tools
- Self-developed HTTP client (urllib, no openai/tiktoken dependency), supports OpenAI / DeepSeek / any OpenAI-compatible API

## WebSocket Server

SDK 内置零第三方依赖的 WebSocket 服务端（RFC 6455 自研协议层，Python 3.6 兼容），
支持 **txcode 桌面版远程连接**：把 SDK 安装到门禁 ARM 设备（Ubuntu 18 / Python 3.6）后，
Agent 循环与全部内置工具（read_file / write_file / edit_file / glob / grep / bash / todo 等）
在**设备本地执行**，桌面版仅作为远程操作界面——实现"直接在门禁系统上开发门禁系统代码"。

### 一条命令启动（主推）

```bash
pip install txcode-sdk

txcode-sdk serve --work-dir 您的目录
```

- `--work-dir`：门禁代码目录（**必填**，仅首次启动无当前项目时注册为当前项目），Agent 与内置工具在此目录下本地执行
- `--host` / `--port`：默认 `0.0.0.0:41000`
- `--agent-type`：默认 `code`
- `--models`：默认供应商初始模型列表 `[显示名=]模型名` 逗号分隔（仅首次注册默认供应商时使用）；缺省读 `TXCODE_MODELS`，再缺省 = 不限制
- `TXCODE_API_KEY`：**可选**——仅当 `~/.txcode/providers.json` 不存在且希望首次自动注册默认供应商时使用；未设置时服务以**空配置**正常启动（stderr 打印 WARN 提示），供应商由桌面端通过 WS `add_provider` / `switch_provider` 动态添加，无需重启
- 兜底启动：`python -m txcode_sdk.server serve --work-dir ...`（无脚本路径时同样可用）

### AI 运行参数（上下文大小 / 循环次数 / 思考强度）

三项参数与桌面端「设置 - 系统配置」一致，**默认值与 txcode（TS 版）完全对齐**；修改后无需重启服务，
**下次 Agent 运行生效**：

| 配置 | `~/.txcode/config.json` key | 默认值 | 可选值 | CLI 参数 |
| --- | --- | --- | --- | --- |
| 上下文大小 | `ai.context.maxTokens` | `150000` | 128k / 150k / 200k / 320k / 1M | `--context-tokens` |
| 循环次数 | `ai.maxIterations` | `1000` | 100 / 500 / 1000 / 5000 | `--max-iterations` |
| 思考强度 | `ai.reasoningEffort` | `max` | none / minimal / low / medium / high / xhigh / max | `--reasoning-effort` |

优先级：**显式 CLI 参数 > `~/.txcode/config.json`（桌面端写入）> 内置默认值**。

```bash
txcode-sdk serve --work-dir /opt/door-access \
  --context-tokens 320000 --max-iterations 500 --reasoning-effort high
```

- 桌面端保存后经 `POST /api/sys_config/set_config` 立即热更新运行中的 client（压缩阈值 / ReAct 循环上限 / 请求体 `thinking` + `reasoning_effort`）；
- 手工编辑 `~/.txcode/config.json` 亦可，下次 `chat` 前自动比对并应用；
- 非法值读取端回退默认值，写入端返回明确错误；`reasoning_effort` 仅在 `chat` 请求发送（`chat_stream` 固定关闭思考）。

### 启动装配（JSON 为权威源，0.4.1）

服务启动时以用户层 JSON 为权威源恢复上次状态，**重启自动恢复上次激活供应商/模型与当前项目**：

1. **供应商**：加载 `~/.txcode/providers.json`——存在则取激活供应商的 `(api_key, base_url, model)` 直接构造
   `TxCodeClient`（不读 `TXCODE_BASE_URL` / `TXCODE_MODEL`）；不存在（首次启动/全新环境）且设置了
   `TXCODE_API_KEY`（可选）时以 `TXCODE_BASE_URL` / `TXCODE_MODEL` 注册默认供应商并激活（`--models` 作为初始模型列表）；
   **未设置 `TXCODE_API_KEY` 时以空配置正常启动**（占位 client，不发起任何 API 请求），
   供应商由桌面端经 WS `add_provider` / `switch_provider` 动态添加；未配置供应商前 `chat` / `name_session`
   会收到「No active provider configured」提示，其余能力（WS 握手、ping、配置/项目管理消息）全部可用
2. **项目**：加载 `~/.txcode/projects.json`——有当前项目则其 `path` 作为 work_dir（不读 `TXCODE_WORK_DIR`）；
   无当前项目则 `--work-dir` 注册为当前项目后使用

配置（供应商/模型/项目列表）存**用户层 `~/.txcode/`**，跨项目共享、切换项目不影响；
会话仍按项目分别存于各自工作目录 `{work_dir}/.txcode/session/`。

### 桌面版连接

1. 桌面版「主机管理」添加远程主机：IP = 门禁设备 IP，端口 = 41000
2. 桌面版自动以 `ws://{ip}:{port}/ws/code` 连接（无需任何桌面版改动）
3. 发起对话：AI 在门禁系统本地读写文件、执行 `bash` 编译/运行/调试代码
4. 文件变更实时推送（`file:changed` 事件），前端自动刷新文件树与编辑器

### 协议消息

| 方向 | type | data |
|---|---|---|
| C→S | `chat` | message, sessionId, mediaFiles, agent, modelName（可选：命中即切换供应商/模型） |
| C→S | `stop` | sessionId（中断运行中会话） |
| C→S | `ping` | - |
| C→S | `get_running_sessions` | -（桌面版 5s 轮询） |
| C→S | `name_session` | sessionId, folderName, userInput |
| C→S | `get_providers` / `get_models` | - |
| C→S | `add_provider` | name, base_url, api_key, models |
| C→S | `update_provider` | providerId, name?, base_url?, api_key?, models? |
| C→S | `delete_provider` | providerId |
| C→S | `add_model` / `delete_model` | providerId, name / modelName |
| C→S | `switch_provider` | providerId, modelName? |
| C→S | `get_projects` | - |
| C→S | `open_project` | name, path |
| C→S | `select_project` / `delete_project` | projectId |
| S→C | `connected` / `step` / `compact` / `done` / `stopped` / `error` / `running_sessions` / `pong` / `rename` | 见下 |
| S→C | `providers_list` / `model_list` | get_providers / get_models 响应（仅发送方） |
| S→C | `providers_changed` | 供应商/模型增删改广播（全局） |
| S→C | `model_changed` | 模型/供应商切换成功广播（全局），data: {providerName, modelName, model} |
| S→C | `projects_list` | get_projects 响应（仅发送方） |
| S→C | `projects_changed` / `project_changed` | 项目列表变更 / 当前项目切换广播（全局） |

### 供应商与模型管理

服务端支持**动态添加/编辑/删除多个供应商**（OpenAI / DeepSeek / 自建网关），配置实时持久化到用户层
`~/.txcode/providers.json`，服务重启自动恢复；聊天消息携带 `modelName` 命中即切换（自动匹配供应商），
也可用 `switch_provider` 显式切换。

`~/.txcode/providers.json` 结构（配置在用户层，跨项目共享，**不随 work_dir 变化**）：

```json
{
  "providers": [
    {
      "id": "3f2a...",
      "name": "OpenAI",
      "base_url": "https://api.openai.com/v1",
      "api_key": "sk-xxx",
      "models": [{"name": "gpt-4o", "display_name": "GPT-4o"}],
      "created_at": "2026-08-14T...",
      "updated_at": "2026-08-14T..."
    }
  ],
  "active_provider_id": "3f2a...",
  "active_model": "gpt-4o"
}
```

- **模型限制规则**：供应商 `models` 为空列表 = 不限制（向后兼容）；非空 = 白名单校验
- **显示名**：`display_name` 对齐桌面版模型选择器语义（如 `DeepSeek V3` = `deepseek-chat`），
  匹配 name 与 display_name 双通道；`add_model` 缺省 display_name = name
- **api_key 安全**：WS 协议返回打码值（`sk-***` + 后 4 位）；`update_provider` 传打码值/空不改原 key；
  明文仅存于用户层本地文件（权限建议 `chmod 600`）
- **模型解析定序**：激活供应商优先 → 跨供应商按列表顺序第一个命中 → 未限制放行 → 全未命中回
  `error: Model not allowed: xxx, available: [..]`

#### 配置导入 / 导出（与桌面版本地后端同一 YAML 契约）

`GET /api/sys_config/export_config` 与 `POST /api/sys_config/import_config`（请求体 `{"content": "<配置文件文本>"}`）
使用**与桌面版本地后端 `tx_server` 完全相同的格式**：YAML、camelCase、模型在顶层 `models` 数组、**无 `success/data` 信封**。
因此桌面端「导出配置」得到的 `config.yml` 可直接导入 SDK 主机，SDK 导出的 `config.yml` 也可直接导入桌面端/其他 SDK 主机。
文本解析/生成由纯标准库模块 `yaml_lite` 完成（零第三方依赖，JSON 文本是 YAML 子集，同一入口天然兼容）。

导出响应为文件附件：`Content-Type: application/x-yaml` + `Content-Disposition: attachment; filename=config.yml`：

```yaml
providers:
  - id: 3f2a1b...                # 命中本地已有 id → 更新；未命中但 name 同名 → 更新该条；否则新增并保留文件中的 id
    name: OpenAI
    apiKey: sk-xxx               # 明文（导入必需，注意保管）；空串或打码值 sk-***xxxx 时不覆盖本地已有 key
    baseUrl: https://api.openai.com/v1
    enabled: true
    isDefault: true
models:
  - id: m-1                      # SDK 无 model id 语义，导出时按 providerId + name 派生
    providerId: 3f2a1b...         # 关联同一文件内 providers[].id（导入期建立「文件 id → 本地 id」映射）
    name: gpt-4o
    contextWindow: 128000        # SDK 无此存储，导入时忽略不报错，导出时省略
    maxOutputTokens: 8192
    supportsVision: true
    supportsTools: true
    enabled: true
projects:                        # SDK 扩展段：目录存在则打开项目；桌面端后端解析时忽略该段，不报错
  - id: a1b2c3
    name: door-access
    path: /opt/door-access
```

- **兼容旧格式**：`providers[].models` 内联的模型数组（旧版 SDK 导出）仍可导入；
- **忽略未知段**：`providerAuth / gateway / wafGateway / email / proxy` 等桌面端专属段只解析不落库，不报错；
- **幂等**：同一文件重复导入不产生重复供应商/模型（id 命中走更新，未命中同名走更新）；
- **可读报错**：语法不合法（含锚点/别名/多文档等 YAML 子集外特性）返回 400
  `{"success": false, "error": "配置文件格式无效（第 N 行）: ..."}`，不再透出 Python 异常串；
- **统计反馈**：成功返回 `{"success": true, "message": "配置导入成功", "data": {"providers": 6, "models": 12, "projects": 2, "skipped": []}}`，
  `skipped` 列出被跳过的条目及原因（缺 apiKey 的新供应商、`providerId` 不存在或目录不存在的项目等）。

### 项目管理

远程模式下桌面版右上角「打开项目 / 选择项目」由 SDK 侧 WS 协议提供等价能力：项目列表 / 打开（目录校验）/
选择（切换当前项目）/ 删除（不删实际文件），数据持久化到用户层 `~/.txcode/projects.json`（跨项目记忆）；
选择/打开项目后 SDK 实时切换 `work_dir`（Agent 与内置工具基准目录立即生效，切换前中断全部运行中会话）。

`~/.txcode/projects.json` 结构：

```json
{
  "projects": [
    {"id": "a1b2...", "name": "door-access", "path": "/opt/door-access",
     "created_at": "2026-08-14T...", "updated_at": "2026-08-14T..."}
  ],
  "current_project_id": "a1b2..."
}
```

> 安全边界：供应商 `api_key` 明文存于用户层 `~/.txcode/providers.json`（本地文件，与 TS 版 sys_config
> 数据库同等级别），仅限内网/受信网络部署，建议 `chmod 600`；WS 协议无鉴权，建议防火墙限制端口来源。

`step` 事件数据形状（对齐桌面版）：

```json
{
  "type": "step",
  "data": {
    "reasoning": "...",
    "toolCalls": [{"id": "call-1", "type": "function", "function": {"name": "bash", "arguments": "{\"command\": \"python3 main.py\"}"}, "status": "completed"}],
    "success": true,
    "iteration": 1,
    "sessionId": "xxx",
    "usage": {"promptTokens": 10, "completionTokens": 5, "totalTokens": 15}
  }
}
```

### 自定义工具（进阶，需写代码）

`txcode-sdk serve` CLI **只支持内置工具**（远程开发场景完全够用）。
需要对接门禁硬件控制（`open_door` / `get_door_status` 等）时，走进阶示例
[`src/example/ws_server.py`](src/example/ws_server.py)：注册自定义工具 + 启动 `TxCodeServer`。

```python
import asyncio
from txcode_sdk import Tool, ToolResult, TxCodeClient
from txcode_sdk.server import TxCodeServer

def open_door(args, ctx):
    return ToolResult(success=True, output="door opened")

client = TxCodeClient(
    api_key="sk-xxx", work_dir="/opt/door-access",
    tools=[Tool(name="open_door", description="打开门禁",
                parameters={"type": "object", "properties": {}}, execute=open_door)],
)
server = TxCodeServer(client, host="0.0.0.0", port=41000)
asyncio.get_event_loop().run_until_complete(server.start())
asyncio.get_event_loop().run_forever()
```

### 门禁系统部署（Ubuntu 18 / ARM）

```bash
# 1. 安装（离线可先下载 wheel 拷贝）
pip install txcode-sdk
python3 -c "import txcode_sdk; print(txcode_sdk.__version__)"

# 2. 验证端口监听
txcode-sdk serve --work-dir /opt/door-access &
ss -ltn | grep 41000

# 3. systemd 常驻（/etc/systemd/system/txcode-sdk.service）
# [Service] Environment=TXCODE_API_KEY=sk-xxx
# ExecStart=/usr/local/bin/txcode-sdk serve --work-dir /opt/door-access
# Restart=always
```

> 安全边界：协议无鉴权（与桌面版/TS 版一致），仅限内网/受信网络部署，
> 建议防火墙限制 41000 端口来源；鉴权（token 校验）列为二期增强。
