From e52df1bc8b6489da6c955edfe6d471b1f97bf8ef Mon Sep 17 00:00:00 2001 From: Dita Aji Pratama Date: Tue, 6 Oct 2026 09:34:47 +0700 Subject: [PATCH] Fixing bug di tools dan di agent loop --- lib/agent_loop.py | 24 ++++++++++++++++++------ tools/coder.py | 13 +++++++++++-- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/agent_loop.py b/lib/agent_loop.py index b9f01ef..099b947 100644 --- a/lib/agent_loop.py +++ b/lib/agent_loop.py @@ -1,5 +1,6 @@ import json from datetime import datetime +import config from lib.personality import PERSONALITY from tools.vision import ImagePayload from scripts import loggorilla @@ -7,25 +8,36 @@ from scripts import loggorilla def _ts(): return datetime.now().strftime('%H:%M:%S') +def _cap_output(result): + # Jaring pengaman ukuran output tool. Hormati semantics config: + # AGENT_MAX_TOOL_OUTPUT <= 0 = unlimited (tidak dipotong). + limit = getattr(config, "AGENT_MAX_TOOL_OUTPUT", 0) + if not limit or limit <= 0: + return result + if isinstance(result, str) and len(result) > limit: + omitted = len(result) - limit + return result[:limit] + f"\n... [truncated: {omitted} chars omitted]" + return result + def execute_tool(tool_call, TOOL_HANDLERS): tname = tool_call['function']['name'] targs = json.loads(tool_call['function']['arguments']) handler = TOOL_HANDLERS.get(tname) if not handler: - return f'Tool {tname} not found' + return _cap_output(f'Tool {tname} not found') try: if tname == 'search_code': - return handler( + return _cap_output(handler( pattern=targs['pattern'], search_type=targs['search_type'], path=targs.get('path', '.'), - ) + )) elif tname == 'git_operation': - return handler(args=targs['args']) + return _cap_output(handler(args=targs['args'])) else: - return handler(**targs) + return _cap_output(handler(**targs)) except Exception as e: - return f'Error executing tool: {str(e)}' + return _cap_output(f'Error executing tool: {str(e)}') def run_agent_loop(session, llm_client, TOOLS, TOOL_HANDLERS, max_iterations, on_tool_calls=None, tool_reminder=None): session_ended = False diff --git a/tools/coder.py b/tools/coder.py index c508d97..4a1a5c2 100644 --- a/tools/coder.py +++ b/tools/coder.py @@ -6,6 +6,15 @@ import glob as glob_module from lib import workspace +# Batas panjang satu baris hasil pencarian. Mencegah satu baris raksasa +# (mis. file minified/generated satu-line) menembus context window model. +MAX_MATCH_LINE = 500 + +def _clip(line): + if len(line) > MAX_MATCH_LINE: + return line[:MAX_MATCH_LINE] + f"... [+{len(line) - MAX_MATCH_LINE} chars]" + return line + schema_read_file = { "type": "function", "function": { @@ -145,7 +154,7 @@ def search_code(pattern, search_type, path="."): with open(file_path, 'r', encoding='utf-8', errors='replace') as f: for i, line in enumerate(f.readlines(), 1): if re.search(pattern, line): - results.append(f"{file_path}:{i}: {line.strip()}") + results.append(f"{file_path}:{i}: {_clip(line.strip())}") except: continue return "\n".join(results[:50]) if results else "No matches found" @@ -211,7 +220,7 @@ def search_grep(pattern, path=".", include=None): with open(file_path, 'r', encoding='utf-8', errors='replace') as f: for i, line in enumerate(f.readlines(), 1): if re.search(pattern, line): - results.append(f"{file_path}:{i}: {line.strip()}") + results.append(f"{file_path}:{i}: {_clip(line.strip())}") except: continue return "\n".join(results[:100]) if results else "No matches found"