Files
All-in-one-Financial-Analysis/atlas-terminal/server/routers/copilot.py
T

67 lines
2.0 KiB
Python

"""Copilot chat router with terminal context injection."""
from __future__ import annotations
import json
from typing import Any, Literal
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field
from server.routers.analysis import _call_gemini, _get_financial_context
router = APIRouter()
class CopilotContext(BaseModel):
activeSymbol: str | None = None
activePage: str = "equity"
recentSymbols: list[str] = Field(default_factory=list)
currency: str = "USD"
theme: str = "bloomberg"
watchlist: list[str] = Field(default_factory=list)
class CopilotMessage(BaseModel):
role: Literal["user", "assistant", "system"]
content: str
class CopilotChatRequest(BaseModel):
message: str
context: CopilotContext = Field(default_factory=CopilotContext)
history: list[CopilotMessage] = Field(default_factory=list)
api_key: str = ""
@router.post("/chat")
async def copilot_chat(req: CopilotChatRequest) -> dict[str, Any]:
api_key = req.api_key.strip()
if not api_key:
raise HTTPException(status_code=400, detail="Gemini API key is required")
active_symbol = (req.context.activeSymbol or "").strip().upper()
context_json = json.dumps(req.context.model_dump(), ensure_ascii=False, indent=2)
financial_context = _get_financial_context(active_symbol) if active_symbol else "No active financial symbol."
history = "\n".join(f"{msg.role}: {msg.content}" for msg in req.history[-8:])
prompt = f"""
You are ATLAS Copilot, a concise equity research assistant embedded in ATLAS Terminal.
Use the terminal context below to answer the user's question. Do not invent numbers.
If a requested figure is not in context, say what data would be needed.
Terminal context:
{context_json}
Financial context for active symbol:
{financial_context}
Recent conversation:
{history or "No prior messages."}
User question:
{req.message}
""".strip()
text = await _call_gemini(api_key=api_key, prompt=prompt, max_tokens=2048, temperature=0.35)
return {"message": text, "context": req.context.model_dump()}