Skip to content

Commit 47ecc60

Browse files
committed
Auto-save proposed skill code to log directory
Save each propose_* tool call's code as a standalone .py file under proposed_code/ in the run's log directory for easier extraction and review.
1 parent 4f9b70f commit 47ecc60

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

predicators/agent_sdk/tools.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Custom MCP tool definitions for the agent SDK approach."""
22
import json
33
import logging
4+
import os
45
import traceback
56
from dataclasses import dataclass, field
67
from typing import Any, Callable, Dict, List, Optional, Set
@@ -80,6 +81,7 @@ class ToolContext:
8081
iteration_history: List[Dict[str, Any]] = field(default_factory=list)
8182
skill_factory_context: Dict[str, Any] = field(default_factory=dict)
8283
proposals_disabled: bool = False # set True during test-time solving
84+
log_dir: Optional[str] = None
8385

8486

8587
def _text_result(text: str) -> Dict[str, Any]:
@@ -105,6 +107,23 @@ def create_mcp_tools(ctx: ToolContext,
105107
"""
106108
from claude_agent_sdk import tool
107109

110+
_propose_count = [0] # mutable counter in closure
111+
112+
def _save_proposal_code(tool_name: str, code: str, names: List[str],
113+
description: str) -> None:
114+
if not ctx.log_dir:
115+
return
116+
_propose_count[0] += 1
117+
subdir = os.path.join(ctx.log_dir, "proposed_code")
118+
os.makedirs(subdir, exist_ok=True)
119+
names_slug = "_".join(names)[:80]
120+
filename = f"{_propose_count[0]:03d}_{tool_name}_{names_slug}.py"
121+
filepath = os.path.join(subdir, filename)
122+
header = f'"""{tool_name}: {description}"""\n\n'
123+
with open(filepath, "w") as f:
124+
f.write(header + code)
125+
logging.info(f"Saved proposal code to {filepath}")
126+
108127
# ===== INSPECTION TOOLS =====
109128

110129
@tool("inspect_types", "List all object types and their features", {})
@@ -338,6 +357,8 @@ async def propose_types(args: Dict[str, Any]) -> Dict[str, Any]:
338357
ctx.iteration_proposals.proposed_types |= proposed
339358
names = [t.name for t in proposed]
340359
logging.info(f"Agent proposed types: {names}")
360+
_save_proposal_code("propose_types", code, names,
361+
args.get("description", ""))
341362
return _text_result(
342363
f"Successfully proposed {len(proposed)} types: {names}")
343364

@@ -389,6 +410,8 @@ async def propose_predicates(args: Dict[str, Any]) -> Dict[str, Any]:
389410
ctx.iteration_proposals.proposed_predicates |= proposed
390411
names = [p.name for p in proposed]
391412
logging.info(f"Agent proposed predicates: {names}")
413+
_save_proposal_code("propose_predicates", code, names,
414+
args.get("description", ""))
392415

393416
msg = f"Successfully proposed {len(proposed)} predicates: {names}"
394417
if errors:
@@ -446,6 +469,8 @@ async def propose_object_augmentor(args: Dict[str, Any]) -> Dict[str, Any]:
446469
ctx.iteration_proposals.augment_task_fn = result
447470
ctx.iteration_proposals.augment_task_code = code
448471
logging.info(f"Agent proposed augmentor adding objects: {obj_names}")
472+
_save_proposal_code("propose_object_augmentor", code, obj_names,
473+
args.get("description", ""))
449474
return _text_result(
450475
f"Successfully proposed augmentor. Test added objects: {obj_names}"
451476
)
@@ -488,6 +513,8 @@ async def propose_processes(args: Dict[str, Any]) -> Dict[str, Any]:
488513
ctx.iteration_proposals.proposed_processes |= proposed
489514
names = [p.name for p in proposed]
490515
logging.info(f"Agent proposed processes: {names}")
516+
_save_proposal_code("propose_processes", code, names,
517+
args.get("description", ""))
491518
return _text_result(
492519
f"Successfully proposed {len(proposed)} processes: {names}")
493520

@@ -538,6 +565,8 @@ async def propose_options(args: Dict[str, Any]) -> Dict[str, Any]:
538565
ctx.options |= proposed
539566
names = [o.name for o in proposed]
540567
logging.info(f"Agent proposed options: {names}")
568+
_save_proposal_code("propose_options", code, names,
569+
args.get("description", ""))
541570
return _text_result(
542571
f"Successfully proposed {len(proposed)} options: {names}")
543572

predicators/approaches/agent_planner_approach.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ def _sync_tool_context(self) -> None:
524524
self._offline_dataset.trajectories
525525
self._tool_context.online_trajectories = self._online_trajectories
526526

527+
self._tool_context.log_dir = self._get_log_dir()
527528
self._tool_context.option_model = self._option_model
528529
all_trajs = (self._offline_dataset.trajectories +
529530
self._online_trajectories)

0 commit comments

Comments
 (0)