xiaozuoassistant 0.2.56 → 0.2.58
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/dist/server/core/brain.js +41 -0
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import { config } from '../config/loader.js';
|
|
|
2
2
|
import { skillRegistry } from '../skills/registry.js';
|
|
3
3
|
import { SYSTEM_PROMPT } from '../config/prompts.js';
|
|
4
4
|
import { createOpenAIClient } from '../llm/openai.js';
|
|
5
|
+
import path from 'path';
|
|
5
6
|
export class Brain {
|
|
6
7
|
constructor() {
|
|
7
8
|
this.openai = createOpenAIClient(config.llm);
|
|
@@ -78,6 +79,7 @@ export class Brain {
|
|
|
78
79
|
if (process.env.DEBUG)
|
|
79
80
|
console.log('[Brain] Calling LLM...');
|
|
80
81
|
let response = await this.callLLM(messages, newMessage);
|
|
82
|
+
const fsToolOutcomes = [];
|
|
81
83
|
// Log only the content snippet to avoid flooding logs with full JSON
|
|
82
84
|
const contentSnippet = response.choices[0].message.content ? response.choices[0].message.content.substring(0, 100) + '...' : 'No content';
|
|
83
85
|
if (process.env.DEBUG)
|
|
@@ -105,9 +107,24 @@ export class Brain {
|
|
|
105
107
|
: undefined;
|
|
106
108
|
const result = await skill.execute(functionArgs, ctxForTool);
|
|
107
109
|
toolResult = JSON.stringify(result);
|
|
110
|
+
if (functionName.startsWith('fs_')) {
|
|
111
|
+
const isErrorString = typeof result === 'string' && /^error/i.test(result.trim());
|
|
112
|
+
fsToolOutcomes.push({
|
|
113
|
+
name: functionName,
|
|
114
|
+
success: !isErrorString,
|
|
115
|
+
error: isErrorString ? String(result) : undefined
|
|
116
|
+
});
|
|
117
|
+
}
|
|
108
118
|
}
|
|
109
119
|
catch (error) {
|
|
110
120
|
toolResult = JSON.stringify({ error: error.message });
|
|
121
|
+
if (functionName.startsWith('fs_')) {
|
|
122
|
+
fsToolOutcomes.push({
|
|
123
|
+
name: functionName,
|
|
124
|
+
success: false,
|
|
125
|
+
error: String(error?.message || error)
|
|
126
|
+
});
|
|
127
|
+
}
|
|
111
128
|
}
|
|
112
129
|
}
|
|
113
130
|
else {
|
|
@@ -132,6 +149,30 @@ export class Brain {
|
|
|
132
149
|
}
|
|
133
150
|
const hitLimit = Boolean(response.choices[0].message.tool_calls) && iterations >= MAX_ITERATIONS;
|
|
134
151
|
const finalContent = response.choices[0].message.content || 'I could not generate a response.';
|
|
152
|
+
// Hard guard: avoid fabricated "file read success" responses when fs tool didn't actually succeed.
|
|
153
|
+
const hasExplicitPath = /\/[\w\-./\\]+|\.\w{1,8}\b/.test(newMessage);
|
|
154
|
+
const asksFileAction = /(读取|读一下|打开|查看|列出|目录|文件|read|open|list|ls|cat)/i.test(newMessage);
|
|
155
|
+
if (hasExplicitPath && asksFileAction) {
|
|
156
|
+
const fsSuccess = fsToolOutcomes.some(x => x.success);
|
|
157
|
+
if (!fsSuccess) {
|
|
158
|
+
const lastFsError = [...fsToolOutcomes].reverse().find(x => !x.success)?.error;
|
|
159
|
+
const attemptedFsTools = fsToolOutcomes.map(x => x.name);
|
|
160
|
+
const absPathMatch = newMessage.match(/\/[^\s"'`]+/);
|
|
161
|
+
const requestedPath = absPathMatch ? absPathMatch[0] : '';
|
|
162
|
+
const resolvedWorkspace = effectiveWorkspace ? path.resolve(effectiveWorkspace) : '';
|
|
163
|
+
const resolvedRequested = requestedPath ? path.resolve(requestedPath) : '';
|
|
164
|
+
let workspaceCheck = '';
|
|
165
|
+
if (resolvedWorkspace && resolvedRequested) {
|
|
166
|
+
const rel = path.relative(resolvedWorkspace, resolvedRequested);
|
|
167
|
+
const outside = Boolean(rel) && (rel.startsWith('..') || path.isAbsolute(rel));
|
|
168
|
+
workspaceCheck = outside
|
|
169
|
+
? `路径检查:目标路径在 workspace 之外(${resolvedRequested} 不在 ${resolvedWorkspace} 内)。`
|
|
170
|
+
: `路径检查:目标路径位于 workspace 内。`;
|
|
171
|
+
}
|
|
172
|
+
const ws = effectiveWorkspace || '(not set)';
|
|
173
|
+
return `未能实际读取文件:文件工具未成功执行。\n当前会话 workspace:${ws}\n请求路径:${requestedPath || '(未识别到明确路径)'}\n${workspaceCheck || '路径检查:无法判定。'}\n${attemptedFsTools.length > 0 ? `已触发工具:${attemptedFsTools.join(', ')}` : '未触发任何 fs_* 文件工具调用(模型未选择工具)。'}\n${lastFsError ? `工具错误:${lastFsError}` : '原因:未拿到可用的文件工具执行结果。请重试,或缩短指令为“读取 <绝对路径>”。'}`;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
135
176
|
if (process.env.DEBUG)
|
|
136
177
|
console.log('[Brain] Final Response (snippet):', finalContent.substring(0, 100) + '...');
|
|
137
178
|
if (!hitLimit)
|