mocode-ai 0.1.6 → 0.1.7
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/agent/core.js
CHANGED
|
@@ -9,8 +9,7 @@ import { chat, planChatTools, } from '../llm/index.js';
|
|
|
9
9
|
import { executeTool } from '../tools/registry.js';
|
|
10
10
|
import { PLAN_DISABLED_TOOLS } from '../tools/constants.js';
|
|
11
11
|
import { getAgentMode, setAgentMode } from './mode.js';
|
|
12
|
-
import { maybeCompact, contextState } from '../session/index.js';
|
|
13
|
-
import { optimizeToolResult } from '../context/index.js';
|
|
12
|
+
import { maybeCompact, capToolResultForHistory, contextState, } from '../session/index.js';
|
|
14
13
|
import { config } from '../config/index.js';
|
|
15
14
|
import { jailResolve } from '../sandbox/index.js';
|
|
16
15
|
/** 解析工具 arguments JSON;非法或空返 null(调用方据此降级到普通 preview)。 */
|
|
@@ -68,16 +67,12 @@ function readDiffContext(tc, parsed) {
|
|
|
68
67
|
}
|
|
69
68
|
return { preWriteOld: null, editStartLine: 1 };
|
|
70
69
|
}
|
|
71
|
-
/** 回灌 tool 结果到 history
|
|
72
|
-
* tool_call_id 与 assistant.tool_calls 按序配对。未注册 encoder 时回落 capToolResultForHistory(零行为变化)。
|
|
73
|
-
* TUI 渲染(hooks.onToolResult)用原始 output,与此解耦——屏上看全量,LLM 看编码后紧凑版。 */
|
|
70
|
+
/** 回灌 tool 结果到 history(裁到单条上限);tool_call_id 与 assistant.tool_calls 按序配对。 */
|
|
74
71
|
function pushToolResult(history, tc, output) {
|
|
75
72
|
history.push({
|
|
76
73
|
role: 'tool',
|
|
77
74
|
tool_call_id: tc.id,
|
|
78
|
-
|
|
79
|
-
// tc.arguments 透传给 encoder(上下文感知编码,如 read_file 的 offset/limit)。永不抛错。
|
|
80
|
-
content: optimizeToolResult(tc.name, output, tc.arguments),
|
|
75
|
+
content: capToolResultForHistory(tc.name, output),
|
|
81
76
|
});
|
|
82
77
|
}
|
|
83
78
|
/**
|
|
@@ -85,7 +80,7 @@ function pushToolResult(history, tc, output) {
|
|
|
85
80
|
* 流式调 LLM(经 hooks.onText 实时渲染)→ 有 tool_calls 就分组执行并回灌
|
|
86
81
|
* → 否则流式正文即最终回复。history 在调用间持久,由调用方持有。
|
|
87
82
|
* 步前经 session/maybeCompact 自动压缩(接近窗口上限时三层压缩);
|
|
88
|
-
* 工具结果进 history 前经
|
|
83
|
+
* 工具结果进 history 前经 capToolResultForHistory 裁到单条上限。
|
|
89
84
|
*
|
|
90
85
|
* 中断语义:signal 经 executeTool(name, args, signal) 串进工具;run_command/web_fetch 等 abort 即时杀
|
|
91
86
|
* (树杀子进程 / 取消 fetch),循环顶 if(signal.aborted) 兜底还原。不会留下未配对的 tool_call_id。
|
package/dist/config/index.js
CHANGED
|
@@ -122,7 +122,6 @@ export const config = {
|
|
|
122
122
|
compactThreshold: Number(process.env.COMPACT_THRESHOLD) || 0.85,
|
|
123
123
|
includeUsage: process.env.LLM_STREAM_USAGE !== 'false',
|
|
124
124
|
autoCompact: process.env.AUTO_COMPACT !== 'false',
|
|
125
|
-
contextOptimize: process.env.MOCODE_CONTEXT_OPTIMIZE !== 'false',
|
|
126
125
|
autoReflect: process.env.AUTO_REFLECT !== 'false',
|
|
127
126
|
reflectEveryN: Number(process.env.REFLECT_EVERY_N) || 5,
|
|
128
127
|
maxSteps: Number(process.env.MAX_STEPS) || 200,
|
|
@@ -19,7 +19,14 @@ export const editFileTool = {
|
|
|
19
19
|
const newStr = String(args.new_string);
|
|
20
20
|
const full = resolve(path);
|
|
21
21
|
const data = await readFile(full, 'utf8');
|
|
22
|
-
|
|
22
|
+
// 行尾归一化:read_file 用 split(/\r?\n/) 输出纯 LF,LLM 据此构造的 old_string/new_string
|
|
23
|
+
// 也是 LF;但本工具原样读文件(CRLF 保留),直接精确匹配会在 CRLF 文件上必败(文件 \r\n 对不上
|
|
24
|
+
// old_string 的 \n)。故匹配/计数在归一化(LF)文本上做,写回时按文件原始行尾风格还原,
|
|
25
|
+
// 不把 CRLF 文件悄悄换成 LF(只含 LF 的纯 LF 文件 norm===data,行为完全不变)。
|
|
26
|
+
const norm = data.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
27
|
+
const normOld = oldStr.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
28
|
+
const normNew = newStr.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
29
|
+
const count = norm.split(normOld).length - 1;
|
|
23
30
|
if (count === 0) {
|
|
24
31
|
return `错误:在 ${path} 中未找到 old_string。请先 read_file 确认实际内容。`;
|
|
25
32
|
}
|
|
@@ -27,8 +34,10 @@ export const editFileTool = {
|
|
|
27
34
|
return `错误:old_string 在 ${path} 中出现 ${count} 次,不唯一。请加入更多上下文使其唯一。`;
|
|
28
35
|
}
|
|
29
36
|
// 用函数形式替换,避免 new_string 里的 $ 被当特殊模式
|
|
30
|
-
const updated =
|
|
31
|
-
|
|
37
|
+
const updated = norm.replace(normOld, () => normNew);
|
|
38
|
+
// 检测原始行尾风格,写回时还原(存在 \r\n 即视为 CRLF 文件;纯 LF 文件保持 LF)
|
|
39
|
+
const out = data.includes('\r\n') ? updated.replace(/\n/g, '\r\n') : updated;
|
|
40
|
+
await writeFile(full, out, 'utf8');
|
|
32
41
|
return `已在 ${path} 中完成 1 处替换。`;
|
|
33
42
|
},
|
|
34
43
|
};
|