Files
Stirling-PDF/engine/src/stirling/api/app.py
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

84 lines
2.8 KiB
Python
Raw Normal View History

2026-03-26 10:35:47 +00:00
from __future__ import annotations
from contextlib import asynccontextmanager
from typing import Annotated
from fastapi import Depends, FastAPI
from pydantic_ai import Agent
from pydantic_ai.models.instrumented import InstrumentationSettings
2026-03-26 10:35:47 +00:00
2026-05-01 14:11:54 +01:00
from stirling.agents import (
ExecutionPlanningAgent,
OrchestratorAgent,
PdfEditAgent,
PdfQuestionAgent,
UserSpecAgent,
)
2026-04-17 10:36:45 +01:00
from stirling.agents.ledger import MathAuditorAgent
2026-05-01 10:19:38 +01:00
from stirling.agents.pdf_comment import PdfCommentAgent
from stirling.api.middleware import UserIdMiddleware
2026-03-26 10:35:47 +00:00
from stirling.api.routes import (
agent_draft_router,
execution_router,
2026-04-17 10:36:45 +01:00
ledger_router,
2026-03-26 10:35:47 +00:00
orchestrator_router,
2026-05-01 10:19:38 +01:00
pdf_comments_router,
2026-03-26 10:35:47 +00:00
pdf_edit_router,
pdf_question_router,
2026-04-21 12:42:33 +01:00
rag_router,
2026-03-26 10:35:47 +00:00
)
from stirling.config import AppSettings, load_settings
from stirling.contracts import HealthResponse
from stirling.services import build_runtime, setup_posthog_tracking
2026-03-26 10:35:47 +00:00
def _load_startup_settings(fast_api: FastAPI) -> AppSettings:
override = fast_api.dependency_overrides.get(load_settings)
if override is not None:
return override()
return load_settings()
@asynccontextmanager
async def lifespan(fast_api: FastAPI):
# Load env vars on startup so we can immediately crash if required env vars aren't set
settings = _load_startup_settings(fast_api)
runtime = build_runtime(settings)
fast_api.state.settings = settings
fast_api.state.runtime = runtime
fast_api.state.orchestrator_agent = OrchestratorAgent(runtime)
fast_api.state.pdf_edit_agent = PdfEditAgent(runtime)
fast_api.state.pdf_question_agent = PdfQuestionAgent(runtime)
fast_api.state.user_spec_agent = UserSpecAgent(runtime)
fast_api.state.execution_planning_agent = ExecutionPlanningAgent(runtime)
2026-04-17 10:36:45 +01:00
fast_api.state.math_auditor_agent = MathAuditorAgent(runtime)
2026-05-01 10:19:38 +01:00
fast_api.state.pdf_comment_agent = PdfCommentAgent(runtime)
tracer_provider = setup_posthog_tracking(settings)
if tracer_provider:
Agent.instrument_all(InstrumentationSettings(tracer_provider=tracer_provider))
2026-03-26 10:35:47 +00:00
yield
2026-05-01 14:11:54 +01:00
await runtime.rag_service.close()
if tracer_provider:
tracer_provider.shutdown()
2026-03-26 10:35:47 +00:00
app = FastAPI(title="Stirling AI Engine", lifespan=lifespan, version="0.1.0")
app.add_middleware(UserIdMiddleware)
2026-03-26 10:35:47 +00:00
app.include_router(orchestrator_router)
app.include_router(pdf_edit_router)
app.include_router(pdf_question_router)
app.include_router(agent_draft_router)
app.include_router(execution_router)
2026-04-21 12:42:33 +01:00
app.include_router(rag_router)
2026-04-17 10:36:45 +01:00
app.include_router(ledger_router)
2026-05-01 10:19:38 +01:00
app.include_router(pdf_comments_router)
2026-03-26 10:35:47 +00:00
@app.get("/health", response_model=HealthResponse)
async def healthcheck(settings: Annotated[AppSettings, Depends(load_settings)]) -> HealthResponse:
return HealthResponse(
status="ok",
smart_model=settings.smart_model_name,
fast_model=settings.fast_model_name,
)