@raolin2025/claude-code-node 2.2.0 → 2.2.2
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.
- package/package.json +1 -1
- package/src/core/query-engine.js +30 -15
- package/src/core/streaming.js +11 -1
- package/src/types/index.js +3 -1
package/package.json
CHANGED
package/src/core/query-engine.js
CHANGED
|
@@ -114,12 +114,12 @@ export class QueryEngine {
|
|
|
114
114
|
// 没有工具调用 → 最终回复
|
|
115
115
|
if (!response.toolCalls || response.toolCalls.length === 0) {
|
|
116
116
|
finalResponse = response.content
|
|
117
|
-
this.state.messages.push(new AssistantMessage(response.content))
|
|
117
|
+
this.state.messages.push(new AssistantMessage(response.content, [], response.reasoningContent))
|
|
118
118
|
break
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
// 有工具调用 → 记录 assistant 消息(含 tool_calls)
|
|
122
|
-
this.state.messages.push(new AssistantMessage(response.content, response.toolCalls))
|
|
122
|
+
this.state.messages.push(new AssistantMessage(response.content, response.toolCalls, response.reasoningContent))
|
|
123
123
|
|
|
124
124
|
// 执行工具
|
|
125
125
|
const toolResults = await this._executeToolCalls(response.toolCalls)
|
|
@@ -168,21 +168,27 @@ export class QueryEngine {
|
|
|
168
168
|
} else if (msg.role === 'user') {
|
|
169
169
|
request.push({ role: 'user', content: this._formatContent(msg.content) })
|
|
170
170
|
} else if (msg.role === 'assistant') {
|
|
171
|
-
//
|
|
171
|
+
// 构建 assistant 消息基础
|
|
172
|
+
const asstMsg = {
|
|
173
|
+
role: 'assistant',
|
|
174
|
+
content: msg.content || null,
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// DeepSeek thinking mode: 必须传回 reasoning_content (tool call 场景)
|
|
178
|
+
if (msg.reasoningContent) {
|
|
179
|
+
asstMsg.reasoning_content = msg.reasoningContent
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// tool_calls
|
|
172
183
|
if (msg.toolCalls && msg.toolCalls.length > 0) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
type: 'function',
|
|
179
|
-
function: { name: tc.name, arguments: typeof tc.input === 'string' ? tc.input : JSON.stringify(tc.input) },
|
|
180
|
-
})),
|
|
181
|
-
})
|
|
182
|
-
} else {
|
|
183
|
-
// 纯文本 assistant 消息
|
|
184
|
-
request.push({ role: 'assistant', content: this._formatContent(msg.content) })
|
|
184
|
+
asstMsg.tool_calls = msg.toolCalls.map(tc => ({
|
|
185
|
+
id: tc.id,
|
|
186
|
+
type: 'function',
|
|
187
|
+
function: { name: tc.name, arguments: typeof tc.input === 'string' ? tc.input : JSON.stringify(tc.input) },
|
|
188
|
+
}))
|
|
185
189
|
}
|
|
190
|
+
|
|
191
|
+
request.push(asstMsg)
|
|
186
192
|
} else if (msg.role === 'tool') {
|
|
187
193
|
// tool 结果消息 — 直接透传
|
|
188
194
|
request.push({
|
|
@@ -287,6 +293,8 @@ export class QueryEngine {
|
|
|
287
293
|
}))
|
|
288
294
|
|
|
289
295
|
const useStream = !this.config.noStream
|
|
296
|
+
const modelLower = this.config.model.toLowerCase()
|
|
297
|
+
|
|
290
298
|
const body = {
|
|
291
299
|
model: this.config.model,
|
|
292
300
|
messages,
|
|
@@ -295,6 +303,13 @@ export class QueryEngine {
|
|
|
295
303
|
...(useStream && { stream: true }),
|
|
296
304
|
}
|
|
297
305
|
|
|
306
|
+
// DeepSeek V4: 默认启用 thinking mode → 要求回传 reasoning_content
|
|
307
|
+
// 这里显式关闭,避免 tool call 场景下的 400 错误
|
|
308
|
+
// thinking 参数是 DeepSeek 私有扩展,直接放在 body 顶层
|
|
309
|
+
if (modelLower.startsWith('deepseek-v')) {
|
|
310
|
+
body.thinking = { type: 'disabled' }
|
|
311
|
+
}
|
|
312
|
+
|
|
298
313
|
const url = apiBase.replace(/\/+$/, '') + '/chat/completions'
|
|
299
314
|
|
|
300
315
|
// H3 修复:SSRF 防护 — 在 fetch 之前检查 API 主机名
|
package/src/core/streaming.js
CHANGED
|
@@ -16,6 +16,7 @@ export async function* parseStream(response) {
|
|
|
16
16
|
|
|
17
17
|
const result = {
|
|
18
18
|
content: '',
|
|
19
|
+
reasoningContent: '',
|
|
19
20
|
toolCalls: [],
|
|
20
21
|
usage: { input_tokens: 0, output_tokens: 0 },
|
|
21
22
|
}
|
|
@@ -40,6 +41,11 @@ export async function* parseStream(response) {
|
|
|
40
41
|
|
|
41
42
|
if (!delta) continue
|
|
42
43
|
|
|
44
|
+
// reasoning_content (DeepSeek thinking mode)
|
|
45
|
+
if (delta.reasoning_content) {
|
|
46
|
+
result.reasoningContent += delta.reasoning_content
|
|
47
|
+
}
|
|
48
|
+
|
|
43
49
|
// 文本
|
|
44
50
|
if (delta.content) {
|
|
45
51
|
result.content += delta.content
|
|
@@ -95,13 +101,17 @@ export async function* parseStream(response) {
|
|
|
95
101
|
* 解析非流式响应
|
|
96
102
|
*/
|
|
97
103
|
export function parseNonStreamResponse(data) {
|
|
98
|
-
const result = { content: '', toolCalls: [], usage: {} }
|
|
104
|
+
const result = { content: '', reasoningContent: '', toolCalls: [], usage: {} }
|
|
99
105
|
const choice = data.choices?.[0]
|
|
100
106
|
|
|
101
107
|
if (choice?.message?.content) {
|
|
102
108
|
result.content = choice.message.content
|
|
103
109
|
}
|
|
104
110
|
|
|
111
|
+
if (choice?.message?.reasoning_content) {
|
|
112
|
+
result.reasoningContent = choice.message.reasoning_content
|
|
113
|
+
}
|
|
114
|
+
|
|
105
115
|
for (const tc of (choice?.message?.tool_calls || [])) {
|
|
106
116
|
let input = {}
|
|
107
117
|
try { input = JSON.parse(tc.function.arguments) } catch {}
|
package/src/types/index.js
CHANGED
|
@@ -31,9 +31,11 @@ export class UserMessage extends Message {
|
|
|
31
31
|
|
|
32
32
|
export class AssistantMessage extends Message {
|
|
33
33
|
toolCalls
|
|
34
|
-
|
|
34
|
+
reasoningContent
|
|
35
|
+
constructor(content, toolCalls = [], reasoningContent = '') {
|
|
35
36
|
super(Role.ASSISTANT, content)
|
|
36
37
|
this.toolCalls = toolCalls
|
|
38
|
+
this.reasoningContent = reasoningContent
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
|