@raolin2025/claude-code-node 2.8.7 → 2.8.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raolin2025/claude-code-node",
3
- "version": "2.8.7",
3
+ "version": "2.8.9",
4
4
  "description": "Node.js AI Code Agent CLI - Zero dependencies, pure JavaScript, security hardened, multi-channel notifications, Telegram & QQ Bot remote programming, rich media upload, multi-account management",
5
5
  "type": "module",
6
6
  "main": "src/core/index.js",
package/src/core/cli.js CHANGED
@@ -732,9 +732,19 @@ const systemPrompt = cliArgs.systemPrompt || DEFAULT_SYSTEM_PROMPT
732
732
  case 'window': {
733
733
  const arg = rest[0] ? rest.join(' ').trim() : ''
734
734
  if (!arg) {
735
- // 无参数:显示当前窗口
735
+ // 无参数:显示当前窗口 + 真实 context 用量
736
+ // 用实时估算(estimateMessages)反映"当前 context 填充了多少窗口",
737
+ // 而非依赖 usage 上报的 inputTokens——本地网关不返回 usage 时
738
+ // inputTokens 恒为 0,无法反映真实填充情况。
739
+ const estTokens = engine.tokenBudget.estimateMessages(engine.state.messages)
740
+ const windowTokens = engine.tokenBudget.maxTokens
741
+ const reserved = engine.tokenBudget.reservedForOutput || 0
742
+ const pct = windowTokens > 0
743
+ ? Math.min(100, Math.round((estTokens / (windowTokens - reserved)) * 100))
744
+ : 0
736
745
  console.log(`Context window: ${formatTokens(tokenBudget.maxTokens)} (${windowSourceLabel(windowSource)})`)
737
- console.log(` Input used: ${tokenBudget.inputTokens.toLocaleString()} / ${tokenBudget.maxTokens.toLocaleString()} (${tokenBudget.usagePercent}%)`)
746
+ console.log(` Context used: ${estTokens.toLocaleString()} / ${windowTokens.toLocaleString()} (${pct}% of usable window)`)
747
+ console.log(` (real-time estimate; API-reported input: ${tokenBudget.inputTokens.toLocaleString()} tok)`)
738
748
  const manual = config.get('maxBudgetTokens') || 0
739
749
  if (manual > 0) console.log(` Manual override: ${formatTokens(manual)} (persisted in config)`)
740
750
  break
@@ -893,6 +903,11 @@ const systemPrompt = cliArgs.systemPrompt || DEFAULT_SYSTEM_PROMPT
893
903
  break
894
904
  case 'budget': {
895
905
  console.log(tokenBudget.format())
906
+ // 追加实时估算的 context 用量(本地网关不返回 usage 时 inputTokens 为 0,无法反映真实填充)
907
+ const estTokens = engine.tokenBudget.estimateMessages(engine.state.messages)
908
+ const winTk = engine.tokenBudget.maxTokens
909
+ const pct = winTk > 0 ? Math.min(100, Math.round((estTokens / winTk) * 100)) : 0
910
+ console.log(` Context (est): ${estTokens.toLocaleString()} / ${winTk.toLocaleString()} (${pct}% of window)`)
896
911
  console.log(`Context window: ${formatTokens(tokenBudget.maxTokens)} (${windowSourceLabel(windowSource)}) | trigger: ${Math.round((tokenBudget.maxTokens * 0.8)).toLocaleString()} (80%)`)
897
912
  break
898
913
  }
@@ -356,6 +356,20 @@ export class QueryEngine {
356
356
  ...(useStream && { stream: true }),
357
357
  }
358
358
 
359
+ // [debug] 打印实际发送请求的关键信息,用于排查"模型为何不调用工具"
360
+ if (this.config.verbose) {
361
+ const sysCount = messages.filter(m => m.role === 'system').length
362
+ const toolCallsInHistory = messages.filter(m => m.role === 'assistant' && m.tool_calls).length
363
+ console.error(`[debug] → ${url}`)
364
+ console.error(`[debug] model=${body.model} | messages=${messages.length} (system=${sysCount}, user=${messages.filter(m=>m.role==='user').length}, assistant=${messages.filter(m=>m.role==='assistant').length}, tool=${messages.filter(m=>m.role==='tool').length}) | tools=${tools.length} | max_tokens=${body.max_tokens}`)
365
+ console.error(`[debug] history tool_calls=${toolCallsInHistory} | 首条=${messages[0]?.role}:${String(messages[0]?.content).slice(0,40)} | 末条=${messages[messages.length-1]?.role}:${String(messages[messages.length-1]?.content).slice(0,40)}`)
366
+ if (tools.length) {
367
+ console.error(`[debug] 工具名: ${tools.map(t=>t.function.name).join(', ')}`)
368
+ } else {
369
+ console.error(`[debug] ⚠️ tools 为空!请求未携带工具定义,模型不会调用工具`)
370
+ }
371
+ }
372
+
359
373
  // DeepSeek V4: 默认启用 thinking mode → 要求回传 reasoning_content
360
374
  // 这里显式关闭,避免 tool call 场景下的 400 错误
361
375
  // thinking 参数是 DeepSeek 私有扩展,直接放在 body 顶层