opencandle 0.5.0 → 0.7.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 +170 -186
- package/dist/analysts/contracts.d.ts +1 -3
- package/dist/analysts/contracts.js +1 -11
- package/dist/analysts/contracts.js.map +1 -1
- package/dist/analysts/orchestrator.d.ts +1 -3
- package/dist/analysts/orchestrator.js +1 -26
- package/dist/analysts/orchestrator.js.map +1 -1
- package/dist/cli.js +66 -7
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +13 -3
- package/dist/config.js +25 -5
- 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 +8 -11
- package/dist/infra/cache.js +17 -15
- package/dist/infra/cache.js.map +1 -1
- package/dist/infra/http-client.d.ts +4 -1
- package/dist/infra/http-client.js +59 -6
- package/dist/infra/http-client.js.map +1 -1
- package/dist/infra/index.d.ts +2 -3
- package/dist/infra/index.js +2 -3
- package/dist/infra/index.js.map +1 -1
- package/dist/infra/native-dependencies.js +2 -2
- package/dist/infra/native-dependencies.js.map +1 -1
- package/dist/infra/node-version.js.map +1 -1
- package/dist/infra/opencandle-paths.d.ts +0 -3
- package/dist/infra/opencandle-paths.js +4 -11
- package/dist/infra/opencandle-paths.js.map +1 -1
- package/dist/infra/rate-limiter.js +12 -9
- package/dist/infra/rate-limiter.js.map +1 -1
- package/dist/market-state/alert-conditions.d.ts +34 -0
- package/dist/market-state/alert-conditions.js +23 -0
- package/dist/market-state/alert-conditions.js.map +1 -0
- package/dist/market-state/alert-runner.d.ts +55 -0
- package/dist/market-state/alert-runner.js +634 -0
- package/dist/market-state/alert-runner.js.map +1 -0
- package/dist/market-state/daily-report.d.ts +26 -0
- package/dist/market-state/daily-report.js +179 -0
- package/dist/market-state/daily-report.js.map +1 -0
- package/dist/market-state/local-automation-service.d.ts +25 -0
- package/dist/market-state/local-automation-service.js +119 -0
- package/dist/market-state/local-automation-service.js.map +1 -0
- package/dist/market-state/notification-delivery.d.ts +14 -0
- package/dist/market-state/notification-delivery.js +139 -0
- package/dist/market-state/notification-delivery.js.map +1 -0
- package/dist/market-state/resolve-for-mutation.d.ts +10 -0
- package/dist/market-state/resolve-for-mutation.js +15 -0
- package/dist/market-state/resolve-for-mutation.js.map +1 -0
- package/dist/market-state/resolve.d.ts +14 -0
- package/dist/market-state/resolve.js +89 -0
- package/dist/market-state/resolve.js.map +1 -0
- package/dist/market-state/service.d.ts +527 -0
- package/dist/market-state/service.js +1099 -0
- package/dist/market-state/service.js.map +1 -0
- package/dist/memory/index.d.ts +7 -7
- package/dist/memory/index.js +6 -6
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/manager.js +11 -11
- package/dist/memory/manager.js.map +1 -1
- package/dist/memory/retrieval.js +7 -4
- package/dist/memory/retrieval.js.map +1 -1
- package/dist/memory/sqlite.js +385 -3
- package/dist/memory/sqlite.js.map +1 -1
- package/dist/memory/storage.js +1 -2
- package/dist/memory/storage.js.map +1 -1
- package/dist/memory/tool-defaults.js +64 -28
- package/dist/memory/tool-defaults.js.map +1 -1
- package/dist/memory/types.js.map +1 -1
- package/dist/monitor.d.ts +2 -0
- package/dist/monitor.js +104 -0
- package/dist/monitor.js.map +1 -0
- package/dist/onboarding/connect.d.ts +2 -2
- package/dist/onboarding/connect.js +13 -8
- package/dist/onboarding/connect.js.map +1 -1
- package/dist/onboarding/credential-interceptor.js +1 -1
- package/dist/onboarding/credential-interceptor.js.map +1 -1
- package/dist/onboarding/degradation-accumulator.js +1 -3
- package/dist/onboarding/degradation-accumulator.js.map +1 -1
- package/dist/onboarding/provider-status.d.ts +48 -0
- package/dist/onboarding/provider-status.js +285 -0
- package/dist/onboarding/provider-status.js.map +1 -0
- package/dist/onboarding/providers.d.ts +85 -8
- package/dist/onboarding/providers.js +83 -18
- package/dist/onboarding/providers.js.map +1 -1
- package/dist/onboarding/state.d.ts +1 -0
- package/dist/onboarding/state.js +5 -0
- package/dist/onboarding/state.js.map +1 -1
- package/dist/onboarding/tool-helpers.js +1 -1
- package/dist/onboarding/tool-helpers.js.map +1 -1
- package/dist/onboarding/tool-tags.d.ts +12 -1
- package/dist/onboarding/tool-tags.js +37 -5
- package/dist/onboarding/tool-tags.js.map +1 -1
- package/dist/onboarding/validation.d.ts +2 -2
- package/dist/onboarding/validation.js +1 -1
- package/dist/onboarding/validation.js.map +1 -1
- package/dist/pi/opencandle-extension.d.ts +8 -0
- package/dist/pi/opencandle-extension.js +502 -42
- package/dist/pi/opencandle-extension.js.map +1 -1
- package/dist/pi/session.d.ts +1 -1
- package/dist/pi/session.js +3 -1
- package/dist/pi/session.js.map +1 -1
- package/dist/pi/setup.js +8 -3
- package/dist/pi/setup.js.map +1 -1
- package/dist/pi/tool-adapter.d.ts +4 -1
- package/dist/pi/tool-adapter.js +10 -6
- package/dist/pi/tool-adapter.js.map +1 -1
- package/dist/prompts/context-builder.d.ts +1 -1
- package/dist/prompts/context-builder.js +20 -7
- package/dist/prompts/context-builder.js.map +1 -1
- package/dist/prompts/policy-cards.d.ts +1 -1
- package/dist/prompts/policy-cards.js +2 -2
- package/dist/prompts/policy-cards.js.map +1 -1
- package/dist/prompts/sections.d.ts +1 -1
- package/dist/prompts/symbol-preflight.d.ts +20 -0
- package/dist/prompts/symbol-preflight.js +49 -0
- package/dist/prompts/symbol-preflight.js.map +1 -0
- package/dist/prompts/workflow-prompts.d.ts +1 -1
- package/dist/prompts/workflow-prompts.js +54 -16
- package/dist/prompts/workflow-prompts.js.map +1 -1
- package/dist/providers/alpha-vantage.d.ts +1 -1
- package/dist/providers/alpha-vantage.js +26 -7
- package/dist/providers/alpha-vantage.js.map +1 -1
- package/dist/providers/coingecko.js +1 -1
- package/dist/providers/coingecko.js.map +1 -1
- package/dist/providers/errors.d.ts +5 -0
- package/dist/providers/errors.js +11 -0
- package/dist/providers/errors.js.map +1 -0
- package/dist/providers/exa-search.d.ts +2 -2
- package/dist/providers/exa-search.js +19 -11
- package/dist/providers/exa-search.js.map +1 -1
- package/dist/providers/external-tool-error.d.ts +10 -0
- package/dist/providers/external-tool-error.js +21 -0
- package/dist/providers/external-tool-error.js.map +1 -0
- package/dist/providers/fear-greed.js +1 -1
- package/dist/providers/fear-greed.js.map +1 -1
- package/dist/providers/finnhub.js +3 -5
- package/dist/providers/finnhub.js.map +1 -1
- package/dist/providers/fred.js +2 -2
- package/dist/providers/fred.js.map +1 -1
- package/dist/providers/index.d.ts +7 -6
- package/dist/providers/index.js +6 -5
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/reddit-cli.d.ts +36 -0
- package/dist/providers/reddit-cli.js +201 -0
- package/dist/providers/reddit-cli.js.map +1 -0
- package/dist/providers/reddit.d.ts +1 -1
- package/dist/providers/reddit.js +9 -37
- package/dist/providers/reddit.js.map +1 -1
- package/dist/providers/sec-edgar.d.ts +1 -0
- package/dist/providers/sec-edgar.js +12 -4
- package/dist/providers/sec-edgar.js.map +1 -1
- package/dist/providers/tradingview.d.ts +47 -0
- package/dist/providers/tradingview.js +275 -0
- package/dist/providers/tradingview.js.map +1 -0
- package/dist/providers/twitter-cli.d.ts +40 -0
- package/dist/providers/twitter-cli.js +153 -0
- package/dist/providers/twitter-cli.js.map +1 -0
- package/dist/providers/twitter.d.ts +0 -8
- package/dist/providers/twitter.js +8 -60
- package/dist/providers/twitter.js.map +1 -1
- package/dist/providers/web-search.js +26 -12
- package/dist/providers/web-search.js.map +1 -1
- package/dist/providers/with-fallback.js +4 -2
- package/dist/providers/with-fallback.js.map +1 -1
- package/dist/providers/wrap-provider.d.ts +2 -3
- package/dist/providers/wrap-provider.js +44 -8
- package/dist/providers/wrap-provider.js.map +1 -1
- package/dist/providers/yahoo-finance.d.ts +1 -1
- package/dist/providers/yahoo-finance.js +153 -48
- package/dist/providers/yahoo-finance.js.map +1 -1
- package/dist/routing/classify-intent.d.ts +6 -0
- package/dist/routing/classify-intent.js +78 -7
- package/dist/routing/classify-intent.js.map +1 -1
- package/dist/routing/defaults.d.ts +1 -1
- package/dist/routing/entity-extractor.d.ts +1 -0
- package/dist/routing/entity-extractor.js +234 -29
- package/dist/routing/entity-extractor.js.map +1 -1
- package/dist/routing/fund-symbols.d.ts +2 -0
- package/dist/routing/fund-symbols.js +55 -0
- package/dist/routing/fund-symbols.js.map +1 -0
- package/dist/routing/horizon.d.ts +1 -0
- package/dist/routing/horizon.js +10 -0
- package/dist/routing/horizon.js.map +1 -0
- package/dist/routing/index.d.ts +10 -10
- package/dist/routing/index.js +6 -6
- package/dist/routing/index.js.map +1 -1
- package/dist/routing/planning.d.ts +2 -2
- package/dist/routing/planning.js +65 -34
- package/dist/routing/planning.js.map +1 -1
- package/dist/routing/route-manifest.d.ts +2 -2
- package/dist/routing/route-manifest.js +25 -4
- package/dist/routing/route-manifest.js.map +1 -1
- package/dist/routing/router-llm-client.js.map +1 -1
- package/dist/routing/router-prompt.js +7 -9
- package/dist/routing/router-prompt.js.map +1 -1
- package/dist/routing/router-types.d.ts +1 -0
- package/dist/routing/router.js +137 -22
- package/dist/routing/router.js.map +1 -1
- package/dist/routing/slot-resolver.d.ts +1 -1
- package/dist/routing/slot-resolver.js +2 -4
- package/dist/routing/slot-resolver.js.map +1 -1
- package/dist/routing/symbol-disambiguator.d.ts +11 -0
- package/dist/routing/symbol-disambiguator.js +52 -0
- package/dist/routing/symbol-disambiguator.js.map +1 -0
- package/dist/routing/turn-context.d.ts +1 -1
- package/dist/routing/turn-context.js +1 -1
- package/dist/routing/turn-context.js.map +1 -1
- package/dist/routing/types.d.ts +2 -0
- package/dist/runtime/answer-contracts.d.ts +1 -1
- package/dist/runtime/answer-contracts.js +48 -9
- package/dist/runtime/answer-contracts.js.map +1 -1
- package/dist/runtime/artifact-contracts.js.map +1 -1
- package/dist/runtime/planning-evidence.js +47 -26
- package/dist/runtime/planning-evidence.js.map +1 -1
- package/dist/runtime/prompt-step.d.ts +1 -9
- package/dist/runtime/prompt-step.js +0 -10
- package/dist/runtime/prompt-step.js.map +1 -1
- package/dist/runtime/run-context.d.ts +5 -2
- package/dist/runtime/run-context.js +8 -1
- package/dist/runtime/run-context.js.map +1 -1
- package/dist/runtime/session-coordinator.d.ts +13 -5
- package/dist/runtime/session-coordinator.js +160 -20
- package/dist/runtime/session-coordinator.js.map +1 -1
- package/dist/runtime/session-title.d.ts +14 -0
- package/dist/runtime/session-title.js +50 -0
- package/dist/runtime/session-title.js.map +1 -0
- package/dist/runtime/tool-defaults-wrapper.js +7 -5
- package/dist/runtime/tool-defaults-wrapper.js.map +1 -1
- package/dist/runtime/validation.js.map +1 -1
- package/dist/runtime/workflow-events.js.map +1 -1
- package/dist/runtime/workflow-runner.d.ts +3 -3
- package/dist/runtime/workflow-runner.js +1 -1
- package/dist/runtime/workflow-runner.js.map +1 -1
- package/dist/sentiment/adapters/finnhub.d.ts +1 -1
- package/dist/sentiment/adapters/finnhub.js +6 -1
- package/dist/sentiment/adapters/finnhub.js.map +1 -1
- package/dist/sentiment/adapters/reddit.d.ts +2 -2
- package/dist/sentiment/adapters/twitter.d.ts +1 -1
- package/dist/sentiment/adapters/web.d.ts +1 -1
- package/dist/sentiment/index.d.ts +10 -11
- package/dist/sentiment/index.js +10 -20
- package/dist/sentiment/index.js.map +1 -1
- package/dist/sentiment/insights.d.ts +17 -0
- package/dist/sentiment/insights.js +206 -0
- package/dist/sentiment/insights.js.map +1 -0
- package/dist/sentiment/keywords.js +26 -4
- package/dist/sentiment/keywords.js.map +1 -1
- package/dist/sentiment/pipeline.d.ts +2 -2
- package/dist/sentiment/pipeline.js +14 -2
- package/dist/sentiment/pipeline.js.map +1 -1
- package/dist/sentiment/scorer.d.ts +2 -0
- package/dist/sentiment/scorer.js +11 -2
- package/dist/sentiment/scorer.js.map +1 -1
- package/dist/sentiment/store.d.ts +1 -1
- package/dist/sentiment/store.js +1 -1
- package/dist/sentiment/store.js.map +1 -1
- package/dist/sentiment/trends.d.ts +1 -1
- package/dist/sentiment/trends.js.map +1 -1
- package/dist/sentiment/types.d.ts +2 -0
- package/dist/sentiment/types.js.map +1 -1
- package/dist/system-prompt.js +6 -9
- package/dist/system-prompt.js.map +1 -1
- package/dist/tool-kit.d.ts +7 -7
- package/dist/tool-kit.js +4 -4
- package/dist/tool-kit.js.map +1 -1
- package/dist/tools/fundamentals/company-overview.js +11 -6
- package/dist/tools/fundamentals/company-overview.js.map +1 -1
- package/dist/tools/fundamentals/comps.js +18 -9
- package/dist/tools/fundamentals/comps.js.map +1 -1
- package/dist/tools/fundamentals/dcf.js +23 -11
- package/dist/tools/fundamentals/dcf.js.map +1 -1
- package/dist/tools/fundamentals/earnings.js +8 -3
- package/dist/tools/fundamentals/earnings.js.map +1 -1
- package/dist/tools/fundamentals/financials.js +8 -3
- package/dist/tools/fundamentals/financials.js.map +1 -1
- package/dist/tools/fundamentals/sec-filings.js +21 -6
- package/dist/tools/fundamentals/sec-filings.js.map +1 -1
- package/dist/tools/index.d.ts +27 -20
- package/dist/tools/index.js +55 -43
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/interaction/ask-user.js +15 -3
- package/dist/tools/interaction/ask-user.js.map +1 -1
- package/dist/tools/macro/fear-greed.js.map +1 -1
- package/dist/tools/macro/fred-data.d.ts +1 -1
- package/dist/tools/macro/fred-data.js +17 -6
- package/dist/tools/macro/fred-data.js.map +1 -1
- package/dist/tools/market/crypto-history.js +3 -1
- package/dist/tools/market/crypto-history.js.map +1 -1
- package/dist/tools/market/crypto-price.js +3 -1
- package/dist/tools/market/crypto-price.js.map +1 -1
- package/dist/tools/market/screen-stocks.d.ts +18 -0
- package/dist/tools/market/screen-stocks.js +252 -0
- package/dist/tools/market/screen-stocks.js.map +1 -0
- package/dist/tools/market/search-ticker.js +160 -8
- package/dist/tools/market/search-ticker.js.map +1 -1
- package/dist/tools/market/stock-history.d.ts +2 -2
- package/dist/tools/market/stock-history.js +26 -7
- package/dist/tools/market/stock-history.js.map +1 -1
- package/dist/tools/market/stock-quote.js +5 -3
- package/dist/tools/market/stock-quote.js.map +1 -1
- package/dist/tools/options/greeks.js +1 -1
- package/dist/tools/options/greeks.js.map +1 -1
- package/dist/tools/options/option-chain.js +19 -6
- package/dist/tools/options/option-chain.js.map +1 -1
- package/dist/tools/portfolio/alerts.d.ts +15 -0
- package/dist/tools/portfolio/alerts.js +357 -0
- package/dist/tools/portfolio/alerts.js.map +1 -0
- package/dist/tools/portfolio/correlation.d.ts +1 -1
- package/dist/tools/portfolio/correlation.js +33 -13
- package/dist/tools/portfolio/correlation.js.map +1 -1
- package/dist/tools/portfolio/daily-report.d.ts +8 -0
- package/dist/tools/portfolio/daily-report.js +83 -0
- package/dist/tools/portfolio/daily-report.js.map +1 -0
- package/dist/tools/portfolio/holdings-overlap.js +10 -3
- package/dist/tools/portfolio/holdings-overlap.js.map +1 -1
- package/dist/tools/portfolio/notifications.d.ts +7 -0
- package/dist/tools/portfolio/notifications.js +43 -0
- package/dist/tools/portfolio/notifications.js.map +1 -0
- package/dist/tools/portfolio/predictions.d.ts +12 -6
- package/dist/tools/portfolio/predictions.js +337 -87
- package/dist/tools/portfolio/predictions.js.map +1 -1
- package/dist/tools/portfolio/risk-analysis.d.ts +1 -1
- package/dist/tools/portfolio/risk-analysis.js +45 -6
- package/dist/tools/portfolio/risk-analysis.js.map +1 -1
- package/dist/tools/portfolio/tracker.d.ts +4 -3
- package/dist/tools/portfolio/tracker.js +246 -101
- package/dist/tools/portfolio/tracker.js.map +1 -1
- package/dist/tools/portfolio/watchlist.d.ts +6 -4
- package/dist/tools/portfolio/watchlist.js +208 -108
- package/dist/tools/portfolio/watchlist.js.map +1 -1
- package/dist/tools/sentiment/insight-format.d.ts +2 -0
- package/dist/tools/sentiment/insight-format.js +36 -0
- package/dist/tools/sentiment/insight-format.js.map +1 -0
- package/dist/tools/sentiment/query-match.d.ts +3 -0
- package/dist/tools/sentiment/query-match.js +113 -0
- package/dist/tools/sentiment/query-match.js.map +1 -0
- package/dist/tools/sentiment/reddit-sentiment.d.ts +12 -1
- package/dist/tools/sentiment/reddit-sentiment.js +266 -107
- package/dist/tools/sentiment/reddit-sentiment.js.map +1 -1
- package/dist/tools/sentiment/sentiment-summary.d.ts +9 -1
- package/dist/tools/sentiment/sentiment-summary.js +223 -205
- package/dist/tools/sentiment/sentiment-summary.js.map +1 -1
- package/dist/tools/sentiment/sentiment-trend.d.ts +1 -1
- package/dist/tools/sentiment/sentiment-trend.js +12 -2
- package/dist/tools/sentiment/sentiment-trend.js.map +1 -1
- package/dist/tools/sentiment/twitter-sentiment.d.ts +11 -1
- package/dist/tools/sentiment/twitter-sentiment.js +188 -58
- package/dist/tools/sentiment/twitter-sentiment.js.map +1 -1
- package/dist/tools/sentiment/untrusted-text.d.ts +2 -0
- package/dist/tools/sentiment/untrusted-text.js +17 -0
- package/dist/tools/sentiment/untrusted-text.js.map +1 -0
- package/dist/tools/sentiment/web-search.js +9 -13
- package/dist/tools/sentiment/web-search.js.map +1 -1
- package/dist/tools/sentiment/web-sentiment.js +19 -3
- package/dist/tools/sentiment/web-sentiment.js.map +1 -1
- package/dist/tools/technical/backtest.d.ts +1 -1
- package/dist/tools/technical/backtest.js +27 -20
- package/dist/tools/technical/backtest.js.map +1 -1
- package/dist/tools/technical/indicators.js +23 -5
- package/dist/tools/technical/indicators.js.map +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js.map +1 -1
- package/dist/types/market.d.ts +1 -0
- package/dist/types/portfolio.d.ts +14 -4
- package/dist/types/sentiment.d.ts +52 -0
- package/dist/workflows/compare-assets.d.ts +0 -3
- package/dist/workflows/compare-assets.js +20 -11
- package/dist/workflows/compare-assets.js.map +1 -1
- package/dist/workflows/index.d.ts +3 -4
- package/dist/workflows/index.js +3 -3
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/options-screener.d.ts +0 -3
- package/dist/workflows/options-screener.js +4 -11
- package/dist/workflows/options-screener.js.map +1 -1
- package/dist/workflows/portfolio-builder.d.ts +0 -3
- package/dist/workflows/portfolio-builder.js +0 -8
- package/dist/workflows/portfolio-builder.js.map +1 -1
- package/gui/server/ask-user-bridge.ts +1 -1
- package/gui/server/automation-heartbeat.ts +97 -0
- package/gui/server/background-quotes.ts +97 -1
- package/gui/server/chat-event-adapter.ts +32 -10
- package/gui/server/chat-run-session.ts +16 -0
- package/gui/server/invoke-tool.ts +160 -3
- package/gui/server/live-chat-event-adapter.ts +21 -6
- package/gui/server/market-state-api.ts +315 -0
- package/gui/server/model-setup.ts +156 -2
- package/gui/server/private-api-access.ts +62 -0
- package/gui/server/projector.ts +18 -9
- package/gui/server/prompt-observation.ts +4 -7
- package/gui/server/quote-snapshot-store.ts +50 -0
- package/gui/server/server.ts +218 -451
- package/gui/server/session-actions.ts +186 -1
- package/gui/server/shutdown.ts +47 -0
- package/gui/server/tool-invoke-ack.ts +49 -0
- package/gui/server/tool-metadata.ts +101 -24
- package/gui/server/websocket.ts +13 -3
- package/gui/server/writer-lock.ts +6 -2
- package/gui/server/ws-hub.ts +311 -0
- package/gui/shared/chat-events.ts +16 -1
- package/gui/shared/event-reducer.ts +24 -6
- package/gui/web/dist/assets/CatalogOverlay-CgeY5Pkp.js +1 -0
- package/gui/web/dist/assets/index-C6W_2eAn.js +69 -0
- package/gui/web/dist/assets/index-hwbx24a5.css +1 -0
- package/gui/web/dist/index.html +2 -2
- package/package.json +9 -6
- package/src/analysts/contracts.ts +10 -23
- package/src/analysts/orchestrator.ts +8 -43
- package/src/cli.ts +76 -12
- package/src/config.ts +44 -9
- package/src/index.ts +1 -1
- package/src/infra/cache.ts +41 -30
- package/src/infra/http-client.ts +72 -6
- package/src/infra/index.ts +6 -10
- package/src/infra/native-dependencies.ts +8 -3
- package/src/infra/node-version.ts +3 -1
- package/src/infra/opencandle-paths.ts +3 -14
- package/src/infra/rate-limiter.ts +22 -19
- package/src/market-state/alert-conditions.ts +82 -0
- package/src/market-state/alert-runner.ts +863 -0
- package/src/market-state/daily-report.ts +247 -0
- package/src/market-state/local-automation-service.ts +162 -0
- package/src/market-state/notification-delivery.ts +158 -0
- package/src/market-state/resolve-for-mutation.ts +24 -0
- package/src/market-state/resolve.ts +112 -0
- package/src/market-state/service.ts +2344 -0
- package/src/memory/index.ts +7 -7
- package/src/memory/manager.ts +14 -16
- package/src/memory/retrieval.ts +8 -7
- package/src/memory/sqlite.ts +407 -6
- package/src/memory/storage.ts +5 -15
- package/src/memory/tool-defaults.ts +60 -39
- package/src/memory/types.ts +3 -3
- package/src/monitor.ts +121 -0
- package/src/onboarding/connect.ts +24 -31
- package/src/onboarding/credential-interceptor.ts +3 -15
- package/src/onboarding/degradation-accumulator.ts +1 -3
- package/src/onboarding/provider-status.ts +410 -0
- package/src/onboarding/providers.ts +144 -45
- package/src/onboarding/state.ts +13 -15
- package/src/onboarding/tool-helpers.ts +2 -9
- package/src/onboarding/tool-tags.ts +51 -8
- package/src/onboarding/validation.ts +16 -22
- package/src/pi/opencandle-extension.ts +643 -101
- package/src/pi/session.ts +7 -5
- package/src/pi/setup.ts +61 -43
- package/src/pi/tool-adapter.ts +19 -6
- package/src/prompts/context-builder.ts +24 -13
- package/src/prompts/policy-cards.ts +3 -3
- package/src/prompts/sections.ts +1 -1
- package/src/prompts/symbol-preflight.ts +80 -0
- package/src/prompts/workflow-prompts.ts +77 -28
- package/src/providers/alpha-vantage.ts +58 -39
- package/src/providers/coingecko.ts +2 -5
- package/src/providers/errors.ts +9 -0
- package/src/providers/exa-search.ts +24 -22
- package/src/providers/external-tool-error.ts +20 -0
- package/src/providers/fear-greed.ts +1 -1
- package/src/providers/finnhub.ts +7 -6
- package/src/providers/fred.ts +3 -3
- package/src/providers/index.ts +14 -6
- package/src/providers/reddit-cli.ts +317 -0
- package/src/providers/reddit.ts +14 -59
- package/src/providers/sec-edgar.ts +20 -6
- package/src/providers/tradingview.ts +399 -0
- package/src/providers/twitter-cli.ts +233 -0
- package/src/providers/twitter.ts +8 -79
- package/src/providers/web-search.ts +30 -20
- package/src/providers/with-fallback.ts +8 -7
- package/src/providers/wrap-provider.ts +49 -10
- package/src/providers/yahoo-finance.ts +204 -66
- package/src/routing/classify-intent.ts +101 -10
- package/src/routing/defaults.ts +1 -1
- package/src/routing/entity-extractor.ts +287 -38
- package/src/routing/fund-symbols.ts +58 -0
- package/src/routing/horizon.ts +7 -0
- package/src/routing/index.ts +48 -48
- package/src/routing/planning.ts +145 -53
- package/src/routing/route-manifest.ts +37 -15
- package/src/routing/router-llm-client.ts +4 -4
- package/src/routing/router-prompt.ts +15 -19
- package/src/routing/router-types.ts +2 -5
- package/src/routing/router.ts +251 -53
- package/src/routing/slot-resolver.ts +34 -11
- package/src/routing/symbol-disambiguator.ts +72 -0
- package/src/routing/turn-context.ts +6 -9
- package/src/routing/types.ts +2 -0
- package/src/runtime/answer-contracts.ts +105 -45
- package/src/runtime/artifact-contracts.ts +2 -1
- package/src/runtime/planning-evidence.ts +157 -66
- package/src/runtime/prompt-step.ts +1 -16
- package/src/runtime/run-context.ts +12 -2
- package/src/runtime/session-coordinator.ts +238 -63
- package/src/runtime/session-title.ts +60 -0
- package/src/runtime/tool-defaults-wrapper.ts +13 -5
- package/src/runtime/validation.ts +1 -4
- package/src/runtime/workflow-events.ts +7 -7
- package/src/runtime/workflow-runner.ts +5 -11
- package/src/sentiment/adapters/finnhub.ts +7 -2
- package/src/sentiment/adapters/reddit.ts +2 -2
- package/src/sentiment/adapters/twitter.ts +1 -1
- package/src/sentiment/adapters/web.ts +1 -1
- package/src/sentiment/index.ts +17 -26
- package/src/sentiment/insights.ts +269 -0
- package/src/sentiment/keywords.ts +26 -4
- package/src/sentiment/pipeline.ts +28 -5
- package/src/sentiment/scorer.ts +13 -2
- package/src/sentiment/store.ts +2 -2
- package/src/sentiment/trends.ts +9 -3
- package/src/sentiment/types.ts +8 -4
- package/src/system-prompt.ts +6 -9
- package/src/tool-kit.ts +10 -9
- package/src/tools/fundamentals/company-overview.ts +19 -9
- package/src/tools/fundamentals/comps.ts +68 -55
- package/src/tools/fundamentals/dcf.ts +145 -95
- package/src/tools/fundamentals/earnings.ts +16 -6
- package/src/tools/fundamentals/financials.ts +16 -7
- package/src/tools/fundamentals/sec-filings.ts +37 -16
- package/src/tools/index.ts +56 -43
- package/src/tools/interaction/ask-user.ts +22 -10
- package/src/tools/macro/fear-greed.ts +1 -1
- package/src/tools/macro/fred-data.ts +58 -46
- package/src/tools/market/crypto-history.ts +8 -3
- package/src/tools/market/crypto-price.ts +6 -6
- package/src/tools/market/screen-stocks.ts +279 -0
- package/src/tools/market/search-ticker.ts +218 -17
- package/src/tools/market/stock-history.ts +37 -12
- package/src/tools/market/stock-quote.ts +10 -7
- package/src/tools/options/greeks.ts +5 -5
- package/src/tools/options/option-chain.ts +41 -17
- package/src/tools/portfolio/alerts.ts +457 -0
- package/src/tools/portfolio/correlation.ts +47 -20
- package/src/tools/portfolio/daily-report.ts +101 -0
- package/src/tools/portfolio/holdings-overlap.ts +31 -15
- package/src/tools/portfolio/notifications.ts +45 -0
- package/src/tools/portfolio/predictions.ts +406 -106
- package/src/tools/portfolio/risk-analysis.ts +46 -7
- package/src/tools/portfolio/tracker.ts +270 -109
- package/src/tools/portfolio/watchlist.ts +250 -121
- package/src/tools/sentiment/insight-format.ts +50 -0
- package/src/tools/sentiment/query-match.ts +117 -0
- package/src/tools/sentiment/reddit-sentiment.ts +360 -121
- package/src/tools/sentiment/sentiment-summary.ts +302 -235
- package/src/tools/sentiment/sentiment-trend.ts +24 -7
- package/src/tools/sentiment/twitter-sentiment.ts +264 -73
- package/src/tools/sentiment/untrusted-text.ts +21 -0
- package/src/tools/sentiment/web-search.ts +21 -18
- package/src/tools/sentiment/web-sentiment.ts +30 -10
- package/src/tools/technical/backtest.ts +32 -22
- package/src/tools/technical/indicators.ts +39 -14
- package/src/types/index.ts +8 -3
- package/src/types/market.ts +1 -0
- package/src/types/portfolio.ts +14 -4
- package/src/types/sentiment.ts +61 -2
- package/src/workflows/compare-assets.ts +33 -21
- package/src/workflows/index.ts +3 -4
- package/src/workflows/options-screener.ts +27 -29
- package/src/workflows/portfolio-builder.ts +34 -27
- package/dist/infra/browser.d.ts +0 -35
- package/dist/infra/browser.js +0 -103
- package/dist/infra/browser.js.map +0 -1
- package/dist/tools/interaction/twitter-login.d.ts +0 -8
- package/dist/tools/interaction/twitter-login.js +0 -77
- package/dist/tools/interaction/twitter-login.js.map +0 -1
- package/dist/workflows/types.d.ts +0 -4
- package/dist/workflows/types.js +0 -2
- package/dist/workflows/types.js.map +0 -1
- package/gui/web/dist/assets/CatalogOverlay-Bmp6Knu7.js +0 -1
- package/gui/web/dist/assets/index-Bxt9QpLX.css +0 -1
- package/gui/web/dist/assets/index-CZ9DHZYy.js +0 -67
- package/src/infra/browser.ts +0 -111
- package/src/tools/interaction/twitter-login.ts +0 -93
- package/src/workflows/types.ts +0 -4
package/src/routing/planning.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ArtifactContractId,
|
|
3
|
+
artifactContractIdsForPlanning,
|
|
4
|
+
} from "../runtime/artifact-contracts.js";
|
|
1
5
|
import type {
|
|
2
6
|
RouterDiagnostic,
|
|
3
7
|
RouterInputContext,
|
|
@@ -6,10 +10,6 @@ import type {
|
|
|
6
10
|
ToolBundleName,
|
|
7
11
|
} from "./router-types.js";
|
|
8
12
|
import type { WorkflowType } from "./types.js";
|
|
9
|
-
import {
|
|
10
|
-
artifactContractIdsForPlanning,
|
|
11
|
-
type ArtifactContractId,
|
|
12
|
-
} from "../runtime/artifact-contracts.js";
|
|
13
13
|
|
|
14
14
|
export const PLANNING_VERSION = "planning-v1" as const;
|
|
15
15
|
|
|
@@ -98,6 +98,7 @@ export type StructuredCheckId =
|
|
|
98
98
|
| "freshness_disclosed"
|
|
99
99
|
| "data_gap_disclosed"
|
|
100
100
|
| "commitment_mode_respected"
|
|
101
|
+
| "required_final_fields_present"
|
|
101
102
|
| "source_coverage_disclosed"
|
|
102
103
|
| "capability_gap_disclosure"
|
|
103
104
|
| "assumption_disclosed"
|
|
@@ -127,7 +128,8 @@ export const CAPABILITY_GAP_REGISTRY: Record<CapabilityGapId, CapabilityGapDefin
|
|
|
127
128
|
market_calendar: {
|
|
128
129
|
id: "market_calendar",
|
|
129
130
|
label: "Market calendar",
|
|
130
|
-
description:
|
|
131
|
+
description:
|
|
132
|
+
"Exchange holiday and session-state data beyond deterministic weekday/known-holiday grounding.",
|
|
131
133
|
v1Status: "classified_gap",
|
|
132
134
|
specialistCompetitive: false,
|
|
133
135
|
},
|
|
@@ -141,7 +143,8 @@ export const CAPABILITY_GAP_REGISTRY: Record<CapabilityGapId, CapabilityGapDefin
|
|
|
141
143
|
brokerage_comparison: {
|
|
142
144
|
id: "brokerage_comparison",
|
|
143
145
|
label: "Brokerage comparison",
|
|
144
|
-
description:
|
|
146
|
+
description:
|
|
147
|
+
"Live brokerage fees, platform features, account support, and execution-quality comparison data.",
|
|
145
148
|
v1Status: "classified_gap",
|
|
146
149
|
specialistCompetitive: false,
|
|
147
150
|
},
|
|
@@ -155,7 +158,8 @@ export const CAPABILITY_GAP_REGISTRY: Record<CapabilityGapId, CapabilityGapDefin
|
|
|
155
158
|
earnings_event_risk: {
|
|
156
159
|
id: "earnings_event_risk",
|
|
157
160
|
label: "Earnings-event risk",
|
|
158
|
-
description:
|
|
161
|
+
description:
|
|
162
|
+
"Upcoming earnings timing, transcript, implied move, and event-specific risk coverage.",
|
|
159
163
|
v1Status: "classified_gap",
|
|
160
164
|
specialistCompetitive: false,
|
|
161
165
|
},
|
|
@@ -176,7 +180,8 @@ export const CAPABILITY_GAP_REGISTRY: Record<CapabilityGapId, CapabilityGapDefin
|
|
|
176
180
|
sentiment_sample_depth: {
|
|
177
181
|
id: "sentiment_sample_depth",
|
|
178
182
|
label: "Sentiment sample depth",
|
|
179
|
-
description:
|
|
183
|
+
description:
|
|
184
|
+
"Coverage, sample-size, source-depth, and low-volume confidence metadata for sentiment evidence.",
|
|
180
185
|
v1Status: "classified_gap",
|
|
181
186
|
specialistCompetitive: false,
|
|
182
187
|
},
|
|
@@ -238,7 +243,11 @@ export const PLANNING_MANIFEST: Record<TaskFamily, PlanningManifestEntry> = {
|
|
|
238
243
|
policyCardId: "asset_compare",
|
|
239
244
|
evidencePlanId: "placeholder_asset_compare",
|
|
240
245
|
answerContractId: "asset_compare_tradeoff",
|
|
241
|
-
structuredCheckIds: [
|
|
246
|
+
structuredCheckIds: [
|
|
247
|
+
"required_evidence_present",
|
|
248
|
+
"data_gap_disclosed",
|
|
249
|
+
"capability_gap_disclosure",
|
|
250
|
+
],
|
|
242
251
|
capabilityGapIds: ["etf_holdings_overlap"],
|
|
243
252
|
compatibleToolBundles: ["core_market", "macro", "sentiment", "clarification"],
|
|
244
253
|
migrated: false,
|
|
@@ -265,7 +274,11 @@ export const PLANNING_MANIFEST: Record<TaskFamily, PlanningManifestEntry> = {
|
|
|
265
274
|
policyCardId: "portfolio_review",
|
|
266
275
|
evidencePlanId: "placeholder_portfolio_review",
|
|
267
276
|
answerContractId: "portfolio_review",
|
|
268
|
-
structuredCheckIds: [
|
|
277
|
+
structuredCheckIds: [
|
|
278
|
+
"required_evidence_present",
|
|
279
|
+
"data_gap_disclosed",
|
|
280
|
+
"commitment_mode_respected",
|
|
281
|
+
],
|
|
269
282
|
capabilityGapIds: [],
|
|
270
283
|
compatibleToolBundles: ["core_market", "macro", "sentiment", "clarification"],
|
|
271
284
|
migrated: false,
|
|
@@ -334,7 +347,11 @@ export const PLANNING_MANIFEST: Record<TaskFamily, PlanningManifestEntry> = {
|
|
|
334
347
|
policyCardId: "sentiment_snapshot",
|
|
335
348
|
evidencePlanId: "placeholder_sentiment_snapshot",
|
|
336
349
|
answerContractId: "sentiment_snapshot",
|
|
337
|
-
structuredCheckIds: [
|
|
350
|
+
structuredCheckIds: [
|
|
351
|
+
"required_evidence_present",
|
|
352
|
+
"source_coverage_disclosed",
|
|
353
|
+
"data_gap_disclosed",
|
|
354
|
+
],
|
|
338
355
|
capabilityGapIds: ["sentiment_sample_depth"],
|
|
339
356
|
compatibleToolBundles: ["core_market", "sentiment"],
|
|
340
357
|
migrated: false,
|
|
@@ -390,7 +407,11 @@ export const PLANNING_MANIFEST: Record<TaskFamily, PlanningManifestEntry> = {
|
|
|
390
407
|
policyCardId: "backtest_review",
|
|
391
408
|
evidencePlanId: "placeholder_backtest_review",
|
|
392
409
|
answerContractId: "backtest_review",
|
|
393
|
-
structuredCheckIds: [
|
|
410
|
+
structuredCheckIds: [
|
|
411
|
+
"required_evidence_present",
|
|
412
|
+
"data_gap_disclosed",
|
|
413
|
+
"source_coverage_disclosed",
|
|
414
|
+
],
|
|
394
415
|
capabilityGapIds: [],
|
|
395
416
|
compatibleToolBundles: ["core_market", "options", "sentiment", "sec", "clarification"],
|
|
396
417
|
migrated: false,
|
|
@@ -433,11 +454,10 @@ export function buildPlanningEnvelope(
|
|
|
433
454
|
const proposed = defaultPlanningSelection(input, output);
|
|
434
455
|
const { selection, diagnostics } = validatePlanningSelection(output, proposed);
|
|
435
456
|
const manifestEntry = PLANNING_MANIFEST[selection.taskFamily];
|
|
436
|
-
const behaviorMode: PlanningBehaviorMode =
|
|
457
|
+
const behaviorMode: PlanningBehaviorMode =
|
|
458
|
+
options.migrationStatuses?.[selection.taskFamily] ??
|
|
437
459
|
manifestEntry.migrationStatus ??
|
|
438
|
-
(manifestEntry.migrated
|
|
439
|
-
? "replacement_active"
|
|
440
|
-
: "observe_only");
|
|
460
|
+
(manifestEntry.migrated ? "replacement_active" : "observe_only");
|
|
441
461
|
|
|
442
462
|
return {
|
|
443
463
|
version: PLANNING_VERSION,
|
|
@@ -449,16 +469,21 @@ export function buildPlanningEnvelope(
|
|
|
449
469
|
diagnostics: [
|
|
450
470
|
...diagnostics,
|
|
451
471
|
...(output.diagnostics.length > 0
|
|
452
|
-
? [
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
472
|
+
? [
|
|
473
|
+
{
|
|
474
|
+
code: "planning_after_router_corrections",
|
|
475
|
+
message: "planning selected after router diagnostics were applied",
|
|
476
|
+
},
|
|
477
|
+
]
|
|
456
478
|
: []),
|
|
457
479
|
...(behaviorMode === "observe_only"
|
|
458
|
-
? [
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
480
|
+
? [
|
|
481
|
+
{
|
|
482
|
+
code: "planning_observe_only",
|
|
483
|
+
message:
|
|
484
|
+
"planning metadata is recorded without changing active prompt, route, workflow, tools, or answer behavior",
|
|
485
|
+
},
|
|
486
|
+
]
|
|
462
487
|
: []),
|
|
463
488
|
],
|
|
464
489
|
};
|
|
@@ -476,10 +501,12 @@ export function validatePlanningSelection(
|
|
|
476
501
|
const fallback = defaultTaskFamilyForOutput(output, "");
|
|
477
502
|
return {
|
|
478
503
|
selection: selectionForTaskFamily(fallback),
|
|
479
|
-
diagnostics: [
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
504
|
+
diagnostics: [
|
|
505
|
+
{
|
|
506
|
+
code: "planning_task_family_corrected",
|
|
507
|
+
message: `${proposed.taskFamily} is not supported for ${output.routeKind}${output.workflow ? `/${output.workflow}` : ""}; using ${fallback}`,
|
|
508
|
+
},
|
|
509
|
+
],
|
|
483
510
|
};
|
|
484
511
|
}
|
|
485
512
|
|
|
@@ -508,7 +535,10 @@ function defaultTaskFamilyForOutput(output: RouterOutput, text: string): TaskFam
|
|
|
508
535
|
const lower = text.toLowerCase();
|
|
509
536
|
if (output.routeKind === "clarification") return "general_fallback";
|
|
510
537
|
if (output.routeKind === "pass_through") return "general_fallback";
|
|
511
|
-
if (
|
|
538
|
+
if (
|
|
539
|
+
output.workflow === "portfolio_builder" &&
|
|
540
|
+
isExistingRetirementAllocationReviewPrompt(lower)
|
|
541
|
+
) {
|
|
512
542
|
return "portfolio_review";
|
|
513
543
|
}
|
|
514
544
|
if (output.workflow === "portfolio_builder") return "portfolio_build";
|
|
@@ -532,7 +562,10 @@ function defaultTaskFamilyForOutput(output: RouterOutput, text: string): TaskFam
|
|
|
532
562
|
if (/\b(?:sentiment|mood|reddit|twitter|x\/twitter)\b/.test(lower)) {
|
|
533
563
|
return "sentiment_snapshot";
|
|
534
564
|
}
|
|
535
|
-
if (
|
|
565
|
+
if (
|
|
566
|
+
isPortfolioRebalancePrompt(lower) ||
|
|
567
|
+
isAddToExistingHoldingsPrompt(lower, output.entities.symbols.length)
|
|
568
|
+
) {
|
|
536
569
|
return "portfolio_review";
|
|
537
570
|
}
|
|
538
571
|
if (/\b(?:today|right now|this morning|after close|moved|catalyst)\b/.test(lower)) {
|
|
@@ -544,17 +577,29 @@ function defaultTaskFamilyForOutput(output: RouterOutput, text: string): TaskFam
|
|
|
544
577
|
if (/\b(?:brokerage|hysa|money-market|t-bills?|cds?|mortgage|taxable account)\b/.test(lower)) {
|
|
545
578
|
return "retail_finance_tradeoff";
|
|
546
579
|
}
|
|
547
|
-
if (
|
|
580
|
+
if (
|
|
581
|
+
/\b(?:btc|bitcoin|crypto)\b/.test(lower) &&
|
|
582
|
+
/\b(?:allocation|range|position\s+size|sizing|drawdown)\b/.test(lower)
|
|
583
|
+
) {
|
|
548
584
|
return "retail_finance_tradeoff";
|
|
549
585
|
}
|
|
550
|
-
if (
|
|
586
|
+
if (
|
|
587
|
+
/\b(?:60\/40|portfolio|allocation)\b/.test(lower) &&
|
|
588
|
+
/\b(?:evaluate|evaluation|review|risk|prospects)\b/.test(lower)
|
|
589
|
+
) {
|
|
551
590
|
return "portfolio_review";
|
|
552
591
|
}
|
|
553
|
-
if (
|
|
592
|
+
if (
|
|
593
|
+
output.entities.symbols.length === 1 &&
|
|
594
|
+
/\b(?:analyze|buy|sell|wait|avoid|recommendation|attractive)\b/.test(lower)
|
|
595
|
+
) {
|
|
554
596
|
return "single_asset_decision";
|
|
555
597
|
}
|
|
556
598
|
if (output.workflow === "single_asset_analysis") return "single_asset_decision";
|
|
557
|
-
if (
|
|
599
|
+
if (
|
|
600
|
+
/\b(?:explain|what is|what does|how to|define)\b/.test(lower) &&
|
|
601
|
+
output.entities.symbols.length === 0
|
|
602
|
+
) {
|
|
558
603
|
return "concept_explainer";
|
|
559
604
|
}
|
|
560
605
|
return "general_fallback";
|
|
@@ -581,7 +626,9 @@ function refinePlanningSelectionForPrompt(
|
|
|
581
626
|
return {
|
|
582
627
|
...selection,
|
|
583
628
|
policyCardId: "concept_inflation_cash_education",
|
|
584
|
-
structuredCheckIds: mergeStructuredChecks(selection.structuredCheckIds, [
|
|
629
|
+
structuredCheckIds: mergeStructuredChecks(selection.structuredCheckIds, [
|
|
630
|
+
"tax_caveat_present",
|
|
631
|
+
]),
|
|
585
632
|
};
|
|
586
633
|
}
|
|
587
634
|
if (isValuationMetricEducationPrompt(lower)) {
|
|
@@ -654,54 +701,99 @@ function refinePlanningSelectionForPrompt(
|
|
|
654
701
|
}
|
|
655
702
|
|
|
656
703
|
function isNoToolConceptEducationPrompt(lower: string): boolean {
|
|
657
|
-
if (
|
|
704
|
+
if (
|
|
705
|
+
!/\b(?:explain|what\s+is|what\s+are|what\s+does|how\s+does|how\s+do|how\s+to|define)\b/.test(
|
|
706
|
+
lower,
|
|
707
|
+
)
|
|
708
|
+
) {
|
|
658
709
|
return false;
|
|
659
710
|
}
|
|
660
|
-
return
|
|
711
|
+
return (
|
|
712
|
+
isOptionsEducationPrompt(lower) ||
|
|
661
713
|
isInflationCashEducationPrompt(lower) ||
|
|
662
|
-
isValuationMetricEducationPrompt(lower)
|
|
714
|
+
isValuationMetricEducationPrompt(lower)
|
|
715
|
+
);
|
|
663
716
|
}
|
|
664
717
|
|
|
665
718
|
function isOptionsEducationPrompt(lower: string): boolean {
|
|
666
|
-
return /\b(?:covered\s+calls?|protective\s+puts?|options?|option\s+premium|assignment\s+risk|strike|expiration|delta|theta|greeks?)\b/.test(
|
|
719
|
+
return /\b(?:covered\s+calls?|protective\s+puts?|options?|option\s+premium|assignment\s+risk|strike|expiration|delta|theta|greeks?)\b/.test(
|
|
720
|
+
lower,
|
|
721
|
+
);
|
|
667
722
|
}
|
|
668
723
|
|
|
669
724
|
function isOptionsStrategyPrompt(lower: string): boolean {
|
|
670
|
-
|
|
671
|
-
/\b(?:
|
|
725
|
+
const explicitOptionsStrategy =
|
|
726
|
+
/\b(?:covered\s+calls?|protective\s+puts?|buy(?:ing)?\s+puts?|sell(?:ing)?\s+calls?|sell(?:ing)?\s+puts?|options?\s+income|option\s+strategy|options?\s+hedge|collar)\b/.test(
|
|
727
|
+
lower,
|
|
728
|
+
);
|
|
729
|
+
const optionsHedge =
|
|
730
|
+
/\bhedg(?:e|ing)\b.{0,80}\b(?:puts|put\s+options?|options?)\b/.test(lower) ||
|
|
731
|
+
/\b(?:puts|put\s+options?|options?)\b.{0,80}\bhedg(?:e|ing)\b/.test(lower);
|
|
732
|
+
return (
|
|
733
|
+
(explicitOptionsStrategy || optionsHedge) &&
|
|
734
|
+
/\b(?:own|have|shares?|position|cost\s+basis|good\s+idea|make\s+sense|income|premium|strike|expiration|assignment|stable|flat|protect|hedge|sell)\b/.test(
|
|
735
|
+
lower,
|
|
736
|
+
)
|
|
737
|
+
);
|
|
672
738
|
}
|
|
673
739
|
|
|
674
740
|
function isTickerDisambiguationPrompt(lower: string): boolean {
|
|
675
741
|
if (/\b(?:ticker|symbol|formerly|old ticker)\b/.test(lower)) return true;
|
|
676
|
-
return
|
|
742
|
+
return (
|
|
743
|
+
/\b(?:earnings are|earnings tonight)\b/.test(lower) &&
|
|
677
744
|
/\b(?:trim|hedge|hold|event[-\s]?risk|position\s+size)\b/.test(lower) &&
|
|
678
|
-
!/\b(?:covered\s+calls?|protective\s+puts?|sell(?:ing)?\s+calls?|sell(?:ing)?\s+puts?|option\s+chain|strike|expiration|premium)\b/.test(
|
|
745
|
+
!/\b(?:covered\s+calls?|protective\s+puts?|sell(?:ing)?\s+calls?|sell(?:ing)?\s+puts?|option\s+chain|strike|expiration|premium)\b/.test(
|
|
746
|
+
lower,
|
|
747
|
+
)
|
|
748
|
+
);
|
|
679
749
|
}
|
|
680
750
|
|
|
681
751
|
function isInflationCashEducationPrompt(lower: string): boolean {
|
|
682
|
-
return
|
|
683
|
-
/\b(?:
|
|
752
|
+
return (
|
|
753
|
+
/\b(?:inflation|purchasing\s+power|real\s+returns?|cash\s+savings?|cash\s+drag|tips|short(?:er)?[-\s]?duration)\b/.test(
|
|
754
|
+
lower,
|
|
755
|
+
) &&
|
|
756
|
+
/\b(?:cash|savings?|purchasing\s+power|real\s+returns?|bonds?|tips|protect|protection|affect)\b/.test(
|
|
757
|
+
lower,
|
|
758
|
+
)
|
|
759
|
+
);
|
|
684
760
|
}
|
|
685
761
|
|
|
686
762
|
function isValuationMetricEducationPrompt(lower: string): boolean {
|
|
687
|
-
return /\b(?:p\/e|pe\s+ratio|price[-\s]?to[-\s]?earnings|ev\/ebitda|p\/s|price[-\s]?to[-\s]?sales|valuation\s+metric|trailing|forward\s+earnings|normalized\s+earnings|cyclically\s+adjusted)\b/.test(
|
|
763
|
+
return /\b(?:p\/e|pe\s+ratio|price[-\s]?to[-\s]?earnings|ev\/ebitda|p\/s|price[-\s]?to[-\s]?sales|valuation\s+metric|trailing|forward\s+earnings|normalized\s+earnings|cyclically\s+adjusted)\b/.test(
|
|
764
|
+
lower,
|
|
765
|
+
);
|
|
688
766
|
}
|
|
689
767
|
|
|
690
768
|
function isPortfolioRebalancePrompt(lower: string): boolean {
|
|
691
|
-
return
|
|
692
|
-
/\b(?:
|
|
769
|
+
return (
|
|
770
|
+
/\b(?:portfolio|allocation|holdings?|sleeves?|ira|etfs?|funds?|s&p\s*500|index|equity|bonds?|cash)\b/.test(
|
|
771
|
+
lower,
|
|
772
|
+
) &&
|
|
773
|
+
/\b(?:rebalance|diversify|diversifying|concentration|overweight|underweight|target\s+bands?|drift|reduce\s+concentration|adjust|adjustment|more\s+aggressive|higher\s+growth|too\s+risky|riskier|worried|crash|hedge|protect|protection|missing\s+out\s+on\s+growth)\b/.test(
|
|
774
|
+
lower,
|
|
775
|
+
)
|
|
776
|
+
);
|
|
693
777
|
}
|
|
694
778
|
|
|
695
779
|
function isAddToExistingHoldingsPrompt(lower: string, symbolCount: number): boolean {
|
|
696
|
-
return
|
|
697
|
-
|
|
698
|
-
/\b(?:
|
|
780
|
+
return (
|
|
781
|
+
symbolCount >= 2 &&
|
|
782
|
+
/\b(?:already\s+own|already\s+hold|current(?:ly)?\s+own|existing\s+(?:holdings?|portfolio|position)|my\s+portfolio)\b/.test(
|
|
783
|
+
lower,
|
|
784
|
+
) &&
|
|
785
|
+
/\b(?:add(?:ing)?|buy(?:ing)?|make\s+sense|fit|long[-\s]?term|growth)\b/.test(lower)
|
|
786
|
+
);
|
|
699
787
|
}
|
|
700
788
|
|
|
701
789
|
function isExistingRetirementAllocationReviewPrompt(lower: string): boolean {
|
|
702
|
-
return
|
|
790
|
+
return (
|
|
791
|
+
/\b(?:401k|401\(k\)|target[-\s]?date|tdf)\b/.test(lower) &&
|
|
703
792
|
/\b(?:mostly|current(?:ly)?|already|have|holding|invested|allocation)\b/.test(lower) &&
|
|
704
|
-
/\b(?:review|solid|worried|inflation|diversify|boost returns?|other options?|without taking crazy risks?|risk)\b/.test(
|
|
793
|
+
/\b(?:review|solid|worried|inflation|diversify|boost returns?|other options?|without taking crazy risks?|risk)\b/.test(
|
|
794
|
+
lower,
|
|
795
|
+
)
|
|
796
|
+
);
|
|
705
797
|
}
|
|
706
798
|
|
|
707
799
|
function mergeCapabilityGaps(
|
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ExtractedEntities,
|
|
3
|
-
WorkflowType,
|
|
4
|
-
} from "./types.js";
|
|
5
|
-
import type {
|
|
6
|
-
RouterOutput,
|
|
7
|
-
RouterRoute,
|
|
8
|
-
RouterRouteKind,
|
|
9
|
-
ToolBundleName,
|
|
10
|
-
} from "./router-types.js";
|
|
11
1
|
import type { MemoryCategory } from "../memory/types.js";
|
|
2
|
+
import type { RouterOutput, RouterRoute, RouterRouteKind, ToolBundleName } from "./router-types.js";
|
|
3
|
+
import type { ExtractedEntities, WorkflowType } from "./types.js";
|
|
12
4
|
|
|
13
5
|
export const ROUTE_KINDS: readonly RouterRouteKind[] = [
|
|
14
6
|
"workflow_dispatch",
|
|
@@ -22,6 +14,7 @@ export const TOOL_BUNDLE_TOOLS: Record<ToolBundleName, readonly string[]> = {
|
|
|
22
14
|
"search_ticker",
|
|
23
15
|
"get_stock_quote",
|
|
24
16
|
"get_stock_history",
|
|
17
|
+
"screen_stocks",
|
|
25
18
|
"get_crypto_price",
|
|
26
19
|
"get_crypto_history",
|
|
27
20
|
"get_company_overview",
|
|
@@ -37,6 +30,9 @@ export const TOOL_BUNDLE_TOOLS: Record<ToolBundleName, readonly string[]> = {
|
|
|
37
30
|
"track_portfolio",
|
|
38
31
|
"manage_watchlist",
|
|
39
32
|
"track_prediction",
|
|
33
|
+
"manage_alerts",
|
|
34
|
+
"daily_watchlist_report",
|
|
35
|
+
"manage_notifications",
|
|
40
36
|
"search_web",
|
|
41
37
|
],
|
|
42
38
|
options: ["get_option_chain", "get_stock_quote", "search_ticker", "search_web"],
|
|
@@ -216,7 +212,11 @@ export function computeMissingRequiredSlots(
|
|
|
216
212
|
if (slot === "symbol" && entities.symbols.length === 0 && !slotHasValue(slots.symbol)) {
|
|
217
213
|
missing.add("symbol");
|
|
218
214
|
}
|
|
219
|
-
if (
|
|
215
|
+
if (
|
|
216
|
+
slot === "symbols" &&
|
|
217
|
+
entities.symbols.length < 2 &&
|
|
218
|
+
!slotHasSymbolListValue(slots.symbols, 2)
|
|
219
|
+
) {
|
|
220
220
|
missing.add("symbols");
|
|
221
221
|
}
|
|
222
222
|
existing.delete(slot);
|
|
@@ -233,22 +233,44 @@ function slotHasValue(slot: RouterOutput["slots"][string] | undefined): boolean
|
|
|
233
233
|
return slot.value !== undefined && slot.value !== null && slot.value !== "";
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
|
|
236
|
+
function slotHasSymbolListValue(
|
|
237
|
+
slot: RouterOutput["slots"][string] | undefined,
|
|
238
|
+
minLength: number,
|
|
239
|
+
): boolean {
|
|
240
|
+
if (!slot) return false;
|
|
241
|
+
if (Array.isArray(slot.value))
|
|
242
|
+
return slot.value.filter((value) => typeof value === "string").length >= minLength;
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function selectToolBundles(
|
|
247
|
+
output: Pick<RouterOutput, "routeKind" | "workflow" | "entities">,
|
|
248
|
+
): ToolBundleName[] {
|
|
237
249
|
if (output.routeKind === "pass_through") return [];
|
|
238
250
|
if (output.routeKind === "clarification") return ["clarification"];
|
|
239
251
|
|
|
240
252
|
const bundles = new Set<ToolBundleName>();
|
|
241
253
|
const routeBundles = ROUTE_CAPABILITY_MANIFEST[output.routeKind]?.toolBundles ?? [];
|
|
242
|
-
|
|
254
|
+
for (const bundle of routeBundles) {
|
|
255
|
+
bundles.add(bundle);
|
|
256
|
+
}
|
|
243
257
|
|
|
244
258
|
if (output.workflow) {
|
|
245
259
|
const workflow = WORKFLOW_CAPABILITY_MANIFEST[output.workflow];
|
|
246
|
-
workflow
|
|
260
|
+
if (workflow) {
|
|
261
|
+
for (const bundle of workflow.toolBundles) {
|
|
262
|
+
bundles.add(bundle);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
247
265
|
}
|
|
248
266
|
|
|
249
267
|
const metrics = output.entities.compareMetrics ?? [];
|
|
250
268
|
const horizon = output.entities.timeHorizon ?? "";
|
|
251
|
-
if (
|
|
269
|
+
if (
|
|
270
|
+
metrics.includes("macro_hedge") ||
|
|
271
|
+
metrics.includes("interest_rates") ||
|
|
272
|
+
/\b(?:macro|rate|inflation)\b/i.test(horizon)
|
|
273
|
+
) {
|
|
252
274
|
bundles.add("macro");
|
|
253
275
|
}
|
|
254
276
|
|
|
@@ -9,7 +9,9 @@ import type { RouterLlmClient } from "./router-types.js";
|
|
|
9
9
|
* Zero tools are passed — the router operates on text alone. Temperature
|
|
10
10
|
* is pinned low for structured-output stability.
|
|
11
11
|
*/
|
|
12
|
-
export function createPiAiRouterClient(
|
|
12
|
+
export function createPiAiRouterClient(
|
|
13
|
+
model: Model<"anthropic-messages"> | Model<any>,
|
|
14
|
+
): RouterLlmClient {
|
|
13
15
|
return {
|
|
14
16
|
async complete(prompt: string): Promise<string> {
|
|
15
17
|
const response = await completeSimple(
|
|
@@ -33,9 +35,7 @@ export function createPiAiRouterClient(model: Model<"anthropic-messages"> | Mode
|
|
|
33
35
|
);
|
|
34
36
|
|
|
35
37
|
if (response.stopReason === "error" || response.stopReason === "aborted") {
|
|
36
|
-
throw new Error(
|
|
37
|
-
`router LLM call failed: ${response.errorMessage ?? response.stopReason}`,
|
|
38
|
-
);
|
|
38
|
+
throw new Error(`router LLM call failed: ${response.errorMessage ?? response.stopReason}`);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
const text = response.content
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ROUTE_CAPABILITY_MANIFEST,
|
|
3
|
-
WORKFLOW_CAPABILITY_MANIFEST,
|
|
4
|
-
} from "./route-manifest.js";
|
|
1
|
+
import { ROUTE_CAPABILITY_MANIFEST, WORKFLOW_CAPABILITY_MANIFEST } from "./route-manifest.js";
|
|
5
2
|
import type { RouterInputContext } from "./router-types.js";
|
|
6
3
|
|
|
7
4
|
/**
|
|
@@ -20,18 +17,21 @@ function renderCatalog(): string {
|
|
|
20
17
|
portfolio_builder: "user asks to build/allocate a portfolio, invest a budget across positions",
|
|
21
18
|
options_screener: "user asks for options trades / calls / puts on a specific ticker",
|
|
22
19
|
compare_assets: "user asks to compare two or more symbols (vs / versus / which is better)",
|
|
23
|
-
single_asset_analysis:
|
|
20
|
+
single_asset_analysis:
|
|
21
|
+
"user asks for a full analysis / deep dive / 'is X attractive' on ONE symbol",
|
|
24
22
|
watchlist_or_tracking: "user manages or asks about their saved watchlist / prediction history",
|
|
25
|
-
general_finance_qa:
|
|
23
|
+
general_finance_qa:
|
|
24
|
+
"definitional / conceptual questions plus broad market structure, sector, industry, monetary policy, and emerging markets research",
|
|
26
25
|
};
|
|
27
26
|
|
|
28
|
-
return Object.values(WORKFLOW_CAPABILITY_MANIFEST)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
return Object.values(WORKFLOW_CAPABILITY_MANIFEST)
|
|
28
|
+
.map((w) => {
|
|
29
|
+
const required =
|
|
30
|
+
w.requiredSlots.length > 0 ? ` [required: ${w.requiredSlots.join(", ")}]` : "";
|
|
31
|
+
const mode = w.dispatchable ? "dispatchable workflow" : "agent-task workflow label";
|
|
32
|
+
return `- "${w.workflow}" (${mode}): ${descriptions[w.workflow]}${required}`;
|
|
33
|
+
})
|
|
34
|
+
.join("\n");
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function renderRouteKinds(): string {
|
|
@@ -46,13 +46,9 @@ function renderProfile(profile: Record<string, unknown>): string {
|
|
|
46
46
|
return entries.map(([k, v]) => `- ${k}: ${JSON.stringify(v)}`).join("\n");
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function renderPriorTurns(
|
|
50
|
-
turns: Array<{ role: "user" | "assistant"; text: string }>,
|
|
51
|
-
): string {
|
|
49
|
+
function renderPriorTurns(turns: Array<{ role: "user" | "assistant"; text: string }>): string {
|
|
52
50
|
if (turns.length === 0) return "(none)";
|
|
53
|
-
return turns
|
|
54
|
-
.map((t) => `[${t.role}] ${t.text.replace(/\n+/g, " ").slice(0, 400)}`)
|
|
55
|
-
.join("\n");
|
|
51
|
+
return turns.map((t) => `[${t.role}] ${t.text.replace(/\n+/g, " ").slice(0, 400)}`).join("\n");
|
|
56
52
|
}
|
|
57
53
|
|
|
58
54
|
function renderRecentRuns(
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import type { ExtractedEntities, SlotSource, WorkflowType } from "./types.js";
|
|
2
2
|
|
|
3
3
|
export type RouterRoute = "workflow" | "fallback";
|
|
4
|
-
export type RouterRouteKind =
|
|
5
|
-
| "workflow_dispatch"
|
|
6
|
-
| "agent_task"
|
|
7
|
-
| "clarification"
|
|
8
|
-
| "pass_through";
|
|
4
|
+
export type RouterRouteKind = "workflow_dispatch" | "agent_task" | "clarification" | "pass_through";
|
|
9
5
|
|
|
10
6
|
export type ToolBundleName =
|
|
11
7
|
| "core_market"
|
|
@@ -33,6 +29,7 @@ export interface RouterPreferenceUpdate {
|
|
|
33
29
|
export interface RouterDiagnostic {
|
|
34
30
|
code: string;
|
|
35
31
|
message: string;
|
|
32
|
+
details?: Record<string, unknown>;
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
/**
|