closer-code 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/.closer-code.example.json +32 -0
  2. package/DUAL_OPTIMIZATION_COMPLETE.md +293 -0
  3. package/README.md +167 -557
  4. package/README_OPENAI.md +163 -0
  5. package/THINKING_THROTTLING_OPTIMIZATION.md +244 -0
  6. package/THROTTLING_1_5S_OPTIMIZATION.md +401 -0
  7. package/TOOLS_IMPROVEMENTS_SUMMARY.md +273 -0
  8. package/cloco.md +5 -1
  9. package/config.example.json +15 -94
  10. package/config.mcp.example.json +81 -0
  11. package/dist/bash-runner.js +5 -126
  12. package/dist/batch-cli.js +286 -20658
  13. package/dist/closer-cli.js +329 -21135
  14. package/dist/index.js +308 -31036
  15. package/docs/ANTHROPIC_TOOL_ERROR_HANDLING.md +220 -0
  16. package/docs/BUILD_COMMANDS.md +79 -0
  17. package/docs/CTRL_Z_SUPPORT.md +189 -0
  18. package/docs/DEEPSEEK_R1_INTEGRATION.md +427 -0
  19. package/docs/FIX_OPENAI_TOOL_ERROR_HANDLING.md +375 -0
  20. package/docs/FIX_OPENAI_TOOL_RESULT.md +198 -0
  21. package/docs/INPUT_ENHANCEMENTS.md +192 -0
  22. package/docs/MCP_IMPLEMENTATION_SUMMARY.md +428 -0
  23. package/docs/MCP_INTEGRATION.md +418 -0
  24. package/docs/MCP_QUICKSTART.md +299 -0
  25. package/docs/MCP_README.md +166 -0
  26. package/docs/MINIFY_BUILD.md +180 -0
  27. package/docs/MULTILINE_INPUT_FEATURE.md +119 -0
  28. package/docs/OPENAI_CLIENT.md +258 -0
  29. package/docs/PROJECT_LOCAL_CONFIG.md +471 -0
  30. package/docs/PROJECT_LOCAL_CONFIG_SUMMARY.md +407 -0
  31. package/docs/REFACTOR_CONVERSATION.md +306 -0
  32. package/docs/REGION_EDIT_DESIGN.md +475 -0
  33. package/docs/SIGNAL_HANDLING.md +171 -0
  34. package/docs/STREAM_UPDATE_THROTTLE.md +273 -0
  35. package/docs/TOOLS_REFACTOR_PLAN.md +520 -0
  36. package/ds_r1.md +249 -0
  37. package/examples/abort-fence-example.js +294 -0
  38. package/package.json +18 -4
  39. package/src/ai-client-legacy.js +6 -1
  40. package/src/ai-client-openai.js +672 -0
  41. package/src/ai-client.js +30 -13
  42. package/src/closer-cli.jsx +450 -162
  43. package/src/components/fullscreen-conversation.jsx +157 -0
  44. package/src/components/ink-text-input/index.jsx +324 -0
  45. package/src/components/multiline-text-input.jsx +614 -0
  46. package/src/components/progress-bar.jsx +135 -0
  47. package/src/components/tool-detail-view.jsx +82 -0
  48. package/src/components/tool-renderers/bash-renderer.jsx +197 -0
  49. package/src/components/tool-renderers/file-edit-renderer.jsx +247 -0
  50. package/src/components/tool-renderers/file-read-renderer.jsx +261 -0
  51. package/src/components/tool-renderers/file-write-renderer.jsx +222 -0
  52. package/src/components/tool-renderers/index.jsx +178 -0
  53. package/src/components/tool-renderers/list-renderer.jsx +274 -0
  54. package/src/components/tool-renderers/search-renderer.jsx +248 -0
  55. package/src/config.js +182 -20
  56. package/src/conversation/abort-fence.js +158 -0
  57. package/src/conversation/core.js +377 -0
  58. package/src/conversation/index.js +33 -0
  59. package/src/conversation/mcp-integration.js +96 -0
  60. package/src/conversation/plan-manager.js +295 -0
  61. package/src/conversation/stream-handler.js +154 -0
  62. package/src/conversation/tool-executor.js +264 -0
  63. package/src/conversation.js +23 -958
  64. package/src/hooks/use-throttled-state.js +158 -0
  65. package/src/input/enhanced-input.jsx +268 -0
  66. package/src/input/history.js +342 -0
  67. package/src/logger.js +20 -0
  68. package/src/mcp/client.js +275 -0
  69. package/src/mcp/tools-adapter.js +149 -0
  70. package/src/planner.js +18 -5
  71. package/src/prompt-builder.js +159 -0
  72. package/src/tools.js +457 -25
  73. package/src/utils/json-parser.js +231 -0
  74. package/src/utils/json-repair.js +146 -0
  75. package/src/utils/platform.js +259 -0
  76. package/test/test-ctrl-bf.js +121 -0
  77. package/test/test-deepseek-reasoning.js +118 -0
  78. package/test/test-history-navigation.js +80 -0
  79. package/test/test-input-fix.js +105 -0
  80. package/test/test-input-history.js +98 -0
  81. package/test/test-mcp.js +115 -0
  82. package/test/test-openai-client.js +152 -0
  83. package/test/test-openai-tool-result.js +199 -0
  84. package/test/test-project-config.js +106 -0
  85. package/test/test-shortcuts.js +79 -0
  86. package/test/test-stream-throttle.js +124 -0
  87. package/test/test-tool-error-handling.js +95 -0
  88. package/test/verify-input-fix.sh +35 -0
  89. package/test-abort-fence.js +263 -0
  90. package/test-abort-fix.js +54 -0
  91. package/test-abort-new-conversation.js +75 -0
  92. package/test-ctrl-z.js +54 -0
  93. package/test-file-read.js +105 -0
  94. package/test-tool-display.js +127 -0
  95. package/src/closer-cli.jsx.backup +0 -948
  96. package/test/workflows/longtalk/cloco.md +0 -19
  97. package/test/workflows/longtalk/emoji_500.txt +0 -63
  98. package/test/workflows/longtalk/emoji_list.txt +0 -20
  99. package/test-ctrl-c.jsx +0 -126
@@ -0,0 +1,166 @@
1
+ # MCP 集成总结
2
+
3
+ ## ✅ 已完成的功能
4
+
5
+ ### 1. MCP Client 实现
6
+
7
+ - **`src/mcp/client.js`**: MCP Client 管理器
8
+ - 连接到多个 MCP Servers
9
+ - 管理工具调用
10
+ - 提供连接状态查询
11
+
12
+ ### 2. 工具适配器
13
+
14
+ - **`src/mcp/tools-adapter.js`**: 将 MCP 工具转换为 betaZodTool 格式
15
+ - JSON Schema → Zod Schema 转换
16
+ - 与现有工具系统无缝集成
17
+
18
+ ### 3. 配置支持
19
+
20
+ - **配置文件扩展**: 在 `config.json` 中添加 MCP 配置
21
+ - **示例配置**: `config.mcp.example.json` 提供完整配置示例
22
+
23
+ ### 4. 对话集成
24
+
25
+ - **Conversation 类增强**: 自动连接 MCP Servers 并加载工具
26
+ - **统一工具调用**: AI 可以同时使用内置工具和 MCP 工具
27
+
28
+ ### 5. 文档和测试
29
+
30
+ - **集成指南**: `docs/MCP_INTEGRATION.md` - 完整的使用文档
31
+ - **测试文件**: `test/test-mcp.js` - MCP 功能测试
32
+
33
+ ## 📁 新增文件
34
+
35
+ ```
36
+ src/mcp/
37
+ ├── client.js # MCP Client 管理器
38
+ └── tools-adapter.js # 工具格式转换器
39
+
40
+ docs/
41
+ └── MCP_INTEGRATION.md # MCP 集成指南
42
+
43
+ test/
44
+ └── test-mcp.js # MCP 测试
45
+
46
+ config.mcp.example.json # MCP 配置示例
47
+ ```
48
+
49
+ ## 🔧 修改的文件
50
+
51
+ ```
52
+ src/config.js # 添加 MCP 配置支持
53
+ src/conversation.js # 集成 MCP Client
54
+ src/tools.js # 添加 getAllToolDefinitions
55
+ src/logger.js # 添加 logger 对象导出
56
+ package.json # 添加 test:mcp 脚本
57
+ ```
58
+
59
+ ## 🚀 使用方法
60
+
61
+ ### 1. 配置 MCP Servers
62
+
63
+ 在 `~/.closer-code/config.json` 中添加:
64
+
65
+ ```json
66
+ {
67
+ "mcp": {
68
+ "enabled": true,
69
+ "servers": {
70
+ "filesystem": {
71
+ "enabled": true,
72
+ "command": "npx",
73
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"]
74
+ }
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ### 2. 启动 Closer Code
81
+
82
+ ```bash
83
+ cloco
84
+ ```
85
+
86
+ ### 3. 使用 MCP 工具
87
+
88
+ ```
89
+ ❯ 读取 /home/user/projects/config.json 文件
90
+ ❯ 列出 /data 目录的所有文件
91
+ ```
92
+
93
+ ## 🧪 测试
94
+
95
+ 运行 MCP 测试:
96
+
97
+ ```bash
98
+ npm run test:mcp
99
+ ```
100
+
101
+ ## 📚 支持的 MCP Servers
102
+
103
+ ### 官方 Servers
104
+
105
+ - `@modelcontextprotocol/server-filesystem` - 文件系统访问
106
+ - `@modelcontextprotocol/server-git` - Git 操作
107
+ - `@modelcontextprotocol/server-postgres` - PostgreSQL 数据库
108
+ - `@modelcontextprotocol/server-sqlite` - SQLite 数据库
109
+ - `@modelcontextprotocol/server-brave-search` - Brave 搜索
110
+ - `@modelcontextprotocol/server-github` - GitHub API
111
+
112
+ ### 自定义 Servers
113
+
114
+ 任何符合 MCP 标准的自定义服务器都可以连接。
115
+
116
+ ## 🎯 核心优势
117
+
118
+ 1. **无缝集成**: MCP 工具与内置工具统一管理
119
+ 2. **标准化**: 使用开放协议,易于扩展
120
+ 3. **灵活性**: 支持任意 MCP Server
121
+ 4. **向后兼容**: 不影响现有功能
122
+
123
+ ## 📝 工具命名规则
124
+
125
+ MCP 工具使用以下命名格式:
126
+
127
+ ```
128
+ {serverName}_{toolName}
129
+ ```
130
+
131
+ 示例:
132
+ - `filesystem_read_file`
133
+ - `git_clone`
134
+ - `postgres_query`
135
+
136
+ ## 🔍 调试
137
+
138
+ 启用调试日志:
139
+
140
+ ```bash
141
+ export CLOSER_DEBUG_LOG=1
142
+ cloco
143
+ ```
144
+
145
+ 日志会显示:
146
+ - MCP Server 连接状态
147
+ - 工具加载信息
148
+ - 工具调用详情
149
+
150
+ ## 🛠️ 开发自定义 MCP Server
151
+
152
+ 参考 `docs/MCP_INTEGRATION.md` 中的"开发自定义 MCP Server"章节。
153
+
154
+ ## 📖 相关文档
155
+
156
+ - [MCP 集成指南](./MCP_INTEGRATION.md) - 完整使用文档
157
+ - [MCP 官方文档](https://modelcontextprotocol.io/)
158
+ - [MCP SDK GitHub](https://github.com/modelcontextprotocol/typescript-sdk)
159
+
160
+ ## 🤝 贡献
161
+
162
+ 欢迎贡献自定义 MCP Servers 或改进建议!
163
+
164
+ ## 📄 许可证
165
+
166
+ MIT License
@@ -0,0 +1,180 @@
1
+ # 压缩构建 (Minify Build)
2
+
3
+ ## 📦 概述
4
+
5
+ `npm run minify-build` 是一个用于生产环境的压缩构建选项,它可以显著减小打包后的文件大小。
6
+
7
+ ## 🚀 使用方法
8
+
9
+ ### 压缩所有组件
10
+ ```bash
11
+ npm run minify-build
12
+ ```
13
+
14
+ ### 压缩单个组件
15
+ ```bash
16
+ # 只压缩主程序
17
+ npm run minify-build:main
18
+
19
+ # 只压缩 CLI
20
+ npm run minify-build:cli
21
+
22
+ # 只压缩 Bash Runner
23
+ npm run minify-build:bash
24
+
25
+ # 只压缩 Batch CLI
26
+ npm run minify-build:batch
27
+ ```
28
+
29
+ ## 📊 文件大小对比
30
+
31
+ ### 主程序 (dist/index.js)
32
+
33
+ | 构建类型 | 文件大小 | 压缩率 |
34
+ |---------|---------|--------|
35
+ | 普通构建 | 656.4 kb | - |
36
+ | 压缩构建 | 270.6 kb | **58.8%** |
37
+
38
+ **节省空间**:385.8 kb (约 59%)
39
+
40
+ ### CLI (dist/closer-cli.js)
41
+
42
+ | 构建类型 | 文件大小 | 压缩率 |
43
+ |---------|---------|--------|
44
+ | 普通构建 | ~1.2 mb | - |
45
+ | 压缩构建 | 1.0 mb | **~16.7%** |
46
+
47
+ ### Batch CLI (dist/batch-cli.js)
48
+
49
+ | 构建类型 | 文件大小 | 压缩率 |
50
+ |---------|---------|--------|
51
+ | 普通构建 | ~1.2 mb | - |
52
+ | 压缩构建 | 1023.3 kb | **~14.7%** |
53
+
54
+ ### Bash Runner (dist/bash-runner.js)
55
+
56
+ | 构建类型 | 文件大小 | 压缩率 |
57
+ |---------|---------|--------|
58
+ | 普通构建 | ~3 kb | - |
59
+ | 压缩构建 | 1.6 kb | **~46.7%** |
60
+
61
+ ## 🎯 何时使用压缩构建
62
+
63
+ ### 推荐使用场景
64
+ - ✅ **生产部署**:减小分发体积
65
+ - ✅ **CI/CD**:加快传输速度
66
+ - ✅ **Docker 镜像**:减小镜像大小
67
+ - ✅ **云函数**:减少冷启动时间
68
+
69
+ ### 不推荐使用场景
70
+ - ❌ **开发调试**:代码不可读
71
+ - ❌ **错误排查**:堆栈信息不清晰
72
+ - ❌ **本地测试**:构建时间稍长
73
+
74
+ ## 🔍 压缩技术
75
+
76
+ esbuild 的 `--minify` 选项包含以下优化:
77
+
78
+ 1. **空白压缩**:移除不必要的空格、换行
79
+ 2. **标识符缩短**:将变量名缩短为单字符
80
+ 3. **语法优化**:简化代码结构
81
+ 4. **死代码消除**:移除未使用的代码
82
+
83
+ ## 📝 构建脚本对比
84
+
85
+ ### 普通构建
86
+ ```json
87
+ {
88
+ "build": "npm run build:main && npm run build:cli && npm run build:bash && npm run build:batch"
89
+ }
90
+ ```
91
+
92
+ ### 压缩构建
93
+ ```json
94
+ {
95
+ "minify-build": "npm run minify-build:main && npm run minify-build:cli && npm run minify-build:bash && npm run minify-build:batch"
96
+ }
97
+ ```
98
+
99
+ ## ⚙️ 可用的构建命令
100
+
101
+ | 命令 | 说明 | 是否压缩 |
102
+ |------|------|---------|
103
+ | `npm run build` | 构建所有组件 | ❌ |
104
+ | `npm run build:main` | 构建主程序 | ❌ |
105
+ | `npm run build:cli` | 构建 CLI | ❌ |
106
+ | `npm run build:bash` | 构建 Bash Runner | ❌ |
107
+ | `npm run build:batch` | 构建 Batch CLI | ❌ |
108
+ | `npm run minify-build` | **压缩构建所有组件** | ✅ |
109
+ | `npm run minify-build:main` | **压缩构建主程序** | ✅ |
110
+ | `npm run minify-build:cli` | **压缩构建 CLI** | ✅ |
111
+ | `npm run minify-build:bash` | **压缩构建 Bash Runner** | ✅ |
112
+ | `npm run minify-build:batch` | **压缩构建 Batch CLI** | ✅ |
113
+
114
+ ## 💡 使用建议
115
+
116
+ ### 开发环境
117
+ ```bash
118
+ # 使用普通构建,便于调试
119
+ npm run build
120
+ npm start
121
+ ```
122
+
123
+ ### 生产环境
124
+ ```bash
125
+ # 使用压缩构建,减小体积
126
+ npm run minify-build
127
+ npm start
128
+ ```
129
+
130
+ ### CI/CD 流程
131
+ ```yaml
132
+ # .github/workflows/deploy.yml
133
+ - name: Build and Minify
134
+ run: npm run minify-build
135
+
136
+ - name: Deploy
137
+ run: # 部署命令
138
+ ```
139
+
140
+ ## 🚨 注意事项
141
+
142
+ 1. **代码可读性**
143
+ - 压缩后的代码不可读
144
+ - 调试时建议使用普通构建
145
+
146
+ 2. **Source Maps**
147
+ - 当前未启用 source maps
148
+ - 如需调试,可以使用普通构建
149
+
150
+ 3. **构建时间**
151
+ - 压缩构建时间稍长(通常 < 2 秒)
152
+ - 但运行时性能不受影响
153
+
154
+ 4. **兼容性**
155
+ - 压缩不影响功能
156
+ - 所有功能与普通构建完全相同
157
+
158
+ ## 📈 性能影响
159
+
160
+ ### 构建时间
161
+ - 普通构建:~450ms
162
+ - 压缩构建:~450ms(几乎相同)
163
+
164
+ ### 运行时性能
165
+ - **无影响**:Node.js 会解析压缩代码
166
+ - **启动速度**:可能稍快(文件更小)
167
+
168
+ ### 内存占用
169
+ - **无影响**:运行时内存占用相同
170
+
171
+ ## 🎉 总结
172
+
173
+ `npm run minify-build` 提供了一个快速、简单的方式来减小生产环境的文件大小:
174
+
175
+ - ✅ **显著减小文件大小**:平均减少 30-60%
176
+ - ✅ **保持功能完整**:所有功能正常工作
177
+ - ✅ **构建快速**:与普通构建时间相近
178
+ - ✅ **易于使用**:一条命令完成所有压缩
179
+
180
+ **推荐在生产环境中使用压缩构建!** 🚀
@@ -0,0 +1,119 @@
1
+ # 多行文本输入功能实现
2
+
3
+ ## 概述
4
+
5
+ 本次更新实现了完整的多行文本输入功能,大幅提升了用户在 CLI 界面中的输入体验。
6
+
7
+ ## 核心功能
8
+
9
+ ### 1. 多行输入组件 (`src/components/multiline-text-input.jsx`)
10
+
11
+ **新增组件**,提供以下特性:
12
+
13
+ - **全程多行模式**:始终支持多行输入
14
+ - **智能换行**:
15
+ - `Enter` - 发送消息
16
+ - `Ctrl+Enter` - 插入换行
17
+ - **光标二维移动**:
18
+ - `↑/↓` - 在行之间移动
19
+ - `←/→` - 在行内移动
20
+ - `Home/End` - 跳转到行首/行尾
21
+ - **编辑功能**:
22
+ - `Backspace/Delete` - 删除字符
23
+ - `Ctrl+K` - 删除到行尾
24
+ - `Ctrl+U` - 删除到行首
25
+ - `Ctrl+L` - 清空所有内容
26
+ - **智能滚动**:自动调整视图确保光标始终可见
27
+ - **历史记录导航**:支持上下箭头浏览历史记录
28
+
29
+ ### 2. 增强输入组件集成 (`src/input/enhanced-input.jsx`)
30
+
31
+ **变更内容**:
32
+
33
+ - 从单行输入切换到多行输入组件
34
+ - 优化历史记录指示器显示
35
+ - 集成历史记录导航回调
36
+ - 默认高度设置为 10 行
37
+
38
+ ### 3. 主应用适配 (`src/closer-cli.jsx`)
39
+
40
+ **关键变更**:
41
+
42
+ - 移除父组件的方向键拦截,让多行输入组件完全处理
43
+ - 优化历史记录导航逻辑
44
+ - 改进输入区域布局(无边框,更简洁)
45
+
46
+ ### 4. UI 改进
47
+
48
+ **边框样式优化**:
49
+
50
+ - 所有面板从 `borderStyle="round"` 改为上下边框
51
+ - 减少视觉干扰,提升内容可读性
52
+ - 修改的组件:
53
+ - `Panel` 组件
54
+ - Thinking 区域
55
+ - Conversation 区域
56
+ - Task Progress 区域
57
+ - Tool Execution 区域
58
+ - 活动提示和退出提示
59
+
60
+ **全屏对话增强**:
61
+
62
+ - 新增 `Ctrl+T` 在全屏模式下切换工具显示/隐藏
63
+ - 优化底部提示信息
64
+
65
+ ## 技术实现
66
+
67
+ ### 状态管理
68
+
69
+ ```javascript
70
+ // 分行数组存储
71
+ const [lines, setLines] = useState(['']);
72
+
73
+ // 二维光标位置
74
+ const [cursorPos, setCursorPos] = useState({ row: 0, col: 0 });
75
+
76
+ // 滚动偏移
77
+ const [scrollOffset, setScrollOffset] = useState(0);
78
+ ```
79
+
80
+ ### 核心算法
81
+
82
+ 1. **光标移动**:支持跨行移动,自动调整到目标行的最大列数
83
+ 2. **智能滚动**:确保光标始终在可视区域内
84
+ 3. **历史记录同步**:使用 `useLayoutEffect` 避免循环更新
85
+
86
+ ### 快捷键映射
87
+
88
+ | 快捷键 | 功能 |
89
+ |--------|------|
90
+ | `Enter` | 发送消息 |
91
+ | `Ctrl+Enter` | 换行 |
92
+ | `↑/↓` | 光标上下移动 / 历史记录导航 |
93
+ | `←/→` | 光标左右移动 |
94
+ | `Home/End` | 跳转到行首/行尾 |
95
+ | `Ctrl+K` | 删除到行尾 |
96
+ | `Ctrl+U` | 删除到行首 |
97
+ | `Ctrl+L` | 清空所有内容 |
98
+ | `Backspace` | 删除光标前字符 |
99
+ | `Delete` | 删除光标后字符 |
100
+
101
+ ## 用户体验提升
102
+
103
+ 1. **更自然的输入**:多行编辑更接近现代编辑器体验
104
+ 2. **更清晰的界面**:简化的边框样式减少视觉干扰
105
+ 3. **更灵活的浏览**:全屏模式下可以隐藏工具记录,专注对话内容
106
+ 4. **更好的导航**:完整的光标移动控制
107
+
108
+ ## 兼容性
109
+
110
+ - 保持与现有历史记录系统的完全兼容
111
+ - 不影响其他功能(滚动、快捷键等)
112
+ - 向后兼容单行输入的使用场景
113
+
114
+ ## 未来改进方向
115
+
116
+ - 支持更多编辑器快捷键(如 Ctrl+D 删除单词)
117
+ - 添加语法高亮支持
118
+ - 支持多行复制粘贴
119
+ - 添加撤销/重做功能
@@ -0,0 +1,258 @@
1
+ # OpenAI Client 实现文档
2
+
3
+ ## 概述
4
+
5
+ 本项目已成功实现基于 `@openai/agents` SDK 的 OpenAI AI 客户端,与现有的 Anthropic SDK 实现保持一致的接口。
6
+
7
+ ## 架构设计
8
+
9
+ ### 文件结构
10
+
11
+ ```
12
+ src/
13
+ ├── ai-client.js # Anthropic 客户端实现(SDK)
14
+ ├── ai-client-openai.js # OpenAI 客户端实现(@openai/agents)✨ 新增
15
+ ├── ai-client-legacy.js # 旧版 OpenAI/Ollama 实现(已废弃)
16
+ ├── conversation.js # 对话管理器(支持多 provider)
17
+ └── tools.js # 工具定义(使用 Anthropic betaZodTool)
18
+ ```
19
+
20
+ ### 核心类:OpenAIClient
21
+
22
+ ```javascript
23
+ export class OpenAIClient {
24
+ constructor(config)
25
+ async chat(messages, options = {})
26
+ async chatStream(messages, options = {}, onChunk)
27
+ async chatWithTools(messages, tools, options = {})
28
+ async countTokens(messages)
29
+ }
30
+ ```
31
+
32
+ ## SDK 对比分析
33
+
34
+ ### Anthropic SDK vs OpenAI Agents SDK
35
+
36
+ | 特性 | Anthropic SDK (@anthropic-ai/sdk) | OpenAI Agents SDK (@openai/agents) |
37
+ |------|-----------------------------------|-------------------------------------|
38
+ | **工具定义** | `betaZodTool({ name, description, inputSchema: z.object(), run })` | `tool({ name, description, parameters: z.object(), execute })` |
39
+ | **自动工具调用循环** | `toolRunner()` | `run(agent, input)` |
40
+ | **流式响应** | `stream.on('thinking', ...)`, `stream.on('text', ...)` | 使用 OpenAI SDK 原生流式 API(无事件 API) |
41
+ | **Agent 创建** | 无(直接使用 client) | `new Agent({ name, instructions, tools })` |
42
+ | **消息格式** | `{ role, content }` (content 可为数组) | `{ role, content }` (content 为字符串) |
43
+ | **多 Agent 支持** | 无 | 支持 handoffs |
44
+
45
+ ### 关键差异说明
46
+
47
+ 1. **工具定义方式**
48
+ - **Anthropic**: 使用 `betaZodTool` 从 `@anthropic-ai/sdk/helpers/beta/zod`
49
+ - **OpenAI**: 使用 `tool` 函数从 `@openai/agents`
50
+
51
+ 2. **工具调用循环处理**
52
+ - **Anthropic**: `client.beta.messages.toolRunner()` - 自动处理工具调用和结果返回
53
+ - **OpenAI**: `run(agent, input)` - 自动执行 agent 循环,包括工具调用
54
+
55
+ 3. **流式响应处理**
56
+ - **Anthropic**: 提供事件监听器 API,可监听 `thinking`、`text`、`signature` 等事件
57
+ - **OpenAI**: 不提供流式事件 API,使用 OpenAI SDK 原生的 `stream` 方法
58
+
59
+ 4. **消息格式转换**
60
+ - **Anthropic**: content 是数组,可包含 text、tool_use、tool_result 等不同类型
61
+ - **OpenAI**: content 是字符串(简化版本)
62
+
63
+ ## 实现细节
64
+
65
+ ### 1. 消息格式转换
66
+
67
+ OpenAI 客户端实现了 `_convertMessageFormat()` 方法:
68
+
69
+ ```javascript
70
+ _convertMessageFormat(message) {
71
+ // Anthropic: { role, content } where content can be string or array
72
+ // OpenAI: { role, content } where content is string
73
+
74
+ if (typeof message.content === 'string') {
75
+ return { role: message.role, content: message.content };
76
+ }
77
+
78
+ // 提取所有文本块
79
+ if (Array.isArray(message.content)) {
80
+ const textParts = message.content
81
+ .filter(block => block.type === 'text')
82
+ .map(block => block.text)
83
+ .join('\n');
84
+
85
+ return { role: message.role, content: textParts };
86
+ }
87
+ }
88
+ ```
89
+
90
+ ### 2. 工具格式转换
91
+
92
+ OpenAI 客户端实现了 `_convertTools()` 方法:
93
+
94
+ ```javascript
95
+ _convertTools(anthropicTools) {
96
+ return anthropicTools.map(tool => ({
97
+ type: 'function',
98
+ function: {
99
+ name: tool.name,
100
+ description: tool.description,
101
+ parameters: tool.input_schema // Zod schema
102
+ }
103
+ }));
104
+ }
105
+ ```
106
+
107
+ ### 3. 流式响应处理
108
+
109
+ OpenAI 客户端使用 OpenAI SDK 原生的流式 API:
110
+
111
+ ```javascript
112
+ async chatStream(messages, options = {}, onChunk) {
113
+ const stream = await this.client.chat.completions.create({
114
+ model: this.model,
115
+ messages: formattedMessages,
116
+ tools: openaiTools,
117
+ stream: true
118
+ });
119
+
120
+ for await (const chunk of stream) {
121
+ const delta = chunk.choices[0]?.delta;
122
+
123
+ // 处理文本内容
124
+ if (delta.content) {
125
+ if (typeof onChunk === 'function') {
126
+ onChunk({
127
+ type: 'text',
128
+ delta: delta.content,
129
+ snapshot: accumulatedText
130
+ });
131
+ }
132
+ }
133
+
134
+ // 处理工具调用
135
+ if (delta.tool_calls) {
136
+ // 累积工具调用参数
137
+ }
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### 4. 工具调用循环
143
+
144
+ 使用 `@openai/agents` 的 `run()` 函数:
145
+
146
+ ```javascript
147
+ async chatWithTools(messages, tools, options = {}) {
148
+ const openaiTools = tools.map(tool => ({
149
+ name: tool.name,
150
+ description: tool.description,
151
+ parameters: tool.input_schema,
152
+ execute: tool.run
153
+ }));
154
+
155
+ const agent = new Agent({
156
+ name: 'Assistant',
157
+ instructions: system,
158
+ tools: openaiTools,
159
+ temperature: temperature
160
+ });
161
+
162
+ const result = await run(agent, input, { maxTurns: 10 });
163
+
164
+ return this._convertResponseToAnthropic(result);
165
+ }
166
+ ```
167
+
168
+ ## 兼容性设计
169
+
170
+ 为了保持与现有代码的兼容性,OpenAIClient 实现了与 AnthropicClient 相同的接口:
171
+
172
+ ```javascript
173
+ // 统一的工厂函数
174
+ export function createAIClient(config) {
175
+ const { provider, anthropic, openai, ollama } = config.ai;
176
+
177
+ switch (provider) {
178
+ case 'anthropic':
179
+ return new AnthropicClient(anthropic);
180
+ case 'openai':
181
+ return createOpenAIClient(openai); // ✨ 使用新的 OpenAI 客户端
182
+ case 'ollama':
183
+ return createOllamaClient(ollama);
184
+ }
185
+ }
186
+ ```
187
+
188
+ ## 配置示例
189
+
190
+ ```javascript
191
+ {
192
+ "ai": {
193
+ "provider": "openai",
194
+ "openai": {
195
+ "apiKey": "sk-...",
196
+ "baseURL": "https://api.openai.com/v1",
197
+ "model": "gpt-4o",
198
+ "maxTokens": 8192
199
+ }
200
+ }
201
+ }
202
+ ```
203
+
204
+ ## 依赖项
205
+
206
+ ```json
207
+ {
208
+ "dependencies": {
209
+ "@openai/agents": "^0.4.0",
210
+ "openai": "^4.73.0",
211
+ "zod": "^4.3.5"
212
+ }
213
+ }
214
+ ```
215
+
216
+ **注意**: `@openai/agents` 包目前与 `zod@3.25.68+` 不兼容,需要使用 `zod@<=3.25.67` 或使用 `--legacy-peer-deps` 安装。
217
+
218
+ ## 测试
219
+
220
+ 构建项目以验证实现:
221
+
222
+ ```bash
223
+ npm run build
224
+ node --check dist/index.js
225
+ node --check dist/closer-cli.js
226
+ ```
227
+
228
+ ## 限制与注意事项
229
+
230
+ 1. **流式响应事件**: OpenAI Agents SDK 不提供与 Anthropic SDK 相同的流式事件 API(如 `thinking` 事件),因此使用 OpenAI SDK 原生的流式 API。
231
+
232
+ 2. **Thinking 功能**: OpenAI 模型不支持 Extended Thinking 功能,因此 `thinking` 参数在 OpenAI 客户端中被忽略。
233
+
234
+ 3. **工具格式差异**: Anthropic 使用 `betaZodTool`,OpenAI 使用 `tool` 函数,需要转换格式。
235
+
236
+ 4. **Zod 版本**: 注意 `@openai/agents` 与 `zod@3.25.68+` 的兼容性问题。
237
+
238
+ ## 参考资源
239
+
240
+ - [OpenAI Agents SDK npm 包](https://www.npmjs.com/package/@openai/agents)
241
+ - [OpenAI Agents 文档](https://platform.openai.com/docs/agents)
242
+ - [Anthropic SDK 文档](https://docs.anthropic.com/en/api/client-sdks)
243
+ - [AgentKit Walkthrough](https://developers.openai.com/cookbook/examples/agentkit/agentkit_walkthrough)
244
+
245
+ ## 总结
246
+
247
+ OpenAI 客户端实现成功地将 `@openai/agents` SDK 集成到项目中,提供了与 Anthropic SDK 一致的接口,使得项目可以无缝切换不同的 AI 提供商。
248
+
249
+ **主要优势**:
250
+ - 统一的客户端接口
251
+ - 自动工具调用循环处理
252
+ - 流式响应支持
253
+ - 完整的类型安全(使用 Zod)
254
+
255
+ **未来改进方向**:
256
+ - 添加 OpenAI 特有的功能(如 structured outputs)
257
+ - 优化流式响应性能
258
+ - 添加更多错误处理和重试逻辑