Repository: aipotheosis-labs/aci
File: aipolabs/server/routes/projects.py (Python)

Code before:


@router.post("/{project_id}/agents/", response_model=AgentPublic, include_in_schema=True)
async def create_agent(
    project_id: UUID,
    body: AgentCreate,
    user: Annotated[User, Depends(deps.validate_http_bearer)],
    db_session: Annotated[Session, Depends(deps.yield_db_session)],
) -> Agent:
    logger.info(f"Creating agent in project={project_id}, user={user.id}")
    acl.validate_user_access_to_project(db_session, user.id, project_id)

    agent = crud.projects.create_agent(
        db_session,
        project_id,
        body.name,
        body.description,
        body.excluded_apps,
        body.excluded_functions,
    )
    db_session.commit()
    logger.info(f"Created agent: {AgentPublic.model_validate(agent)}")
    return agent


@router.post("/agents/{agent_id}/custom-instructions/", response_model=AgentPublic)
async def create_custom_instructions(
    agent_id: UUID,
    body: CustomInstructionsCreate,
    user: Annotated[User, Depends(deps.validate_http_bearer)],
    db_session: Annotated[Session, Depends(deps.yield_db_session)],
) -> Agent:
    logger.info(f"Creating custom instructions for agent={agent_id}, and app={body.app_id}")
    # Get project id from agent
    agent = crud.projects.get_agent_by_id(db_session, agent_id)
    if not agent:
        logger.error(f"Agent not found: {agent_id}")
        raise AgentNotFound(str(agent_id))
    acl.validate_user_access_to_project(db_session, user.id, agent.project_id)
    if body.app_id in agent.excluded_apps:
        logger.error(f"App {body.app_id} is in agent's excluded_apps list")
        raise AppNotFound(f"App {body.app_id} is excluded for this agent")
    # get project
    project = crud.projects.get_project(db_session, agent.project_id)
    if not project:
        logger.error(f"Project not found: {agent.project_id}")
        raise ProjectNotFound(str(agent.project_id))
    # Validate that the app exists
    app = crud.apps.get_app(
        db_session, body.app_id, project.visibility_access == Visibility.PUBLIC, True
    )

Review comment (suggestion):
custom-instructions should just be part of agent resource, instead of having a new endpoint for a new field each time, it's better to:
1. change create agent "POST .../{project_id}/agents/" to allow client specify custom instructions when creating the agent.
2. add "PATCH  .../{project_id}/agents/{agent_id}" for client to update agent data, including but not limited to the new custom instructions.

Code after:
    project_id: UUID,
    body: AgentCreate,
    user: Annotated[User, Depends(deps.validate_http_bearer)],
    db_session: Annotated[Session, Depends(deps.yield_db_session)],
) -> Agent:
    logger.info(f"Creating agent in project={project_id}, user={user.id}")
    acl.validate_user_access_to_project(db_session, user.id, project_id)

    agent = crud.projects.create_agent(
        db_session,
        project_id,
        body.name,
        body.description,
        body.excluded_apps,
        body.excluded_functions,
        body.custom_instructions,
    )
    db_session.commit()
    logger.info(f"Created agent: {AgentPublic.model_validate(agent)}")
    return agent


@router.patch("/{project_id}/agents/{agent_id}", response_model=AgentPublic, include_in_schema=True)
async def update_agent(
    project_id: UUID,
    agent_id: UUID,
    body: AgentUpdate,
    user: Annotated[User, Depends(deps.validate_http_bearer)],
    db_session: Annotated[Session, Depends(deps.yield_db_session)],
) -> Agent:
    logger.info(f"Updating agent={agent_id} in project={project_id}")

    agent = crud.projects.get_agent_by_id(db_session, agent_id)
    if not agent:
        logger.error(f"agent={agent_id} not found")
        raise AgentNotFound(str(agent_id))

    project = crud.projects.get_project(db_session, project_id)
    if not project:
        logger.error(f"project={project_id} not found")
        raise ProjectNotFound(str(project_id))

    if agent.project_id != project_id:
        logger.error(f"agent={agent_id} is not in project={project_id}")
        raise AgentNotFound(str(agent_id))

    acl.validate_user_access_to_project(db_session, user.id, agent.project_id)

    crud.projects.update_agent(db_session, agent, body)
    db_session.commit()