Add large output handling and iteration budget to agent

- Tool outputs >2K chars saved to workspace/tool_outputs/ with preview
- Agent gets first 1500 chars + file path to read the rest
- Iteration budget bumped to 10 rounds (configurable per template)
- Warning injected when 2 rounds remaining to help model wrap up
This commit is contained in:
2026-04-07 20:53:51 +00:00
parent 3c00de75d1
commit 3083b5d9d7

View File

@@ -32,7 +32,7 @@ OLLAMA_URL = CONFIG.get("ollama_url", "http://172.16.0.1:11434")
CONTEXT_SIZE = CONFIG.get("context_size", 20)
MAX_RESPONSE_LINES = CONFIG.get("max_response_lines", 50)
TOOLS_ENABLED = CONFIG.get("tools", True)
MAX_TOOL_ROUNDS = CONFIG.get("max_tool_rounds", 5)
MAX_TOOL_ROUNDS = CONFIG.get("max_tool_rounds", 10)
WORKSPACE = "/workspace"
SKILL_DIRS = ["/opt/skills", f"{WORKSPACE}/skills"]
@@ -169,9 +169,15 @@ def discover_skills():
return tools, scripts
LARGE_OUTPUT_THRESHOLD = 2000
LARGE_OUTPUT_DIR = f"{WORKSPACE}/tool_outputs"
_output_counter = 0
def execute_skill(script_path, args):
"""Execute a skill script with args as JSON on stdin."""
# Pass config extras via env
"""Execute a skill script with args as JSON on stdin.
Large outputs are saved to a file with a preview returned."""
global _output_counter
env = os.environ.copy()
env["WORKSPACE"] = WORKSPACE
env["SEARX_URL"] = CONFIG.get("searx_url", "https://searx.mymx.me")
@@ -188,7 +194,19 @@ def execute_skill(script_path, args):
output = result.stdout
if result.stderr:
output += f"\n[stderr] {result.stderr}"
return output.strip() or "[no output]"
output = output.strip() or "[no output]"
# Large output handling — save to file, return preview
if len(output) > LARGE_OUTPUT_THRESHOLD:
os.makedirs(LARGE_OUTPUT_DIR, exist_ok=True)
_output_counter += 1
filepath = f"{LARGE_OUTPUT_DIR}/output_{_output_counter}.txt"
with open(filepath, "w") as f:
f.write(output)
preview = output[:1500]
return f"{preview}\n\n[output truncated — full result ({len(output)} chars) saved to {filepath}. Use run_command to read it: cat {filepath}]"
return output
except subprocess.TimeoutExpired:
return "[skill timed out after 120s]"
except Exception as e:
@@ -323,6 +341,7 @@ def query_ollama(messages):
payload["tools"] = TOOLS
for round_num in range(MAX_TOOL_ROUNDS):
remaining = MAX_TOOL_ROUNDS - round_num
try:
data = ollama_request(payload)
except (urllib.error.URLError, TimeoutError) as e:
@@ -341,6 +360,9 @@ def query_ollama(messages):
fn.get("arguments", {}),
round_num + 1,
)
# Warn when budget is running low
if remaining <= 2:
result += f"\n[warning: {remaining - 1} tool rounds remaining — wrap up]"
messages.append({"role": "tool", "content": result})
payload["messages"] = messages
continue
@@ -353,6 +375,8 @@ def query_ollama(messages):
if fn_name in SKILL_SCRIPTS:
messages.append({"role": "assistant", "content": content})
result = dispatch_tool(fn_name, fn_args, round_num + 1)
if remaining <= 2:
result += f"\n[warning: {remaining - 1} tool rounds remaining — wrap up]"
messages.append({
"role": "user",
"content": f"Tool result:\n{result}\n\nNow respond to the user based on this result.",