in src/smolagents/agents.py [0:0]
def save(self, output_dir: str | Path, relative_path: str | None = None):
"""
Saves the relevant code files for your agent. This will copy the code of your agent in `output_dir` as well as autogenerate:
- a `tools` folder containing the logic for each of the tools under `tools/{tool_name}.py`.
- a `managed_agents` folder containing the logic for each of the managed agents.
- an `agent.json` file containing a dictionary representing your agent.
- a `prompt.yaml` file containing the prompt templates used by your agent.
- an `app.py` file providing a UI for your agent when it is exported to a Space with `agent.push_to_hub()`
- a `requirements.txt` containing the names of the modules used by your tool (as detected when inspecting its
code)
Args:
output_dir (`str` or `Path`): The folder in which you want to save your agent.
"""
make_init_file(output_dir)
# Recursively save managed agents
if self.managed_agents:
make_init_file(os.path.join(output_dir, "managed_agents"))
for agent_name, agent in self.managed_agents.items():
agent_suffix = f"managed_agents.{agent_name}"
if relative_path:
agent_suffix = relative_path + "." + agent_suffix
agent.save(os.path.join(output_dir, "managed_agents", agent_name), relative_path=agent_suffix)
class_name = self.__class__.__name__
# Save tools to different .py files
for tool in self.tools.values():
make_init_file(os.path.join(output_dir, "tools"))
tool.save(os.path.join(output_dir, "tools"), tool_file_name=tool.name, make_gradio_app=False)
# Save prompts to yaml
yaml_prompts = yaml.safe_dump(
self.prompt_templates,
default_style="|", # This forces block literals for all strings
default_flow_style=False,
width=float("inf"),
sort_keys=False,
allow_unicode=True,
indent=2,
)
with open(os.path.join(output_dir, "prompts.yaml"), "w", encoding="utf-8") as f:
f.write(yaml_prompts)
# Save agent dictionary to json
agent_dict = self.to_dict()
agent_dict["tools"] = [tool.name for tool in self.tools.values()]
agent_dict["managed_agents"] = {agent.name: agent.__class__.__name__ for agent in self.managed_agents.values()}
with open(os.path.join(output_dir, "agent.json"), "w", encoding="utf-8") as f:
json.dump(agent_dict, f, indent=4)
# Save requirements
with open(os.path.join(output_dir, "requirements.txt"), "w", encoding="utf-8") as f:
f.writelines(f"{r}\n" for r in agent_dict["requirements"])
# Make agent.py file with Gradio UI
agent_name = f"agent_{self.name}" if getattr(self, "name", None) else "agent"
managed_agent_relative_path = relative_path + "." if relative_path is not None else ""
app_template = AGENT_GRADIO_APP_TEMPLATE
template_env = jinja2.Environment(loader=jinja2.BaseLoader(), undefined=jinja2.StrictUndefined)
template_env.filters["repr"] = repr
template_env.filters["camelcase"] = lambda value: "".join(word.capitalize() for word in value.split("_"))
template = template_env.from_string(app_template)
# Render the app.py file from Jinja2 template
app_text = template.render(
{
"agent_name": agent_name,
"class_name": class_name,
"agent_dict": agent_dict,
"tools": self.tools,
"managed_agents": self.managed_agents,
"managed_agent_relative_path": managed_agent_relative_path,
}
)
with open(os.path.join(output_dir, "app.py"), "w", encoding="utf-8") as f:
f.write(app_text + "\n") # Append newline at the end