xiaozuoassistant 0.2.56 → 0.2.57

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.
@@ -78,6 +78,7 @@ export class Brain {
78
78
  if (process.env.DEBUG)
79
79
  console.log('[Brain] Calling LLM...');
80
80
  let response = await this.callLLM(messages, newMessage);
81
+ const fsToolOutcomes = [];
81
82
  // Log only the content snippet to avoid flooding logs with full JSON
82
83
  const contentSnippet = response.choices[0].message.content ? response.choices[0].message.content.substring(0, 100) + '...' : 'No content';
83
84
  if (process.env.DEBUG)
@@ -105,9 +106,24 @@ export class Brain {
105
106
  : undefined;
106
107
  const result = await skill.execute(functionArgs, ctxForTool);
107
108
  toolResult = JSON.stringify(result);
109
+ if (functionName.startsWith('fs_')) {
110
+ const isErrorString = typeof result === 'string' && /^error/i.test(result.trim());
111
+ fsToolOutcomes.push({
112
+ name: functionName,
113
+ success: !isErrorString,
114
+ error: isErrorString ? String(result) : undefined
115
+ });
116
+ }
108
117
  }
109
118
  catch (error) {
110
119
  toolResult = JSON.stringify({ error: error.message });
120
+ if (functionName.startsWith('fs_')) {
121
+ fsToolOutcomes.push({
122
+ name: functionName,
123
+ success: false,
124
+ error: String(error?.message || error)
125
+ });
126
+ }
111
127
  }
112
128
  }
113
129
  else {
@@ -132,6 +148,17 @@ export class Brain {
132
148
  }
133
149
  const hitLimit = Boolean(response.choices[0].message.tool_calls) && iterations >= MAX_ITERATIONS;
134
150
  const finalContent = response.choices[0].message.content || 'I could not generate a response.';
151
+ // Hard guard: avoid fabricated "file read success" responses when fs tool didn't actually succeed.
152
+ const hasExplicitPath = /\/[\w\-./\\]+|\.\w{1,8}\b/.test(newMessage);
153
+ const asksFileAction = /(读取|读一下|打开|查看|列出|目录|文件|read|open|list|ls|cat)/i.test(newMessage);
154
+ if (hasExplicitPath && asksFileAction) {
155
+ const fsSuccess = fsToolOutcomes.some(x => x.success);
156
+ if (!fsSuccess) {
157
+ const lastFsError = [...fsToolOutcomes].reverse().find(x => !x.success)?.error;
158
+ const ws = effectiveWorkspace || '(not set)';
159
+ return `未能实际读取文件:文件工具未成功执行。\n当前会话 workspace:${ws}\n${lastFsError ? `工具错误:${lastFsError}` : '请确认目标路径在当前 workspace 内,或先切换会话 workspace 后重试。'}`;
160
+ }
161
+ }
135
162
  if (process.env.DEBUG)
136
163
  console.log('[Brain] Final Response (snippet):', finalContent.substring(0, 100) + '...');
137
164
  if (!hitLimit)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xiaozuoassistant",
3
- "version": "0.2.56",
3
+ "version": "0.2.57",
4
4
  "description": "A local-first personal AI assistant with multi-channel support and enhanced memory.",
5
5
  "author": "mantle.lau",
6
6
  "license": "MIT",