opencandle 0.2.0 → 0.4.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 +110 -87
- package/assets/logo.svg +187 -0
- package/dist/analysts/orchestrator.js +1 -2
- package/dist/analysts/orchestrator.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +38 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +34 -5
- package/dist/config.js +29 -8
- package/dist/config.js.map +1 -1
- package/dist/infra/browser.d.ts +10 -0
- package/dist/infra/browser.js +1 -0
- package/dist/infra/browser.js.map +1 -1
- package/dist/infra/cache.d.ts +4 -0
- package/dist/infra/cache.js +4 -0
- package/dist/infra/cache.js.map +1 -1
- package/dist/infra/native-dependencies.d.ts +1 -0
- package/dist/infra/native-dependencies.js +10 -0
- package/dist/infra/native-dependencies.js.map +1 -0
- package/dist/infra/node-version.d.ts +2 -0
- package/dist/infra/node-version.js +23 -0
- package/dist/infra/node-version.js.map +1 -0
- package/dist/infra/rate-limiter.js +6 -0
- package/dist/infra/rate-limiter.js.map +1 -1
- package/dist/memory/index.d.ts +2 -0
- package/dist/memory/index.js +1 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/sqlite.js +42 -4
- package/dist/memory/sqlite.js.map +1 -1
- package/dist/memory/storage.d.ts +6 -0
- package/dist/memory/storage.js +3 -3
- package/dist/memory/storage.js.map +1 -1
- package/dist/memory/tool-defaults.d.ts +8 -0
- package/dist/memory/tool-defaults.js +59 -0
- package/dist/memory/tool-defaults.js.map +1 -0
- package/dist/onboarding/connect.d.ts +35 -0
- package/dist/onboarding/connect.js +118 -0
- package/dist/onboarding/connect.js.map +1 -0
- package/dist/onboarding/credential-interceptor.d.ts +44 -0
- package/dist/onboarding/credential-interceptor.js +72 -0
- package/dist/onboarding/credential-interceptor.js.map +1 -0
- package/dist/onboarding/degradation-accumulator.d.ts +21 -0
- package/dist/onboarding/degradation-accumulator.js +55 -0
- package/dist/onboarding/degradation-accumulator.js.map +1 -0
- package/dist/onboarding/prompt-user.d.ts +23 -0
- package/dist/onboarding/prompt-user.js +61 -0
- package/dist/onboarding/prompt-user.js.map +1 -0
- package/dist/onboarding/providers.d.ts +116 -0
- package/dist/onboarding/providers.js +239 -0
- package/dist/onboarding/providers.js.map +1 -0
- package/dist/onboarding/state.d.ts +31 -2
- package/dist/onboarding/state.js +141 -13
- package/dist/onboarding/state.js.map +1 -1
- package/dist/onboarding/tool-helpers.d.ts +34 -0
- package/dist/onboarding/tool-helpers.js +80 -0
- package/dist/onboarding/tool-helpers.js.map +1 -0
- package/dist/onboarding/tool-tags.d.ts +37 -0
- package/dist/onboarding/tool-tags.js +149 -0
- package/dist/onboarding/tool-tags.js.map +1 -0
- package/dist/onboarding/validation.d.ts +19 -0
- package/dist/onboarding/validation.js +117 -0
- package/dist/onboarding/validation.js.map +1 -0
- package/dist/pi/opencandle-extension.d.ts +7 -1
- package/dist/pi/opencandle-extension.js +488 -13
- package/dist/pi/opencandle-extension.js.map +1 -1
- package/dist/pi/session-storage.d.ts +2 -0
- package/dist/pi/session-storage.js +5 -0
- package/dist/pi/session-storage.js.map +1 -0
- package/dist/pi/session.d.ts +4 -1
- package/dist/pi/session.js +25 -3
- package/dist/pi/session.js.map +1 -1
- package/dist/pi/setup.d.ts +1 -2
- package/dist/pi/setup.js +67 -120
- package/dist/pi/setup.js.map +1 -1
- package/dist/pi/tool-adapter.d.ts +2 -2
- package/dist/pi/tool-adapter.js +14 -1
- package/dist/pi/tool-adapter.js.map +1 -1
- package/dist/prompts/context-builder.d.ts +22 -0
- package/dist/prompts/context-builder.js +47 -11
- package/dist/prompts/context-builder.js.map +1 -1
- package/dist/prompts/disclaimer.d.ts +6 -0
- package/dist/prompts/disclaimer.js +9 -0
- package/dist/prompts/disclaimer.js.map +1 -0
- package/dist/prompts/workflow-prompts.d.ts +8 -0
- package/dist/prompts/workflow-prompts.js +39 -5
- package/dist/prompts/workflow-prompts.js.map +1 -1
- package/dist/providers/alpha-vantage.js +20 -1
- package/dist/providers/alpha-vantage.js.map +1 -1
- package/dist/providers/exa-search.d.ts +39 -0
- package/dist/providers/exa-search.js +276 -0
- package/dist/providers/exa-search.js.map +1 -0
- package/dist/providers/finnhub.d.ts +17 -0
- package/dist/providers/finnhub.js +94 -0
- package/dist/providers/finnhub.js.map +1 -0
- package/dist/providers/fred.js +13 -1
- package/dist/providers/fred.js.map +1 -1
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.js +1 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/provider-credential-error.d.ts +8 -0
- package/dist/providers/provider-credential-error.js +22 -0
- package/dist/providers/provider-credential-error.js.map +1 -0
- package/dist/providers/reddit.d.ts +8 -0
- package/dist/providers/reddit.js +36 -9
- package/dist/providers/reddit.js.map +1 -1
- package/dist/providers/twitter.js +2 -8
- package/dist/providers/twitter.js.map +1 -1
- package/dist/providers/web-search.d.ts +17 -0
- package/dist/providers/web-search.js +224 -0
- package/dist/providers/web-search.js.map +1 -0
- package/dist/providers/wrap-provider.d.ts +7 -0
- package/dist/providers/wrap-provider.js +15 -0
- package/dist/providers/wrap-provider.js.map +1 -1
- package/dist/providers/yahoo-finance.js +70 -33
- package/dist/providers/yahoo-finance.js.map +1 -1
- package/dist/routing/classify-intent.js +22 -0
- package/dist/routing/classify-intent.js.map +1 -1
- package/dist/routing/defaults.js +1 -1
- package/dist/routing/defaults.js.map +1 -1
- package/dist/routing/index.d.ts +4 -0
- package/dist/routing/index.js +3 -0
- package/dist/routing/index.js.map +1 -1
- package/dist/routing/router-llm-client.d.ts +11 -0
- package/dist/routing/router-llm-client.js +42 -0
- package/dist/routing/router-llm-client.js.map +1 -0
- package/dist/routing/router-prompt.d.ts +2 -0
- package/dist/routing/router-prompt.js +138 -0
- package/dist/routing/router-prompt.js.map +1 -0
- package/dist/routing/router-types.d.ts +62 -0
- package/dist/routing/router-types.js +2 -0
- package/dist/routing/router-types.js.map +1 -0
- package/dist/routing/router.d.ts +10 -0
- package/dist/routing/router.js +194 -0
- package/dist/routing/router.js.map +1 -0
- package/dist/runtime/session-coordinator.d.ts +63 -4
- package/dist/runtime/session-coordinator.js +155 -4
- package/dist/runtime/session-coordinator.js.map +1 -1
- package/dist/runtime/tool-defaults-wrapper.d.ts +3 -0
- package/dist/runtime/tool-defaults-wrapper.js +25 -0
- package/dist/runtime/tool-defaults-wrapper.js.map +1 -0
- package/dist/sentiment/adapters/finnhub.d.ts +7 -0
- package/dist/sentiment/adapters/finnhub.js +39 -0
- package/dist/sentiment/adapters/finnhub.js.map +1 -0
- package/dist/sentiment/adapters/reddit.d.ts +11 -0
- package/dist/sentiment/adapters/reddit.js +54 -0
- package/dist/sentiment/adapters/reddit.js.map +1 -0
- package/dist/sentiment/adapters/twitter.d.ts +9 -0
- package/dist/sentiment/adapters/twitter.js +32 -0
- package/dist/sentiment/adapters/twitter.js.map +1 -0
- package/dist/sentiment/adapters/web.d.ts +9 -0
- package/dist/sentiment/adapters/web.js +40 -0
- package/dist/sentiment/adapters/web.js.map +1 -0
- package/dist/sentiment/index.d.ts +16 -0
- package/dist/sentiment/index.js +44 -0
- package/dist/sentiment/index.js.map +1 -0
- package/dist/sentiment/keywords.d.ts +2 -0
- package/dist/sentiment/keywords.js +9 -0
- package/dist/sentiment/keywords.js.map +1 -0
- package/dist/sentiment/pipeline.d.ts +9 -0
- package/dist/sentiment/pipeline.js +57 -0
- package/dist/sentiment/pipeline.js.map +1 -0
- package/dist/sentiment/scorer.d.ts +9 -0
- package/dist/sentiment/scorer.js +64 -0
- package/dist/sentiment/scorer.js.map +1 -0
- package/dist/sentiment/store.d.ts +24 -0
- package/dist/sentiment/store.js +182 -0
- package/dist/sentiment/store.js.map +1 -0
- package/dist/sentiment/trends.d.ts +13 -0
- package/dist/sentiment/trends.js +73 -0
- package/dist/sentiment/trends.js.map +1 -0
- package/dist/sentiment/types.d.ts +66 -0
- package/dist/sentiment/types.js +54 -0
- package/dist/sentiment/types.js.map +1 -0
- package/dist/system-prompt.js +29 -13
- package/dist/system-prompt.js.map +1 -1
- package/dist/tool-kit.d.ts +4 -4
- package/dist/tools/fundamentals/company-overview.d.ts +4 -2
- package/dist/tools/fundamentals/company-overview.js +27 -27
- package/dist/tools/fundamentals/company-overview.js.map +1 -1
- package/dist/tools/fundamentals/comps.d.ts +1 -1
- package/dist/tools/fundamentals/comps.js +45 -45
- package/dist/tools/fundamentals/comps.js.map +1 -1
- package/dist/tools/fundamentals/dcf.d.ts +1 -1
- package/dist/tools/fundamentals/dcf.js +82 -82
- package/dist/tools/fundamentals/dcf.js.map +1 -1
- package/dist/tools/fundamentals/earnings.d.ts +4 -2
- package/dist/tools/fundamentals/earnings.js +25 -25
- package/dist/tools/fundamentals/earnings.js.map +1 -1
- package/dist/tools/fundamentals/financials.d.ts +4 -2
- package/dist/tools/fundamentals/financials.js +23 -23
- package/dist/tools/fundamentals/financials.js.map +1 -1
- package/dist/tools/fundamentals/sec-filings.d.ts +1 -1
- package/dist/tools/index.d.ts +28 -1
- package/dist/tools/index.js +35 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/interaction/ask-user.d.ts +1 -1
- package/dist/tools/interaction/ask-user.js +28 -64
- package/dist/tools/interaction/ask-user.js.map +1 -1
- package/dist/tools/interaction/twitter-login.d.ts +1 -1
- package/dist/tools/macro/fear-greed.d.ts +1 -1
- package/dist/tools/macro/fred-data.d.ts +4 -2
- package/dist/tools/macro/fred-data.js +26 -26
- package/dist/tools/macro/fred-data.js.map +1 -1
- package/dist/tools/market/crypto-history.d.ts +1 -1
- package/dist/tools/market/crypto-price.d.ts +1 -1
- package/dist/tools/market/search-ticker.d.ts +1 -1
- package/dist/tools/market/stock-history.d.ts +1 -1
- package/dist/tools/market/stock-quote.d.ts +1 -1
- package/dist/tools/options/option-chain.d.ts +1 -1
- package/dist/tools/options/option-chain.js +4 -1
- package/dist/tools/options/option-chain.js.map +1 -1
- package/dist/tools/portfolio/correlation.d.ts +1 -1
- package/dist/tools/portfolio/predictions.d.ts +1 -1
- package/dist/tools/portfolio/risk-analysis.d.ts +1 -1
- package/dist/tools/portfolio/tracker.d.ts +1 -1
- package/dist/tools/portfolio/watchlist.d.ts +1 -1
- package/dist/tools/sentiment/reddit-sentiment.d.ts +4 -2
- package/dist/tools/sentiment/reddit-sentiment.js +107 -22
- package/dist/tools/sentiment/reddit-sentiment.js.map +1 -1
- package/dist/tools/sentiment/sentiment-summary.d.ts +7 -0
- package/dist/tools/sentiment/sentiment-summary.js +230 -0
- package/dist/tools/sentiment/sentiment-summary.js.map +1 -0
- package/dist/tools/sentiment/sentiment-trend.d.ts +22 -0
- package/dist/tools/sentiment/sentiment-trend.js +39 -0
- package/dist/tools/sentiment/sentiment-trend.js.map +1 -0
- package/dist/tools/sentiment/twitter-sentiment.d.ts +1 -1
- package/dist/tools/sentiment/twitter-sentiment.js +17 -0
- package/dist/tools/sentiment/twitter-sentiment.js.map +1 -1
- package/dist/tools/sentiment/web-search.d.ts +11 -0
- package/dist/tools/sentiment/web-search.js +115 -0
- package/dist/tools/sentiment/web-search.js.map +1 -0
- package/dist/tools/sentiment/web-sentiment.d.ts +8 -0
- package/dist/tools/sentiment/web-sentiment.js +66 -0
- package/dist/tools/sentiment/web-sentiment.js.map +1 -0
- package/dist/tools/technical/backtest.d.ts +1 -1
- package/dist/tools/technical/indicators.d.ts +1 -1
- package/dist/tools/technical/indicators.js +7 -1
- package/dist/tools/technical/indicators.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/sentiment.d.ts +21 -0
- package/dist/workflows/options-screener.js +7 -2
- package/dist/workflows/options-screener.js.map +1 -1
- package/dist/workflows/portfolio-builder.js +3 -3
- package/dist/workflows/portfolio-builder.js.map +1 -1
- package/gui/server/background-quotes.ts +31 -0
- package/gui/server/chat-event-adapter.ts +142 -0
- package/gui/server/invoke-tool.ts +89 -0
- package/gui/server/live-chat-event-adapter.ts +181 -0
- package/gui/server/model-setup.ts +100 -0
- package/gui/server/package.json +5 -0
- package/gui/server/projector.ts +212 -0
- package/gui/server/server.ts +592 -0
- package/gui/server/session-actions.ts +31 -0
- package/gui/server/tool-metadata.ts +88 -0
- package/gui/server/websocket.ts +128 -0
- package/gui/server/writer-lock.ts +118 -0
- package/gui/shared/chat-events.ts +118 -0
- package/gui/shared/event-reducer.ts +186 -0
- package/gui/web/dist/assets/CatalogOverlay-D1ImSJTe.js +1 -0
- package/gui/web/dist/assets/index-DBrWq43L.css +1 -0
- package/gui/web/dist/assets/index-RflHaj0y.js +67 -0
- package/gui/web/dist/assets/logo-CWpt6Y2a.svg +187 -0
- package/gui/web/dist/index.html +17 -0
- package/package.json +62 -20
- package/src/analysts/contracts.ts +189 -0
- package/src/analysts/orchestrator.ts +300 -0
- package/src/cli.ts +205 -0
- package/src/config.ts +161 -0
- package/src/index.ts +5 -0
- package/src/infra/browser.ts +111 -0
- package/src/infra/cache.ts +103 -0
- package/src/infra/http-client.ts +68 -0
- package/src/infra/index.ts +18 -0
- package/src/infra/native-dependencies.ts +12 -0
- package/src/infra/node-version.ts +24 -0
- package/src/infra/open-url.ts +28 -0
- package/src/infra/opencandle-paths.ts +64 -0
- package/src/infra/rate-limiter.ts +64 -0
- package/src/memory/index.ts +10 -0
- package/src/memory/manager.ts +159 -0
- package/src/memory/preference-extractor.ts +106 -0
- package/src/memory/retrieval.ts +70 -0
- package/src/memory/sqlite.ts +172 -0
- package/src/memory/storage.ts +204 -0
- package/src/memory/tool-defaults.ts +87 -0
- package/src/memory/types.ts +67 -0
- package/src/onboarding/connect.ts +184 -0
- package/src/onboarding/credential-interceptor.ts +134 -0
- package/src/onboarding/degradation-accumulator.ts +79 -0
- package/src/onboarding/prompt-user.ts +85 -0
- package/src/onboarding/providers.ts +315 -0
- package/src/onboarding/state.ts +218 -0
- package/src/onboarding/tool-helpers.ts +111 -0
- package/src/onboarding/tool-tags.ts +201 -0
- package/src/onboarding/validation.ts +158 -0
- package/src/pi/opencandle-extension.ts +724 -0
- package/src/pi/session-storage.ts +5 -0
- package/src/pi/session.ts +81 -0
- package/src/pi/setup.ts +371 -0
- package/src/pi/tool-adapter.ts +36 -0
- package/src/prompts/context-builder.ts +204 -0
- package/src/prompts/disclaimer.ts +9 -0
- package/src/prompts/sections.ts +46 -0
- package/src/prompts/workflow-prompts.ts +279 -0
- package/src/providers/alpha-vantage.ts +292 -0
- package/src/providers/coingecko.ts +96 -0
- package/src/providers/exa-search.ts +373 -0
- package/src/providers/fear-greed.ts +45 -0
- package/src/providers/finnhub.ts +124 -0
- package/src/providers/fred.ts +83 -0
- package/src/providers/index.ts +9 -0
- package/src/providers/provider-credential-error.ts +23 -0
- package/src/providers/reddit.ts +151 -0
- package/src/providers/sec-edgar.ts +96 -0
- package/src/providers/twitter.ts +173 -0
- package/src/providers/web-search.ts +293 -0
- package/src/providers/with-fallback.ts +41 -0
- package/src/providers/wrap-provider.ts +64 -0
- package/src/providers/yahoo-finance.ts +367 -0
- package/src/routing/classify-intent.ts +194 -0
- package/src/routing/defaults.ts +29 -0
- package/src/routing/entity-extractor.ts +140 -0
- package/src/routing/index.ts +26 -0
- package/src/routing/router-llm-client.ts +51 -0
- package/src/routing/router-prompt.ts +159 -0
- package/src/routing/router-types.ts +66 -0
- package/src/routing/router.ts +213 -0
- package/src/routing/slot-resolver.ts +152 -0
- package/src/routing/types.ts +63 -0
- package/src/runtime/evidence.ts +77 -0
- package/src/runtime/index.ts +55 -0
- package/src/runtime/prompt-step.ts +75 -0
- package/src/runtime/provider-ids.ts +15 -0
- package/src/runtime/provider-tracker.ts +40 -0
- package/src/runtime/run-context.ts +22 -0
- package/src/runtime/session-coordinator.ts +406 -0
- package/src/runtime/tool-defaults-wrapper.ts +35 -0
- package/src/runtime/validation.ts +214 -0
- package/src/runtime/workflow-events.ts +75 -0
- package/src/runtime/workflow-runner.ts +188 -0
- package/src/runtime/workflow-types.ts +102 -0
- package/src/sentiment/adapters/finnhub.ts +44 -0
- package/src/sentiment/adapters/reddit.ts +65 -0
- package/src/sentiment/adapters/twitter.ts +36 -0
- package/src/sentiment/adapters/web.ts +44 -0
- package/src/sentiment/index.ts +58 -0
- package/src/sentiment/keywords.ts +9 -0
- package/src/sentiment/pipeline.ts +68 -0
- package/src/sentiment/scorer.ts +78 -0
- package/src/sentiment/store.ts +260 -0
- package/src/sentiment/trends.ts +90 -0
- package/src/sentiment/types.ts +108 -0
- package/src/system-prompt.ts +115 -0
- package/src/tool-kit.ts +68 -0
- package/src/tools/AGENTS.md +36 -0
- package/src/tools/fundamentals/company-overview.ts +54 -0
- package/src/tools/fundamentals/comps.ts +156 -0
- package/src/tools/fundamentals/dcf.ts +267 -0
- package/src/tools/fundamentals/earnings.ts +47 -0
- package/src/tools/fundamentals/financials.ts +54 -0
- package/src/tools/fundamentals/sec-filings.ts +61 -0
- package/src/tools/index.ts +88 -0
- package/src/tools/interaction/ask-user.ts +81 -0
- package/src/tools/interaction/twitter-login.ts +93 -0
- package/src/tools/macro/fear-greed.ts +41 -0
- package/src/tools/macro/fred-data.ts +54 -0
- package/src/tools/market/crypto-history.ts +51 -0
- package/src/tools/market/crypto-price.ts +53 -0
- package/src/tools/market/search-ticker.ts +53 -0
- package/src/tools/market/stock-history.ts +79 -0
- package/src/tools/market/stock-quote.ts +64 -0
- package/src/tools/options/greeks.ts +82 -0
- package/src/tools/options/option-chain.ts +91 -0
- package/src/tools/portfolio/correlation.ts +162 -0
- package/src/tools/portfolio/predictions.ts +253 -0
- package/src/tools/portfolio/risk-analysis.ts +134 -0
- package/src/tools/portfolio/tracker.ts +147 -0
- package/src/tools/portfolio/watchlist.ts +153 -0
- package/src/tools/sentiment/reddit-sentiment.ts +164 -0
- package/src/tools/sentiment/sentiment-summary.ts +256 -0
- package/src/tools/sentiment/sentiment-trend.ts +58 -0
- package/src/tools/sentiment/twitter-sentiment.ts +96 -0
- package/src/tools/sentiment/web-search.ts +150 -0
- package/src/tools/sentiment/web-sentiment.ts +76 -0
- package/src/tools/technical/backtest.ts +246 -0
- package/src/tools/technical/indicators.ts +258 -0
- package/src/types/fundamentals.ts +46 -0
- package/src/types/index.ts +20 -0
- package/src/types/macro.ts +27 -0
- package/src/types/market.ts +43 -0
- package/src/types/options.ts +35 -0
- package/src/types/portfolio.ts +41 -0
- package/src/types/sentiment.ts +70 -0
- package/src/workflows/compare-assets.ts +39 -0
- package/src/workflows/index.ts +4 -0
- package/src/workflows/options-screener.ts +49 -0
- package/src/workflows/portfolio-builder.ts +52 -0
- package/src/workflows/types.ts +4 -0
- package/dist/tools/sentiment/news-sentiment.d.ts +0 -7
- package/dist/tools/sentiment/news-sentiment.js +0 -55
- package/dist/tools/sentiment/news-sentiment.js.map +0 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import "../infra/node-version.js";
|
|
2
|
+
import {
|
|
3
|
+
type AuthStorage,
|
|
4
|
+
createAgentSession,
|
|
5
|
+
DefaultResourceLoader,
|
|
6
|
+
type ModelRegistry,
|
|
7
|
+
type CreateAgentSessionResult,
|
|
8
|
+
type SettingsManager,
|
|
9
|
+
type SessionManager,
|
|
10
|
+
getAgentDir,
|
|
11
|
+
} from "@earendil-works/pi-coding-agent";
|
|
12
|
+
import { loadEnv } from "../config.js";
|
|
13
|
+
import openCandleExtension from "./opencandle-extension.js";
|
|
14
|
+
import type { AskUserHandler } from "../types/index.js";
|
|
15
|
+
|
|
16
|
+
export interface CreateOpenCandleSessionOptions {
|
|
17
|
+
cwd?: string;
|
|
18
|
+
agentDir?: string;
|
|
19
|
+
authStorage?: AuthStorage;
|
|
20
|
+
modelRegistry?: ModelRegistry;
|
|
21
|
+
settingsManager?: SettingsManager;
|
|
22
|
+
sessionManager?: SessionManager;
|
|
23
|
+
useInlineExtension?: boolean;
|
|
24
|
+
bindExtensions?: boolean;
|
|
25
|
+
askUserHandler?: AskUserHandler;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function createOpenCandleSession(
|
|
29
|
+
options: CreateOpenCandleSessionOptions = {},
|
|
30
|
+
): Promise<CreateAgentSessionResult> {
|
|
31
|
+
loadEnv();
|
|
32
|
+
|
|
33
|
+
const cwd = options.cwd ?? process.cwd();
|
|
34
|
+
const agentDir = options.agentDir ?? getAgentDir();
|
|
35
|
+
const useInlineExtension = options.useInlineExtension ?? true;
|
|
36
|
+
const resourceLoader = useInlineExtension
|
|
37
|
+
? new DefaultResourceLoader({
|
|
38
|
+
cwd,
|
|
39
|
+
agentDir,
|
|
40
|
+
settingsManager: options.settingsManager,
|
|
41
|
+
extensionFactories: [(pi) => openCandleExtension(pi, { askUserHandler: options.askUserHandler })],
|
|
42
|
+
})
|
|
43
|
+
: undefined;
|
|
44
|
+
|
|
45
|
+
if (resourceLoader) {
|
|
46
|
+
await resourceLoader.reload();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const result = await createAgentSession({
|
|
50
|
+
cwd,
|
|
51
|
+
agentDir,
|
|
52
|
+
authStorage: options.authStorage,
|
|
53
|
+
modelRegistry: options.modelRegistry,
|
|
54
|
+
sessionManager: options.sessionManager,
|
|
55
|
+
settingsManager: options.settingsManager,
|
|
56
|
+
resourceLoader,
|
|
57
|
+
noTools: "builtin",
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
await applySavedDefaultModel(result);
|
|
61
|
+
|
|
62
|
+
if (options.bindExtensions !== false) {
|
|
63
|
+
await result.session.bindExtensions({});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function applySavedDefaultModel(result: CreateAgentSessionResult): Promise<void> {
|
|
70
|
+
const provider = result.session.settingsManager.getDefaultProvider();
|
|
71
|
+
const modelId = result.session.settingsManager.getDefaultModel();
|
|
72
|
+
if (!provider || !modelId) return;
|
|
73
|
+
|
|
74
|
+
const savedDefault = result.session.modelRegistry.find(provider, modelId);
|
|
75
|
+
if (!savedDefault || !result.session.modelRegistry.hasConfiguredAuth(savedDefault)) return;
|
|
76
|
+
|
|
77
|
+
const current = result.session.model;
|
|
78
|
+
if (current?.provider === savedDefault.provider && current.id === savedDefault.id) return;
|
|
79
|
+
|
|
80
|
+
await result.session.setModel(savedDefault);
|
|
81
|
+
}
|
package/src/pi/setup.ts
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import type { Model } from "@earendil-works/pi-ai";
|
|
2
|
+
import {
|
|
3
|
+
LoginDialogComponent,
|
|
4
|
+
type ExtensionAPI,
|
|
5
|
+
type ExtensionContext,
|
|
6
|
+
} from "@earendil-works/pi-coding-agent";
|
|
7
|
+
|
|
8
|
+
type SetupMode = "startup" | "manual";
|
|
9
|
+
type SetupRequirement = "ready" | "select_model" | "connect_auth";
|
|
10
|
+
type ApiKeyProviderId = "google" | "openai" | "anthropic";
|
|
11
|
+
type OAuthProviderChoice = "google-gemini-cli" | "openai-codex" | "anthropic" | "advanced";
|
|
12
|
+
type SetupResult = "ready" | "shutdown" | "cancelled";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Registry of "fast default" models for each LLM auth provider. After a fresh
|
|
16
|
+
* sign-in we try to activate the default without opening a picker, falling back
|
|
17
|
+
* to the picker if the registry doesn't have a match available. Keys are auth
|
|
18
|
+
* provider ids (as passed to `authStorage.set`); values are `{ provider, id }`
|
|
19
|
+
* tuples matching `Model.provider` / `Model.id` fields in the Pi model registry.
|
|
20
|
+
*
|
|
21
|
+
* Models here are intentionally mid-tier (flash/haiku/mini) — the goal is a
|
|
22
|
+
* quick-to-respond first chat, not the flagship. Users can swap models later
|
|
23
|
+
* via Pi's built-in model picker.
|
|
24
|
+
*/
|
|
25
|
+
const DEFAULT_LLM_MODELS: Record<string, { provider: string; id: string }> = {
|
|
26
|
+
// API-key providers
|
|
27
|
+
google: { provider: "google", id: "gemini-2.5-flash" },
|
|
28
|
+
openai: { provider: "openai", id: "gpt-5-mini" },
|
|
29
|
+
anthropic: { provider: "anthropic", id: "claude-haiku-4-5" },
|
|
30
|
+
// OAuth providers
|
|
31
|
+
"google-gemini-cli": { provider: "google-gemini-cli", id: "gemini-2.5-flash" },
|
|
32
|
+
"openai-codex": { provider: "openai-codex", id: "gpt-5.1-codex-mini" },
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Human-readable labels for the three API-key providers, used in preamble copy. */
|
|
36
|
+
const API_KEY_PROVIDER_LABELS: Record<ApiKeyProviderId, string> = {
|
|
37
|
+
google: "Google Gemini",
|
|
38
|
+
openai: "OpenAI",
|
|
39
|
+
anthropic: "Anthropic",
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function sortModels(models: Model<any>[], preferredProvider?: string): Model<any>[] {
|
|
43
|
+
return [...models].sort((a, b) => {
|
|
44
|
+
const aPreferred = preferredProvider && a.provider === preferredProvider ? -1 : 0;
|
|
45
|
+
const bPreferred = preferredProvider && b.provider === preferredProvider ? -1 : 0;
|
|
46
|
+
if (aPreferred !== bPreferred) return aPreferred - bPreferred;
|
|
47
|
+
const byProvider = a.provider.localeCompare(b.provider);
|
|
48
|
+
return byProvider !== 0 ? byProvider : a.id.localeCompare(b.id);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getAvailableModels(ctx: ExtensionContext, preferredProvider?: string): Model<any>[] {
|
|
53
|
+
ctx.modelRegistry.refresh();
|
|
54
|
+
return sortModels(ctx.modelRegistry.getAvailable(), preferredProvider);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function getLlmSetupRequirement(ctx: Pick<ExtensionContext, "model" | "modelRegistry">): SetupRequirement {
|
|
58
|
+
if (ctx.model && ctx.modelRegistry.hasConfiguredAuth(ctx.model)) {
|
|
59
|
+
return "ready";
|
|
60
|
+
}
|
|
61
|
+
return ctx.modelRegistry.getAvailable().length > 0 ? "select_model" : "connect_auth";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function selectProviderForApiKey(ctx: ExtensionContext): Promise<ApiKeyProviderId | undefined> {
|
|
65
|
+
const choice = await ctx.ui.select("Connect an AI model", [
|
|
66
|
+
"Google Gemini API",
|
|
67
|
+
"OpenAI API",
|
|
68
|
+
"Anthropic API",
|
|
69
|
+
]);
|
|
70
|
+
switch (choice) {
|
|
71
|
+
case "Google Gemini API":
|
|
72
|
+
return "google";
|
|
73
|
+
case "OpenAI API":
|
|
74
|
+
return "openai";
|
|
75
|
+
case "Anthropic API":
|
|
76
|
+
return "anthropic";
|
|
77
|
+
default:
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function selectProviderForLogin(ctx: ExtensionContext): Promise<OAuthProviderChoice | undefined> {
|
|
83
|
+
const choice = await ctx.ui.select("Connect an AI model", [
|
|
84
|
+
"Google",
|
|
85
|
+
"OpenAI",
|
|
86
|
+
"Anthropic",
|
|
87
|
+
"Advanced setup",
|
|
88
|
+
]);
|
|
89
|
+
switch (choice) {
|
|
90
|
+
case "Google":
|
|
91
|
+
return "google-gemini-cli";
|
|
92
|
+
case "OpenAI":
|
|
93
|
+
return "openai-codex";
|
|
94
|
+
case "Anthropic":
|
|
95
|
+
return "anthropic";
|
|
96
|
+
case "Advanced setup":
|
|
97
|
+
return "advanced";
|
|
98
|
+
default:
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function selectAdvancedOAuthProvider(ctx: ExtensionContext): Promise<string | undefined> {
|
|
104
|
+
const providers = ctx.modelRegistry.authStorage.getOAuthProviders();
|
|
105
|
+
if (providers.length === 0) {
|
|
106
|
+
ctx.ui.notify("No sign-in providers are available.", "warning");
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
const labels = providers.map((provider) => provider.name);
|
|
110
|
+
const choice = await ctx.ui.select("Choose a provider", labels);
|
|
111
|
+
return providers.find((provider) => provider.name === choice)?.id;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function runLoginDialog(ctx: ExtensionContext, providerId: string): Promise<boolean> {
|
|
115
|
+
const provider = ctx.modelRegistry.authStorage.getOAuthProviders().find((item) => item.id === providerId);
|
|
116
|
+
const providerName = provider?.name ?? providerId;
|
|
117
|
+
const usesCallbackServer = provider?.usesCallbackServer ?? false;
|
|
118
|
+
|
|
119
|
+
const success = await ctx.ui.custom<boolean>((tui, _theme, _keybindings, done) => {
|
|
120
|
+
let finished = false;
|
|
121
|
+
const finish = (value: boolean) => {
|
|
122
|
+
if (finished) return;
|
|
123
|
+
finished = true;
|
|
124
|
+
done(value);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const dialog = new LoginDialogComponent(tui, providerId, (completed) => {
|
|
128
|
+
finish(completed);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
let manualCodeResolve: ((value: string) => void) | undefined;
|
|
132
|
+
let manualCodeReject: ((error: Error) => void) | undefined;
|
|
133
|
+
const manualCodePromise = new Promise<string>((resolve, reject) => {
|
|
134
|
+
manualCodeResolve = resolve;
|
|
135
|
+
manualCodeReject = reject;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Cast required: advanced providers return dynamic IDs outside the SDK's static union type
|
|
139
|
+
void ctx.modelRegistry.authStorage.login(providerId as any, {
|
|
140
|
+
onAuth: (info) => {
|
|
141
|
+
dialog.showAuth(info.url, info.instructions);
|
|
142
|
+
if (usesCallbackServer) {
|
|
143
|
+
void dialog
|
|
144
|
+
.showManualInput("Paste redirect URL below, or complete login in your browser:")
|
|
145
|
+
.then((value) => {
|
|
146
|
+
if (value && manualCodeResolve) {
|
|
147
|
+
manualCodeResolve(value);
|
|
148
|
+
manualCodeResolve = undefined;
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
.catch(() => {
|
|
152
|
+
if (manualCodeReject) {
|
|
153
|
+
manualCodeReject(new Error("Login cancelled"));
|
|
154
|
+
manualCodeReject = undefined;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
} else if (providerId === "github-copilot") {
|
|
158
|
+
dialog.showWaiting("Waiting for browser authentication...");
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
onPrompt: async (prompt) => dialog.showPrompt(prompt.message, prompt.placeholder),
|
|
162
|
+
onProgress: (message) => dialog.showProgress(message),
|
|
163
|
+
onManualCodeInput: () => manualCodePromise,
|
|
164
|
+
signal: dialog.signal,
|
|
165
|
+
})
|
|
166
|
+
.then(() => finish(true))
|
|
167
|
+
.catch((error) => {
|
|
168
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
169
|
+
if (message !== "Login cancelled") {
|
|
170
|
+
ctx.ui.notify(`Failed to connect ${providerName}: ${message}`, "error");
|
|
171
|
+
}
|
|
172
|
+
finish(false);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return dialog;
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (success) {
|
|
179
|
+
ctx.modelRegistry.refresh();
|
|
180
|
+
ctx.ui.notify(`Connected ${providerName}.`, "info");
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async function runApiKeySetup(ctx: ExtensionContext, provider: ApiKeyProviderId): Promise<boolean> {
|
|
188
|
+
const label = API_KEY_PROVIDER_LABELS[provider];
|
|
189
|
+
ctx.ui.notify(
|
|
190
|
+
`OpenCandle stores your ${label} API key locally and only sends it to ${label}.`,
|
|
191
|
+
"info",
|
|
192
|
+
);
|
|
193
|
+
const key = await ctx.ui.input(`Paste your ${label} API key for OpenCandle`, "sk-...");
|
|
194
|
+
const trimmed = key?.trim();
|
|
195
|
+
if (!trimmed) {
|
|
196
|
+
ctx.ui.notify("No API key entered.", "warning");
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
ctx.modelRegistry.authStorage.set(provider, { type: "api_key", key: trimmed });
|
|
200
|
+
ctx.modelRegistry.refresh();
|
|
201
|
+
ctx.ui.notify(`${label} API key saved to OpenCandle.`, "info");
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Attempt to activate the registered default model for `authProviderId`.
|
|
207
|
+
* Returns `true` on success, `false` if no default is registered, the default
|
|
208
|
+
* isn't currently available in `getAvailable()`, or `api.setModel` fails (in
|
|
209
|
+
* which case the caller should fall through to the model picker).
|
|
210
|
+
*/
|
|
211
|
+
async function activateDefaultModel(
|
|
212
|
+
api: ExtensionAPI,
|
|
213
|
+
ctx: ExtensionContext,
|
|
214
|
+
authProviderId: string,
|
|
215
|
+
): Promise<boolean> {
|
|
216
|
+
const defaultModel = DEFAULT_LLM_MODELS[authProviderId];
|
|
217
|
+
if (!defaultModel) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
ctx.modelRegistry.refresh();
|
|
222
|
+
const match = ctx.modelRegistry
|
|
223
|
+
.getAvailable()
|
|
224
|
+
.find(
|
|
225
|
+
(candidate) =>
|
|
226
|
+
candidate.provider === defaultModel.provider && candidate.id === defaultModel.id,
|
|
227
|
+
);
|
|
228
|
+
if (!match) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const ok = await api.setModel(match);
|
|
233
|
+
if (!ok) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
ctx.ui.notify(`Model selected: ${match.provider}/${match.id}`, "info");
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async function selectModel(api: ExtensionAPI, ctx: ExtensionContext, preferredProvider?: string): Promise<boolean> {
|
|
242
|
+
const models = getAvailableModels(ctx, preferredProvider);
|
|
243
|
+
if (models.length === 0) {
|
|
244
|
+
ctx.ui.notify("No available models found yet. Connect a provider first.", "warning");
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const labels = models.map((model) => `${model.provider}/${model.id}`);
|
|
249
|
+
const choice = await ctx.ui.select("Choose a model", labels);
|
|
250
|
+
if (!choice) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const model = models.find((candidate) => `${candidate.provider}/${candidate.id}` === choice);
|
|
255
|
+
if (!model) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const ok = await api.setModel(model);
|
|
260
|
+
if (!ok) {
|
|
261
|
+
ctx.ui.notify("Unable to activate the selected model.", "error");
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
ctx.ui.notify(`Model selected: ${model.provider}/${model.id}`, "info");
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async function runLlmSetup(
|
|
270
|
+
api: ExtensionAPI,
|
|
271
|
+
ctx: ExtensionContext,
|
|
272
|
+
mode: SetupMode,
|
|
273
|
+
): Promise<SetupResult> {
|
|
274
|
+
while (true) {
|
|
275
|
+
const requirement = getLlmSetupRequirement(ctx);
|
|
276
|
+
if (requirement === "ready") {
|
|
277
|
+
return "ready";
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (requirement === "select_model") {
|
|
281
|
+
const selected = await selectModel(api, ctx);
|
|
282
|
+
if (selected) {
|
|
283
|
+
return "ready";
|
|
284
|
+
}
|
|
285
|
+
const retry = await ctx.ui.select("Model setup", ["Try again", "Exit setup"]);
|
|
286
|
+
if (retry !== "Try again") {
|
|
287
|
+
if (mode === "startup") {
|
|
288
|
+
ctx.ui.notify("OpenCandle needs an AI model before chat can start.", "warning");
|
|
289
|
+
ctx.shutdown();
|
|
290
|
+
return "shutdown";
|
|
291
|
+
}
|
|
292
|
+
return "cancelled";
|
|
293
|
+
}
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const choice = await ctx.ui.select(
|
|
298
|
+
"Welcome to OpenCandle — sign in or paste an API key to start chatting",
|
|
299
|
+
["Sign in", "Paste API key", "Exit setup"],
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
if (choice !== "Sign in" && choice !== "Paste API key") {
|
|
303
|
+
if (mode === "startup") {
|
|
304
|
+
ctx.ui.notify("OpenCandle needs an AI model before chat can start.", "warning");
|
|
305
|
+
ctx.shutdown();
|
|
306
|
+
return "shutdown";
|
|
307
|
+
}
|
|
308
|
+
return "cancelled";
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (choice === "Sign in") {
|
|
312
|
+
const providerChoice = await selectProviderForLogin(ctx);
|
|
313
|
+
if (!providerChoice) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const providerId =
|
|
318
|
+
providerChoice === "advanced" ? await selectAdvancedOAuthProvider(ctx) : providerChoice;
|
|
319
|
+
if (!providerId) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const loggedIn = await runLoginDialog(ctx, providerId);
|
|
324
|
+
if (!loggedIn) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Try the registered default for the provider we just signed into —
|
|
329
|
+
// this is the fast path that avoids the model picker entirely.
|
|
330
|
+
if (await activateDefaultModel(api, ctx, providerId)) {
|
|
331
|
+
return "ready";
|
|
332
|
+
}
|
|
333
|
+
const selected = await selectModel(api, ctx, providerId);
|
|
334
|
+
if (selected) {
|
|
335
|
+
return "ready";
|
|
336
|
+
}
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const provider = await selectProviderForApiKey(ctx);
|
|
341
|
+
if (!provider) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const saved = await runApiKeySetup(ctx, provider);
|
|
346
|
+
if (!saved) {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Try the registered default for the provider we just pasted a key for.
|
|
351
|
+
if (await activateDefaultModel(api, ctx, provider)) {
|
|
352
|
+
return "ready";
|
|
353
|
+
}
|
|
354
|
+
const selected = await selectModel(api, ctx, provider);
|
|
355
|
+
if (selected) {
|
|
356
|
+
return "ready";
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export async function runOpenCandleSetup(
|
|
362
|
+
api: ExtensionAPI,
|
|
363
|
+
ctx: ExtensionContext,
|
|
364
|
+
options: { mode: SetupMode } = { mode: "startup" },
|
|
365
|
+
): Promise<SetupResult> {
|
|
366
|
+
const initialRequirement = getLlmSetupRequirement(ctx);
|
|
367
|
+
if (initialRequirement !== "ready" || options.mode === "manual") {
|
|
368
|
+
return runLlmSetup(api, ctx, options.mode);
|
|
369
|
+
}
|
|
370
|
+
return "ready";
|
|
371
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AgentTool } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import type { TSchema } from "@sinclair/typebox";
|
|
4
|
+
import { getAllTools } from "../tools/index.js";
|
|
5
|
+
import { getDefaults } from "../memory/tool-defaults.js";
|
|
6
|
+
import { wrapWithDefaults } from "../runtime/tool-defaults-wrapper.js";
|
|
7
|
+
|
|
8
|
+
export function agentToolToPiTool<TParams extends TSchema, TDetails>(
|
|
9
|
+
tool: AgentTool<TParams, TDetails>,
|
|
10
|
+
): ToolDefinition<TParams, TDetails> {
|
|
11
|
+
return {
|
|
12
|
+
name: tool.name,
|
|
13
|
+
label: tool.label,
|
|
14
|
+
description: tool.description,
|
|
15
|
+
promptSnippet: `${tool.name}: ${tool.description}`,
|
|
16
|
+
parameters: tool.parameters,
|
|
17
|
+
execute: async (toolCallId, params, signal, onUpdate) => {
|
|
18
|
+
return tool.execute(toolCallId, params, signal, onUpdate);
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getOpenCandleToolDefinitions(): ToolDefinition[] {
|
|
24
|
+
return getAllTools()
|
|
25
|
+
.map((tool) => ({ tool, defaults: safeGetDefaults(tool.name) }))
|
|
26
|
+
.filter(({ defaults }) => defaults.__enabled !== false)
|
|
27
|
+
.map(({ tool, defaults }) => agentToolToPiTool(wrapWithDefaults(tool, defaults)));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function safeGetDefaults(toolName: string): Record<string, unknown> {
|
|
31
|
+
try {
|
|
32
|
+
return getDefaults(toolName);
|
|
33
|
+
} catch {
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
}
|