mirror of
https://github.com/microsoft/autogen.git
synced 2025-07-19 15:01:52 +00:00

<!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> This PR has 3 main improvements. - Token streaming - Adds support for environment variables in the app settings - Updates AGS to persist Gallery entry in db. ## Adds Token Streaming in AGS. Agentchat now supports streaming of tokens via `ModelClientStreamingChunkEvent `. This PR is to track progress on supporting that in the AutoGen Studio UI. If `model_client_stream` is enabled in an assitant agent, then token will be streamed in UI. ```python streaming_assistant = AssistantAgent( name="assistant", model_client=model_client, system_message="You are a helpful assistant.", model_client_stream=True, # Enable streaming tokens. ) ``` https://github.com/user-attachments/assets/74d43d78-6359-40c3-a78e-c84dcb5e02a1 ## Env Variables Also adds support for env variables in AGS Settings You can set env variables that are loaded just before a team is run. Handy to set variable to be used by tools etc. <img width="1291" alt="image" src="https://github.com/user-attachments/assets/437b9d90-ccee-42f7-be5d-94ab191afd67" /> > Note: the set variables are available to the server process. <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> Closes #5627 Closes #5662 Closes #5619 ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed.
184 lines
4.4 KiB
Python
184 lines
4.4 KiB
Python
# api/app.py
|
|
import os
|
|
from contextlib import asynccontextmanager
|
|
from typing import AsyncGenerator
|
|
|
|
# import logging
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.staticfiles import StaticFiles
|
|
from loguru import logger
|
|
|
|
from ..version import VERSION
|
|
from .config import settings
|
|
from .deps import cleanup_managers, init_managers
|
|
from .initialization import AppInitializer
|
|
from .routes import gallery, runs, sessions, settingsroute, teams, validation, ws
|
|
|
|
# Initialize application
|
|
app_file_path = os.path.dirname(os.path.abspath(__file__))
|
|
initializer = AppInitializer(settings, app_file_path)
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
|
"""
|
|
Lifecycle manager for the FastAPI application.
|
|
Handles initialization and cleanup of application resources.
|
|
"""
|
|
|
|
try:
|
|
# Initialize managers (DB, Connection, Team)
|
|
await init_managers(initializer.database_uri, initializer.config_dir, initializer.app_root)
|
|
|
|
# Any other initialization code
|
|
logger.info(
|
|
f"Application startup complete. Navigate to http://{os.environ.get('AUTOGENSTUDIO_HOST', '127.0.0.1')}:{os.environ.get('AUTOGENSTUDIO_PORT', '8081')}"
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to initialize application: {str(e)}")
|
|
raise
|
|
|
|
yield # Application runs here
|
|
|
|
# Shutdown
|
|
try:
|
|
logger.info("Cleaning up application resources...")
|
|
await cleanup_managers()
|
|
logger.info("Application shutdown complete")
|
|
except Exception as e:
|
|
logger.error(f"Error during shutdown: {str(e)}")
|
|
|
|
|
|
# Create FastAPI application
|
|
app = FastAPI(lifespan=lifespan, debug=True)
|
|
|
|
# CORS middleware configuration
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=[
|
|
"http://localhost:8000",
|
|
"http://127.0.0.1:8000",
|
|
"http://localhost:8001",
|
|
"http://localhost:8081",
|
|
],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# Create API router with version and documentation
|
|
api = FastAPI(
|
|
root_path="/api",
|
|
title="AutoGen Studio API",
|
|
version=VERSION,
|
|
description="AutoGen Studio is a low-code tool for building and testing multi-agent workflows.",
|
|
docs_url="/docs" if settings.API_DOCS else None,
|
|
)
|
|
|
|
# Include all routers with their prefixes
|
|
api.include_router(
|
|
sessions.router,
|
|
prefix="/sessions",
|
|
tags=["sessions"],
|
|
responses={404: {"description": "Not found"}},
|
|
)
|
|
|
|
api.include_router(
|
|
runs.router,
|
|
prefix="/runs",
|
|
tags=["runs"],
|
|
responses={404: {"description": "Not found"}},
|
|
)
|
|
|
|
api.include_router(
|
|
teams.router,
|
|
prefix="/teams",
|
|
tags=["teams"],
|
|
responses={404: {"description": "Not found"}},
|
|
)
|
|
|
|
|
|
api.include_router(
|
|
ws.router,
|
|
prefix="/ws",
|
|
tags=["websocket"],
|
|
responses={404: {"description": "Not found"}},
|
|
)
|
|
|
|
api.include_router(
|
|
validation.router,
|
|
prefix="/validate",
|
|
tags=["validation"],
|
|
responses={404: {"description": "Not found"}},
|
|
)
|
|
|
|
api.include_router(
|
|
settingsroute.router,
|
|
prefix="/settings",
|
|
tags=["settings"],
|
|
responses={404: {"description": "Not found"}},
|
|
)
|
|
|
|
api.include_router(
|
|
gallery.router,
|
|
prefix="/gallery",
|
|
tags=["gallery"],
|
|
responses={404: {"description": "Not found"}},
|
|
)
|
|
|
|
# Version endpoint
|
|
|
|
|
|
@api.get("/version")
|
|
async def get_version():
|
|
"""Get API version"""
|
|
return {
|
|
"status": True,
|
|
"message": "Version retrieved successfully",
|
|
"data": {"version": VERSION},
|
|
}
|
|
|
|
|
|
# Health check endpoint
|
|
|
|
|
|
@api.get("/health")
|
|
async def health_check():
|
|
"""API health check endpoint"""
|
|
return {
|
|
"status": True,
|
|
"message": "Service is healthy",
|
|
}
|
|
|
|
|
|
# Mount static file directories
|
|
app.mount("/api", api)
|
|
app.mount(
|
|
"/files",
|
|
StaticFiles(directory=initializer.static_root, html=True),
|
|
name="files",
|
|
)
|
|
app.mount("/", StaticFiles(directory=initializer.ui_root, html=True), name="ui")
|
|
|
|
# Error handlers
|
|
|
|
|
|
@app.exception_handler(500)
|
|
async def internal_error_handler(request, exc):
|
|
logger.error(f"Internal error: {str(exc)}")
|
|
return {
|
|
"status": False,
|
|
"message": "Internal server error",
|
|
"detail": str(exc) if settings.API_DOCS else "Internal server error",
|
|
}
|
|
|
|
|
|
def create_app() -> FastAPI:
|
|
"""
|
|
Factory function to create and configure the FastAPI application.
|
|
Useful for testing and different deployment scenarios.
|
|
"""
|
|
return app
|