file_write: support content arg in native mode, strip it in text-emulated mode

This commit is contained in:
Liang Jiaqing committed 2026-05-06 10:30:08 +08:00
1 parent f98f6eac39
commit 6e2ec39052
4 files changed
+19 -7

No files matched your search

+2 -1
View File
@@ -29,9 +29,10 @@
}},
{"type": "function", "function": {
"name": "file_write",
"description": "Create/overwrite/append files. HUGE edits ONLY. Content must in <file_content>...</file_content> in reply body BEFORE the file_write call (not args). Supports {{file:path:startLine:endLine}}, auto-expanded",
"description": "Create/overwrite/append files. HUGE edits ONLY. Supports {{file:path:startLine:endLine}}, auto-expanded",
"parameters": {"type": "object", "properties": {
"path": {"type": "string", "description": "File path"},
"content": {"type": "string"},
"mode": {"type": "string", "enum": ["overwrite", "append", "prepend"], "description": "Write mode", "default": "overwrite"}}}
}},
{"type": "function", "function": {
+2 -1
View File
@@ -29,9 +29,10 @@
}},
{"type": "function", "function": {
"name": "file_write",
"description": "用于文件的新建、全量覆盖或追加写入。对于精细的代码修改,应优先使用 file_patch。注意:要写入的内容必须放在回复正文的 <file_content> 标签或代码块中。写入内容支持 {{file:路径:起始行:结束行}} 语法引用文件片段,写入前自动展开",
"description": "用于文件的新建、全量覆盖或追加写入。对于精细的代码修改,应优先使用 file_patch。写入内容支持 {{file:路径:起始行:结束行}} 语法引用文件片段,写入前自动展开",
"parameters": {"type": "object", "properties": {
"path": {"type": "string", "description": "文件路径"},
"content": {"type": "string"},
"mode": {"type": "string", "enum": ["overwrite", "append", "prepend"], "description": "写入模式覆盖、追加或在开头追加", "default": "overwrite"}}}
}},
{"type": "function", "function": {
+6 -5
View File
@@ -284,7 +284,8 @@ class GenericAgentHandler(BaseHandler):
if not code:
code = self._extract_code_block(response, code_type)
if not code: return StepOutcome("[Error] Code missing. Must use reply code block or 'script' arg.", next_prompt="\n")
timeout = args.get("timeout", 60)
try: timeout = int(args.get("timeout", 60))
except: timeout = 60
raw_path = os.path.join(self.cwd, args.get("cwd", './'))
cwd = os.path.normpath(os.path.abspath(raw_path))
code_cwd = os.path.normpath(self.cwd)
@@ -380,12 +381,12 @@ class GenericAgentHandler(BaseHandler):
if blocks: return blocks[-1].strip()
return None
blocks = extract_robust_content(response.content)
if not blocks:
content = args.get('content') or extract_robust_content(response.content)
if not content:
yield f"[Status] ❌ 失败: 未在回复中找到<file_content>代码块内容\n"
return StepOutcome({"status": "error", "msg": "No content found. Put content inside <file_content>...</file_content> tags in your reply body before call file_write."}, next_prompt="\n")
return StepOutcome({"status": "error", "msg": "No content found. Blank is not supported. Put content inside <file_content>...</file_content> tags in your reply body before call file_write."}, next_prompt="\n")
try:
new_content = expand_file_refs(blocks, base_dir=self.cwd)
new_content = expand_file_refs(content, base_dir=self.cwd)
if mode == "prepend":
old = open(path, 'r', encoding="utf-8").read() if os.path.exists(path) else ""
open(path, 'w', encoding="utf-8").write(new_content + old)
+9
View File
@@ -736,6 +736,15 @@ class ToolClient:
self.total_cd_tokens = 0
def chat(self, messages, tools=None):
tools = json.loads(json.dumps(tools, ensure_ascii=False)) if tools else tools
for t in tools or []:
f = t.get('function', {})
if f.get('name') == 'file_write':
props = f.get('parameters', {}).get('properties', {})
props.pop('content', None)
extra = '. Content must be placed in <file_content> tags in reply body, not in args'
if extra not in f.get('description', ''): f['description'] = f.get('description', '') + extra
break
full_prompt = self._build_protocol_prompt(messages, tools)
print("Full prompt length:", len(full_prompt), 'chars')
gen = self.backend.ask(full_prompt)