open-webui/backend/open_webui/routers/agents.py
google-labs-jules[bot] 1345b55fe1 feat: Implement Agent Creation with Generalized Model Support
This commit introduces the initial Agent Creation Playground feature and ensures it supports all model types available in Open WebUI, not just Ollama models.

Key changes include:

Frontend:
- Created a new Agent Creation form at `/agents/create`.
- Added a link to the playground in the sidebar (admin only).
- The form now fetches and displays all available models from the `/api/models` endpoint.
- Updated UI to correctly handle generalized model IDs.

Backend:
- Modified the `Agent` model to store a generic `model_id` (foreign key to the `models` table) instead of a specific `llm_model`.
- Updated API endpoints and Pydantic schemas accordingly.
- Created database migrations to reflect schema changes.
- Verified that the existing `/api/models` endpoint can be used to list all models for the creation form.

Testing:
- Added Cypress E2E tests for the agent creation form.
- Tests verify that different model types can be selected and that the correct `model_id` and other agent details are submitted to the backend.

This provides a foundation for you to define agents using any model integrated with your Open WebUI instance.
2025-05-28 11:03:52 +00:00

77 lines
2.9 KiB
Python

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List, Optional
from open_webui.models.agents import Agent as AgentModel
from open_webui.models.auths import User as UserModel
from open_webui.utils.utils import get_current_user, get_db
from pydantic import BaseModel, Field
from datetime import datetime
router = APIRouter()
# Pydantic Schemas for Agent CRUD operations
class AgentBase(BaseModel):
name: str
role: str
system_message: Optional[str] = None
model_id: str # Changed from llm_model to model_id
skills: Optional[List[str]] = None # Assuming skills are a list of strings for now
class AgentCreate(AgentBase):
pass
class AgentResponse(AgentBase):
id: int
user_id: str
timestamp: datetime
class Config:
orm_mode = True # For FastAPI to map SQLAlchemy models to Pydantic models
# API Endpoints
@router.post("/", response_model=AgentResponse)
async def create_agent(agent_data: AgentCreate, db: Session = Depends(get_db), current_user: UserModel = Depends(get_current_user)):
agent = AgentModel(**agent_data.model_dump(), user_id=current_user.id)
db.add(agent)
db.commit()
db.refresh(agent)
return agent
@router.get("/", response_model=List[AgentResponse])
async def get_agents(db: Session = Depends(get_db), current_user: UserModel = Depends(get_current_user)):
agents = db.query(AgentModel).filter(AgentModel.user_id == current_user.id).all()
return agents
@router.get("/{agent_id}", response_model=AgentResponse)
async def get_agent(agent_id: int, db: Session = Depends(get_db), current_user: UserModel = Depends(get_current_user)):
agent = db.query(AgentModel).filter(AgentModel.id == agent_id, AgentModel.user_id == current_user.id).first()
if not agent:
raise HTTPException(status_code=404, detail="Agent not found")
return agent
@router.put("/{agent_id}", response_model=AgentResponse)
async def update_agent(agent_id: int, agent_data: AgentCreate, db: Session = Depends(get_db), current_user: UserModel = Depends(get_current_user)):
agent = db.query(AgentModel).filter(AgentModel.id == agent_id, AgentModel.user_id == current_user.id).first()
if not agent:
raise HTTPException(status_code=404, detail="Agent not found")
for key, value in agent_data.model_dump(exclude_unset=True).items():
setattr(agent, key, value)
agent.timestamp = datetime.utcnow() # Update timestamp
db.commit()
db.refresh(agent)
return agent
@router.delete("/{agent_id}", status_code=204)
async def delete_agent(agent_id: int, db: Session = Depends(get_db), current_user: UserModel = Depends(get_current_user)):
agent = db.query(AgentModel).filter(AgentModel.id == agent_id, AgentModel.user_id == current_user.id).first()
if not agent:
raise HTTPException(status_code=404, detail="Agent not found")
db.delete(agent)
db.commit()
return None