-
Notifications
You must be signed in to change notification settings - Fork 24
Add finance-insight-agent sample #237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ef55bd4
2d3309d
788b548
04ffbf0
48fe91b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Finance Insight Service - Environment Variables Template | ||
| # Copy this file to .env and fill in your API keys | ||
|
|
||
| # Required: OpenAI API for AI agents (GPT-4, embeddings) | ||
| OPENAI_API_KEY=sk-... | ||
|
|
||
| # News Search (required) | ||
| ## Get from serpapi.com | ||
| SERPAPI_API_KEY= | ||
|
|
||
| ## Market Data (required) - Get from twelvedata.com | ||
| TWELVE_DATA_API_KEY= | ||
|
|
||
| ## Company Fundamentals (required for fundamental analysis) - Get from alphavantage.co | ||
| ALPHAVANTAGE_API_KEY= | ||
|
|
||
| # Optional: Backend API authentication (protects endpoints like /config) | ||
| API_KEY= | ||
|
|
||
| # Optional: CORS allow-list (comma-separated origins) | ||
| CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:3001 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| .env | ||
| __pycache__/ | ||
| .venv/ | ||
| .pytest_cache/ | ||
| *.egg-info/ | ||
| data/ | ||
| node_modules/ | ||
| .next/ | ||
| .choreo/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| # API Key Management | ||
|
|
||
| ## Quick Links | ||
|
|
||
| | Service | Purpose | Get API Key | Free Tier | | ||
| |---------|---------|-------------|-----------| | ||
| | **OpenAI** | LLM for agents (Required) | [platform.openai.com/api-keys](https://platform.openai.com/api-keys) | $5 free credit | | ||
| | **SerpAPI** | Google search for news (Required) | [serpapi.com](https://serpapi.com) | 250 searches/month | | ||
| | **Alpha Vantage** | Company fundamentals (Required for ratios) | [alphavantage.co/support/#api-key](https://www.alphavantage.co/support/#api-key) | 25 requests/day | | ||
| | **Twelve Data** | Market data (Required) | [twelvedata.com/apikey](https://twelvedata.com/apikey) | Credits/day (varies by endpoint) | | ||
|
|
||
| --- | ||
|
|
||
| ## How to Get API Keys | ||
|
|
||
| ### 1. OpenAI API Key (Required) | ||
|
|
||
| **Step-by-step:** | ||
| 1. Go to [platform.openai.com](https://platform.openai.com) | ||
| 2. Sign up or log in to your account | ||
| 3. Click your profile icon → **View API Keys** | ||
| 4. Click **Create new secret key** | ||
| 5. Name it "Finance Insight Service" | ||
| 6. Copy the key (starts with `sk-proj-...`) | ||
| 7. **Save it immediately** - you won't see it again! | ||
|
|
||
| **Pricing:** | ||
| - GPT-4o: $2.50 / 1M input tokens, $10 / 1M output tokens | ||
| - GPT-4o-mini: $0.15 / 1M input tokens, $0.60 / 1M output tokens | ||
| - Average query cost: ~$0.10-0.30 with GPT-4o | ||
|
|
||
| **Important:** Add billing information at [platform.openai.com/settings/billing](https://platform.openai.com/settings/billing) to increase rate limits. | ||
|
|
||
| ### 2. SerpAPI Key (Required) | ||
|
|
||
| **Step-by-step:** | ||
| 1. Go to [serpapi.com](https://serpapi.com) | ||
| 2. Sign up for an account | ||
| 3. Go to your dashboard and find the API key | ||
| 4. Copy the key (long alphanumeric string) | ||
|
|
||
| **Free Tier:** | ||
| - 250 searches per month (free tier may change) | ||
| - See pricing and free-tier limits: https://serpapi.com/pricing | ||
| - Credit card might be required depending on plan | ||
|
|
||
| ### 3. Alpha Vantage API Key (Required for fundamentals) | ||
|
|
||
| **Step-by-step:** | ||
| 1. Go to [alphavantage.co/support/#api-key](https://www.alphavantage.co/support/#api-key) | ||
| 2. Enter your email and click **GET FREE API KEY** | ||
| 3. Key is sent to your email instantly | ||
| 4. Copy the key (alphanumeric string) | ||
|
|
||
| **Free Tier:** | ||
| - 25 API requests per day | ||
| - 5 requests per minute | ||
| - No credit card required | ||
|
|
||
| ### 4. Twelve Data API Key (Required for market data) | ||
|
|
||
| **Step-by-step:** | ||
| 1. Go to [twelvedata.com](https://twelvedata.com) | ||
| 2. Sign up for free account | ||
| 3. Go to [Dashboard → API Key](https://twelvedata.com/apikey) | ||
| 4. Copy your API key | ||
|
|
||
| **Free Tier:** | ||
| - Quota is based on credits per day (endpoint costs vary) | ||
| - See pricing and limits: https://twelvedata.com/pricing | ||
|
|
||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| --- | ||
|
|
||
| ## How It Works | ||
|
|
||
| ### Development Mode | ||
| In development, the backend reads API keys from a `.env` file in the project root: | ||
|
|
||
| ```bash | ||
| # Copy the example file | ||
| cp .env.example .env | ||
|
|
||
| # Edit with your keys | ||
| nano .env | ||
| ``` | ||
|
|
||
| The backend must be **restarted** after changing `.env`: | ||
| ```bash | ||
| uv run finance_insight_api --host 0.0.0.0 --port 5000 | ||
| ``` | ||
|
|
||
| ### Production Mode | ||
| For production deployments, set environment variables directly: | ||
|
|
||
| **Docker (recommended):** | ||
| ```bash | ||
| # Create .env with your secrets (keep it out of git) | ||
| docker run --env-file .env finance-insight | ||
| ``` | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| **Systemd Service:** | ||
| ```ini | ||
| [Service] | ||
| Environment="OPENAI_API_KEY=sk-..." | ||
| Environment="SERPAPI_API_KEY=..." | ||
| Environment="TWELVE_DATA_API_KEY=..." | ||
| Environment="ALPHAVANTAGE_API_KEY=..." | ||
| ``` | ||
|
|
||
| **OpenChoreo / AMP:** | ||
| - Set these as environment variables when creating or updating the agent in the AMP UI. | ||
|
|
||
|
|
||
| ## Required Keys | ||
|
|
||
| - **OPENAI_API_KEY** - AI agents won't work without this | ||
| - **SERPAPI_API_KEY** - Required for news search | ||
| - **TWELVE_DATA_API_KEY** - Required for market data | ||
| - **ALPHAVANTAGE_API_KEY** - Required for fundamentals | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,22 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||
| FROM python:3.11-slim | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| ENV PYTHONUNBUFFERED=1 \ | ||||||||||||||||||||||||||||||||||||||||||||||||
| PIP_DISABLE_PIP_VERSION_CHECK=1 | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| WORKDIR /app | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| RUN apt-get update \ | ||||||||||||||||||||||||||||||||||||||||||||||||
| && apt-get install -y --no-install-recommends build-essential libgomp1 \ | ||||||||||||||||||||||||||||||||||||||||||||||||
| && rm -rf /var/lib/apt/lists/* | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| COPY . . | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prevent accidental secret leakage in the image. 🛡️ Suggested .dockerignore (new file)+.env
+.env.*
+__pycache__/
+.venv/
+.pytest_cache/
+*.egg-info/
+data/
+node_modules/
+.next/
+.choreo/
+dist/
+build/🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| RUN pip install --no-cache-dir uv \ | ||||||||||||||||||||||||||||||||||||||||||||||||
| && uv sync --frozen | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| ENV VIRTUAL_ENV=/app/.venv | ||||||||||||||||||||||||||||||||||||||||||||||||
| ENV PATH="$VIRTUAL_ENV/bin:$PATH" | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+19
|
||||||||||||||||||||||||||||||||||||||||||||||||
| && rm -rf /var/lib/apt/lists/* | |
| COPY . . | |
| RUN pip install --no-cache-dir uv \ | |
| && uv sync --frozen | |
| ENV VIRTUAL_ENV=/app/.venv | |
| ENV PATH="$VIRTUAL_ENV/bin:$PATH" | |
| && rm -rf /var/lib/apt/lists/* \ | |
| && useradd --create-home --shell /usr/sbin/nologin appuser | |
| COPY . . | |
| RUN chown -R appuser:appuser /app | |
| RUN pip install --no-cache-dir uv \ | |
| && uv sync --frozen | |
| ENV VIRTUAL_ENV=/app/.venv | |
| ENV PATH="$VIRTUAL_ENV/bin:$PATH" | |
| USER appuser |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Dockerfile runs as root user, which is a security risk. Consider adding a non-root user to run the application. Add these lines before CMD: RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app and USER appuser.
| RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app | |
| USER appuser |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| # Finance Insight Service | ||
|
|
||
| ## Overview | ||
| Finance Insight Service is a stateless, async report generator for financial research and analysis. It combines current market context with deterministic calculations to deliver concise, evidence-aware responses. | ||
|
|
||
| ## Key Features | ||
| - **Evidence-aware research** - Collects relevant financial context before answering | ||
| - **Deterministic quant** - All numbers are computed, not guessed | ||
| - **Audit + report split** - Validation and reporting are separated for clarity | ||
| - **Stateless requests** - Each request runs independently (no chat memory) | ||
|
|
||
|
|
||
| ## Architecture | ||
|
|
||
| The system runs a sequential, agent-based workflow with explicit quality gates: | ||
|
|
||
| 1. **Research** - Collects relevant financial context and evidence | ||
| 2. **Quant** - Computes required metrics and scenarios deterministically | ||
| 3. **Audit** - Validates outputs and flags issues | ||
| 4. **Report** - Produces the final user-facing response | ||
|
|
||
| Request flow (stateless): | ||
| - UI submits a request to `/chat/async` | ||
| - API server starts a background job and emits progress traces | ||
| - UI polls `/chat/async/<job_id>/status` and fetches `/result` when complete | ||
|
|
||
| Core components: | ||
| - **Scenario UI** (web) for request submission and report viewing | ||
| - **API server (Flask)** for async job execution and status/result APIs | ||
| - **Agent orchestrator (CrewAI)** running Research → Quant → Audit → Report | ||
| - **Tools**: SerpAPI news search, Twelve Data OHLCV, Alpha Vantage fundamentals, Safe Python Exec | ||
| - **LLM provider**: OpenAI for reasoning and embeddings in tools | ||
|
|
||
| Design principles: | ||
| - Strict handoff between stages to preserve context and quality | ||
| - Deterministic computations instead of LLM-generated numbers | ||
| - Transparent limitations whenever data is missing or uncertain | ||
|
|
||
|  | ||
|
|
||
| ## AMP / Choreo Deployment | ||
|
|
||
| AMP repo: <https://github.com/wso2/ai-agent-management-platform/tree/amp/v0> | ||
|
|
||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ### Prerequisites | ||
| - Kubernetes cluster (k3d or equivalent) | ||
| - AMP installed (see AMP quick start guide) | ||
| - Docker registry accessible to the cluster | ||
| - API keys for OpenAI, SerpAPI, Twelve Data, Alpha Vantage (the service will start without them, but related features will fail or degrade at runtime) | ||
|
|
||
| ### Create Component Definition | ||
| Create `.choreo/component.yaml` in your project root: | ||
|
|
||
| ```yaml | ||
| schemaVersion: "1.0" | ||
| id: finance-insight | ||
| name: Finance Insight Service | ||
| type: service | ||
| description: AI-powered financial research assistant | ||
| runtime: python | ||
| buildType: dockerfile | ||
| image: Dockerfile | ||
| ports: | ||
| - port: 8000 | ||
| type: http | ||
| env: | ||
| - name: OPENAI_API_KEY | ||
| valueFrom: SECRET | ||
| - name: SERPAPI_API_KEY | ||
| valueFrom: SECRET | ||
| - name: TWELVE_DATA_API_KEY | ||
| valueFrom: SECRET | ||
| - name: ALPHAVANTAGE_API_KEY | ||
| valueFrom: SECRET | ||
| ``` | ||
|
|
||
| ### Build and Push Image | ||
| ```bash | ||
| docker build -t finance-insight-service:latest . | ||
| docker tag finance-insight-service:latest \ | ||
| localhost:10082/default-finance-insight-image:v1 | ||
| docker push localhost:10082/default-finance-insight-image:v1 | ||
| ``` | ||
|
|
||
| ### Deploy via AMP Console | ||
| 1. Open AMP Console at `http://default.localhost:9080` | ||
| 2. Create Agent → Service → Python → Port 8000 | ||
| 3. Add environment variables listed above | ||
| 4. Deploy and verify health at `/finance-insight/health` | ||
|
|
||
| ## Configuration | ||
| Copy `.env.example` to `.env` and set these keys: | ||
| - `OPENAI_API_KEY` | ||
| - `SERPAPI_API_KEY` | ||
| - `TWELVE_DATA_API_KEY` | ||
| - `ALPHAVANTAGE_API_KEY` | ||
| - `CORS_ALLOWED_ORIGINS` (optional, comma-separated origins for allowed frontend URLs, e.g. `http://localhost:3000,http://localhost:3001`) | ||
|
|
||
| See key setup details in [API_KEYS.md](API_KEYS.md). | ||
|
|
||
| ## Contributing | ||
| Open an issue or submit a pull request with clear context and test notes. | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,24 @@ | ||||||||||
| [project] | ||||||||||
| name = "finance-insight-service" | ||||||||||
| version = "0.1.0" | ||||||||||
| description = "Finance Insight Service - research agent" | ||||||||||
| readme = "README.md" | ||||||||||
| requires-python = ">=3.10" | ||||||||||
| dependencies = [ | ||||||||||
| "crewai[tools]>=1.8.0,<1.9.0", | ||||||||||
| "crewai-tools>=1.8.0,<1.9.0", | ||||||||||
|
Comment on lines
+8
to
+9
|
||||||||||
| "crewai[tools]>=1.8.0,<1.9.0", | |
| "crewai-tools>=1.8.0,<1.9.0", | |
| "crewai[tools]>=1.8.0,<2.0.0", | |
| "crewai-tools>=1.8.0,<2.0.0", |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The project has no test files despite being a complex sample with API integrations, data processing, and async job handling. For a sample intended to demonstrate best practices, consider adding at least basic unit tests for critical components like the tools (serpapi_news_search, safe_python_exec) and API endpoints to show how to test such systems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify package structure and UV configuration for finance-insight-agent
echo "=== Directory structure ==="
tree -L 3 samples/finance-insight-agent/ 2>/dev/null || find samples/finance-insight-agent/ -type f -o -type d | head -30
echo -e "\n=== Check if src layout exists ==="
if [ -d "samples/finance-insight-agent/src" ]; then
echo "src/ directory exists"
ls -la samples/finance-insight-agent/src/
else
echo "src/ directory does not exist"
fi
echo -e "\n=== Check package location ==="
fd "finance_insight_service" samples/finance-insight-agent/ -type d
echo -e "\n=== Check api_server.py and main function ==="
if [ -f "samples/finance-insight-agent/src/finance_insight_service/api_server.py" ]; then
echo "Found at src/finance_insight_service/api_server.py"
grep -n "def main" samples/finance-insight-agent/src/finance_insight_service/api_server.py
elif [ -f "samples/finance-insight-agent/finance_insight_service/api_server.py" ]; then
echo "Found at finance_insight_service/api_server.py"
grep -n "def main" samples/finance-insight-agent/finance_insight_service/api_server.py
else
echo "api_server.py not found in expected locations"
find samples/finance-insight-agent/ -name "api_server.py" 2>/dev/null
fi
echo -e "\n=== Full pyproject.toml content ==="
cat samples/finance-insight-agent/pyproject.tomlRepository: wso2/ai-agent-management-platform
Length of output: 1838
Configure package-dir in [tool.uv] for proper src-layout support.
The src/ layout exists with the package correctly placed at src/finance_insight_service/ and the entry point api_server.py:main is present. However, [tool.uv] lacks explicit package-dir configuration. Add package-dir = "src" to ensure UV correctly resolves the package for installation and entry point execution:
[tool.uv]
package = true
package-dir = "src"
🤖 Prompt for AI Agents
In `@samples/finance-insight-agent/pyproject.toml` around lines 19 - 23, The
project uses a src/ layout with the package at src/finance_insight_service and
the entry point finance_insight_service.api_server:main, but [tool.uv] is
missing the package-dir setting; update the [tool.uv] section to add package-dir
= "src" so UV can resolve the finance_insight_service package for installation
and the finance_insight_api entry point to run correctly.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| """Finance Insight Service package.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid real-looking key prefixes in templates.
OPENAI_API_KEY=sk-...can trip secret scanners and encourages copying a real-looking key. Use a neutral placeholder (e.g.,OPENAI_API_KEY=orOPENAI_API_KEY=YOUR_OPENAI_API_KEY).🔧 Suggested change
📝 Committable suggestion
🤖 Prompt for AI Agents