-
Install with uv (virtualenv is at
.venv):uv sync
-
Set your API keys (see below for how to get them):
export ANTHROPIC_API_KEY="your-anthropic-api-key" export PERPLEXITY_API_KEY="your-perplexity-api-key" export GOOGLE_API_KEY="your-google-api-key" export FMP_API_KEY="your-fmp-api-key"
Or create a
.envfile in the project root with:ANTHROPIC_API_KEY=your-anthropic-api-key PERPLEXITY_API_KEY=your-perplexity-api-key GOOGLE_API_KEY=your-google-api-key FMP_API_KEY=your-fmp-api-keyThe Perplexity key is used by the
scoped_perplexity_searchtool. The Google key is used by the agent’s LiteLLM model (Gemini). The FMP key is used by the server's/newsendpoint. See below for how to get each key.
- Go to API Keys on the Claude Developer Platform.
- Sign in or create an Anthropic account if needed.
- Click Create Key.
- Give the key a name (e.g. “Wealthsimple Deepsearch”), then confirm.
- Copy the key immediately—it starts with
sk-ant-and is shown only once. If you lose it, you’ll need to create a new key. - Set it in your environment or in a
.envfile asANTHROPIC_API_KEY=sk-ant-....
- Go to API Keys on your Perplexity account.
- Sign in or create a Perplexity account if needed.
- Click Create API Key (or equivalent).
- Name the key if prompted, then create it.
- Copy the key and store it securely—it may only be shown once.
- Set it in your environment or in a
.envfile asPERPLEXITY_API_KEY=....
The project uses the key with Google AI Studio (Gemini API). To get one:
- Go to Google AI Studio.
- Sign in with your Google account.
- In the left sidebar, open Get API key (under “API keys” or “Get started”).
- Click Create API key and choose an existing Google Cloud project or create a new one.
- Copy the generated key (it may start with
AIza...). Store it securely. - Set it in your environment or in a
.envfile asGOOGLE_API_KEY=....
If you prefer to use a key from Google Cloud Console instead: go to APIs & Services → Credentials, create an API key, and enable the Generative Language API for the project.
Financial Modeling Prep provides stock market data. To get a free API key:
- Go to Register and create an account.
- Verify your email and sign in.
- Open the Developer Docs — your API key is shown there (free tier: 250 requests/day).
- Set it in your environment or in a
.envfile asFMP_API_KEY=....
Run the agent with the Gradio interface, then open the URL (e.g. http://127.0.0.1:7860) in your browser.
With Make:
make run-agentOr with uv directly:
uv run python -m app.agents.deep_research_agentRun the same agent as a headless HTTP API (e.g. for the Grease Monkey injector).
With Make:
make run-serverOr with uv directly:
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000Then call it with curl:
curl -X POST http://localhost:8000/run \
-H "Content-Type: application/json" \
-d '{"task": "What is the current stock price of Apple (AAPL)?"}'GET /health– health checkPOST /run– body{"task": "your question"}→{"result": "..."}
Deep Search responses are cached in a local SQLite database keyed by company (parsed from the task’s Company: ... line). The next time you click Deep Research for the same company, the server returns the cached result instead of running the agent again.
- Database location:
data/deep_search.dbin the project root (created automatically). Override withDEEPSEARCH_DB_PATH(e.g.export DEEPSEARCH_DB_PATH=/path/to/deep_search.db).
We use Gemini 2.0 Flash (gemini/gemini-2.0-flash) as the orchestrator model for the agent. It is cheap and fast, and a good starting point for tool-calling and reasoning over search and financial data.
Anthropic cannot be used as the brain behind the agent because the rate limit set by Anthropic is too low for it to be useful.
We use Perplexity (via the scoped_perplexity_search tool) because it scrapes the entire web and exposes a clean API that returns LLM-friendly results. It also has a partnership with Financial Modelling Prep, which makes it very useful when querying for basic financial information.
The grease_monkey userscript runs in the browser (e.g. on Wealthsimple) and talks to the local agent server. Flow:
┌─────────────────────────────────────────────────────────────────┐
│ Browser (e.g. Wealthsimple) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ grease_monkey.user.js (Tampermonkey / Greasemonkey) │ │
│ │ • Injects "Deep Research" button (e.g. under About section) │ │
│ │ • User enters/confirms task → POST /run │ │
│ │ • Renders streaming or final result in UI │ │
│ └───────────────────────────┬─────────────────────────────────┘ │
└──────────────────────────────┼───────────────────────────────────┘
│
│ HTTP POST /run {"task": "..."}
│ GET /health
▼
┌─────────────────────────────────────────────────────────────────┐
│ Agent server (uvicorn app.main:app --port 8000) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ FastAPI • /health • /run │ │
│ │ CodeAgent (Gemini 2.0 Flash) + tools │ │
│ │ → scoped_perplexity_search, yfinance_*, generic_search… │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
- Install the userscript in Tampermonkey (or Greasemonkey) and ensure the agent server is running (
make run-serveroruv run uvicorn app.main:app --host 0.0.0.0 --port 8000). - Open a matching page; the script injects the button and checks
/healthto confirm the server is up. - User triggers Deep Research; the script sends the task to
POST /runand displays the agent’s response.
The userscript lives in this repo at:
wealthsimple_injector/grease_monkey.user.js
Follow the same approach as Wealthsimple Utilities (Greasemonkey userscripts on Wealthsimple):
- Install a userscript manager in your browser:
- Firefox: Greasemonkey
- Chrome / Edge: Tampermonkey
- Open the manager and create a new user script.
- Copy the full contents of
wealthsimple_injector/grease_monkey.user.jsinto the script editor. Review the code if you want to confirm it only talks to your local agent server and does not send data elsewhere. - Save the script.
- Ensure the agent server is running, then go to the Wealthsimple site (or a matching page). The injected “Deep Research” button should appear where the script places it (e.g. under the About section).
See architecture.md for a full component map, data flow, API surface, and rendered system diagram.
app/– Python application package:main.py– FastAPI app for headless agent:GET /health,POST /run.prompt.py– System prompt and instructions for the agent.agents/– Agent driver and tools:deep_research_agent.py– CodeAgent (Gemini 2.0 Flash) + Gradio UI entry point.tools/– Tool package:agent_tools.py– Custom tools:scoped_perplexity_search,generic_search,generate_deep_research_hypothesis,output_formatter.yfinance_tools.py– yfinance tools (each takes aticker, e.g. AAPL, RY.TO):ticker_history,ticker_info,ticker_dividends,ticker_splits,ticker_calendarticker_financials,ticker_quarterly_financials,ticker_balance_sheet,ticker_quarterly_balance_sheetticker_cashflow,ticker_quarterly_cashflow,ticker_institutional_holders,ticker_sustainabilityticker_options,ticker_option_chain,ticker_download
test_yfinance_tools.py– Test script for yfinance tools.
wealthsimple_injector/– Browser userscript that injects the Deep Research UI and calls the agent server:grease_monkey.user.js– Tampermonkey/Greasemonkey script; install in your browser to use on Wealthsimple (see Installing the script).
Run uv run python -m app.test_yfinance_tools to verify all yfinance tools (uses ticker AAPL).
- About section only detected on second reload — The shadow DOM needs to load once before the detection script can find the About section. If the Deep Research button does not appear, reload the page once and it should show up.
- Deep Research not using all tools; results less deep than Google Deep Search — The agent is not yet tuned to use all available tools consistently, so the output is qualitatively shallower than Google’s Deep Search. Tuning (prompts, tool selection, and orchestration) is required.