EastSync-AI / tools /plan_tool.py
StanSava's picture
add logging, metaprompt setup, add planning flow for agent and update… (#7)
78adee5
import json, os
from smolagents import Tool
PLAN_PATH = "./execution_plan.json"
def load_plan():
if not os.path.exists(PLAN_PATH):
return []
with open(PLAN_PATH, "r") as f:
return json.load(f)
def save_plan(plan):
with open(PLAN_PATH, "w") as f:
json.dump(plan, f, indent=2)
class UpdatePlanTool(Tool):
"""
Tool to update the execution plan stored on disk.
Maintains a persistent execution plan that can be updated during multi-step operations.
The plan is stored in JSON format at './execution_plan.json'.
Usage:
- Set merge=False to overwrite the entire plan
- Set merge=True to update specific items by ID while preserving others
Example input:
{
"merge": true,
"todos": [
{"id": "1", "content": "Research market trends", "status": "completed"},
{"id": "2", "content": "Analyze competitor data", "status": "in_progress"}
]
}
Returns:
- {"result": "plan overwritten", "plan": updated_plan} when merge=False
- {"result": "plan updated", "plan": updated_plan} when merge=True
- {"error": "...", "plan": current_plan} when invariant violated
output_type: object
"""
name = "update_plan"
description = (
"Update the current execution plan on disk. "
"Use for multi-step tasks only. Maintains 2–5 non-operational items. "
"Requires exactly one item in_progress during execution."
)
inputs = {
"merge": {"type": "boolean", "description": "Merge with existing plan"},
"todos": {"type": "array", "description": "List of objects {id, content, status}"}
}
output_type = "string"
def forward(self, merge: bool, todos: list) -> str:
plan = load_plan()
if not merge:
save_plan(todos)
return json.dumps({"result": "plan overwritten", "plan": todos})
# merge: update items by id
plan_by_id = {item["id"]: item for item in plan}
for new_item in todos:
plan_by_id[new_item["id"]] = new_item
merged_plan = list(plan_by_id.values())
# enforce invariant: at most one in_progress
in_prog = [t for t in merged_plan if t["status"] == "in_progress"]
if len(in_prog) > 1:
return {
"error": "Only one item may be in_progress at a time. Fix your update.",
"plan": merged_plan
}
save_plan(merged_plan)
return json.dumps({"result": "plan updated", "plan": merged_plan})