file_read: default 200 lines, total line count report, fix L_MAX dynamic calc
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
"parameters": {"type": "object", "properties": {
|
||||
"path": {"type": "string", "description": "文件相对或绝对路径。"},
|
||||
"start": {"type": "integer", "description": "起始行号(从 1 开始)。", "default": 1},
|
||||
"count": {"type": "integer", "description": "读取的行数。", "default": 100},
|
||||
"count": {"type": "integer", "description": "读取的行数。", "default": 200},
|
||||
"keyword": {"type": "string", "description": "可选搜索关键字。如果提供,将返回第一个匹配项(忽略大小写)及其周边的内容。"},
|
||||
"show_linenos": {"type": "boolean", "description": "是否显示行号,建议开启以辅助 file_patch 定位。", "default": true}}, "required": ["path"]}
|
||||
}},
|
||||
|
||||
19
ga.py
19
ga.py
@@ -194,13 +194,9 @@ def file_patch(path: str, old_content: str, new_content: str):
|
||||
return {"status": "error", "msg": str(e)}
|
||||
|
||||
def file_read(path, start=1, keyword=None, count=200, show_linenos=True):
|
||||
L_MAX = max(100, 1024000//count); TAG = " ... [TRUNCATED]"
|
||||
try:
|
||||
with open(path, 'r', encoding='utf-8', errors='replace') as f:
|
||||
stream = (
|
||||
(i, (l[:L_MAX].rstrip() + TAG if len(l) > L_MAX else l.rstrip('\r\n')))
|
||||
for i, l in enumerate(f, 1)
|
||||
)
|
||||
stream = ((i, l.rstrip('\r\n')) for i, l in enumerate(f, 1))
|
||||
stream = itertools.dropwhile(lambda x: x[0] < start, stream)
|
||||
if keyword:
|
||||
before = collections.deque(maxlen=count//3)
|
||||
@@ -211,8 +207,15 @@ def file_read(path, start=1, keyword=None, count=200, show_linenos=True):
|
||||
before.append((i, l))
|
||||
else: return f"Keyword '{keyword}' not found after line {start}. Falling back to content from line {start}:\n\n" \
|
||||
+ file_read(path, start, None, count, show_linenos)
|
||||
else: res = itertools.islice(stream, count)
|
||||
return "\n".join(f"{i}|{l}" if show_linenos else l for i, l in res)
|
||||
else: res = list(itertools.islice(stream, count))
|
||||
realcnt = len(res); L_MAX = max(100, 512000//realcnt); TAG = " ... [TRUNCATED]"
|
||||
remaining = sum(1 for _ in itertools.islice(stream, 5000))
|
||||
total_lines = (start - 1) + realcnt + remaining
|
||||
total_tag = "[FILE] Total " + (f"{total_lines}+" if remaining >= 5000 else str(total_lines)) + ' lines\n'
|
||||
res = [(i, l if len(l) <= L_MAX else l[:L_MAX] + TAG) for i, l in res]
|
||||
result = "\n".join(f"{i}|{l}" if show_linenos else l for i, l in res)
|
||||
if show_linenos: result = total_tag + result
|
||||
return result
|
||||
except Exception as e:
|
||||
return f"Error: {str(e)}"
|
||||
|
||||
@@ -370,7 +373,7 @@ class GenericAgentHandler(BaseHandler):
|
||||
path = self._get_abs_path(args.get("path", ""))
|
||||
yield f"\n[Action] Reading file: {path}\n"
|
||||
start = args.get("start", 1)
|
||||
count = args.get("count", 100)
|
||||
count = args.get("count", 200)
|
||||
keyword = args.get("keyword")
|
||||
show_linenos = args.get("show_linenos", True)
|
||||
result = file_read(path, start=start, keyword=keyword,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
选择规则:
|
||||
- cwd下有 `TODO.txt` 时优先执行其中任务,完成后移除条目
|
||||
- 不连续选择相同方向(TODO除外),选择前先读 history.txt 了解近期已做方向
|
||||
- 方向平衡:近10轮内同一方向≤3次,同一具体主题(如"磁盘健康""书签")不重复
|
||||
- 选定后先声明一句话预期收益,写入报告开头
|
||||
|
||||
目标排序(按价值递减):
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
- 共享资源冲突:键鼠/浏览器主体不可共享(浏览器可分tab但需谨慎),subagent任务应限于文件处理
|
||||
- 不满足map模式的任务 → 主agent顺序执行即可,别用subagent
|
||||
|
||||
**额外场景:SOP dry-run验证**——启动单个subagent执行目标SOP,通过output日志发现SOP缺陷(缺参数/选择器不准/步骤模糊),主agent据此patch优化SOP。单subagent不存在资源冲突。
|
||||
|
||||
**标准流程(map-reduce)**:
|
||||
1. 主agent准备阶段:爬取/dump数据,存为多个独立输入文件
|
||||
2. 分发:对每个文件启动一个subagent处理(主agent自己也可以处理其中一个)
|
||||
|
||||
@@ -55,7 +55,7 @@ class ClaudeSession:
|
||||
headers = {"x-api-key": self.api_key, "Content-Type": "application/json", "anthropic-version": "2023-06-01"}
|
||||
payload = {"model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens, "stream": True}
|
||||
try:
|
||||
with requests.post(f"{self.api_base}/v1/messages", headers=headers, json=payload, stream=True, timeout=(5,60)) as r:
|
||||
with requests.post(f"{self.api_base}/v1/messages", headers=headers, json=payload, stream=True, timeout=(5,30)) as r:
|
||||
r.raise_for_status()
|
||||
for line in r.iter_lines():
|
||||
if not line: continue
|
||||
|
||||
Reference in New Issue
Block a user