Skip to content

Tayne78/finsight-agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FinSight Agent

FinSight Agent is a full-stack investor research workflow:

  • React frontend sends a finance question to FastAPI.
  • FastAPI validates and guards the question, optionally exposes the plan, and coordinates specialist research agents.
  • Amazon Bedrock powers a multi-agent pipeline: Amazon Nova Pro plans the run and synthesizes the final report, while Amazon Nova Lite writes specialist analysis sections.
  • Market data, price history, and recent headlines are prefetched before agent execution.
  • The backend returns normalized JSON for the UI or deterministic PDF bytes for download.

This repository is intentionally structured so new contributors can extend it without having to load the entire codebase into context first.

Architecture

Current request flow:

Frontend -> /analyze/plan (optional) or /analyze -> guardrails -> analysis_service -> planner -> data_prefetcher -> selected specialist agents (parallel) -> report agent -> JSON response

/analyze/pdf can either run the same full pipeline from a question or render a cached report object directly into PDF bytes.

Separation of concerns:

  • backend/app/main.py: API wiring only
  • backend/app/schemas/: request and response contracts
  • backend/app/agents/: planner, orchestrator, report synthesis, and specialist agent definitions
  • backend/app/tools/: external data collection
  • backend/app/services/: request-level coordination, integrations, guardrails, and output generation
  • frontend/: React UI scaffold and API client
  • backend/app/config.py: environment-driven settings, loads backend/.env

Execution Model

  1. POST /analyze/plan or the internal planner chooses entities, specialist agents, and report style.
  2. backend/app/tools/data_prefetcher.py inspects the selected agents' required_data and fetches only the needed metrics, headlines, and price history in parallel.
  3. backend/app/agents/orchestrator.py builds a shared AgentContext and runs the selected specialists in parallel with ThreadPoolExecutor.
  4. backend/app/agents/report_agent.py synthesizes the specialist outputs into a normalized report dict.
  5. backend/app/services/pdf_service.py renders that report deterministically without any extra Bedrock or data-fetch calls.

Current specialist agents:

  • news_sentiment
  • fundamental_analysis
  • risk_assessment
  • peer_comparison
  • technical_analysis
  • market_context
  • wealth_strategy
  • income_strategy
  • financial_education

Project Structure

finsight-agent/
├── AGENTS.md
├── README.md
├── backend/
│   ├── requirements.txt
│   ├── .env.example
│   ├── tests/
│   │   ├── test_analysis_fallbacks.py
│   │   ├── test_analysis_service.py
│   │   ├── test_data_prefetcher.py
│   │   ├── test_input_guardrails.py
│   │   └── test_main_error_handling.py
│   └── app/
│       ├── main.py
│       ├── config.py
│       ├── agents/
│       │   ├── base_agent.py
│       │   ├── planner_agent.py
│       │   ├── report_agent.py
│       │   ├── orchestrator.py
│       │   ├── news_agent.py
│       │   ├── fundamentals_agent.py
│       │   ├── risk_agent.py
│       │   ├── comparison_agent.py
│       │   ├── technical_agent.py
│       │   ├── market_context_agent.py
│       │   ├── wealth_strategy_agent.py
│       │   ├── income_strategy_agent.py
│       │   ├── education_agent.py
│       │   ├── registry.py
│       │   └── shared.py
│       ├── schemas/
│       │   └── analysis.py
│       ├── services/
│       │   ├── analysis_service.py
│       │   ├── bedrock_service.py
│       │   ├── errors.py
│       │   ├── input_guardrails.py
│       │   └── pdf_service.py
│       └── tools/
│           ├── data_prefetcher.py
│           ├── finance_tools.py
│           └── search_tools.py
├── frontend/
└── scripts/

Design Rules

These rules keep the backend extensible:

  1. Keep API handlers thin.
  2. Put request/response models in backend/app/schemas/, not inside route files.
  3. Keep orchestration in backend/app/agents/; avoid letting route handlers call tools directly.
  4. Put provider-specific code in backend/app/services/ or backend/app/tools/, never scattered across agent modules.
  5. Extend the analysis result by adding fields in one place first: backend/app/schemas/analysis.py.
  6. Prefer adding new modules over growing one large file.

Current Coverage

  • backend/tests/ covers service fallbacks, guardrails, prefetching, and FastAPI error handling.
  • Prompt logic still lives with the agents and services; add backend/app/prompts/ if prompt templates need versioning or become hard to review.

API

GET /health

Returns:

{ "status": "ok" }

POST /analyze

Request:

{
  "question": "Compare Nvidia and AMD for a long-term investor"
}

Optional planned execution:

{
  "question": "Compare Nvidia and AMD for a long-term investor",
  "plan": {
    "entities": [
      { "company_name": "NVIDIA", "ticker": "NVDA" },
      { "company_name": "Advanced Micro Devices", "ticker": "AMD" }
    ],
    "agents": [
      { "agent_id": "peer_comparison", "task": "Compare the two companies." },
      { "agent_id": "fundamental_analysis", "task": "Assess relative fundamentals." }
    ],
    "report_style": "comparison"
  }
}

Response:

{
  "title": "Comparative Financial Analysis: Compare Nvidia and AMD for a long-term investor",
  "summary": "string",
  "sections": [
    {
      "title": "Peer Comparison",
      "agent": "peer_comparison",
      "content": "string"
    }
  ],
  "verdict": "string",
  "entities": [
    { "company_name": "NVIDIA", "ticker": "NVDA" },
    { "company_name": "Advanced Micro Devices", "ticker": "AMD" }
  ],
  "warnings": [],
  "orchestration": [
    {
      "step_id": "planner",
      "label": "Planner",
      "status": "completed",
      "task": "Selected the best specialist agents for the question."
    }
  ],
  "pdf_meta": {
    "report_style": "comparison",
    "entities": [],
    "specialists": [],
    "headlines": [],
    "warnings": []
  }
}

POST /analyze/plan

Request:

{
  "question": "Compare Nvidia and AMD for a long-term investor"
}

Response:

{
  "entities": [
    { "company_name": "NVIDIA", "ticker": "NVDA" },
    { "company_name": "Advanced Micro Devices", "ticker": "AMD" }
  ],
  "agents": [
    { "agent_id": "peer_comparison", "task": "Compare the two companies." },
    { "agent_id": "fundamental_analysis", "task": "Assess relative fundamentals." }
  ],
  "report_style": "comparison"
}

POST /analyze/pdf

Returns application/pdf.

Two supported request shapes:

Generate a fresh report from a question:

{
  "question": "Compare Nvidia and AMD for a long-term investor"
}

Or render a cached analysis response directly to PDF:

{
  "report": {
    "title": "Comparative Financial Analysis: Compare Nvidia and AMD for a long-term investor",
    "summary": "string",
    "sections": [],
    "verdict": "string",
    "entities": [],
    "warnings": [],
    "orchestration": [],
    "pdf_meta": {}
  }
}

If a cached report is provided, question may be omitted.

Validation and Error Shape

  • Question guardrails run before planning and analysis.
  • Guardrail failures return HTTP 422 with a structured detail object.
  • Service failures return structured error payloads instead of raw tracebacks.

Example guardrail error:

{
  "detail": {
    "code": "out_of_scope",
    "message": "FinSight only accepts genuine finance, investing, or market questions.",
    "suggested_question": "Compare Nvidia and AMD for a long-term investor",
    "category": "scope"
  }
}

Local Setup

# 1. one-time setup (venv + pip + npm)
./scripts/dev_setup.sh

# 2. fill in AWS credentials
#    edit backend/.env

# 3. start backend (terminal 1)
./scripts/dev_backend.sh   # → http://localhost:8000

# 4. start frontend (terminal 2)
./scripts/dev_frontend.sh  # → http://localhost:5173

Dev Scripts

From the repo root:

./scripts/dev_setup.sh
./scripts/dev_backend.sh
./scripts/dev_frontend.sh

Optional env overrides:

  • PORT=8010 ./scripts/dev_backend.sh
  • FRONTEND_PORT=5174 ./scripts/dev_frontend.sh

Environment Variables

Required:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_DEFAULT_REGION
  • BEDROCK_MODEL_ID

Optional:

  • BEDROCK_RESEARCH_MODEL_ID
  • APP_ENV
  • FRONTEND_ORIGIN

Defaults from backend/.env.example:

  • AWS_DEFAULT_REGION=us-east-1
  • BEDROCK_MODEL_ID=amazon.nova-pro-v1:0
  • BEDROCK_RESEARCH_MODEL_ID=amazon.nova-lite-v1:0
  • APP_ENV=development
  • FRONTEND_ORIGIN=http://localhost:5173

Bedrock Notes

  • Use us-east-1 unless you have confirmed another enabled region.
  • Confirm Amazon Nova model access in the Bedrock console before debugging code.
  • Bedrock calls use the bedrock-runtime converse API through backend/app/services/bedrock_service.py.
  • BEDROCK_MODEL_ID is used for JSON-producing planner and report-agent calls.
  • BEDROCK_RESEARCH_MODEL_ID is used for plain-text specialist agent sections.
  • The current default split is amazon.nova-pro-v1:0 for planning and synthesis, and amazon.nova-lite-v1:0 for specialist research.

Frontend

The React scaffold lives in frontend/README.md.

Default local split:

  • backend: http://localhost:8000
  • frontend: http://localhost:5173

For AI Agents

If you are an AI coding agent, read AGENTS.md first.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors