xiaozhou-chat 1.0.22 → 1.0.24

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/lib/chat.js CHANGED
@@ -136,9 +136,30 @@ export async function chatStream(context, userInput = null, options = {}) {
136
136
 
137
137
  // 构造请求 Body
138
138
  const createBody = (withTools = true) => {
139
+ let safeMessages = requestMessages;
140
+
141
+ // 如果禁用工具,必须清理消息历史中的工具相关字段,否则会导致 400 错误
142
+ if (!withTools) {
143
+ safeMessages = requestMessages
144
+ .filter(m => m.role !== 'tool') // 移除工具输出
145
+ .map(m => {
146
+ if (m.role === 'assistant' && m.tool_calls) {
147
+ // 移除 tool_calls 字段
148
+ const { tool_calls, ...rest } = m;
149
+ return rest;
150
+ }
151
+ return m;
152
+ })
153
+ .filter(m => {
154
+ // 移除可能变为空的助手消息 (既没内容也没工具调用)
155
+ if (m.role === 'assistant' && !m.content) return false;
156
+ return true;
157
+ });
158
+ }
159
+
139
160
  const body = {
140
161
  model: config.model,
141
- messages: requestMessages,
162
+ messages: safeMessages,
142
163
  stream: true,
143
164
  max_tokens: 8192
144
165
  };
package/lib/config.js CHANGED
@@ -76,10 +76,33 @@ export function initProjectConfigFile() {
76
76
  console.log("🔒 建议将 .newapi-chat-config.json 添加到 .gitignore 以防泄露。");
77
77
  }
78
78
 
79
+ function sanitizeString(str) {
80
+ if (typeof str !== 'string') return str;
81
+ // Remove backticks, single quotes, double quotes (if mistakenly included inside the string) and surrounding whitespace
82
+ // But wait, removing quotes inside might be dangerous if they are part of a valid value (unlikely for URL/Key/ModelName)
83
+ // Let's stick to backticks and whitespace as seen in the user issue.
84
+ return str.replace(/`/g, '').trim();
85
+ }
86
+
87
+ function sanitizeConfigObj(obj) {
88
+ if (!obj) return obj;
89
+ if (obj.apiKey) obj.apiKey = sanitizeString(obj.apiKey);
90
+ if (obj.baseUrl) obj.baseUrl = sanitizeString(obj.baseUrl);
91
+ if (obj.model) obj.model = sanitizeString(obj.model);
92
+
93
+ if (obj.profiles) {
94
+ for (const key in obj.profiles) {
95
+ sanitizeConfigObj(obj.profiles[key]);
96
+ }
97
+ }
98
+ return obj;
99
+ }
100
+
79
101
  function loadConfigFrom(file) {
80
102
  if (!fs.existsSync(file)) return {};
81
103
  try {
82
- return JSON.parse(fs.readFileSync(file, "utf-8"));
104
+ const raw = JSON.parse(fs.readFileSync(file, "utf-8"));
105
+ return sanitizeConfigObj(raw);
83
106
  } catch {
84
107
  return {};
85
108
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xiaozhou-chat",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "description": "CLI chatbot based on NewAPI",
5
5
  "bin": {
6
6
  "xiaozhou-chat": "bin/cli.js"