opencandle 0.11.1 → 0.12.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 +20 -24
- package/dist/analysts/contracts.js +0 -1
- package/dist/analysts/orchestrator.js +0 -1
- package/dist/cli-main.js +13 -7
- package/dist/cli-options.d.ts +4 -0
- package/dist/cli-options.js +33 -0
- package/dist/cli.js +8 -3
- package/dist/config.js +0 -1
- package/dist/doctor/cli-command.js +2 -1
- package/dist/doctor/render.js +0 -1
- package/dist/doctor/report.js +40 -11
- package/dist/gui/server/ask-user-bridge.d.ts +19 -0
- package/dist/gui/server/ask-user-bridge.js +55 -0
- package/dist/gui/server/automation-heartbeat.d.ts +25 -0
- package/dist/gui/server/automation-heartbeat.js +61 -0
- package/dist/gui/server/background-quotes.d.ts +39 -0
- package/dist/gui/server/background-quotes.js +71 -0
- package/dist/gui/server/chat-event-adapter.d.ts +16 -0
- package/dist/gui/server/chat-event-adapter.js +263 -0
- package/dist/gui/server/gui-session-manager.d.ts +2 -0
- package/dist/gui/server/gui-session-manager.js +4 -0
- package/dist/gui/server/http-routes.d.ts +69 -0
- package/dist/gui/server/http-routes.js +1008 -0
- package/dist/gui/server/invoke-tool.d.ts +47 -0
- package/dist/gui/server/invoke-tool.js +373 -0
- package/dist/gui/server/live-chat-event-adapter.d.ts +19 -0
- package/dist/gui/server/live-chat-event-adapter.js +206 -0
- package/dist/gui/server/local-session-coordinator.d.ts +26 -0
- package/dist/gui/server/local-session-coordinator.js +53 -0
- package/dist/gui/server/market-state-api.d.ts +138 -0
- package/dist/gui/server/market-state-api.js +355 -0
- package/dist/gui/server/model-setup.d.ts +64 -0
- package/dist/gui/server/model-setup.js +150 -0
- package/dist/gui/server/private-api-access.d.ts +6 -0
- package/dist/gui/server/private-api-access.js +53 -0
- package/dist/gui/server/projector.d.ts +49 -0
- package/dist/gui/server/projector.js +296 -0
- package/dist/gui/server/prompt-observation.d.ts +8 -0
- package/dist/gui/server/prompt-observation.js +43 -0
- package/dist/gui/server/quote-snapshot-store.d.ts +14 -0
- package/dist/gui/server/quote-snapshot-store.js +49 -0
- package/dist/gui/server/server.d.ts +1 -0
- package/dist/gui/server/server.js +259 -0
- package/dist/gui/server/session-actions.d.ts +60 -0
- package/dist/gui/server/session-actions.js +218 -0
- package/dist/gui/server/session-entry-wait.d.ts +27 -0
- package/dist/gui/server/session-entry-wait.js +129 -0
- package/dist/gui/server/session-list.d.ts +2 -0
- package/dist/gui/server/session-list.js +11 -0
- package/dist/gui/server/shutdown.d.ts +10 -0
- package/dist/gui/server/shutdown.js +29 -0
- package/dist/gui/server/tool-invoke-ack.d.ts +17 -0
- package/dist/gui/server/tool-invoke-ack.js +26 -0
- package/dist/gui/server/tool-metadata.d.ts +93 -0
- package/dist/gui/server/tool-metadata.js +148 -0
- package/dist/gui/server/websocket.d.ts +9 -0
- package/dist/gui/server/websocket.js +124 -0
- package/dist/gui/server/writer-lock.d.ts +1 -0
- package/dist/gui/server/writer-lock.js +1 -0
- package/dist/gui/server/ws-hub.d.ts +50 -0
- package/dist/gui/server/ws-hub.js +284 -0
- package/dist/gui/shared/chat-events.d.ts +174 -0
- package/dist/gui/shared/chat-events.js +13 -0
- package/dist/gui/shared/event-reducer.d.ts +3 -0
- package/dist/gui/shared/event-reducer.js +187 -0
- package/dist/index.js +0 -1
- package/dist/infra/cache.js +0 -1
- package/dist/infra/freshness.js +0 -1
- package/dist/infra/http-client.js +1 -2
- package/dist/infra/index.js +0 -1
- package/dist/infra/market-calendar.js +0 -1
- package/dist/infra/native-dependencies.js +0 -1
- package/dist/infra/node-version.js +0 -1
- package/dist/infra/open-url.js +0 -1
- package/dist/infra/opencandle-paths.js +0 -1
- package/dist/infra/rate-limiter.js +0 -1
- package/dist/market-state/alert-conditions.js +0 -1
- package/dist/market-state/alert-runner.d.ts +1 -0
- package/dist/market-state/alert-runner.js +5 -4
- package/dist/market-state/daily-report.js +0 -1
- package/dist/market-state/local-automation-service.js +0 -1
- package/dist/market-state/notification-delivery.js +0 -1
- package/dist/market-state/resolve-for-mutation.js +0 -1
- package/dist/market-state/resolve.js +0 -1
- package/dist/market-state/service.d.ts +26 -21
- package/dist/market-state/service.js +175 -36
- package/dist/market-state/summaries.js +1 -13
- package/dist/memory/index.js +0 -1
- package/dist/memory/manager.js +0 -1
- package/dist/memory/preference-extractor.js +0 -1
- package/dist/memory/retrieval.js +0 -1
- package/dist/memory/sqlite.js +60 -11
- package/dist/memory/storage.js +0 -1
- package/dist/memory/tool-defaults.js +0 -1
- package/dist/memory/types.js +0 -1
- package/dist/monitor.js +0 -1
- package/dist/onboarding/connect.js +0 -1
- package/dist/onboarding/credential-interceptor.js +0 -1
- package/dist/onboarding/degradation-accumulator.js +0 -1
- package/dist/onboarding/prompt-user.d.ts +1 -1
- package/dist/onboarding/prompt-user.js +0 -1
- package/dist/onboarding/provider-status.js +0 -1
- package/dist/onboarding/providers.js +0 -1
- package/dist/onboarding/state.js +0 -1
- package/dist/onboarding/tool-helpers.js +0 -1
- package/dist/onboarding/tool-tags.js +0 -1
- package/dist/onboarding/validate-model-key.d.ts +17 -0
- package/dist/onboarding/validate-model-key.js +54 -0
- package/dist/onboarding/validation.js +0 -1
- package/dist/pi/opencandle-extension.js +2 -2
- package/dist/pi/session-action-dedupe.js +0 -1
- package/dist/pi/session-storage.js +0 -1
- package/dist/pi/session-writer-lock.js +0 -1
- package/dist/pi/session.js +0 -1
- package/dist/pi/setup.d.ts +2 -0
- package/dist/pi/setup.js +10 -3
- package/dist/pi/tool-adapter.js +0 -1
- package/dist/pi/tui-session-coordinator.js +0 -1
- package/dist/prompts/context-builder.js +1 -2
- package/dist/prompts/disclaimer.js +0 -1
- package/dist/prompts/policy-cards.js +0 -1
- package/dist/prompts/sections.js +0 -1
- package/dist/prompts/symbol-preflight.js +0 -1
- package/dist/prompts/workflow-prompts.js +0 -1
- package/dist/providers/alpha-vantage.js +2 -3
- package/dist/providers/coingecko.js +0 -1
- package/dist/providers/errors.js +0 -1
- package/dist/providers/exa-search.js +11 -10
- package/dist/providers/external-tool-command.js +0 -1
- package/dist/providers/external-tool-error.js +0 -1
- package/dist/providers/fear-greed.js +0 -1
- package/dist/providers/finnhub.js +0 -1
- package/dist/providers/fred.js +0 -1
- package/dist/providers/index.js +0 -1
- package/dist/providers/polymarket.js +0 -1
- package/dist/providers/provider-credential-error.js +0 -1
- package/dist/providers/reddit-cli.js +0 -1
- package/dist/providers/reddit.js +0 -1
- package/dist/providers/sec-edgar.js +0 -1
- package/dist/providers/tradingview.js +1 -2
- package/dist/providers/twitter-cli.js +0 -1
- package/dist/providers/twitter.js +0 -1
- package/dist/providers/web-search.js +15 -12
- package/dist/providers/with-fallback.js +0 -1
- package/dist/providers/wrap-provider.js +0 -1
- package/dist/providers/yahoo-finance.js +67 -4
- package/dist/routing/classify-intent.js +0 -1
- package/dist/routing/defaults.js +0 -1
- package/dist/routing/entity-extractor.js +2 -3
- package/dist/routing/fund-symbols.js +0 -1
- package/dist/routing/horizon.js +0 -1
- package/dist/routing/index.js +0 -1
- package/dist/routing/legacy-rule-router.js +0 -1
- package/dist/routing/planning.js +0 -1
- package/dist/routing/route-manifest.js +0 -1
- package/dist/routing/router-llm-client.d.ts +2 -2
- package/dist/routing/router-llm-client.js +0 -1
- package/dist/routing/router-prompt.js +0 -1
- package/dist/routing/router-types.js +0 -1
- package/dist/routing/router.js +1 -2
- package/dist/routing/slot-resolver.js +0 -1
- package/dist/routing/symbol-disambiguator.js +0 -1
- package/dist/routing/turn-context.js +0 -1
- package/dist/routing/types.js +0 -1
- package/dist/runtime/answer-contracts.js +0 -1
- package/dist/runtime/artifact-contracts.js +0 -1
- package/dist/runtime/evidence.js +0 -1
- package/dist/runtime/numeric-claims.js +0 -1
- package/dist/runtime/planning-evidence.js +0 -1
- package/dist/runtime/prompt-step.js +0 -1
- package/dist/runtime/provider-tracker.js +0 -1
- package/dist/runtime/run-context.js +0 -1
- package/dist/runtime/session-coordinator.js +0 -1
- package/dist/runtime/session-title.js +0 -1
- package/dist/runtime/tool-defaults-wrapper.js +0 -1
- package/dist/runtime/validation.js +0 -1
- package/dist/runtime/workflow-events.js +0 -1
- package/dist/runtime/workflow-runner.d.ts +1 -0
- package/dist/runtime/workflow-runner.js +8 -3
- package/dist/runtime/workflow-types.js +0 -1
- package/dist/sentiment/adapters/finnhub.js +0 -1
- package/dist/sentiment/adapters/reddit.js +0 -1
- package/dist/sentiment/adapters/twitter.js +0 -1
- package/dist/sentiment/adapters/web.js +0 -1
- package/dist/sentiment/index.js +4 -2
- package/dist/sentiment/insights.js +0 -1
- package/dist/sentiment/keywords.js +0 -1
- package/dist/sentiment/pipeline.js +0 -1
- package/dist/sentiment/scorer.js +0 -1
- package/dist/sentiment/store.js +0 -1
- package/dist/sentiment/trends.js +0 -1
- package/dist/sentiment/types.js +0 -1
- package/dist/system-prompt.js +0 -1
- package/dist/tool-kit.js +0 -1
- package/dist/tools/fundamentals/company-overview.d.ts +1 -1
- package/dist/tools/fundamentals/company-overview.js +2 -1
- package/dist/tools/fundamentals/comps.js +6 -4
- package/dist/tools/fundamentals/dcf.js +0 -1
- package/dist/tools/fundamentals/earnings.d.ts +1 -1
- package/dist/tools/fundamentals/earnings.js +2 -1
- package/dist/tools/fundamentals/financials.js +2 -1
- package/dist/tools/fundamentals/sec-filings.js +0 -1
- package/dist/tools/index.d.ts +116 -2
- package/dist/tools/index.js +0 -1
- package/dist/tools/interaction/ask-user.js +11 -1
- package/dist/tools/macro/event-probabilities.js +0 -1
- package/dist/tools/macro/fear-greed.d.ts +1 -1
- package/dist/tools/macro/fear-greed.js +0 -1
- package/dist/tools/macro/fred-data.d.ts +1 -1
- package/dist/tools/macro/fred-data.js +2 -1
- package/dist/tools/market/crypto-history.js +0 -1
- package/dist/tools/market/crypto-price.d.ts +2 -2
- package/dist/tools/market/crypto-price.js +0 -1
- package/dist/tools/market/screen-stocks.js +0 -1
- package/dist/tools/market/search-ticker.js +1 -2
- package/dist/tools/market/stock-history.js +0 -1
- package/dist/tools/market/stock-quote.d.ts +2 -2
- package/dist/tools/market/stock-quote.js +0 -1
- package/dist/tools/options/greeks.js +0 -1
- package/dist/tools/options/option-chain.d.ts +2 -2
- package/dist/tools/options/option-chain.js +0 -1
- package/dist/tools/portfolio/alerts.d.ts +2 -1
- package/dist/tools/portfolio/alerts.js +228 -2
- package/dist/tools/portfolio/correlation.js +23 -5
- package/dist/tools/portfolio/daily-report.js +0 -1
- package/dist/tools/portfolio/holdings-overlap.js +0 -1
- package/dist/tools/portfolio/notifications.js +0 -1
- package/dist/tools/portfolio/risk-analysis.d.ts +1 -1
- package/dist/tools/portfolio/risk-analysis.js +0 -1
- package/dist/tools/portfolio/tracker.d.ts +3 -1
- package/dist/tools/portfolio/tracker.js +57 -10
- package/dist/tools/portfolio/watchlist.d.ts +3 -6
- package/dist/tools/portfolio/watchlist.js +101 -110
- package/dist/tools/sentiment/insight-format.js +0 -1
- package/dist/tools/sentiment/query-match.js +0 -1
- package/dist/tools/sentiment/reddit-sentiment.js +0 -1
- package/dist/tools/sentiment/sentiment-summary.js +8 -4
- package/dist/tools/sentiment/sentiment-trend.d.ts +5 -1
- package/dist/tools/sentiment/sentiment-trend.js +6 -2
- package/dist/tools/sentiment/twitter-sentiment.js +0 -1
- package/dist/tools/sentiment/untrusted-text.js +0 -1
- package/dist/tools/sentiment/web-search.d.ts +1 -1
- package/dist/tools/sentiment/web-search.js +0 -1
- package/dist/tools/sentiment/web-sentiment.js +0 -1
- package/dist/tools/technical/backtest.js +0 -1
- package/dist/tools/technical/indicators.js +0 -1
- package/dist/types/fundamentals.js +0 -1
- package/dist/types/index.js +0 -1
- package/dist/types/macro.js +0 -1
- package/dist/types/market.d.ts +6 -0
- package/dist/types/market.js +0 -1
- package/dist/types/options.js +0 -1
- package/dist/types/portfolio.js +0 -1
- package/dist/types/prediction-markets.js +0 -1
- package/dist/types/sentiment.js +0 -1
- package/dist/workflows/compare-assets.js +0 -1
- package/dist/workflows/index.js +0 -1
- package/dist/workflows/options-screener.js +0 -1
- package/dist/workflows/portfolio-builder.js +0 -1
- package/gui/web/dist/assets/CatalogOverlay-CAc7e3Pf.js +1 -0
- package/gui/web/dist/assets/index-BOEKd9wT.css +2 -0
- package/gui/web/dist/assets/index-C-H05cQ2.js +65 -0
- package/gui/web/dist/index.html +2 -2
- package/package.json +11 -12
- package/dist/analysts/contracts.js.map +0 -1
- package/dist/analysts/orchestrator.js.map +0 -1
- package/dist/cli-main.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/doctor/cli-command.js.map +0 -1
- package/dist/doctor/render.js.map +0 -1
- package/dist/doctor/report.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/infra/cache.js.map +0 -1
- package/dist/infra/freshness.js.map +0 -1
- package/dist/infra/http-client.js.map +0 -1
- package/dist/infra/index.js.map +0 -1
- package/dist/infra/market-calendar.js.map +0 -1
- package/dist/infra/native-dependencies.js.map +0 -1
- package/dist/infra/node-version.js.map +0 -1
- package/dist/infra/open-url.js.map +0 -1
- package/dist/infra/opencandle-paths.js.map +0 -1
- package/dist/infra/rate-limiter.js.map +0 -1
- package/dist/market-state/alert-conditions.js.map +0 -1
- package/dist/market-state/alert-runner.js.map +0 -1
- package/dist/market-state/daily-report.js.map +0 -1
- package/dist/market-state/local-automation-service.js.map +0 -1
- package/dist/market-state/notification-delivery.js.map +0 -1
- package/dist/market-state/resolve-for-mutation.js.map +0 -1
- package/dist/market-state/resolve.js.map +0 -1
- package/dist/market-state/service.js.map +0 -1
- package/dist/market-state/summaries.js.map +0 -1
- package/dist/memory/index.js.map +0 -1
- package/dist/memory/manager.js.map +0 -1
- package/dist/memory/preference-extractor.js.map +0 -1
- package/dist/memory/retrieval.js.map +0 -1
- package/dist/memory/sqlite.js.map +0 -1
- package/dist/memory/storage.js.map +0 -1
- package/dist/memory/tool-defaults.js.map +0 -1
- package/dist/memory/types.js.map +0 -1
- package/dist/monitor.js.map +0 -1
- package/dist/onboarding/connect.js.map +0 -1
- package/dist/onboarding/credential-interceptor.js.map +0 -1
- package/dist/onboarding/degradation-accumulator.js.map +0 -1
- package/dist/onboarding/prompt-user.js.map +0 -1
- package/dist/onboarding/provider-status.js.map +0 -1
- package/dist/onboarding/providers.js.map +0 -1
- package/dist/onboarding/state.js.map +0 -1
- package/dist/onboarding/tool-helpers.js.map +0 -1
- package/dist/onboarding/tool-tags.js.map +0 -1
- package/dist/onboarding/validation.js.map +0 -1
- package/dist/pi/opencandle-extension.js.map +0 -1
- package/dist/pi/session-action-dedupe.js.map +0 -1
- package/dist/pi/session-storage.js.map +0 -1
- package/dist/pi/session-writer-lock.js.map +0 -1
- package/dist/pi/session.js.map +0 -1
- package/dist/pi/setup.js.map +0 -1
- package/dist/pi/tool-adapter.js.map +0 -1
- package/dist/pi/tui-session-coordinator.js.map +0 -1
- package/dist/prompts/context-builder.js.map +0 -1
- package/dist/prompts/disclaimer.js.map +0 -1
- package/dist/prompts/policy-cards.js.map +0 -1
- package/dist/prompts/sections.js.map +0 -1
- package/dist/prompts/symbol-preflight.js.map +0 -1
- package/dist/prompts/workflow-prompts.js.map +0 -1
- package/dist/providers/alpha-vantage.js.map +0 -1
- package/dist/providers/coingecko.js.map +0 -1
- package/dist/providers/errors.js.map +0 -1
- package/dist/providers/exa-search.js.map +0 -1
- package/dist/providers/external-tool-command.js.map +0 -1
- package/dist/providers/external-tool-error.js.map +0 -1
- package/dist/providers/fear-greed.js.map +0 -1
- package/dist/providers/finnhub.js.map +0 -1
- package/dist/providers/fred.js.map +0 -1
- package/dist/providers/index.js.map +0 -1
- package/dist/providers/polymarket.js.map +0 -1
- package/dist/providers/provider-credential-error.js.map +0 -1
- package/dist/providers/reddit-cli.js.map +0 -1
- package/dist/providers/reddit.js.map +0 -1
- package/dist/providers/sec-edgar.js.map +0 -1
- package/dist/providers/tradingview.js.map +0 -1
- package/dist/providers/twitter-cli.js.map +0 -1
- package/dist/providers/twitter.js.map +0 -1
- package/dist/providers/web-search.js.map +0 -1
- package/dist/providers/with-fallback.js.map +0 -1
- package/dist/providers/wrap-provider.js.map +0 -1
- package/dist/providers/yahoo-finance.js.map +0 -1
- package/dist/routing/classify-intent.js.map +0 -1
- package/dist/routing/defaults.js.map +0 -1
- package/dist/routing/entity-extractor.js.map +0 -1
- package/dist/routing/fund-symbols.js.map +0 -1
- package/dist/routing/horizon.js.map +0 -1
- package/dist/routing/index.js.map +0 -1
- package/dist/routing/legacy-rule-router.js.map +0 -1
- package/dist/routing/planning.js.map +0 -1
- package/dist/routing/route-manifest.js.map +0 -1
- package/dist/routing/router-llm-client.js.map +0 -1
- package/dist/routing/router-prompt.js.map +0 -1
- package/dist/routing/router-types.js.map +0 -1
- package/dist/routing/router.js.map +0 -1
- package/dist/routing/slot-resolver.js.map +0 -1
- package/dist/routing/symbol-disambiguator.js.map +0 -1
- package/dist/routing/turn-context.js.map +0 -1
- package/dist/routing/types.js.map +0 -1
- package/dist/runtime/answer-contracts.js.map +0 -1
- package/dist/runtime/artifact-contracts.js.map +0 -1
- package/dist/runtime/evidence.js.map +0 -1
- package/dist/runtime/numeric-claims.js.map +0 -1
- package/dist/runtime/planning-evidence.js.map +0 -1
- package/dist/runtime/prompt-step.js.map +0 -1
- package/dist/runtime/provider-tracker.js.map +0 -1
- package/dist/runtime/run-context.js.map +0 -1
- package/dist/runtime/session-coordinator.js.map +0 -1
- package/dist/runtime/session-title.js.map +0 -1
- package/dist/runtime/tool-defaults-wrapper.js.map +0 -1
- package/dist/runtime/validation.js.map +0 -1
- package/dist/runtime/workflow-events.js.map +0 -1
- package/dist/runtime/workflow-runner.js.map +0 -1
- package/dist/runtime/workflow-types.js.map +0 -1
- package/dist/sentiment/adapters/finnhub.js.map +0 -1
- package/dist/sentiment/adapters/reddit.js.map +0 -1
- package/dist/sentiment/adapters/twitter.js.map +0 -1
- package/dist/sentiment/adapters/web.js.map +0 -1
- package/dist/sentiment/index.js.map +0 -1
- package/dist/sentiment/insights.js.map +0 -1
- package/dist/sentiment/keywords.js.map +0 -1
- package/dist/sentiment/pipeline.js.map +0 -1
- package/dist/sentiment/scorer.js.map +0 -1
- package/dist/sentiment/store.js.map +0 -1
- package/dist/sentiment/trends.js.map +0 -1
- package/dist/sentiment/types.js.map +0 -1
- package/dist/system-prompt.js.map +0 -1
- package/dist/tool-kit.js.map +0 -1
- package/dist/tools/fundamentals/company-overview.js.map +0 -1
- package/dist/tools/fundamentals/comps.js.map +0 -1
- package/dist/tools/fundamentals/dcf.js.map +0 -1
- package/dist/tools/fundamentals/earnings.js.map +0 -1
- package/dist/tools/fundamentals/financials.js.map +0 -1
- package/dist/tools/fundamentals/sec-filings.js.map +0 -1
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/interaction/ask-user.js.map +0 -1
- package/dist/tools/macro/event-probabilities.js.map +0 -1
- package/dist/tools/macro/fear-greed.js.map +0 -1
- package/dist/tools/macro/fred-data.js.map +0 -1
- package/dist/tools/market/crypto-history.js.map +0 -1
- package/dist/tools/market/crypto-price.js.map +0 -1
- package/dist/tools/market/screen-stocks.js.map +0 -1
- package/dist/tools/market/search-ticker.js.map +0 -1
- package/dist/tools/market/stock-history.js.map +0 -1
- package/dist/tools/market/stock-quote.js.map +0 -1
- package/dist/tools/options/greeks.js.map +0 -1
- package/dist/tools/options/option-chain.js.map +0 -1
- package/dist/tools/portfolio/alerts.js.map +0 -1
- package/dist/tools/portfolio/correlation.js.map +0 -1
- package/dist/tools/portfolio/daily-report.js.map +0 -1
- package/dist/tools/portfolio/holdings-overlap.js.map +0 -1
- package/dist/tools/portfolio/notifications.js.map +0 -1
- package/dist/tools/portfolio/risk-analysis.js.map +0 -1
- package/dist/tools/portfolio/tracker.js.map +0 -1
- package/dist/tools/portfolio/watchlist.js.map +0 -1
- package/dist/tools/sentiment/insight-format.js.map +0 -1
- package/dist/tools/sentiment/query-match.js.map +0 -1
- package/dist/tools/sentiment/reddit-sentiment.js.map +0 -1
- package/dist/tools/sentiment/sentiment-summary.js.map +0 -1
- package/dist/tools/sentiment/sentiment-trend.js.map +0 -1
- package/dist/tools/sentiment/twitter-sentiment.js.map +0 -1
- package/dist/tools/sentiment/untrusted-text.js.map +0 -1
- package/dist/tools/sentiment/web-search.js.map +0 -1
- package/dist/tools/sentiment/web-sentiment.js.map +0 -1
- package/dist/tools/technical/backtest.js.map +0 -1
- package/dist/tools/technical/indicators.js.map +0 -1
- package/dist/types/fundamentals.js.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/types/macro.js.map +0 -1
- package/dist/types/market.js.map +0 -1
- package/dist/types/options.js.map +0 -1
- package/dist/types/portfolio.js.map +0 -1
- package/dist/types/prediction-markets.js.map +0 -1
- package/dist/types/sentiment.js.map +0 -1
- package/dist/workflows/compare-assets.js.map +0 -1
- package/dist/workflows/index.js.map +0 -1
- package/dist/workflows/options-screener.js.map +0 -1
- package/dist/workflows/portfolio-builder.js.map +0 -1
- package/gui/server/ask-user-bridge.ts +0 -89
- package/gui/server/automation-heartbeat.ts +0 -97
- package/gui/server/background-quotes.ts +0 -127
- package/gui/server/chat-event-adapter.ts +0 -294
- package/gui/server/gui-session-manager.ts +0 -5
- package/gui/server/http-routes.ts +0 -1201
- package/gui/server/invoke-tool.ts +0 -490
- package/gui/server/live-chat-event-adapter.ts +0 -243
- package/gui/server/local-session-coordinator.ts +0 -97
- package/gui/server/market-state-api.ts +0 -331
- package/gui/server/model-setup.ts +0 -254
- package/gui/server/package.json +0 -5
- package/gui/server/private-api-access.ts +0 -62
- package/gui/server/projector.ts +0 -392
- package/gui/server/prompt-observation.ts +0 -58
- package/gui/server/quote-snapshot-store.ts +0 -50
- package/gui/server/server.ts +0 -289
- package/gui/server/session-actions.ts +0 -323
- package/gui/server/session-entry-wait.ts +0 -179
- package/gui/server/shutdown.ts +0 -47
- package/gui/server/tool-invoke-ack.ts +0 -49
- package/gui/server/tool-metadata.ts +0 -167
- package/gui/server/websocket.ts +0 -138
- package/gui/server/writer-lock.ts +0 -1
- package/gui/server/ws-hub.ts +0 -403
- package/gui/shared/chat-events.ts +0 -165
- package/gui/shared/event-reducer.ts +0 -220
- package/gui/web/dist/assets/CatalogOverlay-DZ1niyQm.js +0 -1
- package/gui/web/dist/assets/index-D4F9AJnn.css +0 -2
- package/gui/web/dist/assets/index-DtqMMBTr.js +0 -65
- package/src/analysts/contracts.ts +0 -176
- package/src/analysts/orchestrator.ts +0 -244
- package/src/cli-main.ts +0 -510
- package/src/cli.ts +0 -17
- package/src/config.ts +0 -272
- package/src/doctor/cli-command.ts +0 -83
- package/src/doctor/render.ts +0 -37
- package/src/doctor/report.ts +0 -638
- package/src/index.ts +0 -5
- package/src/infra/cache.ts +0 -127
- package/src/infra/freshness.ts +0 -165
- package/src/infra/http-client.ts +0 -134
- package/src/infra/index.ts +0 -14
- package/src/infra/market-calendar.ts +0 -193
- package/src/infra/native-dependencies.ts +0 -84
- package/src/infra/node-version.ts +0 -23
- package/src/infra/open-url.ts +0 -28
- package/src/infra/opencandle-paths.ts +0 -53
- package/src/infra/rate-limiter.ts +0 -77
- package/src/market-state/alert-conditions.ts +0 -82
- package/src/market-state/alert-runner.ts +0 -863
- package/src/market-state/daily-report.ts +0 -237
- package/src/market-state/local-automation-service.ts +0 -162
- package/src/market-state/notification-delivery.ts +0 -158
- package/src/market-state/resolve-for-mutation.ts +0 -24
- package/src/market-state/resolve.ts +0 -112
- package/src/market-state/service.ts +0 -2208
- package/src/market-state/summaries.ts +0 -75
- package/src/memory/index.ts +0 -10
- package/src/memory/manager.ts +0 -190
- package/src/memory/preference-extractor.ts +0 -106
- package/src/memory/retrieval.ts +0 -71
- package/src/memory/sqlite.ts +0 -577
- package/src/memory/storage.ts +0 -195
- package/src/memory/tool-defaults.ts +0 -108
- package/src/memory/types.ts +0 -71
- package/src/monitor.ts +0 -123
- package/src/onboarding/connect.ts +0 -177
- package/src/onboarding/credential-interceptor.ts +0 -122
- package/src/onboarding/degradation-accumulator.ts +0 -77
- package/src/onboarding/prompt-user.ts +0 -85
- package/src/onboarding/provider-status.ts +0 -382
- package/src/onboarding/providers.ts +0 -442
- package/src/onboarding/state.ts +0 -216
- package/src/onboarding/tool-helpers.ts +0 -104
- package/src/onboarding/tool-tags.ts +0 -244
- package/src/onboarding/validation.ts +0 -152
- package/src/pi/opencandle-extension.ts +0 -1294
- package/src/pi/session-action-dedupe.ts +0 -155
- package/src/pi/session-storage.ts +0 -5
- package/src/pi/session-writer-lock.ts +0 -426
- package/src/pi/session.ts +0 -84
- package/src/pi/setup.ts +0 -399
- package/src/pi/tool-adapter.ts +0 -49
- package/src/pi/tui-session-coordinator.ts +0 -351
- package/src/prompts/context-builder.ts +0 -326
- package/src/prompts/disclaimer.ts +0 -9
- package/src/prompts/policy-cards.ts +0 -228
- package/src/prompts/sections.ts +0 -46
- package/src/prompts/symbol-preflight.ts +0 -80
- package/src/prompts/workflow-prompts.ts +0 -504
- package/src/providers/alpha-vantage.ts +0 -340
- package/src/providers/coingecko.ts +0 -95
- package/src/providers/errors.ts +0 -9
- package/src/providers/exa-search.ts +0 -375
- package/src/providers/external-tool-command.ts +0 -164
- package/src/providers/external-tool-error.ts +0 -20
- package/src/providers/fear-greed.ts +0 -45
- package/src/providers/finnhub.ts +0 -125
- package/src/providers/fred.ts +0 -83
- package/src/providers/index.ts +0 -17
- package/src/providers/polymarket.ts +0 -214
- package/src/providers/provider-credential-error.ts +0 -23
- package/src/providers/reddit-cli.ts +0 -286
- package/src/providers/reddit.ts +0 -106
- package/src/providers/sec-edgar.ts +0 -326
- package/src/providers/tradingview.ts +0 -399
- package/src/providers/twitter-cli.ts +0 -202
- package/src/providers/twitter.ts +0 -102
- package/src/providers/web-search.ts +0 -303
- package/src/providers/with-fallback.ts +0 -42
- package/src/providers/wrap-provider.ts +0 -105
- package/src/providers/yahoo-finance.ts +0 -984
- package/src/routing/classify-intent.ts +0 -380
- package/src/routing/defaults.ts +0 -29
- package/src/routing/entity-extractor.ts +0 -557
- package/src/routing/fund-symbols.ts +0 -58
- package/src/routing/horizon.ts +0 -7
- package/src/routing/index.ts +0 -70
- package/src/routing/legacy-rule-router.ts +0 -13
- package/src/routing/planning.ts +0 -829
- package/src/routing/route-manifest.ts +0 -308
- package/src/routing/router-llm-client.ts +0 -64
- package/src/routing/router-prompt.ts +0 -159
- package/src/routing/router-types.ts +0 -84
- package/src/routing/router.ts +0 -1332
- package/src/routing/slot-resolver.ts +0 -213
- package/src/routing/symbol-disambiguator.ts +0 -72
- package/src/routing/turn-context.ts +0 -108
- package/src/routing/types.ts +0 -77
- package/src/runtime/answer-contracts.ts +0 -693
- package/src/runtime/artifact-contracts.ts +0 -77
- package/src/runtime/evidence.ts +0 -78
- package/src/runtime/numeric-claims.ts +0 -108
- package/src/runtime/planning-evidence.ts +0 -597
- package/src/runtime/prompt-step.ts +0 -185
- package/src/runtime/provider-tracker.ts +0 -40
- package/src/runtime/run-context.ts +0 -32
- package/src/runtime/session-coordinator.ts +0 -1037
- package/src/runtime/session-title.ts +0 -60
- package/src/runtime/tool-defaults-wrapper.ts +0 -43
- package/src/runtime/validation.ts +0 -211
- package/src/runtime/workflow-events.ts +0 -77
- package/src/runtime/workflow-runner.ts +0 -182
- package/src/runtime/workflow-types.ts +0 -105
- package/src/sentiment/adapters/finnhub.ts +0 -49
- package/src/sentiment/adapters/reddit.ts +0 -65
- package/src/sentiment/adapters/twitter.ts +0 -36
- package/src/sentiment/adapters/web.ts +0 -44
- package/src/sentiment/index.ts +0 -49
- package/src/sentiment/insights.ts +0 -269
- package/src/sentiment/keywords.ts +0 -31
- package/src/sentiment/pipeline.ts +0 -91
- package/src/sentiment/scorer.ts +0 -89
- package/src/sentiment/store.ts +0 -260
- package/src/sentiment/trends.ts +0 -96
- package/src/sentiment/types.ts +0 -112
- package/src/system-prompt.ts +0 -115
- package/src/tool-kit.ts +0 -69
- package/src/tools/AGENTS.md +0 -36
- package/src/tools/fundamentals/company-overview.ts +0 -64
- package/src/tools/fundamentals/comps.ts +0 -180
- package/src/tools/fundamentals/dcf.ts +0 -447
- package/src/tools/fundamentals/earnings.ts +0 -57
- package/src/tools/fundamentals/financials.ts +0 -63
- package/src/tools/fundamentals/sec-filings.ts +0 -105
- package/src/tools/index.ts +0 -104
- package/src/tools/interaction/ask-user.ts +0 -93
- package/src/tools/macro/event-probabilities.ts +0 -141
- package/src/tools/macro/fear-greed.ts +0 -41
- package/src/tools/macro/fred-data.ts +0 -92
- package/src/tools/market/crypto-history.ts +0 -72
- package/src/tools/market/crypto-price.ts +0 -65
- package/src/tools/market/screen-stocks.ts +0 -290
- package/src/tools/market/search-ticker.ts +0 -254
- package/src/tools/market/stock-history.ts +0 -104
- package/src/tools/market/stock-quote.ts +0 -73
- package/src/tools/options/greeks.ts +0 -81
- package/src/tools/options/option-chain.ts +0 -134
- package/src/tools/portfolio/alerts.ts +0 -457
- package/src/tools/portfolio/correlation.ts +0 -189
- package/src/tools/portfolio/daily-report.ts +0 -107
- package/src/tools/portfolio/holdings-overlap.ts +0 -139
- package/src/tools/portfolio/notifications.ts +0 -45
- package/src/tools/portfolio/risk-analysis.ts +0 -173
- package/src/tools/portfolio/tracker.ts +0 -308
- package/src/tools/portfolio/watchlist.ts +0 -288
- package/src/tools/sentiment/insight-format.ts +0 -50
- package/src/tools/sentiment/query-match.ts +0 -117
- package/src/tools/sentiment/reddit-sentiment.ts +0 -403
- package/src/tools/sentiment/sentiment-summary.ts +0 -383
- package/src/tools/sentiment/sentiment-trend.ts +0 -75
- package/src/tools/sentiment/twitter-sentiment.ts +0 -287
- package/src/tools/sentiment/untrusted-text.ts +0 -21
- package/src/tools/sentiment/web-search.ts +0 -186
- package/src/tools/sentiment/web-sentiment.ts +0 -96
- package/src/tools/technical/backtest.ts +0 -336
- package/src/tools/technical/indicators.ts +0 -281
- package/src/types/fundamentals.ts +0 -47
- package/src/types/index.ts +0 -26
- package/src/types/macro.ts +0 -27
- package/src/types/market.ts +0 -46
- package/src/types/options.ts +0 -53
- package/src/types/portfolio.ts +0 -83
- package/src/types/prediction-markets.ts +0 -13
- package/src/types/sentiment.ts +0 -129
- package/src/workflows/compare-assets.ts +0 -89
- package/src/workflows/index.ts +0 -3
- package/src/workflows/options-screener.ts +0 -125
- package/src/workflows/portfolio-builder.ts +0 -63
|
@@ -39,9 +39,16 @@ export function alignReturnsByDate(historiesBySymbol, minOverlap = DEFAULT_MIN_O
|
|
|
39
39
|
}
|
|
40
40
|
// Find common dates across all symbols
|
|
41
41
|
const symbols = [...historiesBySymbol.keys()];
|
|
42
|
-
const
|
|
42
|
+
const firstSymbol = symbols[0];
|
|
43
|
+
if (!firstSymbol) {
|
|
44
|
+
throw new Error("No histories available for correlation analysis.");
|
|
45
|
+
}
|
|
46
|
+
const firstDates = priceByDate.get(firstSymbol);
|
|
47
|
+
if (!firstDates) {
|
|
48
|
+
throw new Error(`Missing price history for ${firstSymbol}.`);
|
|
49
|
+
}
|
|
43
50
|
const commonDates = [...firstDates.keys()]
|
|
44
|
-
.filter((date) => symbols.every((s) => priceByDate.get(s)
|
|
51
|
+
.filter((date) => symbols.every((s) => priceByDate.get(s)?.has(date)))
|
|
45
52
|
.sort();
|
|
46
53
|
if (commonDates.length < minOverlap) {
|
|
47
54
|
throw new Error(`Insufficient date overlap for correlation: ${commonDates.length} common dates (need ${minOverlap}+). Symbols may trade on different exchanges or have sparse history.`);
|
|
@@ -50,7 +57,14 @@ export function alignReturnsByDate(historiesBySymbol, minOverlap = DEFAULT_MIN_O
|
|
|
50
57
|
const result = new Map();
|
|
51
58
|
for (const symbol of symbols) {
|
|
52
59
|
const dateMap = priceByDate.get(symbol);
|
|
53
|
-
|
|
60
|
+
if (!dateMap)
|
|
61
|
+
throw new Error(`Missing price history for ${symbol}.`);
|
|
62
|
+
const alignedCloses = commonDates.map((d) => {
|
|
63
|
+
const close = dateMap.get(d);
|
|
64
|
+
if (close === undefined)
|
|
65
|
+
throw new Error(`Missing close for ${symbol} on ${d}.`);
|
|
66
|
+
return close;
|
|
67
|
+
});
|
|
54
68
|
result.set(symbol, computeDailyReturns(alignedCloses));
|
|
55
69
|
}
|
|
56
70
|
return result;
|
|
@@ -116,7 +130,12 @@ export const correlationTool = {
|
|
|
116
130
|
matrix[a][b] = matrix[b][a];
|
|
117
131
|
}
|
|
118
132
|
else {
|
|
119
|
-
const
|
|
133
|
+
const returnsA = returnsBySymbol.get(a);
|
|
134
|
+
const returnsB = returnsBySymbol.get(b);
|
|
135
|
+
if (!returnsA || !returnsB) {
|
|
136
|
+
throw new Error(`Missing aligned returns for ${a}/${b}.`);
|
|
137
|
+
}
|
|
138
|
+
const r = computeCorrelation(returnsA, returnsB);
|
|
120
139
|
matrix[a][b] = r;
|
|
121
140
|
if (Math.abs(r) > 0.7 && a < b) {
|
|
122
141
|
warnings.push(`${a}/${b}: r=${r.toFixed(2)} — high correlation, concentration risk`);
|
|
@@ -151,4 +170,3 @@ export const correlationTool = {
|
|
|
151
170
|
};
|
|
152
171
|
},
|
|
153
172
|
};
|
|
154
|
-
//# sourceMappingURL=correlation.js.map
|
|
@@ -4,7 +4,7 @@ declare const params: import("@sinclair/typebox").TObject<{
|
|
|
4
4
|
symbol: import("@sinclair/typebox").TString;
|
|
5
5
|
period: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"6mo" | "1y" | "2y">[]>>;
|
|
6
6
|
}>;
|
|
7
|
-
export declare const riskAnalysisTool: AgentTool<typeof params, RiskMetrics>;
|
|
7
|
+
export declare const riskAnalysisTool: AgentTool<typeof params, RiskMetrics | null>;
|
|
8
8
|
export declare function computeRiskMetrics(symbol: string, closes: number[]): RiskMetrics;
|
|
9
9
|
export declare function computeDailyReturns(prices: number[]): number[];
|
|
10
10
|
export declare function computeMaxDrawdown(prices: number[]): number;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { AgentTool } from "@earendil-works/pi-agent-core";
|
|
2
2
|
declare const params: import("@sinclair/typebox").TObject<{
|
|
3
|
-
action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"add">, import("@sinclair/typebox").TLiteral<"update">, import("@sinclair/typebox").TLiteral<"remove">, import("@sinclair/typebox").TLiteral<"view">]>;
|
|
3
|
+
action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"create">, import("@sinclair/typebox").TLiteral<"rename">, import("@sinclair/typebox").TLiteral<"add">, import("@sinclair/typebox").TLiteral<"update">, import("@sinclair/typebox").TLiteral<"remove">, import("@sinclair/typebox").TLiteral<"view">]>;
|
|
4
|
+
portfolio_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
5
|
+
new_portfolio_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
4
6
|
lot_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
5
7
|
symbol: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
6
8
|
shares: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
@@ -17,7 +17,20 @@ async function getCurrentPrice(symbol) {
|
|
|
17
17
|
return { status: "ok", price: result.data.price, currency: result.data.currency ?? null };
|
|
18
18
|
}
|
|
19
19
|
const params = Type.Object({
|
|
20
|
-
action: Type.Union([
|
|
20
|
+
action: Type.Union([
|
|
21
|
+
Type.Literal("create"),
|
|
22
|
+
Type.Literal("rename"),
|
|
23
|
+
Type.Literal("add"),
|
|
24
|
+
Type.Literal("update"),
|
|
25
|
+
Type.Literal("remove"),
|
|
26
|
+
Type.Literal("view"),
|
|
27
|
+
], {
|
|
28
|
+
description: "Action: create or rename a portfolio, add a position, update a lot, remove a position, or view portfolio",
|
|
29
|
+
}),
|
|
30
|
+
portfolio_name: Type.Optional(Type.String({
|
|
31
|
+
description: "Portfolio name. Defaults to the Default portfolio when omitted.",
|
|
32
|
+
})),
|
|
33
|
+
new_portfolio_name: Type.Optional(Type.String({ description: "New portfolio name (required for rename)." })),
|
|
21
34
|
lot_id: Type.Optional(Type.Integer({
|
|
22
35
|
minimum: 1,
|
|
23
36
|
description: "Portfolio lot id for precise update or single-lot removal",
|
|
@@ -37,12 +50,39 @@ const params = Type.Object({
|
|
|
37
50
|
export const portfolioTrackerTool = {
|
|
38
51
|
name: "track_portfolio",
|
|
39
52
|
label: "Portfolio Tracker",
|
|
40
|
-
description: "Track
|
|
53
|
+
description: "Track named portfolios of stocks and crypto. Create or rename portfolios, add/remove positions with cost basis, or view current holdings with live P&L. For stocks use standard tickers (AAPL, MSFT). For crypto use the -USD suffix (BTC-USD, ETH-USD, SOL-USD). Use search_ticker first if you're unsure of the exact ticker.",
|
|
41
54
|
parameters: params,
|
|
42
55
|
async execute(_toolCallId, args) {
|
|
43
56
|
const db = initDefaultDatabase();
|
|
44
57
|
const service = new MarketStateService(db);
|
|
45
58
|
try {
|
|
59
|
+
if (args.action === "create") {
|
|
60
|
+
if (!args.portfolio_name)
|
|
61
|
+
throw new Error("portfolio_name is required for create action.");
|
|
62
|
+
const portfolio = service.createPortfolio(args.portfolio_name);
|
|
63
|
+
return {
|
|
64
|
+
content: [{ type: "text", text: `Created portfolio ${portfolio.name}` }],
|
|
65
|
+
details: portfolio,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (args.action === "rename") {
|
|
69
|
+
if (!args.new_portfolio_name) {
|
|
70
|
+
throw new Error("new_portfolio_name is required for rename action.");
|
|
71
|
+
}
|
|
72
|
+
const currentName = args.portfolio_name?.trim() || service.getDefaultPortfolio().name;
|
|
73
|
+
const current = args.portfolio_name
|
|
74
|
+
? service.getPortfolioByName(currentName)
|
|
75
|
+
: service.getDefaultPortfolio();
|
|
76
|
+
if (current == null) {
|
|
77
|
+
throw new Error(`portfolio ${currentName} not found.`);
|
|
78
|
+
}
|
|
79
|
+
const portfolio = service.renamePortfolio(current.name, args.new_portfolio_name);
|
|
80
|
+
return {
|
|
81
|
+
content: [{ type: "text", text: `Renamed ${current.name} to ${portfolio.name}` }],
|
|
82
|
+
details: portfolio,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const portfolio = service.getOrCreatePortfolio(args.portfolio_name);
|
|
46
86
|
if (args.action === "add") {
|
|
47
87
|
if (!args.symbol || args.shares == null || args.avg_cost == null) {
|
|
48
88
|
throw new Error("symbol, shares, and avg_cost are required for add action.");
|
|
@@ -81,6 +121,7 @@ export const portfolioTrackerTool = {
|
|
|
81
121
|
const currency = resolvedCurrency.toUpperCase();
|
|
82
122
|
const lot = service.addPortfolioLot({
|
|
83
123
|
instrument: instrument.instrument,
|
|
124
|
+
portfolioId: portfolio.id,
|
|
84
125
|
quantity: args.shares,
|
|
85
126
|
avgCost: args.avg_cost,
|
|
86
127
|
currency,
|
|
@@ -115,10 +156,12 @@ export const portfolioTrackerTool = {
|
|
|
115
156
|
throw new Error("lot_id or symbol is required for remove action.");
|
|
116
157
|
}
|
|
117
158
|
const symbol = args.symbol.toUpperCase();
|
|
118
|
-
const removedLots = service
|
|
119
|
-
|
|
159
|
+
const removedLots = service
|
|
160
|
+
.listPortfolioLots(portfolio.id)
|
|
161
|
+
.filter((lot) => lot.symbol === symbol);
|
|
162
|
+
if (!service.removePortfolioLotsBySymbol(symbol, portfolio.id)) {
|
|
120
163
|
return {
|
|
121
|
-
content: [{ type: "text", text: `${symbol} not found in portfolio` }],
|
|
164
|
+
content: [{ type: "text", text: `${symbol} not found in ${portfolio.name}` }],
|
|
122
165
|
details: null,
|
|
123
166
|
};
|
|
124
167
|
}
|
|
@@ -173,14 +216,19 @@ export const portfolioTrackerTool = {
|
|
|
173
216
|
details: updated,
|
|
174
217
|
};
|
|
175
218
|
}
|
|
176
|
-
const lots = service.listPortfolioLots();
|
|
219
|
+
const lots = service.listPortfolioLots(portfolio.id);
|
|
220
|
+
const displayPortfolioName = portfolio.isDefault ? "Portfolio" : portfolio.name;
|
|
177
221
|
if (lots.length === 0) {
|
|
178
222
|
return {
|
|
179
|
-
content: [
|
|
223
|
+
content: [
|
|
224
|
+
{
|
|
225
|
+
type: "text",
|
|
226
|
+
text: `${displayPortfolioName} is empty. Use add action to add positions.`,
|
|
227
|
+
},
|
|
228
|
+
],
|
|
180
229
|
details: null,
|
|
181
230
|
};
|
|
182
231
|
}
|
|
183
|
-
const portfolio = service.getDefaultPortfolio();
|
|
184
232
|
const baseCurrency = portfolio.baseCurrency ?? "USD";
|
|
185
233
|
const enriched = await Promise.all(lots.map(async (p) => {
|
|
186
234
|
const quote = await getCurrentPrice(p.symbol);
|
|
@@ -241,7 +289,7 @@ export const portfolioTrackerTool = {
|
|
|
241
289
|
totalPnlPercent: totalCost > 0 ? ((totalValue - totalCost) / totalCost) * 100 : 0,
|
|
242
290
|
excludedFromTotals,
|
|
243
291
|
};
|
|
244
|
-
const header =
|
|
292
|
+
const header = `**${displayPortfolioName}** — ${enriched.length} positions | Value: ${formatMoney(totalValue, baseCurrency)} | P&L: ${formatMoney(summary.totalPnl, baseCurrency)} (${summary.totalPnlPercent >= 0 ? "+" : ""}${summary.totalPnlPercent.toFixed(2)}%)`;
|
|
245
293
|
const rows = enriched.map((p) => {
|
|
246
294
|
const excluded = p.includedInTotals
|
|
247
295
|
? ""
|
|
@@ -270,4 +318,3 @@ function formatMoney(value, currency) {
|
|
|
270
318
|
return `$${value.toFixed(2)}`;
|
|
271
319
|
return `${currency} ${value.toFixed(2)}`;
|
|
272
320
|
}
|
|
273
|
-
//# sourceMappingURL=tracker.js.map
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import type { AgentTool } from "@earendil-works/pi-agent-core";
|
|
2
2
|
declare const params: import("@sinclair/typebox").TObject<{
|
|
3
|
-
action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"
|
|
3
|
+
action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"create">, import("@sinclair/typebox").TLiteral<"rename">, import("@sinclair/typebox").TLiteral<"delete">, import("@sinclair/typebox").TLiteral<"add">, import("@sinclair/typebox").TLiteral<"remove">, import("@sinclair/typebox").TLiteral<"check">]>;
|
|
4
|
+
watchlist_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
4
5
|
symbol: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
5
|
-
|
|
6
|
-
stop_price: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TNumber, import("@sinclair/typebox").TNull]>>;
|
|
7
|
-
notes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TNull]>>;
|
|
8
|
-
thesis: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TNull]>>;
|
|
9
|
-
tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
6
|
+
new_watchlist_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
10
7
|
}>;
|
|
11
8
|
export declare const watchlistTool: AgentTool<typeof params>;
|
|
12
9
|
export {};
|
|
@@ -1,41 +1,83 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
2
|
import { isZeroFilledQuote } from "../../market-state/resolve.js";
|
|
3
3
|
import { resolveInstrumentForMutation } from "../../market-state/resolve-for-mutation.js";
|
|
4
|
-
import { MarketStateService } from "../../market-state/service.js";
|
|
4
|
+
import { MarketStateService, } from "../../market-state/service.js";
|
|
5
5
|
import { initDefaultDatabase } from "../../memory/sqlite.js";
|
|
6
6
|
import { getQuotes } from "../../providers/tradingview.js";
|
|
7
7
|
import { wrapProvider } from "../../providers/wrap-provider.js";
|
|
8
8
|
import { getQuote } from "../../providers/yahoo-finance.js";
|
|
9
9
|
const params = Type.Object({
|
|
10
|
-
action: Type.Union([
|
|
10
|
+
action: Type.Union([
|
|
11
|
+
Type.Literal("create"),
|
|
12
|
+
Type.Literal("rename"),
|
|
13
|
+
Type.Literal("delete"),
|
|
14
|
+
Type.Literal("add"),
|
|
15
|
+
Type.Literal("remove"),
|
|
16
|
+
Type.Literal("check"),
|
|
17
|
+
], { description: "One of: 'create', 'rename', 'delete', 'add', 'remove', or 'check'" }),
|
|
18
|
+
watchlist_name: Type.Optional(Type.String({
|
|
19
|
+
description: "Named watchlist to create or use. Omit to use the default watchlist.",
|
|
20
|
+
})),
|
|
11
21
|
symbol: Type.Optional(Type.String({ description: "Ticker symbol (required for add/remove)" })),
|
|
12
|
-
|
|
13
|
-
Type.Number({ description: "Alert when price rises above this level" }),
|
|
14
|
-
Type.Null({ description: "Clear the existing target price during update" }),
|
|
15
|
-
])),
|
|
16
|
-
stop_price: Type.Optional(Type.Union([
|
|
17
|
-
Type.Number({ description: "Alert when price falls below this level" }),
|
|
18
|
-
Type.Null({ description: "Clear the existing stop price during update" }),
|
|
19
|
-
])),
|
|
20
|
-
notes: Type.Optional(Type.Union([
|
|
21
|
-
Type.String({ description: "Optional notes for why you're watching this" }),
|
|
22
|
-
Type.Null({ description: "Clear existing notes during update" }),
|
|
23
|
-
])),
|
|
24
|
-
thesis: Type.Optional(Type.Union([
|
|
25
|
-
Type.String({ description: "Optional thesis for why you're watching this" }),
|
|
26
|
-
Type.Null({ description: "Clear the existing thesis during update" }),
|
|
27
|
-
])),
|
|
28
|
-
tags: Type.Optional(Type.Array(Type.String(), { description: "Optional tags for organizing the watchlist item" })),
|
|
22
|
+
new_watchlist_name: Type.Optional(Type.String({ description: "New watchlist name (required for rename)." })),
|
|
29
23
|
});
|
|
30
24
|
export const watchlistTool = {
|
|
31
25
|
name: "manage_watchlist",
|
|
32
26
|
label: "Watchlist",
|
|
33
|
-
description: "Manage
|
|
27
|
+
description: "Manage named watchlists of stocks and crypto. Create, rename, or delete watchlists, add symbols, remove symbols, or check current prices.",
|
|
34
28
|
parameters: params,
|
|
35
29
|
async execute(_toolCallId, args) {
|
|
36
30
|
const db = initDefaultDatabase();
|
|
37
31
|
const service = new MarketStateService(db);
|
|
38
32
|
try {
|
|
33
|
+
if (args.action === "create") {
|
|
34
|
+
if (!args.watchlist_name) {
|
|
35
|
+
throw new Error("watchlist_name is required for create action.");
|
|
36
|
+
}
|
|
37
|
+
const watchlist = service.createWatchlist(args.watchlist_name);
|
|
38
|
+
return {
|
|
39
|
+
content: [{ type: "text", text: `Created watchlist ${watchlist.name}` }],
|
|
40
|
+
details: watchlist,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (args.action === "rename") {
|
|
44
|
+
if (!args.new_watchlist_name) {
|
|
45
|
+
throw new Error("new_watchlist_name is required for rename action.");
|
|
46
|
+
}
|
|
47
|
+
const currentName = args.watchlist_name?.trim() || service.getDefaultWatchlist().name;
|
|
48
|
+
const current = args.watchlist_name
|
|
49
|
+
? service.getWatchlistByName(currentName)
|
|
50
|
+
: service.getDefaultWatchlist();
|
|
51
|
+
if (current == null) {
|
|
52
|
+
throw new Error(`watchlist ${currentName} not found.`);
|
|
53
|
+
}
|
|
54
|
+
const watchlist = service.renameWatchlist(current.name, args.new_watchlist_name);
|
|
55
|
+
return {
|
|
56
|
+
content: [{ type: "text", text: `Renamed ${current.name} to ${watchlist.name}` }],
|
|
57
|
+
details: watchlist,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (args.action === "delete") {
|
|
61
|
+
service.listWatchlists();
|
|
62
|
+
const currentName = args.watchlist_name?.trim() || service.getDefaultWatchlist().name;
|
|
63
|
+
const current = args.watchlist_name
|
|
64
|
+
? service.getWatchlistByName(currentName)
|
|
65
|
+
: service.getDefaultWatchlist();
|
|
66
|
+
if (current == null) {
|
|
67
|
+
throw new Error(`watchlist ${currentName} not found.`);
|
|
68
|
+
}
|
|
69
|
+
const watchlist = service.deleteWatchlist(current.name);
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: "text",
|
|
74
|
+
text: `Deleted ${current.name}. ${watchlist.name} is now active.`,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
details: watchlist,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const watchlist = service.getOrCreateWatchlist(args.watchlist_name);
|
|
39
81
|
if (args.action === "add") {
|
|
40
82
|
if (!args.symbol) {
|
|
41
83
|
throw new Error("symbol is required for add action.");
|
|
@@ -46,7 +88,7 @@ export const watchlistTool = {
|
|
|
46
88
|
content: [
|
|
47
89
|
{
|
|
48
90
|
type: "text",
|
|
49
|
-
text: `Could not verify ${instrument.query}. Choose one of the returned candidates before adding it to
|
|
91
|
+
text: `Could not verify ${instrument.query}. Choose one of the returned candidates before adding it to ${watchlist.name}.`,
|
|
50
92
|
},
|
|
51
93
|
],
|
|
52
94
|
details: instrument,
|
|
@@ -54,20 +96,10 @@ export const watchlistTool = {
|
|
|
54
96
|
}
|
|
55
97
|
const item = service.addWatchlistItem({
|
|
56
98
|
instrument: instrument.instrument,
|
|
57
|
-
|
|
58
|
-
stopPrice: args.stop_price,
|
|
59
|
-
thesis: args.thesis,
|
|
60
|
-
notes: args.notes,
|
|
61
|
-
tags: args.tags,
|
|
99
|
+
watchlistId: watchlist.id,
|
|
62
100
|
});
|
|
63
|
-
const alerts = [];
|
|
64
|
-
if (args.target_price)
|
|
65
|
-
alerts.push(`target: $${args.target_price}`);
|
|
66
|
-
if (args.stop_price)
|
|
67
|
-
alerts.push(`stop: $${args.stop_price}`);
|
|
68
|
-
const alertStr = alerts.length > 0 ? ` (${alerts.join(", ")})` : "";
|
|
69
101
|
return {
|
|
70
|
-
content: [{ type: "text", text: `Added ${item.symbol} to
|
|
102
|
+
content: [{ type: "text", text: `Added ${item.symbol} to ${watchlist.name}` }],
|
|
71
103
|
details: item,
|
|
72
104
|
};
|
|
73
105
|
}
|
|
@@ -76,74 +108,33 @@ export const watchlistTool = {
|
|
|
76
108
|
throw new Error("symbol is required for remove action.");
|
|
77
109
|
}
|
|
78
110
|
const symbol = args.symbol.toUpperCase();
|
|
79
|
-
if (!service.removeWatchlistItemBySymbol(symbol)) {
|
|
111
|
+
if (!service.removeWatchlistItemBySymbol(symbol, watchlist.id)) {
|
|
80
112
|
return {
|
|
81
|
-
content: [{ type: "text", text: `${symbol} not found in watchlist` }],
|
|
113
|
+
content: [{ type: "text", text: `${symbol} not found in ${watchlist.name}` }],
|
|
82
114
|
details: null,
|
|
83
115
|
};
|
|
84
116
|
}
|
|
85
117
|
return {
|
|
86
|
-
content: [{ type: "text", text: `Removed ${symbol} from watchlist` }],
|
|
118
|
+
content: [{ type: "text", text: `Removed ${symbol} from ${watchlist.name}` }],
|
|
87
119
|
details: null,
|
|
88
120
|
};
|
|
89
121
|
}
|
|
90
|
-
|
|
91
|
-
if (!args.symbol) {
|
|
92
|
-
throw new Error("symbol is required for update action.");
|
|
93
|
-
}
|
|
94
|
-
const symbol = args.symbol.toUpperCase();
|
|
95
|
-
const item = service.updateWatchlistItemBySymbol(symbol, {
|
|
96
|
-
targetPrice: args.target_price,
|
|
97
|
-
stopPrice: args.stop_price,
|
|
98
|
-
notes: args.notes,
|
|
99
|
-
thesis: args.thesis,
|
|
100
|
-
tags: args.tags,
|
|
101
|
-
});
|
|
102
|
-
if (item == null) {
|
|
103
|
-
return {
|
|
104
|
-
content: [{ type: "text", text: `${symbol} not found in watchlist` }],
|
|
105
|
-
details: null,
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
return {
|
|
109
|
-
content: [{ type: "text", text: `Updated ${item.symbol} in watchlist` }],
|
|
110
|
-
details: item,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
const items = service.listWatchlistItems();
|
|
122
|
+
const items = service.listWatchlistItems(watchlist.id);
|
|
114
123
|
if (items.length === 0) {
|
|
115
124
|
return {
|
|
116
|
-
content: [
|
|
117
|
-
|
|
125
|
+
content: [
|
|
126
|
+
{
|
|
127
|
+
type: "text",
|
|
128
|
+
text: `${watchlist.name} is empty. Use add action to add symbols.`,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
details: { watchlist, items: [] },
|
|
118
132
|
};
|
|
119
133
|
}
|
|
120
134
|
const checks = await checkWatchlistPrices(items);
|
|
121
|
-
const alertItems = checks.filter((c) => c.alerts.length > 0);
|
|
122
|
-
const lines = [
|
|
123
|
-
`**Watchlist** — ${items.length} symbols${alertItems.length > 0 ? ` | ${alertItems.length} ALERT(S)` : ""}`,
|
|
124
|
-
"",
|
|
125
|
-
];
|
|
126
|
-
const tradingViewCaveats = Array.from(new Set(checks
|
|
127
|
-
.filter((c) => c.sourceProvider === "tradingview")
|
|
128
|
-
.map((c) => c.dataCaveat ??
|
|
129
|
-
"TradingView scanner data may be delayed about 15 minutes and comes from an unofficial endpoint.")));
|
|
130
|
-
if (tradingViewCaveats.length > 0) {
|
|
131
|
-
lines.push(...tradingViewCaveats.map((caveat) => `Data caveat: ${caveat}`), "");
|
|
132
|
-
}
|
|
133
|
-
for (const c of checks) {
|
|
134
|
-
const alertStr = c.alerts.length > 0 ? ` ** ${c.alerts.join(" | ")} **` : "";
|
|
135
|
-
const statusStr = c.statuses.length > 0 ? ` | ${c.statuses.join(" | ")}` : "";
|
|
136
|
-
const targetStr = c.targetPrice ? ` | Target: $${c.targetPrice}` : "";
|
|
137
|
-
const stopStr = c.stopPrice ? ` | Stop: $${c.stopPrice}` : "";
|
|
138
|
-
const sourceStr = c.sourceProvider
|
|
139
|
-
? ` | Source: ${c.sourceProvider === "tradingview" ? "TradingView" : "Yahoo"}`
|
|
140
|
-
: "";
|
|
141
|
-
const priceStr = typeof c.currentPrice === "number" ? `$${c.currentPrice.toFixed(2)}` : "Unavailable";
|
|
142
|
-
lines.push(` ${c.symbol}: ${priceStr}${targetStr}${stopStr}${sourceStr}${statusStr}${alertStr}`);
|
|
143
|
-
}
|
|
144
135
|
return {
|
|
145
|
-
content: [{ type: "text", text:
|
|
146
|
-
details: { items: checks },
|
|
136
|
+
content: [{ type: "text", text: formatWatchlistCheck(watchlist, checks) }],
|
|
137
|
+
details: { watchlist, items: checks },
|
|
147
138
|
};
|
|
148
139
|
}
|
|
149
140
|
finally {
|
|
@@ -151,6 +142,25 @@ export const watchlistTool = {
|
|
|
151
142
|
}
|
|
152
143
|
},
|
|
153
144
|
};
|
|
145
|
+
function formatWatchlistCheck(watchlist, checks) {
|
|
146
|
+
const lines = [`**${watchlist.name}** — ${checks.length} symbols`, ""];
|
|
147
|
+
const tradingViewCaveats = Array.from(new Set(checks
|
|
148
|
+
.filter((c) => c.sourceProvider === "tradingview")
|
|
149
|
+
.map((c) => c.dataCaveat ??
|
|
150
|
+
"TradingView scanner data may be delayed about 15 minutes and comes from an unofficial endpoint.")));
|
|
151
|
+
if (tradingViewCaveats.length > 0) {
|
|
152
|
+
lines.push(...tradingViewCaveats.map((caveat) => `Data caveat: ${caveat}`), "");
|
|
153
|
+
}
|
|
154
|
+
for (const c of checks) {
|
|
155
|
+
const statusStr = c.statuses.length > 0 ? ` | ${c.statuses.join(" | ")}` : "";
|
|
156
|
+
const sourceStr = c.sourceProvider
|
|
157
|
+
? ` | Source: ${c.sourceProvider === "tradingview" ? "TradingView" : "Yahoo"}`
|
|
158
|
+
: "";
|
|
159
|
+
const priceStr = typeof c.currentPrice === "number" ? `$${c.currentPrice.toFixed(2)}` : "Unavailable";
|
|
160
|
+
lines.push(` ${c.symbol}: ${priceStr}${sourceStr}${statusStr}`);
|
|
161
|
+
}
|
|
162
|
+
return lines.join("\n");
|
|
163
|
+
}
|
|
154
164
|
async function checkWatchlistPrices(items) {
|
|
155
165
|
const tradingViewSymbols = items
|
|
156
166
|
.map((item) => item.symbol)
|
|
@@ -179,16 +189,14 @@ async function checkWatchlistPrices(items) {
|
|
|
179
189
|
return {
|
|
180
190
|
...item,
|
|
181
191
|
currentPrice: null,
|
|
182
|
-
|
|
183
|
-
statuses: [],
|
|
192
|
+
statuses: [`UNAVAILABLE: ${result.reason}`],
|
|
184
193
|
};
|
|
185
194
|
}
|
|
186
195
|
if (result.stale) {
|
|
187
196
|
return {
|
|
188
197
|
...item,
|
|
189
198
|
currentPrice: null,
|
|
190
|
-
|
|
191
|
-
statuses: [],
|
|
199
|
+
statuses: ["UNAVAILABLE: provider returned stale market data"],
|
|
192
200
|
};
|
|
193
201
|
}
|
|
194
202
|
const quote = result.data;
|
|
@@ -196,33 +204,17 @@ async function checkWatchlistPrices(items) {
|
|
|
196
204
|
return {
|
|
197
205
|
...item,
|
|
198
206
|
currentPrice: null,
|
|
199
|
-
|
|
200
|
-
statuses: [],
|
|
207
|
+
statuses: ["UNAVAILABLE: Yahoo returned no valid market data."],
|
|
201
208
|
};
|
|
202
209
|
}
|
|
203
210
|
return buildCheckResult(item, quote.price, "yahoo");
|
|
204
211
|
}));
|
|
205
212
|
}
|
|
206
213
|
function buildCheckResult(item, price, sourceProvider, dataCaveat) {
|
|
207
|
-
const alerts = [];
|
|
208
|
-
const statuses = [];
|
|
209
|
-
if (item.targetPrice && price >= item.targetPrice) {
|
|
210
|
-
alerts.push(`TARGET HIT: $${price.toFixed(2)} >= $${item.targetPrice}`);
|
|
211
|
-
}
|
|
212
|
-
else if (item.targetPrice) {
|
|
213
|
-
statuses.push(`Target pending: $${price.toFixed(2)} < $${item.targetPrice}`);
|
|
214
|
-
}
|
|
215
|
-
if (item.stopPrice && price <= item.stopPrice) {
|
|
216
|
-
alerts.push(`STOP ALERT: $${price.toFixed(2)} fell below $${item.stopPrice}`);
|
|
217
|
-
}
|
|
218
|
-
else if (item.stopPrice) {
|
|
219
|
-
statuses.push(`Stop OK: $${price.toFixed(2)} > $${item.stopPrice}`);
|
|
220
|
-
}
|
|
221
214
|
return {
|
|
222
215
|
...item,
|
|
223
216
|
currentPrice: price,
|
|
224
|
-
|
|
225
|
-
statuses,
|
|
217
|
+
statuses: [],
|
|
226
218
|
sourceProvider,
|
|
227
219
|
dataCaveat,
|
|
228
220
|
};
|
|
@@ -230,4 +222,3 @@ function buildCheckResult(item, price, sourceProvider, dataCaveat) {
|
|
|
230
222
|
function shouldSkipTradingView(symbol) {
|
|
231
223
|
return /(?:-USD|\.(?:TO|DE|T|L|HK))$/i.test(symbol.trim());
|
|
232
224
|
}
|
|
233
|
-
//# sourceMappingURL=watchlist.js.map
|
|
@@ -43,8 +43,11 @@ export function createSentimentSummaryTool(options = {}) {
|
|
|
43
43
|
const fetchFinnhub = async () => {
|
|
44
44
|
if (!includeFinnhub)
|
|
45
45
|
return [];
|
|
46
|
+
const finnhubApiKey = config.finnhubApiKey;
|
|
47
|
+
if (!finnhubApiKey)
|
|
48
|
+
return [];
|
|
46
49
|
const { from, to } = finnhubDateRange("day");
|
|
47
|
-
const arrays = await Promise.all(finnhubTickers.map((sym) => getCompanyNews(sym, from, to,
|
|
50
|
+
const arrays = await Promise.all(finnhubTickers.map((sym) => getCompanyNews(sym, from, to, finnhubApiKey)));
|
|
48
51
|
return arrays.flat();
|
|
49
52
|
};
|
|
50
53
|
// External-tool sources may need ask_user setup. Run them through the
|
|
@@ -104,7 +107,9 @@ export function createSentimentSummaryTool(options = {}) {
|
|
|
104
107
|
else {
|
|
105
108
|
const reason = webResult.status === "rejected"
|
|
106
109
|
? (webResult.reason?.message ?? "unknown error")
|
|
107
|
-
:
|
|
110
|
+
: webResult.value.status === "unavailable"
|
|
111
|
+
? webResult.value.reason
|
|
112
|
+
: "unavailable";
|
|
108
113
|
warnings.push(`Web: ${reason}`);
|
|
109
114
|
}
|
|
110
115
|
// Process Finnhub (only when included — otherwise resolves to empty array anyway)
|
|
@@ -194,7 +199,7 @@ export function createSentimentSummaryTool(options = {}) {
|
|
|
194
199
|
lines.push("");
|
|
195
200
|
lines.push("Source-coverage risk: sentiment can be noisy and missing sources can skew the signal; treat this as supporting evidence, not a standalone buy/sell input.");
|
|
196
201
|
// Divergence
|
|
197
|
-
if (result.divergence
|
|
202
|
+
if (result.divergence?.detected) {
|
|
198
203
|
lines.push("");
|
|
199
204
|
lines.push(result.divergence.message);
|
|
200
205
|
}
|
|
@@ -300,4 +305,3 @@ function stripOpenCandleControlLines(text) {
|
|
|
300
305
|
.join("\n");
|
|
301
306
|
return stripped || "unavailable";
|
|
302
307
|
}
|
|
303
|
-
//# sourceMappingURL=sentiment-summary.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentTool } from "@earendil-works/pi-agent-core";
|
|
2
2
|
import type { SentimentStore } from "../../sentiment/store.js";
|
|
3
|
+
import type { TrendBucket, TrendResult } from "../../sentiment/types.js";
|
|
3
4
|
declare const params: import("@sinclair/typebox").TObject<{
|
|
4
5
|
query: import("@sinclair/typebox").TString;
|
|
5
6
|
days: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
@@ -10,7 +11,10 @@ interface TrendToolResult {
|
|
|
10
11
|
type: "text";
|
|
11
12
|
text: string;
|
|
12
13
|
}>;
|
|
13
|
-
details:
|
|
14
|
+
details: {
|
|
15
|
+
trend: TrendResult;
|
|
16
|
+
series: TrendBucket[];
|
|
17
|
+
} | null;
|
|
14
18
|
}
|
|
15
19
|
export declare const sentimentTrendTool: AgentTool<typeof params> & {
|
|
16
20
|
executeWithStore: (toolCallId: string, args: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
2
|
import { getSentimentStore } from "../../sentiment/index.js";
|
|
3
3
|
import { computeTrend } from "../../sentiment/trends.js";
|
|
4
|
+
import { SENTIMENT_SOURCES } from "../../sentiment/types.js";
|
|
4
5
|
const params = Type.Object({
|
|
5
6
|
query: Type.String({ description: "Ticker or topic to look up sentiment history" }),
|
|
6
7
|
days: Type.Optional(Type.Number({ description: "Number of days of history. Default: 7, max: 30" })),
|
|
@@ -36,7 +37,8 @@ export const sentimentTrendTool = {
|
|
|
36
37
|
details: null,
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
|
-
const
|
|
40
|
+
const source = isSentimentTrendSource(args.source) ? args.source : "aggregate";
|
|
41
|
+
const trend = computeTrend(series, source);
|
|
40
42
|
const lines = [
|
|
41
43
|
`**Sentiment trend for "${args.query}"** (${days}d):`,
|
|
42
44
|
"",
|
|
@@ -46,4 +48,6 @@ export const sentimentTrendTool = {
|
|
|
46
48
|
return { content: [{ type: "text", text: lines.join("\n") }], details: { trend, series } };
|
|
47
49
|
},
|
|
48
50
|
};
|
|
49
|
-
|
|
51
|
+
function isSentimentTrendSource(source) {
|
|
52
|
+
return source !== undefined && SENTIMENT_SOURCES.includes(source);
|
|
53
|
+
}
|