@hflin/cclin 0.1.0

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 (200) hide show
  1. package/README.md +124 -0
  2. package/dist/index.d.ts +10 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +165 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/llm/client.d.ts +32 -0
  7. package/dist/llm/client.d.ts.map +1 -0
  8. package/dist/llm/client.js +280 -0
  9. package/dist/llm/client.js.map +1 -0
  10. package/dist/runtime/compaction.d.ts +49 -0
  11. package/dist/runtime/compaction.d.ts.map +1 -0
  12. package/dist/runtime/compaction.js +118 -0
  13. package/dist/runtime/compaction.js.map +1 -0
  14. package/dist/runtime/compaction.test.d.ts +7 -0
  15. package/dist/runtime/compaction.test.d.ts.map +1 -0
  16. package/dist/runtime/compaction.test.js +70 -0
  17. package/dist/runtime/compaction.test.js.map +1 -0
  18. package/dist/runtime/history.d.ts +34 -0
  19. package/dist/runtime/history.d.ts.map +1 -0
  20. package/dist/runtime/history.js +63 -0
  21. package/dist/runtime/history.js.map +1 -0
  22. package/dist/runtime/hooks.d.ts +54 -0
  23. package/dist/runtime/hooks.d.ts.map +1 -0
  24. package/dist/runtime/hooks.js +113 -0
  25. package/dist/runtime/hooks.js.map +1 -0
  26. package/dist/runtime/hooks.test.d.ts +7 -0
  27. package/dist/runtime/hooks.test.d.ts.map +1 -0
  28. package/dist/runtime/hooks.test.js +73 -0
  29. package/dist/runtime/hooks.test.js.map +1 -0
  30. package/dist/runtime/model-profile.d.ts +42 -0
  31. package/dist/runtime/model-profile.d.ts.map +1 -0
  32. package/dist/runtime/model-profile.js +84 -0
  33. package/dist/runtime/model-profile.js.map +1 -0
  34. package/dist/runtime/prompt.d.ts +38 -0
  35. package/dist/runtime/prompt.d.ts.map +1 -0
  36. package/dist/runtime/prompt.js +152 -0
  37. package/dist/runtime/prompt.js.map +1 -0
  38. package/dist/runtime/prompt.md +64 -0
  39. package/dist/runtime/prompt.test.d.ts +7 -0
  40. package/dist/runtime/prompt.test.d.ts.map +1 -0
  41. package/dist/runtime/prompt.test.js +38 -0
  42. package/dist/runtime/prompt.test.js.map +1 -0
  43. package/dist/runtime/react-loop.d.ts +82 -0
  44. package/dist/runtime/react-loop.d.ts.map +1 -0
  45. package/dist/runtime/react-loop.js +311 -0
  46. package/dist/runtime/react-loop.js.map +1 -0
  47. package/dist/runtime/react-loop.test.d.ts +7 -0
  48. package/dist/runtime/react-loop.test.d.ts.map +1 -0
  49. package/dist/runtime/react-loop.test.js +78 -0
  50. package/dist/runtime/react-loop.test.js.map +1 -0
  51. package/dist/runtime/session.d.ts +109 -0
  52. package/dist/runtime/session.d.ts.map +1 -0
  53. package/dist/runtime/session.js +252 -0
  54. package/dist/runtime/session.js.map +1 -0
  55. package/dist/runtime/skills.d.ts +36 -0
  56. package/dist/runtime/skills.d.ts.map +1 -0
  57. package/dist/runtime/skills.js +187 -0
  58. package/dist/runtime/skills.js.map +1 -0
  59. package/dist/runtime/skills.test.d.ts +7 -0
  60. package/dist/runtime/skills.test.d.ts.map +1 -0
  61. package/dist/runtime/skills.test.js +92 -0
  62. package/dist/runtime/skills.test.js.map +1 -0
  63. package/dist/tools/approval.d.ts +61 -0
  64. package/dist/tools/approval.d.ts.map +1 -0
  65. package/dist/tools/approval.js +119 -0
  66. package/dist/tools/approval.js.map +1 -0
  67. package/dist/tools/approval.test.d.ts +9 -0
  68. package/dist/tools/approval.test.d.ts.map +1 -0
  69. package/dist/tools/approval.test.js +112 -0
  70. package/dist/tools/approval.test.js.map +1 -0
  71. package/dist/tools/bash.d.ts +6 -0
  72. package/dist/tools/bash.d.ts.map +1 -0
  73. package/dist/tools/bash.js +58 -0
  74. package/dist/tools/bash.js.map +1 -0
  75. package/dist/tools/edit-file.d.ts +6 -0
  76. package/dist/tools/edit-file.d.ts.map +1 -0
  77. package/dist/tools/edit-file.js +58 -0
  78. package/dist/tools/edit-file.js.map +1 -0
  79. package/dist/tools/get-memory.d.ts +9 -0
  80. package/dist/tools/get-memory.d.ts.map +1 -0
  81. package/dist/tools/get-memory.js +56 -0
  82. package/dist/tools/get-memory.js.map +1 -0
  83. package/dist/tools/list-directory.d.ts +6 -0
  84. package/dist/tools/list-directory.d.ts.map +1 -0
  85. package/dist/tools/list-directory.js +68 -0
  86. package/dist/tools/list-directory.js.map +1 -0
  87. package/dist/tools/mcp-client.d.ts +74 -0
  88. package/dist/tools/mcp-client.d.ts.map +1 -0
  89. package/dist/tools/mcp-client.js +129 -0
  90. package/dist/tools/mcp-client.js.map +1 -0
  91. package/dist/tools/mcp-config.d.ts +31 -0
  92. package/dist/tools/mcp-config.d.ts.map +1 -0
  93. package/dist/tools/mcp-config.js +55 -0
  94. package/dist/tools/mcp-config.js.map +1 -0
  95. package/dist/tools/mcp-registry.d.ts +39 -0
  96. package/dist/tools/mcp-registry.d.ts.map +1 -0
  97. package/dist/tools/mcp-registry.js +88 -0
  98. package/dist/tools/mcp-registry.js.map +1 -0
  99. package/dist/tools/orchestrator.d.ts +52 -0
  100. package/dist/tools/orchestrator.d.ts.map +1 -0
  101. package/dist/tools/orchestrator.js +190 -0
  102. package/dist/tools/orchestrator.js.map +1 -0
  103. package/dist/tools/orchestrator.test.d.ts +8 -0
  104. package/dist/tools/orchestrator.test.d.ts.map +1 -0
  105. package/dist/tools/orchestrator.test.js +122 -0
  106. package/dist/tools/orchestrator.test.js.map +1 -0
  107. package/dist/tools/read-file.d.ts +6 -0
  108. package/dist/tools/read-file.d.ts.map +1 -0
  109. package/dist/tools/read-file.js +50 -0
  110. package/dist/tools/read-file.js.map +1 -0
  111. package/dist/tools/registry.d.ts +55 -0
  112. package/dist/tools/registry.d.ts.map +1 -0
  113. package/dist/tools/registry.js +75 -0
  114. package/dist/tools/registry.js.map +1 -0
  115. package/dist/tools/registry.test.d.ts +8 -0
  116. package/dist/tools/registry.test.d.ts.map +1 -0
  117. package/dist/tools/registry.test.js +100 -0
  118. package/dist/tools/registry.test.js.map +1 -0
  119. package/dist/tools/router.d.ts +62 -0
  120. package/dist/tools/router.d.ts.map +1 -0
  121. package/dist/tools/router.js +119 -0
  122. package/dist/tools/router.js.map +1 -0
  123. package/dist/tools/router.test.d.ts +7 -0
  124. package/dist/tools/router.test.d.ts.map +1 -0
  125. package/dist/tools/router.test.js +102 -0
  126. package/dist/tools/router.test.js.map +1 -0
  127. package/dist/tools/safety.d.ts +16 -0
  128. package/dist/tools/safety.d.ts.map +1 -0
  129. package/dist/tools/safety.js +81 -0
  130. package/dist/tools/safety.js.map +1 -0
  131. package/dist/tools/safety.test.d.ts +7 -0
  132. package/dist/tools/safety.test.d.ts.map +1 -0
  133. package/dist/tools/safety.test.js +104 -0
  134. package/dist/tools/safety.test.js.map +1 -0
  135. package/dist/tools/search-files.d.ts +9 -0
  136. package/dist/tools/search-files.d.ts.map +1 -0
  137. package/dist/tools/search-files.js +114 -0
  138. package/dist/tools/search-files.js.map +1 -0
  139. package/dist/tools/update-plan.d.ts +9 -0
  140. package/dist/tools/update-plan.d.ts.map +1 -0
  141. package/dist/tools/update-plan.js +99 -0
  142. package/dist/tools/update-plan.js.map +1 -0
  143. package/dist/tools/write-file.d.ts +6 -0
  144. package/dist/tools/write-file.d.ts.map +1 -0
  145. package/dist/tools/write-file.js +41 -0
  146. package/dist/tools/write-file.js.map +1 -0
  147. package/dist/tui/app.d.ts +31 -0
  148. package/dist/tui/app.d.ts.map +1 -0
  149. package/dist/tui/app.js +121 -0
  150. package/dist/tui/app.js.map +1 -0
  151. package/dist/tui/chatwidget/markdown_renderer.d.ts +20 -0
  152. package/dist/tui/chatwidget/markdown_renderer.d.ts.map +1 -0
  153. package/dist/tui/chatwidget/markdown_renderer.js +188 -0
  154. package/dist/tui/chatwidget/markdown_renderer.js.map +1 -0
  155. package/dist/tui/cjk_text.d.ts +25 -0
  156. package/dist/tui/cjk_text.d.ts.map +1 -0
  157. package/dist/tui/cjk_text.js +84 -0
  158. package/dist/tui/cjk_text.js.map +1 -0
  159. package/dist/tui/cjk_text.test.d.ts +2 -0
  160. package/dist/tui/cjk_text.test.d.ts.map +1 -0
  161. package/dist/tui/cjk_text.test.js +62 -0
  162. package/dist/tui/cjk_text.test.js.map +1 -0
  163. package/dist/tui/composer_input.d.ts +31 -0
  164. package/dist/tui/composer_input.d.ts.map +1 -0
  165. package/dist/tui/composer_input.js +184 -0
  166. package/dist/tui/composer_input.js.map +1 -0
  167. package/dist/tui/composer_input.test.d.ts +2 -0
  168. package/dist/tui/composer_input.test.d.ts.map +1 -0
  169. package/dist/tui/composer_input.test.js +87 -0
  170. package/dist/tui/composer_input.test.js.map +1 -0
  171. package/dist/tui/input.d.ts +21 -0
  172. package/dist/tui/input.d.ts.map +1 -0
  173. package/dist/tui/input.js +166 -0
  174. package/dist/tui/input.js.map +1 -0
  175. package/dist/tui/output.d.ts +17 -0
  176. package/dist/tui/output.d.ts.map +1 -0
  177. package/dist/tui/output.js +104 -0
  178. package/dist/tui/output.js.map +1 -0
  179. package/dist/tui/state/chat_timeline.d.ts +50 -0
  180. package/dist/tui/state/chat_timeline.d.ts.map +1 -0
  181. package/dist/tui/state/chat_timeline.js +129 -0
  182. package/dist/tui/state/chat_timeline.js.map +1 -0
  183. package/dist/tui/types.d.ts +45 -0
  184. package/dist/tui/types.d.ts.map +1 -0
  185. package/dist/tui/types.js +14 -0
  186. package/dist/tui/types.js.map +1 -0
  187. package/dist/types.d.ts +435 -0
  188. package/dist/types.d.ts.map +1 -0
  189. package/dist/types.js +8 -0
  190. package/dist/types.js.map +1 -0
  191. package/dist/utils/tokenizer.d.ts +21 -0
  192. package/dist/utils/tokenizer.d.ts.map +1 -0
  193. package/dist/utils/tokenizer.js +71 -0
  194. package/dist/utils/tokenizer.js.map +1 -0
  195. package/dist/utils/tokenizer.test.d.ts +7 -0
  196. package/dist/utils/tokenizer.test.d.ts.map +1 -0
  197. package/dist/utils/tokenizer.test.js +51 -0
  198. package/dist/utils/tokenizer.test.js.map +1 -0
  199. package/package.json +41 -0
  200. package/src/runtime/prompt.md +64 -0
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # cclin
2
+
3
+ > 从零构建的生产级 CLI Code Agent,对标 [memo-code](https://github.com/anthropics/claude-code) 架构。
4
+
5
+ 一个运行在终端里的 AI 编程助手,能读写文件、执行命令、调用 MCP 工具,在本地环境中完成软件工程任务。
6
+
7
+ ## ✨ 特性
8
+
9
+ - **ReAct 循环** — 手写 Think → Act → Observe 循环,脱离 SDK 自动编排
10
+ - **8 个内置工具** — `read_file` / `write_file` / `edit_file` / `bash` / `list_directory` / `search_files` / `update_plan` / `get_memory`
11
+ - **MCP 集成** — 通过配置文件接入任意 MCP Server 的外部工具
12
+ - **Ink TUI** — 基于 React + Ink 的终端界面,实时展示工具调用和流式输出
13
+ - **审批系统** — 危险操作自动暂停等待确认(always / once / session 三级策略)
14
+ - **上下文压缩** — 长对话自动压缩,不丢失关键上下文
15
+ - **Skills 系统** — 发现并加载 `SKILL.md` 技能文件,扩展 Agent 能力
16
+ - **Model Profile** — 不同模型的参数差异化配置
17
+ - **会话持久化** — JSONL 日志记录,支持历史回放
18
+
19
+ ## 🚀 快速开始
20
+
21
+ ```bash
22
+ # 克隆项目
23
+ git clone <repo-url> && cd cclin
24
+
25
+ # 安装依赖
26
+ pnpm install
27
+
28
+ # 配置 API Key
29
+ cp .env.example .env
30
+ # 编辑 .env,填入你的 OPENAI_API_KEY
31
+
32
+ # 启动
33
+ pnpm run dev
34
+ ```
35
+
36
+ ## ⌨️ 内置命令
37
+
38
+ | 命令 | 说明 |
39
+ |------|------|
40
+ | `/compact` | 手动压缩上下文 |
41
+ | `/retry` | 重新发送上一次输入 |
42
+ | `/approve <mode>` | 切换审批策略(`always` / `once` / `session`) |
43
+ | `Ctrl+C` | 退出 |
44
+
45
+ ## 🏗️ 架构
46
+
47
+ ```
48
+ cclin/
49
+ ├── src/
50
+ │ ├── index.ts # 入口 + TUI 桥接
51
+ │ ├── types.ts # 共享类型定义
52
+ │ ├── llm/
53
+ │ │ └── client.ts # OpenAI SDK 封装(流式/非流式)
54
+ │ ├── runtime/
55
+ │ │ ├── session.ts # 会话管理
56
+ │ │ ├── react-loop.ts # ReAct 循环引擎
57
+ │ │ ├── prompt.ts # 系统提示词组装
58
+ │ │ ├── compaction.ts # 上下文压缩
59
+ │ │ ├── hooks.ts # 生命周期 Hook 系统
60
+ │ │ ├── skills.ts # 技能发现与加载
61
+ │ │ ├── model-profile.ts # 模型参数配置
62
+ │ │ └── history.ts # JSONL 会话持久化
63
+ │ ├── tools/
64
+ │ │ ├── router.ts # 工具路由(Native + MCP)
65
+ │ │ ├── orchestrator.ts # 工具编排器
66
+ │ │ ├── approval.ts # 审批管理器
67
+ │ │ └── *.ts # 各工具实现
68
+ │ ├── tui/ # Ink TUI 组件
69
+ │ └── utils/ # 工具函数
70
+ ├── .env.example # 配置模板
71
+ ├── AGENTS.md # 项目级 Agent 指令
72
+ ├── PLAN.md # 开发路线图
73
+ └── docs/ # 学习笔记(Phase 2-10)
74
+ ```
75
+
76
+ ## ⚙️ 配置
77
+
78
+ ### 环境变量(`.env`)
79
+
80
+ | 变量 | 必填 | 默认值 | 说明 |
81
+ |------|:----:|--------|------|
82
+ | `OPENAI_API_KEY` | ✅ | — | OpenAI 兼容 API Key |
83
+ | `OPENAI_BASE_URL` | — | `https://api.openai.com/v1` | API 地址(支持 DeepSeek 等) |
84
+ | `MODEL_NAME` | — | `gpt-4o-mini` | 模型名称 |
85
+ | `CCLIN_HOME` | — | `~/.cclin` | 用户级配置目录 |
86
+
87
+ ### 扩展文件
88
+
89
+ - **`AGENTS.md`** — 放在项目根目录,包含项目级开发规范
90
+ - **`~/.cclin/SOUL.md`** — 用户人格偏好(语言、风格等)
91
+ - **`.agents/skills/*/SKILL.md`** — 技能文件
92
+ - **`mcp_config.json`** — MCP Server 配置
93
+
94
+ ## 📦 安装
95
+
96
+ **方式一:从 npm 安装(推荐)**
97
+
98
+ ```bash
99
+ npm install -g @hflin/cclin
100
+ cclin
101
+ ```
102
+
103
+ **方式二:从源码构建**
104
+
105
+ ```bash
106
+ # 编译 TypeScript
107
+ pnpm run build
108
+
109
+ # 本地全局链接
110
+ npm link
111
+ cclin
112
+ ```
113
+
114
+ ## 🧪 测试
115
+
116
+ ```bash
117
+ pnpm test # 运行所有测试
118
+ pnpm test:watch # 监视模式
119
+ pnpm typecheck # TypeScript 类型检查
120
+ ```
121
+
122
+ ## 📄 License
123
+
124
+ MIT
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @file 入口文件 — Ink TUI,通过 Session 驱动 ReAct 循环。
4
+ *
5
+ * Phase 8:从 readline REPL 升级为 Ink TUI。
6
+ * 核心改动:用 App 组件的 tuiMiddleware 替代 loggerMiddleware,
7
+ * 审批交互从 rl.question 改为 App 组件的审批 UI。
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;GAMG"}
package/dist/index.js ADDED
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @file 入口文件 — Ink TUI,通过 Session 驱动 ReAct 循环。
4
+ *
5
+ * Phase 8:从 readline REPL 升级为 Ink TUI。
6
+ * 核心改动:用 App 组件的 tuiMiddleware 替代 loggerMiddleware,
7
+ * 审批交互从 rl.question 改为 App 组件的审批 UI。
8
+ */
9
+ import React from 'react';
10
+ import { render } from 'ink';
11
+ import dotenv from 'dotenv';
12
+ import { createCallLLM } from './llm/client.js';
13
+ import { Session } from './runtime/session.js';
14
+ import { ApprovalManager } from './tools/approval.js';
15
+ import { ToolOrchestrator } from './tools/orchestrator.js';
16
+ import { ToolRouter } from './tools/router.js';
17
+ import { loadMcpConfig } from './tools/mcp-config.js';
18
+ import { loadSystemPrompt } from './runtime/prompt.js';
19
+ import { createTokenCounter } from './utils/tokenizer.js';
20
+ import { readFileTool } from './tools/read-file.js';
21
+ import { writeFileTool } from './tools/write-file.js';
22
+ import { editFileTool } from './tools/edit-file.js';
23
+ import { bashTool } from './tools/bash.js';
24
+ import { listDirectoryTool } from './tools/list-directory.js';
25
+ import { updatePlanTool } from './tools/update-plan.js';
26
+ import { getMemoryTool } from './tools/get-memory.js';
27
+ import { searchFilesTool } from './tools/search-files.js';
28
+ import { loadSkills, renderSkillsSection } from './runtime/skills.js';
29
+ import { App } from './tui/app.js';
30
+ // 加载 .env 环境变量
31
+ dotenv.config();
32
+ const apiKey = process.env.OPENAI_API_KEY;
33
+ const baseURL = process.env.OPENAI_BASE_URL ?? 'https://api.openai.com/v1';
34
+ const model = process.env.MODEL_NAME ?? 'gpt-4o-mini';
35
+ if (!apiKey) {
36
+ console.error('❌ Missing OPENAI_API_KEY in .env');
37
+ process.exit(1);
38
+ }
39
+ // 使用 async IIFE 包裹启动逻辑
40
+ ;
41
+ (async () => {
42
+ // 创建工具路由器(统一管理内置 + MCP 工具)
43
+ const router = new ToolRouter();
44
+ router.registerNativeTools([
45
+ readFileTool,
46
+ writeFileTool,
47
+ editFileTool,
48
+ bashTool,
49
+ listDirectoryTool,
50
+ updatePlanTool,
51
+ getMemoryTool,
52
+ searchFilesTool,
53
+ ]);
54
+ // 加载 MCP 配置并连接 MCP Server
55
+ const mcpConfig = await loadMcpConfig();
56
+ if (Object.keys(mcpConfig).length > 0) {
57
+ await router.loadMcpServers(mcpConfig);
58
+ }
59
+ // 创建 LLM 调用函数
60
+ const callLLM = createCallLLM({
61
+ apiKey,
62
+ baseURL,
63
+ model,
64
+ tools: router.toOpenAITools(),
65
+ });
66
+ // 创建审批管理器和工具编排器
67
+ const approvalManager = new ApprovalManager({ policy: 'once' });
68
+ const orchestrator = new ToolOrchestrator(router, approvalManager);
69
+ // 加载 Skills
70
+ const skills = await loadSkills({ cwd: process.cwd() });
71
+ const skillsText = renderSkillsSection(skills) ?? undefined;
72
+ // 动态加载系统提示词
73
+ const systemPrompt = await loadSystemPrompt({
74
+ cwd: process.cwd(),
75
+ toolsText: router.toMarkdown(),
76
+ skillsText,
77
+ });
78
+ // 创建 Token 计数器
79
+ const tokenCounter = createTokenCounter();
80
+ // ─── TUI 桥接 ────────────────────────────────────────────────────────────
81
+ // Session 需要 middleware,但 middleware 来自已渲染的 App 组件。
82
+ // 解法:先渲染 App → App 回传 middleware → 再创建 Session。
83
+ // Session 通过 ref 延迟绑定,onSubmit 闭包引用 ref。
84
+ let session = null;
85
+ let requestApprovalFn = null;
86
+ let onAssistantChunkFn = null;
87
+ let lastInput = '';
88
+ const handleSubmit = async (input) => {
89
+ if (!session)
90
+ return;
91
+ // /compact 命令
92
+ if (input === '/compact') {
93
+ await session.compactHistory('manual');
94
+ return;
95
+ }
96
+ // /approve 命令
97
+ if (input.startsWith('/approve')) {
98
+ const mode = input.split(' ')[1]?.toLowerCase();
99
+ if (['always', 'once', 'session'].includes(mode ?? '')) {
100
+ approvalManager.policy = mode;
101
+ }
102
+ return;
103
+ }
104
+ // /retry 命令 — 重新发送上一次用户输入
105
+ if (input === '/retry') {
106
+ if (!lastInput)
107
+ return;
108
+ await session.runTurn(lastInput);
109
+ return;
110
+ }
111
+ lastInput = input;
112
+ await session.runTurn(input);
113
+ };
114
+ const handleExit = () => {
115
+ tokenCounter.dispose();
116
+ router.dispose().catch(() => { });
117
+ };
118
+ const handleMiddlewareReady = (mw) => {
119
+ // Session 在中间件就绪后创建
120
+ session = new Session({
121
+ callLLM,
122
+ systemPrompt,
123
+ executeTool: orchestrator.createExecuteTool({
124
+ requestApproval: (req) => {
125
+ if (!requestApprovalFn)
126
+ return Promise.resolve('deny');
127
+ return requestApprovalFn(req);
128
+ },
129
+ }),
130
+ tokenCounter,
131
+ contextWindow: 128_000,
132
+ compactThreshold: 80,
133
+ middlewares: [mw],
134
+ clearApprovalsFn: () => orchestrator.clearOnceApprovals(),
135
+ onAssistantChunk: (step, chunk) => {
136
+ if (onAssistantChunkFn)
137
+ onAssistantChunkFn(step, chunk);
138
+ },
139
+ });
140
+ };
141
+ const handleApprovalReady = (fn) => {
142
+ requestApprovalFn = fn;
143
+ };
144
+ const handleAssistantChunkReady = (fn) => {
145
+ onAssistantChunkFn = fn;
146
+ };
147
+ // 渲染 Ink TUI
148
+ const app = render(React.createElement(App, {
149
+ model,
150
+ baseURL,
151
+ toolCount: router.getToolCount().total,
152
+ approvalPolicy: approvalManager.policy,
153
+ cwd: process.cwd(),
154
+ onSubmit: handleSubmit,
155
+ onExit: handleExit,
156
+ onMiddlewareReady: handleMiddlewareReady,
157
+ onApprovalReady: handleApprovalReady,
158
+ onAssistantChunkReady: handleAssistantChunkReady,
159
+ }), { exitOnCtrlC: true });
160
+ await app.waitUntilExit();
161
+ })().catch((err) => {
162
+ console.error(`❌ Startup failed: ${err.message}`);
163
+ process.exit(1);
164
+ });
165
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @file LLM 客户端 — 将 OpenAI SDK 封装为 CallLLM 接口。
3
+ *
4
+ * 设计:工厂函数 `createCallLLM(config)` 返回一个 `CallLLM`。
5
+ * 这使得 LLM 依赖可注入且可测试。
6
+ */
7
+ import type { CallLLM } from '../types.js';
8
+ export type LLMClientConfig = {
9
+ apiKey: string;
10
+ baseURL: string;
11
+ model: string;
12
+ /** OpenAI function calling tools(可选,Phase 3+)。 */
13
+ tools?: Array<{
14
+ type: 'function';
15
+ function: {
16
+ name: string;
17
+ description: string;
18
+ parameters: Record<string, unknown>;
19
+ };
20
+ }>;
21
+ };
22
+ /**
23
+ * 创建一个绑定指定配置的 `CallLLM` 函数。
24
+ *
25
+ * 用法:
26
+ * ```ts
27
+ * const callLLM = createCallLLM({ apiKey, baseURL, model })
28
+ * const response = await callLLM(messages)
29
+ * ```
30
+ */
31
+ export declare function createCallLLM(config: LLMClientConfig): CallLLM;
32
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/llm/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACR,OAAO,EAIV,MAAM,aAAa,CAAA;AAQpB,MAAM,MAAM,eAAe,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,KAAK,CAAC,EAAE,KAAK,CAAC;QACV,IAAI,EAAE,UAAU,CAAA;QAChB,QAAQ,EAAE;YACN,IAAI,EAAE,MAAM,CAAA;YACZ,WAAW,EAAE,MAAM,CAAA;YACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SACtC,CAAA;KACJ,CAAC,CAAA;CACL,CAAA;AA+DD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CA8N9D"}
@@ -0,0 +1,280 @@
1
+ /**
2
+ * @file LLM 客户端 — 将 OpenAI SDK 封装为 CallLLM 接口。
3
+ *
4
+ * 设计:工厂函数 `createCallLLM(config)` 返回一个 `CallLLM`。
5
+ * 这使得 LLM 依赖可注入且可测试。
6
+ */
7
+ import OpenAI from 'openai';
8
+ import { resolveModelProfile, buildChatCompletionRequest, } from '../runtime/model-profile.js';
9
+ // ─── 内部工具函数 ───────────────────────────────────────────────────────────────
10
+ /**
11
+ * 将 ChatMessage 转换为 OpenAI SDK 消息格式。
12
+ */
13
+ function toOpenAIMessage(msg) {
14
+ if (msg.role === 'assistant') {
15
+ return {
16
+ role: 'assistant',
17
+ content: msg.content,
18
+ tool_calls: msg.tool_calls?.map((tc) => ({
19
+ id: tc.id,
20
+ type: tc.type,
21
+ function: {
22
+ name: tc.function.name,
23
+ arguments: tc.function.arguments,
24
+ },
25
+ })),
26
+ };
27
+ }
28
+ if (msg.role === 'tool') {
29
+ return {
30
+ role: 'tool',
31
+ content: msg.content,
32
+ tool_call_id: msg.tool_call_id,
33
+ };
34
+ }
35
+ // system | user 角色
36
+ return { role: msg.role, content: msg.content };
37
+ }
38
+ /**
39
+ * 安全地解析工具调用的 JSON 参数。
40
+ */
41
+ function parseToolArguments(raw) {
42
+ try {
43
+ return { ok: true, data: JSON.parse(raw) };
44
+ }
45
+ catch (err) {
46
+ return { ok: false, error: err.message };
47
+ }
48
+ }
49
+ /**
50
+ * 从响应中提取 reasoning_content(DeepSeek 思考模型)。
51
+ */
52
+ function extractReasoningContent(message) {
53
+ const raw = message
54
+ ?.reasoning_content;
55
+ if (typeof raw !== 'string')
56
+ return undefined;
57
+ const trimmed = raw.trim();
58
+ return trimmed.length > 0 ? trimmed : undefined;
59
+ }
60
+ // ─── 工厂函数 ──────────────────────────────────────────────────────────────────
61
+ /**
62
+ * 创建一个绑定指定配置的 `CallLLM` 函数。
63
+ *
64
+ * 用法:
65
+ * ```ts
66
+ * const callLLM = createCallLLM({ apiKey, baseURL, model })
67
+ * const response = await callLLM(messages)
68
+ * ```
69
+ */
70
+ export function createCallLLM(config) {
71
+ const client = new OpenAI({
72
+ apiKey: config.apiKey,
73
+ baseURL: config.baseURL,
74
+ timeout: 60000, // 60s timeout to prevent infinite API hangs
75
+ maxRetries: 1, // fail fast
76
+ });
77
+ return async (messages, onChunk) => {
78
+ // 1. 转换消息格式
79
+ const openAIMessages = messages.map(toOpenAIMessage);
80
+ // 2. 构建请求(使用 model profile)
81
+ const profile = resolveModelProfile(config.model);
82
+ const requestParams = buildChatCompletionRequest({
83
+ model: config.model,
84
+ messages: openAIMessages,
85
+ tools: config.tools,
86
+ profile,
87
+ });
88
+ // ─── 流式模式 ─────────────────────────────────────────────
89
+ if (onChunk) {
90
+ const IDLE_TIMEOUT_MS = 60_000;
91
+ const STALL_TIMEOUT_MS = 120_000; // no meaningful content for 2 min → stalled
92
+ let stream;
93
+ try {
94
+ stream = await client.chat.completions.create({
95
+ ...requestParams,
96
+ stream: true,
97
+ });
98
+ }
99
+ catch (err) {
100
+ throw err;
101
+ }
102
+ let textContent = '';
103
+ let reasoningContent = '';
104
+ const toolCallDeltas = new Map();
105
+ let promptTokens = 0;
106
+ let completionTokens = 0;
107
+ let totalTokens = 0;
108
+ // Use manual async iterator + Promise.race for reliable idle timeout
109
+ const iterator = stream[Symbol.asyncIterator]();
110
+ let lastMeaningfulAt = Date.now();
111
+ let done = false;
112
+ while (!done) {
113
+ let timer;
114
+ const timeoutPromise = new Promise((_, reject) => {
115
+ timer = setTimeout(() => reject(new Error('LLM Stream idle timeout (>60s)')), IDLE_TIMEOUT_MS);
116
+ });
117
+ let result;
118
+ try {
119
+ result = await Promise.race([
120
+ iterator.next(),
121
+ timeoutPromise,
122
+ ]);
123
+ }
124
+ catch (err) {
125
+ // Timeout or other error — try to close the stream
126
+ try {
127
+ await iterator.return?.();
128
+ }
129
+ catch { /* ignore */ }
130
+ throw err;
131
+ }
132
+ finally {
133
+ if (timer)
134
+ clearTimeout(timer);
135
+ }
136
+ if (result.done) {
137
+ done = true;
138
+ break;
139
+ }
140
+ const chunk = result.value;
141
+ const delta = chunk.choices?.[0]?.delta;
142
+ // 文本 delta
143
+ if (delta?.content) {
144
+ textContent += delta.content;
145
+ onChunk(delta.content);
146
+ lastMeaningfulAt = Date.now();
147
+ }
148
+ // Reasoning delta (DeepSeek / proxy extensions)
149
+ const rd = delta
150
+ ?.reasoning_content;
151
+ if (rd) {
152
+ reasoningContent += rd;
153
+ if (onChunk)
154
+ onChunk(rd);
155
+ lastMeaningfulAt = Date.now();
156
+ }
157
+ // Tool call deltas(增量拼接)
158
+ if (delta?.tool_calls) {
159
+ lastMeaningfulAt = Date.now();
160
+ for (const tc of delta.tool_calls) {
161
+ const existing = toolCallDeltas.get(tc.index);
162
+ if (existing) {
163
+ existing.args += tc.function?.arguments ?? '';
164
+ }
165
+ else {
166
+ toolCallDeltas.set(tc.index, {
167
+ id: tc.id ?? '',
168
+ name: tc.function?.name ?? '',
169
+ args: tc.function?.arguments ?? '',
170
+ });
171
+ }
172
+ }
173
+ }
174
+ // Stall detection: stream alive but no meaningful content
175
+ if (Date.now() - lastMeaningfulAt > STALL_TIMEOUT_MS) {
176
+ try {
177
+ await iterator.return?.();
178
+ }
179
+ catch { /* ignore */ }
180
+ throw new Error('LLM Stream stalled: no meaningful content for >120s');
181
+ }
182
+ // Usage(最后一个 chunk 包含)
183
+ if (chunk.usage) {
184
+ promptTokens = chunk.usage.prompt_tokens ?? 0;
185
+ completionTokens = chunk.usage.completion_tokens ?? 0;
186
+ totalTokens = chunk.usage.total_tokens ?? 0;
187
+ }
188
+ }
189
+ // 组装最终响应
190
+ const content = [];
191
+ const toolBlocks = Array.from(toolCallDeltas.values());
192
+ if (toolBlocks.length > 0) {
193
+ if (textContent)
194
+ content.push({ type: 'text', text: textContent });
195
+ for (const tb of toolBlocks) {
196
+ const parsed = parseToolArguments(tb.args);
197
+ if (parsed.ok) {
198
+ content.push({
199
+ type: 'tool_use',
200
+ id: tb.id,
201
+ name: tb.name,
202
+ input: parsed.data,
203
+ });
204
+ }
205
+ else {
206
+ content.push({
207
+ type: 'text',
208
+ text: `[tool parse error] ${parsed.error}`,
209
+ });
210
+ }
211
+ }
212
+ }
213
+ else {
214
+ content.push({ type: 'text', text: textContent });
215
+ }
216
+ const hasToolUse = content.some(c => c.type === 'tool_use');
217
+ return {
218
+ content,
219
+ reasoning_content: reasoningContent.trim() || undefined,
220
+ stop_reason: hasToolUse ? 'tool_use' : 'end_turn',
221
+ usage: {
222
+ prompt: promptTokens,
223
+ completion: completionTokens,
224
+ total: totalTokens,
225
+ },
226
+ };
227
+ }
228
+ // ─── 非流式模式(向后兼容) ────────────────────────────────
229
+ const data = await client.chat.completions.create({
230
+ ...requestParams,
231
+ stream: false,
232
+ });
233
+ const choice = data.choices?.[0];
234
+ const message = choice?.message;
235
+ const reasoningContent = extractReasoningContent(message);
236
+ const usage = {
237
+ prompt: data.usage?.prompt_tokens,
238
+ completion: data.usage?.completion_tokens,
239
+ total: data.usage?.total_tokens,
240
+ };
241
+ const content = [];
242
+ if (message?.tool_calls && message.tool_calls.length > 0) {
243
+ if (message.content) {
244
+ content.push({ type: 'text', text: message.content });
245
+ }
246
+ for (const tc of message.tool_calls) {
247
+ if (tc.type === 'function') {
248
+ const parsed = parseToolArguments(tc.function.arguments);
249
+ if (parsed.ok) {
250
+ content.push({
251
+ type: 'tool_use',
252
+ id: tc.id,
253
+ name: tc.function.name,
254
+ input: parsed.data,
255
+ });
256
+ }
257
+ else {
258
+ content.push({
259
+ type: 'text',
260
+ text: `[tool parse error] ${parsed.error}`,
261
+ });
262
+ }
263
+ }
264
+ }
265
+ }
266
+ else {
267
+ const text = message?.content ?? '';
268
+ content.push({ type: 'text', text });
269
+ }
270
+ const hasToolUse = content.some((c) => c.type === 'tool_use');
271
+ const response = {
272
+ content,
273
+ reasoning_content: reasoningContent,
274
+ stop_reason: hasToolUse ? 'tool_use' : 'end_turn',
275
+ usage,
276
+ };
277
+ return response;
278
+ };
279
+ }
280
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/llm/client.ts"],"names":[],"mappings":"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"}