feat: Update builder/save endpoint to accept files as input. Write the agent yaml file to the agent folder

PiperOrigin-RevId: 783963934
This commit is contained in:
Jianfeng Zeng
2025-07-16 17:55:55 -07:00
committed by Copybara-Service
parent b705b35977
commit 31fa5d91bd
2 changed files with 26 additions and 28 deletions
+1
View File
@@ -105,6 +105,7 @@ test = [
"pytest-mock>=3.14.0",
"pytest-xdist>=3.6.1",
"pytest>=8.3.4",
"python-multipart>=0.0.9",
# go/keep-sorted end
]
+25 -28
View File
@@ -20,6 +20,7 @@ import json
import logging
import os
from pathlib import Path
import shutil
import time
import traceback
import typing
@@ -32,6 +33,7 @@ import click
from fastapi import FastAPI
from fastapi import HTTPException
from fastapi import Query
from fastapi import UploadFile
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse
from fastapi.responses import StreamingResponse
@@ -51,7 +53,6 @@ from starlette.types import Lifespan
from typing_extensions import override
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
import yaml
from ..agents import RunConfig
from ..agents.live_request_queue import LiveRequest
@@ -212,14 +213,6 @@ class GetEventGraphResult(common.BaseModel):
dot_src: str
class AgentBuildRequest(common.BaseModel):
agent_name: str
agent_type: str
model: str
description: str
instruction: str
def get_fast_api_app(
*,
agents_dir: str,
@@ -820,26 +813,30 @@ def get_fast_api_app(
@working_in_progress("builder_save is not ready for use.")
@app.post("/builder/save", response_model_exclude_none=True)
async def builder_build(req: AgentBuildRequest):
async def builder_build(files: list[UploadFile]) -> bool:
base_path = Path.cwd() / agents_dir
agent = {
"agent_class": req.agent_type,
"name": req.agent_name,
"model": req.model,
"description": req.description,
"instruction": f"""{req.instruction}""",
}
try:
agent_dir = os.path.join(base_path, req.agent_name)
os.makedirs(agent_dir, exist_ok=True)
file_path = os.path.join(agent_dir, "root_agent.yaml")
with open(file_path, "w") as file:
yaml.dump(agent, file, default_flow_style=False)
agent_loader.load_agent(agent_name=req.agent_name)
return True
except Exception as e:
logger.exception("Error in builder_build: %s", e)
return False
for file in files:
try:
# File name format: {app_name}/{agent_name}.yaml
if not file.filename:
logger.exception("Agent name is missing in the input files")
return False
agent_name, filename = file.filename.split("/")
agent_dir = os.path.join(base_path, agent_name)
os.makedirs(agent_dir, exist_ok=True)
file_path = os.path.join(agent_dir, filename)
with open(file_path, "w") as buffer:
shutil.copyfileobj(file.file, buffer)
except Exception as e:
logger.exception("Error in builder_build: %s", e)
return False
return True
@app.post("/run", response_model_exclude_none=True)
async def agent_run(req: AgentRunRequest) -> list[Event]: