opencandle 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -79
- package/dist/analysts/contracts.d.ts +31 -0
- package/dist/analysts/contracts.js +158 -0
- package/dist/analysts/contracts.js.map +1 -0
- package/dist/analysts/orchestrator.d.ts +11 -2
- package/dist/analysts/orchestrator.js +156 -9
- package/dist/analysts/orchestrator.js.map +1 -1
- package/dist/cli.js +26 -10
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +29 -5
- package/dist/config.js +18 -8
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/infra/cache.d.ts +34 -0
- package/dist/infra/cache.js +44 -3
- package/dist/infra/cache.js.map +1 -1
- package/dist/infra/index.d.ts +1 -1
- package/dist/infra/index.js +1 -1
- package/dist/infra/index.js.map +1 -1
- package/dist/infra/opencandle-paths.d.ts +1 -0
- package/dist/infra/opencandle-paths.js +3 -0
- package/dist/infra/opencandle-paths.js.map +1 -1
- package/dist/infra/rate-limiter.js +7 -0
- package/dist/infra/rate-limiter.js.map +1 -1
- package/dist/memory/index.d.ts +3 -0
- package/dist/memory/index.js +2 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/manager.d.ts +19 -0
- package/dist/memory/manager.js +132 -0
- package/dist/memory/manager.js.map +1 -0
- package/dist/memory/sqlite.js +12 -1
- package/dist/memory/sqlite.js.map +1 -1
- package/dist/memory/types.d.ts +21 -0
- package/dist/memory/types.js +47 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/onboarding/connect.d.ts +23 -0
- package/dist/onboarding/connect.js +107 -0
- package/dist/onboarding/connect.js.map +1 -0
- package/dist/onboarding/credential-interceptor.d.ts +44 -0
- package/dist/onboarding/credential-interceptor.js +72 -0
- package/dist/onboarding/credential-interceptor.js.map +1 -0
- package/dist/onboarding/degradation-accumulator.d.ts +21 -0
- package/dist/onboarding/degradation-accumulator.js +55 -0
- package/dist/onboarding/degradation-accumulator.js.map +1 -0
- package/dist/onboarding/prompt-user.d.ts +23 -0
- package/dist/onboarding/prompt-user.js +61 -0
- package/dist/onboarding/prompt-user.js.map +1 -0
- package/dist/onboarding/providers.d.ts +109 -0
- package/dist/onboarding/providers.js +236 -0
- package/dist/onboarding/providers.js.map +1 -0
- package/dist/onboarding/state.d.ts +31 -2
- package/dist/onboarding/state.js +141 -13
- package/dist/onboarding/state.js.map +1 -1
- package/dist/onboarding/tool-helpers.d.ts +34 -0
- package/dist/onboarding/tool-helpers.js +80 -0
- package/dist/onboarding/tool-helpers.js.map +1 -0
- package/dist/onboarding/tool-tags.d.ts +37 -0
- package/dist/onboarding/tool-tags.js +149 -0
- package/dist/onboarding/tool-tags.js.map +1 -0
- package/dist/onboarding/validation.d.ts +19 -0
- package/dist/onboarding/validation.js +117 -0
- package/dist/onboarding/validation.js.map +1 -0
- package/dist/pi/opencandle-extension.d.ts +5 -1
- package/dist/pi/opencandle-extension.js +345 -143
- package/dist/pi/opencandle-extension.js.map +1 -1
- package/dist/pi/session.d.ts +2 -0
- package/dist/pi/session.js +1 -1
- package/dist/pi/session.js.map +1 -1
- package/dist/pi/setup.d.ts +0 -1
- package/dist/pi/setup.js +66 -119
- package/dist/pi/setup.js.map +1 -1
- package/dist/prompts/context-builder.d.ts +26 -0
- package/dist/prompts/context-builder.js +127 -0
- package/dist/prompts/context-builder.js.map +1 -0
- package/dist/prompts/sections.d.ts +13 -0
- package/dist/prompts/sections.js +35 -0
- package/dist/prompts/sections.js.map +1 -0
- package/dist/providers/alpha-vantage.d.ts +3 -0
- package/dist/providers/alpha-vantage.js +204 -77
- package/dist/providers/alpha-vantage.js.map +1 -1
- package/dist/providers/coingecko.js +53 -37
- package/dist/providers/coingecko.js.map +1 -1
- package/dist/providers/exa-search.d.ts +39 -0
- package/dist/providers/exa-search.js +276 -0
- package/dist/providers/exa-search.js.map +1 -0
- package/dist/providers/fear-greed.js +23 -15
- package/dist/providers/fear-greed.js.map +1 -1
- package/dist/providers/finnhub.d.ts +17 -0
- package/dist/providers/finnhub.js +94 -0
- package/dist/providers/finnhub.js.map +1 -0
- package/dist/providers/fred.js +48 -28
- package/dist/providers/fred.js.map +1 -1
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.js +1 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/provider-credential-error.d.ts +8 -0
- package/dist/providers/provider-credential-error.js +22 -0
- package/dist/providers/provider-credential-error.js.map +1 -0
- package/dist/providers/reddit.d.ts +8 -0
- package/dist/providers/reddit.js +78 -43
- package/dist/providers/reddit.js.map +1 -1
- package/dist/providers/twitter.d.ts +20 -0
- package/dist/providers/twitter.js +137 -0
- package/dist/providers/twitter.js.map +1 -0
- package/dist/providers/web-search.d.ts +17 -0
- package/dist/providers/web-search.js +224 -0
- package/dist/providers/web-search.js.map +1 -0
- package/dist/providers/with-fallback.d.ts +15 -0
- package/dist/providers/with-fallback.js +32 -0
- package/dist/providers/with-fallback.js.map +1 -0
- package/dist/providers/wrap-provider.d.ts +20 -0
- package/dist/providers/wrap-provider.js +58 -0
- package/dist/providers/wrap-provider.js.map +1 -0
- package/dist/providers/yahoo-finance.js +77 -57
- package/dist/providers/yahoo-finance.js.map +1 -1
- package/dist/routing/classify-intent.js +22 -0
- package/dist/routing/classify-intent.js.map +1 -1
- package/dist/runtime/evidence.d.ts +35 -0
- package/dist/runtime/evidence.js +29 -0
- package/dist/runtime/evidence.js.map +1 -0
- package/dist/runtime/index.d.ts +16 -0
- package/dist/runtime/index.js +10 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/prompt-step.d.ts +41 -0
- package/dist/runtime/prompt-step.js +42 -0
- package/dist/runtime/prompt-step.js.map +1 -0
- package/dist/runtime/provider-ids.d.ts +14 -0
- package/dist/runtime/provider-ids.js +14 -0
- package/dist/runtime/provider-ids.js.map +1 -0
- package/dist/runtime/provider-tracker.d.ts +20 -0
- package/dist/runtime/provider-tracker.js +36 -0
- package/dist/runtime/provider-tracker.js.map +1 -0
- package/dist/runtime/run-context.d.ts +11 -0
- package/dist/runtime/run-context.js +14 -0
- package/dist/runtime/run-context.js.map +1 -0
- package/dist/runtime/session-coordinator.d.ts +47 -0
- package/dist/runtime/session-coordinator.js +171 -0
- package/dist/runtime/session-coordinator.js.map +1 -0
- package/dist/runtime/validation.d.ts +44 -0
- package/dist/runtime/validation.js +157 -0
- package/dist/runtime/validation.js.map +1 -0
- package/dist/runtime/workflow-events.d.ts +21 -0
- package/dist/runtime/workflow-events.js +31 -0
- package/dist/runtime/workflow-events.js.map +1 -0
- package/dist/runtime/workflow-runner.d.ts +36 -0
- package/dist/runtime/workflow-runner.js +129 -0
- package/dist/runtime/workflow-runner.js.map +1 -0
- package/dist/runtime/workflow-types.d.ts +60 -0
- package/dist/runtime/workflow-types.js +32 -0
- package/dist/runtime/workflow-types.js.map +1 -0
- package/dist/sentiment/adapters/finnhub.d.ts +7 -0
- package/dist/sentiment/adapters/finnhub.js +39 -0
- package/dist/sentiment/adapters/finnhub.js.map +1 -0
- package/dist/sentiment/adapters/reddit.d.ts +11 -0
- package/dist/sentiment/adapters/reddit.js +54 -0
- package/dist/sentiment/adapters/reddit.js.map +1 -0
- package/dist/sentiment/adapters/twitter.d.ts +9 -0
- package/dist/sentiment/adapters/twitter.js +32 -0
- package/dist/sentiment/adapters/twitter.js.map +1 -0
- package/dist/sentiment/adapters/web.d.ts +9 -0
- package/dist/sentiment/adapters/web.js +40 -0
- package/dist/sentiment/adapters/web.js.map +1 -0
- package/dist/sentiment/index.d.ts +16 -0
- package/dist/sentiment/index.js +44 -0
- package/dist/sentiment/index.js.map +1 -0
- package/dist/sentiment/keywords.d.ts +2 -0
- package/dist/sentiment/keywords.js +9 -0
- package/dist/sentiment/keywords.js.map +1 -0
- package/dist/sentiment/pipeline.d.ts +9 -0
- package/dist/sentiment/pipeline.js +57 -0
- package/dist/sentiment/pipeline.js.map +1 -0
- package/dist/sentiment/scorer.d.ts +9 -0
- package/dist/sentiment/scorer.js +64 -0
- package/dist/sentiment/scorer.js.map +1 -0
- package/dist/sentiment/store.d.ts +24 -0
- package/dist/sentiment/store.js +177 -0
- package/dist/sentiment/store.js.map +1 -0
- package/dist/sentiment/trends.d.ts +13 -0
- package/dist/sentiment/trends.js +73 -0
- package/dist/sentiment/trends.js.map +1 -0
- package/dist/sentiment/types.d.ts +66 -0
- package/dist/sentiment/types.js +54 -0
- package/dist/sentiment/types.js.map +1 -0
- package/dist/system-prompt.js +60 -2
- package/dist/system-prompt.js.map +1 -1
- package/dist/tool-kit.d.ts +9 -5
- package/dist/tool-kit.js +29 -6
- package/dist/tool-kit.js.map +1 -1
- package/dist/tools/fundamentals/company-overview.d.ts +3 -1
- package/dist/tools/fundamentals/company-overview.js +28 -17
- package/dist/tools/fundamentals/company-overview.js.map +1 -1
- package/dist/tools/fundamentals/comps.js +47 -39
- package/dist/tools/fundamentals/comps.js.map +1 -1
- package/dist/tools/fundamentals/dcf.js +83 -65
- package/dist/tools/fundamentals/dcf.js.map +1 -1
- package/dist/tools/fundamentals/earnings.d.ts +3 -1
- package/dist/tools/fundamentals/earnings.js +26 -18
- package/dist/tools/fundamentals/earnings.js.map +1 -1
- package/dist/tools/fundamentals/financials.d.ts +3 -1
- package/dist/tools/fundamentals/financials.js +24 -16
- package/dist/tools/fundamentals/financials.js.map +1 -1
- package/dist/tools/fundamentals/sec-filings.js +9 -1
- package/dist/tools/fundamentals/sec-filings.js.map +1 -1
- package/dist/tools/index.js +10 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/interaction/ask-user.d.ts +3 -0
- package/dist/tools/interaction/ask-user.js +51 -0
- package/dist/tools/interaction/ask-user.js.map +1 -0
- package/dist/tools/interaction/twitter-login.d.ts +8 -0
- package/dist/tools/interaction/twitter-login.js +77 -0
- package/dist/tools/interaction/twitter-login.js.map +1 -0
- package/dist/tools/macro/fear-greed.js +9 -1
- package/dist/tools/macro/fear-greed.js.map +1 -1
- package/dist/tools/macro/fred-data.d.ts +3 -1
- package/dist/tools/macro/fred-data.js +27 -16
- package/dist/tools/macro/fred-data.js.map +1 -1
- package/dist/tools/market/crypto-history.js +9 -1
- package/dist/tools/market/crypto-history.js.map +1 -1
- package/dist/tools/market/crypto-price.js +9 -1
- package/dist/tools/market/crypto-price.js.map +1 -1
- package/dist/tools/market/stock-history.js +28 -1
- package/dist/tools/market/stock-history.js.map +1 -1
- package/dist/tools/market/stock-quote.js +29 -4
- package/dist/tools/market/stock-quote.js.map +1 -1
- package/dist/tools/options/option-chain.js +9 -1
- package/dist/tools/options/option-chain.js.map +1 -1
- package/dist/tools/portfolio/correlation.js +15 -3
- package/dist/tools/portfolio/correlation.js.map +1 -1
- package/dist/tools/portfolio/predictions.js +6 -5
- package/dist/tools/portfolio/predictions.js.map +1 -1
- package/dist/tools/portfolio/risk-analysis.js +9 -1
- package/dist/tools/portfolio/risk-analysis.js.map +1 -1
- package/dist/tools/portfolio/tracker.js +6 -3
- package/dist/tools/portfolio/tracker.js.map +1 -1
- package/dist/tools/portfolio/watchlist.js +6 -1
- package/dist/tools/portfolio/watchlist.js.map +1 -1
- package/dist/tools/sentiment/reddit-sentiment.d.ts +3 -1
- package/dist/tools/sentiment/reddit-sentiment.js +112 -19
- package/dist/tools/sentiment/reddit-sentiment.js.map +1 -1
- package/dist/tools/sentiment/sentiment-summary.d.ts +7 -0
- package/dist/tools/sentiment/sentiment-summary.js +230 -0
- package/dist/tools/sentiment/sentiment-summary.js.map +1 -0
- package/dist/tools/sentiment/sentiment-trend.d.ts +22 -0
- package/dist/tools/sentiment/sentiment-trend.js +39 -0
- package/dist/tools/sentiment/sentiment-trend.js.map +1 -0
- package/dist/tools/sentiment/twitter-sentiment.d.ts +9 -0
- package/dist/tools/sentiment/twitter-sentiment.js +75 -0
- package/dist/tools/sentiment/twitter-sentiment.js.map +1 -0
- package/dist/tools/sentiment/web-search.d.ts +11 -0
- package/dist/tools/sentiment/web-search.js +115 -0
- package/dist/tools/sentiment/web-search.js.map +1 -0
- package/dist/tools/sentiment/web-sentiment.d.ts +8 -0
- package/dist/tools/sentiment/web-sentiment.js +66 -0
- package/dist/tools/sentiment/web-sentiment.js.map +1 -0
- package/dist/tools/technical/backtest.js +9 -1
- package/dist/tools/technical/backtest.js.map +1 -1
- package/dist/tools/technical/indicators.js +9 -1
- package/dist/tools/technical/indicators.js.map +1 -1
- package/dist/types/index.d.ts +16 -1
- package/dist/types/sentiment.d.ts +41 -0
- package/dist/workflows/compare-assets.d.ts +3 -0
- package/dist/workflows/compare-assets.js +21 -5
- package/dist/workflows/compare-assets.js.map +1 -1
- package/dist/workflows/index.d.ts +3 -3
- package/dist/workflows/index.js +3 -3
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/options-screener.d.ts +3 -0
- package/dist/workflows/options-screener.js +24 -7
- package/dist/workflows/options-screener.js.map +1 -1
- package/dist/workflows/portfolio-builder.d.ts +3 -0
- package/dist/workflows/portfolio-builder.js +30 -9
- package/dist/workflows/portfolio-builder.js.map +1 -1
- package/package.json +27 -7
- package/dist/tools/sentiment/news-sentiment.d.ts +0 -7
- package/dist/tools/sentiment/news-sentiment.js +0 -57
- package/dist/tools/sentiment/news-sentiment.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,55 +1,65 @@
|
|
|
1
1
|
# OpenCandle
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
OpenCandle is a terminal-first financial data agent built with TypeScript and Pi. It fetches market, macro, options, fundamentals, sentiment, and portfolio data from real providers, then lets the model synthesize that data into an answer.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This repository is useful in two ways:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- Run `opencandle` as an interactive CLI for market research
|
|
8
|
+
- Extend OpenCandle with new tools, providers, or Pi-compatible add-on packages
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
## What You Can Use It For
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
- Quote and history lookups for stocks and crypto
|
|
13
|
+
- Options chains with locally computed Greeks
|
|
14
|
+
- Company fundamentals, earnings, and SEC filings
|
|
15
|
+
- FRED macro series and Fear & Greed data
|
|
16
|
+
- Reddit-based sentiment and discussion lookups
|
|
17
|
+
- Portfolio tracking, watchlists, correlation, and risk analysis
|
|
18
|
+
- Multi-step workflows such as `/analyze NVDA`
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
OpenCandle is designed to fetch and format data. The model handles synthesis. Tool code should not invent financial conclusions or hardcode market numbers.
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
## Install And Run
|
|
23
|
+
|
|
24
|
+
Requires Node.js 20+.
|
|
25
|
+
|
|
26
|
+
### CLI
|
|
16
27
|
|
|
17
28
|
```bash
|
|
18
29
|
npm install -g opencandle
|
|
19
30
|
opencandle
|
|
20
31
|
|
|
21
|
-
# or
|
|
32
|
+
# or without installing globally
|
|
22
33
|
npx opencandle@latest
|
|
23
34
|
```
|
|
24
35
|
|
|
25
|
-
On first run, OpenCandle guides you through AI model setup before chat starts. If you want to rerun that flow later, use `/setup`.
|
|
26
|
-
|
|
27
36
|
### From Source
|
|
28
37
|
|
|
29
38
|
```bash
|
|
30
39
|
npm install
|
|
31
40
|
cp .env.example .env
|
|
32
|
-
# Add any LLM env vars you want to use locally (for example GEMINI_API_KEY)
|
|
33
41
|
npm start
|
|
34
42
|
```
|
|
35
43
|
|
|
36
|
-
|
|
44
|
+
On first run, OpenCandle walks you through model setup. You can rerun that flow later with `/setup`.
|
|
37
45
|
|
|
38
|
-
|
|
39
|
-
|-----|----------|-----------|-----------------|
|
|
40
|
-
| `GEMINI_API_KEY` | No | Yes | Google Gemini via Pi auth/model registry |
|
|
41
|
-
| `OPENAI_API_KEY` | No | Paid | OpenAI models via Pi auth/model registry |
|
|
42
|
-
| `ANTHROPIC_API_KEY` | No | Paid | Anthropic models via Pi auth/model registry |
|
|
43
|
-
| `ALPHA_VANTAGE_API_KEY` | No | 25 req/day | Company fundamentals, earnings, financials |
|
|
44
|
-
| `FRED_API_KEY` | No | Generous | Fed rates, CPI, GDP, unemployment, yield curve |
|
|
46
|
+
## Configuration
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
Pi also supports OAuth-backed and custom providers through `~/.pi/agent/auth.json`, `/login`, `/model`, and `~/.pi/agent/models.json`.
|
|
48
|
+
Model access comes from Pi. Market data providers are optional and additive.
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
| Key | Required | Used For |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| `GEMINI_API_KEY` | No | Google models through Pi |
|
|
53
|
+
| `OPENAI_API_KEY` | No | OpenAI models through Pi |
|
|
54
|
+
| `ANTHROPIC_API_KEY` | No | Anthropic models through Pi |
|
|
55
|
+
| `ALPHA_VANTAGE_API_KEY` | No | Fundamentals, earnings, financial statements |
|
|
56
|
+
| `FRED_API_KEY` | No | Macro series such as rates, CPI, GDP, unemployment |
|
|
50
57
|
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
Yahoo Finance, CoinGecko, Reddit, SEC EDGAR, and Fear & Greed data do not require keys.
|
|
59
|
+
|
|
60
|
+
OpenCandle stores its own user state in `~/.opencandle/` by default. Pi configuration stays in `.pi/` and `~/.pi/agent/`. The CLI should not depend on repo-local `.pi/extensions/`.
|
|
61
|
+
|
|
62
|
+
Provider keys can also be stored in `~/.opencandle/config.json`:
|
|
53
63
|
|
|
54
64
|
```json
|
|
55
65
|
{
|
|
@@ -64,87 +74,109 @@ Pi also supports OAuth-backed and custom providers through `~/.pi/agent/auth.jso
|
|
|
64
74
|
}
|
|
65
75
|
```
|
|
66
76
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- `~/.opencandle/portfolio.json`
|
|
71
|
-
- `~/.opencandle/predictions.json`
|
|
72
|
-
- `~/.opencandle/state.db`
|
|
73
|
-
- `~/.opencandle/logs/...`
|
|
74
|
-
- The published CLI should work from any directory without depending on a repo-local `.pi/extensions/...` file. Project `.pi/` remains optional for user overrides.
|
|
77
|
+
Environment variables override values from `~/.opencandle/config.json`. Set `OPENCANDLE_HOME` if you want OpenCandle state somewhere other than `~/.opencandle/`.
|
|
78
|
+
|
|
79
|
+
## Basic Usage
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
OpenCandle runs inside Pi's interactive terminal UI.
|
|
77
82
|
|
|
78
|
-
|
|
83
|
+
Useful commands:
|
|
79
84
|
|
|
80
85
|
```text
|
|
81
|
-
/
|
|
82
|
-
/login
|
|
83
|
-
/
|
|
84
|
-
/analyze
|
|
86
|
+
/setup
|
|
87
|
+
/login
|
|
88
|
+
/model
|
|
89
|
+
/analyze AAPL
|
|
85
90
|
```
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
Example prompts:
|
|
88
93
|
|
|
89
94
|
```text
|
|
90
|
-
What
|
|
95
|
+
What is AAPL trading at?
|
|
91
96
|
Get the options chain for TSLA expiring April 24
|
|
92
97
|
Show me MSFT puts with Greeks
|
|
93
|
-
What's the Fear and Greed index?
|
|
94
98
|
Get the fed funds rate from FRED
|
|
95
99
|
Add 100 shares of NVDA at 120 to my portfolio, then show my portfolio
|
|
96
100
|
Run risk analysis on SPY
|
|
97
|
-
analyze AAPL
|
|
98
101
|
```
|
|
99
102
|
|
|
100
|
-
##
|
|
103
|
+
## Data Sources And Tool Coverage
|
|
101
104
|
|
|
102
|
-
|
|
|
103
|
-
|
|
104
|
-
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
105
|
+
| Area | Examples | Source |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| Market data | quotes, history, ticker search, crypto price/history | Yahoo Finance, CoinGecko |
|
|
108
|
+
| Options | chains, open interest, IV, Greeks | Yahoo Finance plus local calculations |
|
|
109
|
+
| Fundamentals | overview, financials, earnings, DCF, company comparison | Alpha Vantage |
|
|
110
|
+
| Macro | economic series, Fear & Greed | FRED, alternative.me |
|
|
111
|
+
| Sentiment | Reddit, Twitter/X, and web sentiment with cross-source pipeline | Reddit JSON API, Twitter/X, DuckDuckGo, Brave |
|
|
112
|
+
| Filings | SEC filing search | SEC EDGAR |
|
|
113
|
+
| Portfolio | watchlist, prediction tracking, correlation, risk | Local state plus market data |
|
|
111
114
|
|
|
112
|
-
##
|
|
115
|
+
## Engineering Notes
|
|
113
116
|
|
|
114
|
-
|
|
117
|
+
### Project Shape
|
|
115
118
|
|
|
119
|
+
```text
|
|
120
|
+
src/
|
|
121
|
+
├── providers/ API clients
|
|
122
|
+
├── tools/ Tool implementations by domain
|
|
123
|
+
├── infra/ Cache, rate limiter, HTTP, browser, paths
|
|
124
|
+
├── routing/ Intent classification and slot resolution
|
|
125
|
+
├── workflows/ Multi-step workflow builders
|
|
126
|
+
├── memory/ SQLite-backed state and retrieval
|
|
127
|
+
├── analysts/ Multi-analyst orchestration
|
|
128
|
+
├── pi/ Pi integration and session wiring
|
|
129
|
+
└── index.ts Public exports
|
|
116
130
|
```
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
131
|
+
|
|
132
|
+
### Development Commands
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npm start
|
|
136
|
+
npm test
|
|
137
|
+
npm run test:watch
|
|
138
|
+
npm run test:e2e
|
|
139
|
+
npm run test:e2e:cli
|
|
140
|
+
npm run test:e2e:providers
|
|
120
141
|
```
|
|
121
142
|
|
|
122
|
-
|
|
123
|
-
- **Local computation** over API calls for math (indicators, Greeks, risk metrics)
|
|
124
|
-
- **Stealth browser fallback** via [Camoufox](https://github.com/daijro/camoufox) when Yahoo rate-limits Node.js `fetch`
|
|
125
|
-
- **TTL caching + token bucket rate limiting** per provider
|
|
126
|
-
- **Pi-native auth/model flow** via `/model`, `/login`, `auth.json`, and `models.json`
|
|
127
|
-
- **Global OpenCandle state** under `~/.opencandle/`, separate from Pi config
|
|
128
|
-
- **Multi-analyst orchestration** via Pi extension commands and follow-up message hooks
|
|
143
|
+
`npm test` is the required baseline check after changes.
|
|
129
144
|
|
|
130
|
-
|
|
145
|
+
### Repository Rules That Matter
|
|
146
|
+
|
|
147
|
+
- TDD is mandatory for behavior changes
|
|
148
|
+
- Unit tests mock `globalThis.fetch` and use JSON fixtures
|
|
149
|
+
- Use `cache` and `rateLimiter` for external calls
|
|
150
|
+
- Tools fetch and format data; analysts and prompts synthesize
|
|
151
|
+
- Keep typing strict and use `.js` extensions on relative imports
|
|
152
|
+
|
|
153
|
+
### Public Package Exports
|
|
154
|
+
|
|
155
|
+
Besides the CLI, the package exposes pieces for engineers building on top of OpenCandle:
|
|
156
|
+
|
|
157
|
+
- `opencandle`
|
|
158
|
+
- `opencandle/tool-kit`
|
|
159
|
+
- `opencandle/infra`
|
|
160
|
+
- `opencandle/types`
|
|
161
|
+
- `opencandle/providers`
|
|
162
|
+
|
|
163
|
+
If you want to add a new tool or publish an add-on package, start with [docs/build-a-tool.md](./docs/build-a-tool.md).
|
|
164
|
+
|
|
165
|
+
## Testing The Agent
|
|
166
|
+
|
|
167
|
+
For end-to-end agent driving with file-based IPC:
|
|
131
168
|
|
|
132
169
|
```bash
|
|
133
|
-
|
|
134
|
-
npm run test:watch # watch mode
|
|
170
|
+
npx tsx tests/harness/manual-run.ts /tmp/opencandle-ipc "What is AAPL trading at?"
|
|
135
171
|
```
|
|
136
172
|
|
|
137
|
-
|
|
173
|
+
The harness writes status and trace files into the IPC directory. See [tests/harness/README.md](./tests/harness/README.md) for the full flow.
|
|
138
174
|
|
|
139
|
-
|
|
140
|
-
- Contributor guide: [CONTRIBUTING.md](https://github.com/Kahtaf/OpenCandle/blob/main/CONTRIBUTING.md)
|
|
141
|
-
- Security policy: [SECURITY.md](https://github.com/Kahtaf/OpenCandle/blob/main/SECURITY.md)
|
|
142
|
-
- Release history: [CHANGELOG.md](https://github.com/Kahtaf/OpenCandle/blob/main/CHANGELOG.md)
|
|
143
|
-
|
|
144
|
-
## Tech Stack
|
|
175
|
+
## Project Docs
|
|
145
176
|
|
|
146
|
-
-
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
-
|
|
150
|
-
-
|
|
177
|
+
- [CONTRIBUTING.md](./CONTRIBUTING.md)
|
|
178
|
+
- [docs/build-a-tool.md](./docs/build-a-tool.md)
|
|
179
|
+
- [tests/harness/README.md](./tests/harness/README.md)
|
|
180
|
+
- [CHANGELOG.md](./CHANGELOG.md)
|
|
181
|
+
- [SECURITY.md](./SECURITY.md)
|
|
182
|
+
- [LICENSE](./LICENSE)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AnalystOutput, AnalystSignal, DebateSide, DebateOutput } from "../runtime/workflow-types.js";
|
|
2
|
+
import type { EvidenceRecord } from "../runtime/evidence.js";
|
|
3
|
+
/** All analyst roles. */
|
|
4
|
+
export type AnalystRole = "valuation" | "momentum" | "options" | "contrarian" | "risk";
|
|
5
|
+
/** Evidence fields expected per analyst role. */
|
|
6
|
+
export declare const ROLE_EXPECTED_EVIDENCE: Record<AnalystRole, string[]>;
|
|
7
|
+
/**
|
|
8
|
+
* Parse an LLM response into a structured AnalystOutput.
|
|
9
|
+
* Falls back to raw text if parsing fails.
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseAnalystOutput(role: string, responseText: string): AnalystOutput;
|
|
12
|
+
/** Build a structured vote tally from analyst outputs. */
|
|
13
|
+
export declare function tallyVotes(outputs: AnalystOutput[]): {
|
|
14
|
+
buy: number;
|
|
15
|
+
hold: number;
|
|
16
|
+
sell: number;
|
|
17
|
+
weightedConviction: number;
|
|
18
|
+
verdict: AnalystSignal;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Parse an LLM debate response into a structured DebateOutput.
|
|
22
|
+
* Eval/test helper only — not used in the live workflow path.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseDebateOutput(side: DebateSide, responseText: string): DebateOutput;
|
|
25
|
+
/**
|
|
26
|
+
* Check whether analysts produced a BUY+SELL split.
|
|
27
|
+
* Eval/test helper only — not used in the live workflow path.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isAnalystSplit(outputs: AnalystOutput[]): boolean;
|
|
30
|
+
/** Collect all evidence from analyst outputs. */
|
|
31
|
+
export declare function collectEvidence(outputs: AnalystOutput[]): EvidenceRecord[];
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/** Evidence fields expected per analyst role. */
|
|
2
|
+
export const ROLE_EXPECTED_EVIDENCE = {
|
|
3
|
+
valuation: ["P/E Ratio", "Forward P/E", "EPS", "Intrinsic Value", "Revenue Growth"],
|
|
4
|
+
momentum: ["RSI", "MACD", "SMA 50", "SMA 200", "Volume Trend"],
|
|
5
|
+
options: ["Put/Call Ratio", "IV Level", "Unusual Volume", "Max Pain"],
|
|
6
|
+
contrarian: ["Fear & Greed Index", "Reddit Sentiment", "Sentiment Score"],
|
|
7
|
+
risk: ["Annualized Volatility", "Sharpe Ratio", "Max Drawdown", "VaR 95%", "Position Size"],
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Parse an LLM response into a structured AnalystOutput.
|
|
11
|
+
* Falls back to raw text if parsing fails.
|
|
12
|
+
*/
|
|
13
|
+
export function parseAnalystOutput(role, responseText) {
|
|
14
|
+
const signal = extractSignal(responseText);
|
|
15
|
+
const conviction = extractConviction(responseText);
|
|
16
|
+
const thesis = extractThesis(responseText);
|
|
17
|
+
return {
|
|
18
|
+
role,
|
|
19
|
+
signal: signal ?? "HOLD",
|
|
20
|
+
conviction: conviction ?? 5,
|
|
21
|
+
thesis: thesis ?? "",
|
|
22
|
+
evidence: [],
|
|
23
|
+
rawText: responseText,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function extractSignal(text) {
|
|
27
|
+
const match = text.match(/SIGNAL:\s*(BUY|HOLD|SELL)/i);
|
|
28
|
+
if (match)
|
|
29
|
+
return match[1].toUpperCase();
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
function extractConviction(text) {
|
|
33
|
+
const match = text.match(/CONVICTION:\s*(\d+)/i);
|
|
34
|
+
if (match) {
|
|
35
|
+
const value = parseInt(match[1], 10);
|
|
36
|
+
if (value >= 1 && value <= 10)
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
function extractThesis(text) {
|
|
42
|
+
const match = text.match(/THESIS:\s*(.+)/i);
|
|
43
|
+
return match ? match[1].trim() : null;
|
|
44
|
+
}
|
|
45
|
+
/** Build a structured vote tally from analyst outputs. */
|
|
46
|
+
export function tallyVotes(outputs) {
|
|
47
|
+
let buy = 0;
|
|
48
|
+
let hold = 0;
|
|
49
|
+
let sell = 0;
|
|
50
|
+
let totalWeight = 0;
|
|
51
|
+
let weightedSum = 0;
|
|
52
|
+
for (const output of outputs) {
|
|
53
|
+
switch (output.signal) {
|
|
54
|
+
case "BUY":
|
|
55
|
+
buy++;
|
|
56
|
+
break;
|
|
57
|
+
case "HOLD":
|
|
58
|
+
hold++;
|
|
59
|
+
break;
|
|
60
|
+
case "SELL":
|
|
61
|
+
sell++;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
totalWeight += output.conviction;
|
|
65
|
+
const signalValue = output.signal === "BUY" ? 1 : output.signal === "SELL" ? -1 : 0;
|
|
66
|
+
weightedSum += signalValue * output.conviction;
|
|
67
|
+
}
|
|
68
|
+
const weightedConviction = totalWeight > 0
|
|
69
|
+
? Math.round((totalWeight / outputs.length) * 10) / 10
|
|
70
|
+
: 0;
|
|
71
|
+
let verdict;
|
|
72
|
+
if (weightedSum > 0)
|
|
73
|
+
verdict = "BUY";
|
|
74
|
+
else if (weightedSum < 0)
|
|
75
|
+
verdict = "SELL";
|
|
76
|
+
else
|
|
77
|
+
verdict = "HOLD";
|
|
78
|
+
return { buy, hold, sell, weightedConviction, verdict };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse an LLM debate response into a structured DebateOutput.
|
|
82
|
+
* Eval/test helper only — not used in the live workflow path.
|
|
83
|
+
*/
|
|
84
|
+
export function parseDebateOutput(side, responseText) {
|
|
85
|
+
// Detect skipped rebuttal
|
|
86
|
+
if (/^rebuttal skipped/i.test(responseText.trim())) {
|
|
87
|
+
return {
|
|
88
|
+
side,
|
|
89
|
+
thesis: "",
|
|
90
|
+
keyRisk: "",
|
|
91
|
+
concessions: [],
|
|
92
|
+
remainingConviction: 0,
|
|
93
|
+
evidence: [],
|
|
94
|
+
rawText: responseText,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const thesis = extractDebateThesis(side, responseText);
|
|
98
|
+
const keyRisk = extractKeyRisk(side, responseText);
|
|
99
|
+
const concessions = extractConcessions(responseText);
|
|
100
|
+
const remainingConviction = extractRemainingConviction(responseText);
|
|
101
|
+
return {
|
|
102
|
+
side,
|
|
103
|
+
thesis,
|
|
104
|
+
keyRisk,
|
|
105
|
+
concessions,
|
|
106
|
+
remainingConviction,
|
|
107
|
+
evidence: [],
|
|
108
|
+
rawText: responseText,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function extractDebateThesis(side, text) {
|
|
112
|
+
const label = side === "bull" ? "BULL THESIS" : "BEAR THESIS";
|
|
113
|
+
const match = text.match(new RegExp(`${label}:\\s*(.+)`, "i"));
|
|
114
|
+
return match ? match[1].trim() : "";
|
|
115
|
+
}
|
|
116
|
+
function extractKeyRisk(side, text) {
|
|
117
|
+
if (side === "bear") {
|
|
118
|
+
const match = text.match(/WHAT WOULD CHANGE MY MIND:\s*(.+)/i);
|
|
119
|
+
return match ? match[1].trim() : "";
|
|
120
|
+
}
|
|
121
|
+
const match = text.match(/KEY RISK(?:\s+TO THIS THESIS)?:\s*(.+)/i);
|
|
122
|
+
return match ? match[1].trim() : "";
|
|
123
|
+
}
|
|
124
|
+
function extractConcessions(text) {
|
|
125
|
+
const match = text.match(/CONCESSIONS:\s*([\s\S]*?)(?=REMAINING CONVICTION:|$)/i);
|
|
126
|
+
if (!match)
|
|
127
|
+
return [];
|
|
128
|
+
return match[1]
|
|
129
|
+
.split("\n")
|
|
130
|
+
.map((line) => line.replace(/^[-*•]\s*/, "").trim())
|
|
131
|
+
.filter(Boolean);
|
|
132
|
+
}
|
|
133
|
+
function extractRemainingConviction(text) {
|
|
134
|
+
const match = text.match(/REMAINING CONVICTION:\s*(\d+)/i);
|
|
135
|
+
if (match) {
|
|
136
|
+
const value = parseInt(match[1], 10);
|
|
137
|
+
if (value >= 1 && value <= 10)
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check whether analysts produced a BUY+SELL split.
|
|
144
|
+
* Eval/test helper only — not used in the live workflow path.
|
|
145
|
+
*/
|
|
146
|
+
export function isAnalystSplit(outputs) {
|
|
147
|
+
const votes = tallyVotes(outputs);
|
|
148
|
+
return votes.buy > 0 && votes.sell > 0;
|
|
149
|
+
}
|
|
150
|
+
/** Collect all evidence from analyst outputs. */
|
|
151
|
+
export function collectEvidence(outputs) {
|
|
152
|
+
const evidence = [];
|
|
153
|
+
for (const output of outputs) {
|
|
154
|
+
evidence.push(...output.evidence);
|
|
155
|
+
}
|
|
156
|
+
return evidence;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/analysts/contracts.ts"],"names":[],"mappings":"AAWA,iDAAiD;AACjD,MAAM,CAAC,MAAM,sBAAsB,GAAkC;IACnE,SAAS,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,CAAC;IACnF,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAC;IAC9D,OAAO,EAAE,CAAC,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,CAAC;IACrE,UAAU,EAAE,CAAC,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,CAAC;IACzE,IAAI,EAAE,CAAC,uBAAuB,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,CAAC;CAC5F,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,YAAoB;IAEpB,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAE3C,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,MAAM,IAAI,MAAM;QACxB,UAAU,EAAE,UAAU,IAAI,CAAC;QAC3B,MAAM,EAAE,MAAM,IAAI,EAAE;QACpB,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,YAAY;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACvD,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAmB,CAAC;IAC1D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACjD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC5C,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,UAAU,CAAC,OAAwB;IAOjD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,KAAK,KAAK;gBACR,GAAG,EAAE,CAAC;gBACN,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,EAAE,CAAC;gBACP,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,EAAE,CAAC;gBACP,MAAM;QACV,CAAC;QACD,WAAW,IAAI,MAAM,CAAC,UAAU,CAAC;QACjC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,WAAW,IAAI,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;IACjD,CAAC;IAED,MAAM,kBAAkB,GAAG,WAAW,GAAG,CAAC;QACxC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE;QACtD,CAAC,CAAC,CAAC,CAAC;IAEN,IAAI,OAAsB,CAAC;IAC3B,IAAI,WAAW,GAAG,CAAC;QAAE,OAAO,GAAG,KAAK,CAAC;SAChC,IAAI,WAAW,GAAG,CAAC;QAAE,OAAO,GAAG,MAAM,CAAC;;QACtC,OAAO,GAAG,MAAM,CAAC;IAEtB,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC;AAC1D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAgB,EAAE,YAAoB;IACtE,0BAA0B;IAC1B,IAAI,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACnD,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,mBAAmB,EAAE,CAAC;YACtB,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,YAAY;SACtB,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACrD,MAAM,mBAAmB,GAAG,0BAA0B,CAAC,YAAY,CAAC,CAAC;IAErE,OAAO;QACL,IAAI;QACJ,MAAM;QACN,OAAO;QACP,WAAW;QACX,mBAAmB;QACnB,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,YAAY;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAgB,EAAE,IAAY;IACzD,MAAM,KAAK,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC;AAED,SAAS,cAAc,CAAC,IAAgB,EAAE,IAAY;IACpD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC/D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtC,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACpE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAClF,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK,CAAC,CAAC,CAAC;SACZ,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;SACnD,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,0BAA0B,CAAC,IAAY;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAC3D,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC;IAC9C,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAAwB;IACrD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,eAAe,CAAC,OAAwB;IACtD,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
export type AnalystRole = "valuation" | "momentum" | "options" | "contrarian" | "risk";
|
|
2
|
+
export declare function buildBullPrompt(symbol: string): string;
|
|
3
|
+
export declare function buildBearPrompt(symbol: string): string;
|
|
4
|
+
export declare function buildRebuttalPrompt(symbol: string): string;
|
|
5
|
+
export declare function buildSynthesisPrompt(symbol: string): string;
|
|
2
6
|
export declare function getInitialAnalysisPrompt(symbol: string): string;
|
|
3
|
-
export
|
|
4
|
-
|
|
7
|
+
export interface ComprehensiveAnalysisOptions {
|
|
8
|
+
debate?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function getComprehensiveAnalysisPrompts(symbol: string, options?: ComprehensiveAnalysisOptions): string[];
|
|
11
|
+
import type { WorkflowDefinition } from "../runtime/prompt-step.js";
|
|
12
|
+
export declare function buildComprehensiveAnalysisDefinition(symbol: string, options?: ComprehensiveAnalysisOptions): WorkflowDefinition;
|
|
13
|
+
export declare function runComprehensiveAnalysis(enqueueFollowUp: (prompt: string) => void, symbol: string, options?: ComprehensiveAnalysisOptions): void;
|
|
5
14
|
export declare function isAnalysisRequest(input: string): {
|
|
6
15
|
match: boolean;
|
|
7
16
|
symbol?: string;
|