mirror of
https://github.com/shawnkim1997/All-in-one-Financial-Analysis.git
synced 2026-08-18 21:08:07 +00:00
67 lines
2.0 KiB
Python
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()}
|