Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions samples/finance-insight-agent/.env.example
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-...

Comment on lines +4 to +6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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= or OPENAI_API_KEY=YOUR_OPENAI_API_KEY).

🔧 Suggested change
-OPENAI_API_KEY=sk-...
+OPENAI_API_KEY=
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Required: OpenAI API for AI agents (GPT-4, embeddings)
OPENAI_API_KEY=sk-...
# Required: OpenAI API for AI agents (GPT-4, embeddings)
OPENAI_API_KEY=
🤖 Prompt for AI Agents
In `@samples/finance-insight-agent/.env.example` around lines 4 - 6, The
.env.example currently uses a realistic-looking API key prefix
("OPENAI_API_KEY=sk-...") which can trigger secret scanners; update the
placeholder for the OPENAI_API_KEY entry to a neutral value such as
"OPENAI_API_KEY=" or "OPENAI_API_KEY=YOUR_OPENAI_API_KEY" (i.e., remove the
"sk-" prefix and any realistic characters) so the template no longer resembles a
real secret.

# 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
9 changes: 9 additions & 0 deletions samples/finance-insight-agent/.gitignore
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/
119 changes: 119 additions & 0 deletions samples/finance-insight-agent/API_KEYS.md
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

---

## 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
```

**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
22 changes: 22 additions & 0 deletions samples/finance-insight-agent/Dockerfile
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 . .
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Prevent accidental secret leakage in the image.
COPY . . will include any local .env or other sensitive files unless a .dockerignore is present, which can bake secrets into the image. Consider adding a .dockerignore for secrets and bulky artifacts.

🛡️ Suggested .dockerignore (new file)
+.env
+.env.*
+__pycache__/
+.venv/
+.pytest_cache/
+*.egg-info/
+data/
+node_modules/
+.next/
+.choreo/
+dist/
+build/
🤖 Prompt for AI Agents
In `@samples/finance-insight-agent/Dockerfile` at line 12, The Dockerfile uses a
broad COPY . . which can accidentally bake local secrets (like .env) into the
image; create a .dockerignore that excludes sensitive files and bulky artifacts
(e.g., .env, .env.* , .git, node_modules, build/, *.pem, credentials/*) and then
update build steps to copy only required artifacts or rely on the .dockerignore;
reference the COPY . . instruction in the Dockerfile and add the new
.dockerignore to the project to prevent secret leakage.


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
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The container image runs the application as the default root user because no non-privileged USER is defined before the CMD, which is a risky configuration in production. If an attacker exploits the app or a dependency, root inside the container increases the potential impact (e.g., easier container escape, filesystem damage, or lateral movement). Define and switch to a dedicated non-root user (with only the minimal required permissions) before starting finance_insight_service.api_server to reduce privilege and harden the runtime environment.

Suggested change
&& 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 uses AI. Check for mistakes.
EXPOSE 8000

Copy link

Copilot AI Jan 27, 2026

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.

Suggested change
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser

Copilot uses AI. Check for mistakes.
CMD ["python", "-m", "finance_insight_service.api_server", "--host", "0.0.0.0", "--port", "8000"]
102 changes: 102 additions & 0 deletions samples/finance-insight-agent/README.md
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

![Architecture diagram](image.png)

## AMP / Choreo Deployment

AMP repo: <https://github.com/wso2/ai-agent-management-platform/tree/amp/v0>

### 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.
Binary file added samples/finance-insight-agent/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions samples/finance-insight-agent/pyproject.toml
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
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The crewAI dependency version is pinned to >=1.8.0,<1.9.0 in pyproject.toml. This is a narrow version range that may cause compatibility issues. If crewAI releases 1.9.0 with breaking changes, this is good. However, ensure this aligns with the features used in the code (like the events API and instrumentation).

Suggested change
"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 uses AI. Check for mistakes.
"openinference-instrumentation-crewai>=0.1.0,<0.2.0",
"flask>=3.0.0,<4.0.0",
"flask-cors>=4.0.0,<5.0.0",
"numpy>=1.26.4,<2.0.0",
"openai>=1.40.0,<2.0.0",
"pandas>=2.2.2,<3.0.0",
"python-dotenv>=1.0.1,<2.0.0",
"setuptools>=65.0.0,<80.0.0",
]

[project.scripts]
finance_insight_api = "finance_insight_service.api_server:main"

[tool.uv]
package = true
Comment on lines +1 to +24
Copy link

Copilot AI Jan 27, 2026

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.

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 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.toml

Repository: 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."""
Loading