apteva 0.4.57 → 0.7.1
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 +216 -54
- package/cli.js +35 -0
- package/install.js +92 -0
- package/package.json +15 -76
- package/LICENSE +0 -63
- package/bin/apteva.js +0 -196
- package/dist/ActivityPage.kxzzb4yc.js +0 -3
- package/dist/ApiDocsPage.zq998hbm.js +0 -4
- package/dist/App.55rea8mn.js +0 -61
- package/dist/App.5ywb23z4.js +0 -53
- package/dist/App.6thds120.js +0 -4
- package/dist/App.9tctxzqm.js +0 -8
- package/dist/App.a8r8ttaz.js +0 -4
- package/dist/App.agsv5bje.js +0 -4
- package/dist/App.cepapqmx.js +0 -4
- package/dist/App.dp041gb3.js +0 -221
- package/dist/App.fds72zb5.js +0 -4
- package/dist/App.fg9qj2dq.js +0 -4
- package/dist/App.ndfejbm9.js +0 -4
- package/dist/App.nxmfmq1h.js +0 -13
- package/dist/App.qdfyt8ba.js +0 -4
- package/dist/App.x2d0ygt6.js +0 -4
- package/dist/App.yt9p4nr3.js +0 -20
- package/dist/App.zn4mw16t.js +0 -1
- package/dist/ConnectionsPage.8r96ryw7.js +0 -3
- package/dist/McpPage.3cwh0gnd.js +0 -3
- package/dist/SettingsPage.ykgdh5ev.js +0 -3
- package/dist/SkillsPage.4np1s65b.js +0 -3
- package/dist/TasksPage.4g08t7p6.js +0 -3
- package/dist/TelemetryPage.72w9pwcp.js +0 -3
- package/dist/TestsPage.z4fk3r7r.js +0 -3
- package/dist/ThreadsPage.63tcajeh.js +0 -3
- package/dist/apteva-kit.css +0 -1
- package/dist/icon.png +0 -0
- package/dist/index.html +0 -16
- package/dist/styles.css +0 -1
- package/scripts/postinstall.mjs +0 -102
- package/src/auth/index.ts +0 -394
- package/src/auth/middleware.ts +0 -213
- package/src/binary.ts +0 -536
- package/src/channels/index.ts +0 -40
- package/src/channels/telegram.ts +0 -311
- package/src/crypto.ts +0 -301
- package/src/db-tests.ts +0 -174
- package/src/db.ts +0 -3133
- package/src/integrations/agentdojo.ts +0 -559
- package/src/integrations/composio.ts +0 -437
- package/src/integrations/index.ts +0 -87
- package/src/integrations/skillsmp.ts +0 -318
- package/src/mcp-client.ts +0 -605
- package/src/mcp-handler.ts +0 -394
- package/src/mcp-platform.ts +0 -2403
- package/src/openapi.ts +0 -2410
- package/src/providers.ts +0 -597
- package/src/routes/api/agent-utils.ts +0 -890
- package/src/routes/api/agents.ts +0 -916
- package/src/routes/api/api-keys.ts +0 -95
- package/src/routes/api/channels.ts +0 -182
- package/src/routes/api/helpers.ts +0 -12
- package/src/routes/api/integrations.ts +0 -639
- package/src/routes/api/mcp.ts +0 -574
- package/src/routes/api/meta-agent.ts +0 -195
- package/src/routes/api/projects.ts +0 -112
- package/src/routes/api/providers.ts +0 -424
- package/src/routes/api/skills.ts +0 -537
- package/src/routes/api/system.ts +0 -333
- package/src/routes/api/telemetry.ts +0 -203
- package/src/routes/api/tests.ts +0 -148
- package/src/routes/api/triggers.ts +0 -518
- package/src/routes/api/users.ts +0 -148
- package/src/routes/api/webhooks.ts +0 -171
- package/src/routes/api.ts +0 -53
- package/src/routes/auth.ts +0 -251
- package/src/routes/share.ts +0 -86
- package/src/routes/static.ts +0 -131
- package/src/server.ts +0 -642
- package/src/test-runner.ts +0 -598
- package/src/triggers/agentdojo.ts +0 -253
- package/src/triggers/composio.ts +0 -264
- package/src/triggers/index.ts +0 -71
- package/src/tui/AgentList.tsx +0 -145
- package/src/tui/App.tsx +0 -102
- package/src/tui/Login.tsx +0 -104
- package/src/tui/api.ts +0 -72
- package/src/tui/index.tsx +0 -7
- package/src/web/App.tsx +0 -455
- package/src/web/components/activity/ActivityPage.tsx +0 -314
- package/src/web/components/activity/index.ts +0 -1
- package/src/web/components/agents/AgentCard.tsx +0 -189
- package/src/web/components/agents/AgentPanel.tsx +0 -2244
- package/src/web/components/agents/AgentsView.tsx +0 -180
- package/src/web/components/agents/CreateAgentModal.tsx +0 -475
- package/src/web/components/agents/index.ts +0 -4
- package/src/web/components/api/ApiDocsPage.tsx +0 -842
- package/src/web/components/auth/CreateAccountStep.tsx +0 -176
- package/src/web/components/auth/LoginPage.tsx +0 -91
- package/src/web/components/auth/index.ts +0 -2
- package/src/web/components/common/Icons.tsx +0 -250
- package/src/web/components/common/LoadingSpinner.tsx +0 -44
- package/src/web/components/common/Modal.tsx +0 -199
- package/src/web/components/common/Select.tsx +0 -97
- package/src/web/components/common/index.ts +0 -20
- package/src/web/components/connections/ConnectionsPage.tsx +0 -54
- package/src/web/components/connections/IntegrationsTab.tsx +0 -170
- package/src/web/components/connections/OverviewTab.tsx +0 -137
- package/src/web/components/connections/TriggersTab.tsx +0 -1346
- package/src/web/components/dashboard/Dashboard.tsx +0 -572
- package/src/web/components/dashboard/index.ts +0 -1
- package/src/web/components/index.ts +0 -21
- package/src/web/components/layout/ErrorBanner.tsx +0 -18
- package/src/web/components/layout/Header.tsx +0 -332
- package/src/web/components/layout/Sidebar.tsx +0 -231
- package/src/web/components/layout/index.ts +0 -3
- package/src/web/components/mcp/IntegrationsPanel.tsx +0 -857
- package/src/web/components/mcp/McpPage.tsx +0 -2515
- package/src/web/components/mcp/index.ts +0 -1
- package/src/web/components/meta-agent/MetaAgent.tsx +0 -245
- package/src/web/components/onboarding/OnboardingWizard.tsx +0 -404
- package/src/web/components/onboarding/index.ts +0 -1
- package/src/web/components/settings/SettingsPage.tsx +0 -2776
- package/src/web/components/settings/index.ts +0 -1
- package/src/web/components/skills/SkillsPage.tsx +0 -1200
- package/src/web/components/tasks/TasksPage.tsx +0 -1116
- package/src/web/components/tasks/index.ts +0 -1
- package/src/web/components/telemetry/TelemetryPage.tsx +0 -1129
- package/src/web/components/tests/TestsPage.tsx +0 -594
- package/src/web/components/threads/ThreadsPage.tsx +0 -315
- package/src/web/context/AuthContext.tsx +0 -242
- package/src/web/context/ProjectContext.tsx +0 -214
- package/src/web/context/TelemetryContext.tsx +0 -299
- package/src/web/context/ThemeContext.tsx +0 -90
- package/src/web/context/UIModeContext.tsx +0 -49
- package/src/web/context/index.ts +0 -12
- package/src/web/hooks/index.ts +0 -3
- package/src/web/hooks/useAgents.ts +0 -115
- package/src/web/hooks/useOnboarding.ts +0 -20
- package/src/web/hooks/useProviders.ts +0 -75
- package/src/web/icon.png +0 -0
- package/src/web/index.html +0 -16
- package/src/web/styles.css +0 -118
- package/src/web/themes.ts +0 -162
- package/src/web/types.ts +0 -298
package/src/providers.ts
DELETED
|
@@ -1,597 +0,0 @@
|
|
|
1
|
-
import { ProviderKeysDB, SettingsDB } from "./db";
|
|
2
|
-
import { encrypt, decrypt, createKeyHint, validateKeyFormat } from "./crypto";
|
|
3
|
-
|
|
4
|
-
// Provider configuration with API URLs and key testing endpoints
|
|
5
|
-
export const PROVIDERS = {
|
|
6
|
-
anthropic: {
|
|
7
|
-
id: "anthropic",
|
|
8
|
-
name: "Anthropic",
|
|
9
|
-
displayName: "Anthropic",
|
|
10
|
-
type: "llm" as const,
|
|
11
|
-
envVar: "ANTHROPIC_API_KEY",
|
|
12
|
-
docsUrl: "https://console.anthropic.com/settings/keys",
|
|
13
|
-
testEndpoint: "https://api.anthropic.com/v1/messages",
|
|
14
|
-
models: [
|
|
15
|
-
{ value: "claude-sonnet-4-6", label: "Claude Sonnet 4.6", recommended: true, input_cost: 3, output_cost: 15, cache_creation_cost: 3.75, cache_read_cost: 0.3 },
|
|
16
|
-
{ value: "claude-haiku-4-5", label: "Claude Haiku 4.5 (Fast)", input_cost: 0.8, output_cost: 4, cache_creation_cost: 1, cache_read_cost: 0.08 },
|
|
17
|
-
],
|
|
18
|
-
},
|
|
19
|
-
openai: {
|
|
20
|
-
id: "openai",
|
|
21
|
-
name: "OpenAI",
|
|
22
|
-
displayName: "OpenAI",
|
|
23
|
-
type: "llm" as const,
|
|
24
|
-
envVar: "OPENAI_API_KEY",
|
|
25
|
-
docsUrl: "https://platform.openai.com/api-keys",
|
|
26
|
-
testEndpoint: "https://api.openai.com/v1/models",
|
|
27
|
-
models: [
|
|
28
|
-
{ value: "gpt-5.4", label: "GPT-5.4 (Latest)", recommended: true, input_cost: 2.5, output_cost: 10 },
|
|
29
|
-
],
|
|
30
|
-
},
|
|
31
|
-
groq: {
|
|
32
|
-
id: "groq",
|
|
33
|
-
name: "Groq",
|
|
34
|
-
displayName: "Groq",
|
|
35
|
-
type: "llm" as const,
|
|
36
|
-
envVar: "GROQ_API_KEY",
|
|
37
|
-
docsUrl: "https://console.groq.com/keys",
|
|
38
|
-
testEndpoint: "https://api.groq.com/openai/v1/models",
|
|
39
|
-
models: [
|
|
40
|
-
{ value: "llama-3.3-70b-versatile", label: "Llama 3.3 70B", recommended: true, input_cost: 0, output_cost: 0 },
|
|
41
|
-
{ value: "llama-3.1-8b-instant", label: "Llama 3.1 8B (Fast)", input_cost: 0, output_cost: 0 },
|
|
42
|
-
],
|
|
43
|
-
},
|
|
44
|
-
gemini: {
|
|
45
|
-
id: "gemini",
|
|
46
|
-
name: "Google",
|
|
47
|
-
displayName: "Google Gemini",
|
|
48
|
-
type: "llm" as const,
|
|
49
|
-
envVar: "GEMINI_API_KEY",
|
|
50
|
-
docsUrl: "https://aistudio.google.com/app/apikey",
|
|
51
|
-
testEndpoint: "https://generativelanguage.googleapis.com/v1/models",
|
|
52
|
-
models: [
|
|
53
|
-
{ value: "gemini-3.1-pro-preview", label: "Gemini 3.1 Pro Preview (Latest)", recommended: true, input_cost: 2, output_cost: 12 },
|
|
54
|
-
{ value: "gemini-3-pro-preview", label: "Gemini 3 Pro Preview", input_cost: 2, output_cost: 12 },
|
|
55
|
-
{ value: "gemini-3.1-flash-lite-preview", label: "Gemini 3.1 Flash Lite Preview (Fast)", input_cost: 0.25, output_cost: 1.5 },
|
|
56
|
-
{ value: "gemini-3-flash-preview", label: "Gemini 3 Flash Preview", input_cost: 0.5, output_cost: 3 },
|
|
57
|
-
],
|
|
58
|
-
},
|
|
59
|
-
xai: {
|
|
60
|
-
id: "xai",
|
|
61
|
-
name: "xAI",
|
|
62
|
-
displayName: "xAI Grok",
|
|
63
|
-
type: "llm" as const,
|
|
64
|
-
envVar: "XAI_API_KEY",
|
|
65
|
-
docsUrl: "https://console.x.ai/",
|
|
66
|
-
testEndpoint: "https://api.x.ai/v1/models",
|
|
67
|
-
models: [
|
|
68
|
-
{ value: "grok-2", label: "Grok 2", recommended: true, input_cost: 2, output_cost: 10 },
|
|
69
|
-
{ value: "grok-2-mini", label: "Grok 2 Mini (Fast)", input_cost: 0.3, output_cost: 1 },
|
|
70
|
-
],
|
|
71
|
-
},
|
|
72
|
-
together: {
|
|
73
|
-
id: "together",
|
|
74
|
-
name: "Together",
|
|
75
|
-
displayName: "Together AI",
|
|
76
|
-
type: "llm" as const,
|
|
77
|
-
envVar: "TOGETHER_API_KEY",
|
|
78
|
-
docsUrl: "https://api.together.xyz/settings/api-keys",
|
|
79
|
-
testEndpoint: "https://api.together.xyz/v1/models",
|
|
80
|
-
models: [
|
|
81
|
-
{ value: "moonshotai/Kimi-K2.5", label: "Kimi K2.5", recommended: true, input_cost: 1, output_cost: 4 },
|
|
82
|
-
{ value: "moonshotai/Kimi-K2-Thinking", label: "Kimi K2 Thinking (Reasoning)", input_cost: 1, output_cost: 4 },
|
|
83
|
-
],
|
|
84
|
-
},
|
|
85
|
-
fireworks: {
|
|
86
|
-
id: "fireworks",
|
|
87
|
-
name: "Fireworks",
|
|
88
|
-
displayName: "Fireworks AI",
|
|
89
|
-
type: "llm" as const,
|
|
90
|
-
envVar: "FIREWORKS_API_KEY",
|
|
91
|
-
docsUrl: "https://fireworks.ai/api-keys",
|
|
92
|
-
testEndpoint: "https://api.fireworks.ai/inference/v1/models",
|
|
93
|
-
models: [
|
|
94
|
-
{ value: "accounts/fireworks/models/kimi-k2p5", label: "Kimi K2.5", recommended: true, input_cost: 1, output_cost: 4 },
|
|
95
|
-
{ value: "accounts/fireworks/models/kimi-k2-thinking", label: "Kimi K2 Thinking (Reasoning)", input_cost: 1, output_cost: 4 },
|
|
96
|
-
{ value: "accounts/fireworks/models/minimax-m2p5", label: "MiniMax M2.5", input_cost: 1, output_cost: 4 },
|
|
97
|
-
{ value: "accounts/fireworks/models/glm-5", label: "GLM 5", input_cost: 1, output_cost: 4 },
|
|
98
|
-
],
|
|
99
|
-
},
|
|
100
|
-
moonshot: {
|
|
101
|
-
id: "moonshot",
|
|
102
|
-
name: "Moonshot",
|
|
103
|
-
displayName: "Moonshot AI",
|
|
104
|
-
type: "llm" as const,
|
|
105
|
-
envVar: "MOONSHOT_API_KEY",
|
|
106
|
-
docsUrl: "https://platform.moonshot.cn/console/api-keys",
|
|
107
|
-
testEndpoint: "https://api.moonshot.cn/v1/models",
|
|
108
|
-
models: [
|
|
109
|
-
{ value: "moonshot-v1-128k", label: "Kimi 128K", recommended: true, input_cost: 1, output_cost: 4 },
|
|
110
|
-
{ value: "moonshot-v1-32k", label: "Kimi 32K (Fast)", input_cost: 0.5, output_cost: 2 },
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
venice: {
|
|
114
|
-
id: "venice",
|
|
115
|
-
name: "Venice",
|
|
116
|
-
displayName: "Venice AI",
|
|
117
|
-
type: "llm" as const,
|
|
118
|
-
envVar: "VENICE_API_KEY",
|
|
119
|
-
docsUrl: "https://docs.venice.ai/overview/pricing",
|
|
120
|
-
testEndpoint: "https://api.venice.ai/api/v1/models",
|
|
121
|
-
models: [
|
|
122
|
-
{ value: "llama-3.3-70b", label: "Llama 3.3 70B", recommended: true, input_cost: 0.7, output_cost: 2.8 },
|
|
123
|
-
{ value: "olafangensan-glm-4.7-flash-heretic", label: "GLM 4.7 Flash Heretic", input_cost: 0.14, output_cost: 0.8 },
|
|
124
|
-
{ value: "qwen3-235b-a22b-instruct-2507", label: "Qwen 3 235B Instruct", input_cost: 0.15, output_cost: 0.75 },
|
|
125
|
-
{ value: "deepseek-v3.2", label: "DeepSeek V3.2", input_cost: 0.4, output_cost: 1 },
|
|
126
|
-
{ value: "venice-uncensored", label: "Venice Uncensored 1.1", input_cost: 0.2, output_cost: 0.9 },
|
|
127
|
-
],
|
|
128
|
-
},
|
|
129
|
-
cerebras: {
|
|
130
|
-
id: "cerebras",
|
|
131
|
-
name: "Cerebras",
|
|
132
|
-
displayName: "Cerebras",
|
|
133
|
-
type: "llm" as const,
|
|
134
|
-
envVar: "CEREBRAS_API_KEY",
|
|
135
|
-
docsUrl: "https://cloud.cerebras.ai/",
|
|
136
|
-
testEndpoint: "https://api.cerebras.ai/v1/models",
|
|
137
|
-
models: [
|
|
138
|
-
{ value: "gpt-oss-120b", label: "GPT-OSS 120B", recommended: true, input_cost: 0.2, output_cost: 1 },
|
|
139
|
-
{ value: "llama-4-scout-17b-16e-instruct", label: "Llama 4 Scout 17B (Fast)", input_cost: 0.05, output_cost: 0.25 },
|
|
140
|
-
{ value: "llama3.3-70b", label: "Llama 3.3 70B", input_cost: 0.1, output_cost: 0.5 },
|
|
141
|
-
],
|
|
142
|
-
},
|
|
143
|
-
ollama: {
|
|
144
|
-
id: "ollama",
|
|
145
|
-
name: "Ollama",
|
|
146
|
-
displayName: "Ollama (Local)",
|
|
147
|
-
type: "llm" as const,
|
|
148
|
-
envVar: "OLLAMA_BASE_URL",
|
|
149
|
-
docsUrl: "https://ollama.ai/download",
|
|
150
|
-
testEndpoint: "", // Dynamic - uses configured base URL
|
|
151
|
-
isLocal: true,
|
|
152
|
-
defaultBaseUrl: "http://localhost:11434",
|
|
153
|
-
models: [
|
|
154
|
-
// Default models - actual list fetched dynamically from Ollama
|
|
155
|
-
{ value: "llama3.3", label: "Llama 3.3 (70B)", recommended: true, input_cost: 0, output_cost: 0 },
|
|
156
|
-
{ value: "llama3.2", label: "Llama 3.2 (3B)", input_cost: 0, output_cost: 0 },
|
|
157
|
-
{ value: "qwen2.5", label: "Qwen 2.5", input_cost: 0, output_cost: 0 },
|
|
158
|
-
{ value: "mistral", label: "Mistral", input_cost: 0, output_cost: 0 },
|
|
159
|
-
{ value: "deepseek-r1", label: "DeepSeek R1", input_cost: 0, output_cost: 0 },
|
|
160
|
-
],
|
|
161
|
-
},
|
|
162
|
-
// Browser Providers
|
|
163
|
-
browserbase: {
|
|
164
|
-
id: "browserbase",
|
|
165
|
-
name: "Browserbase",
|
|
166
|
-
displayName: "Browserbase",
|
|
167
|
-
type: "browser" as const,
|
|
168
|
-
envVar: "BROWSERBASE_API_KEY",
|
|
169
|
-
docsUrl: "https://www.browserbase.com/",
|
|
170
|
-
description: "Cloud browser sessions with proxies and stealth mode",
|
|
171
|
-
models: [],
|
|
172
|
-
},
|
|
173
|
-
steel: {
|
|
174
|
-
id: "steel",
|
|
175
|
-
name: "Steel",
|
|
176
|
-
displayName: "Steel.dev",
|
|
177
|
-
type: "browser" as const,
|
|
178
|
-
envVar: "STEEL_API_KEY",
|
|
179
|
-
docsUrl: "https://steel.dev/",
|
|
180
|
-
description: "Cloud browser automation with CDP",
|
|
181
|
-
models: [],
|
|
182
|
-
},
|
|
183
|
-
browserengine: {
|
|
184
|
-
id: "browserengine",
|
|
185
|
-
name: "BrowserEngine",
|
|
186
|
-
displayName: "BrowserEngine",
|
|
187
|
-
type: "browser" as const,
|
|
188
|
-
envVar: "BROWSERENGINE_API_KEY",
|
|
189
|
-
docsUrl: "https://browserengine.co",
|
|
190
|
-
description: "Cloud browser automation with stealth browsing and proxies",
|
|
191
|
-
models: [],
|
|
192
|
-
},
|
|
193
|
-
cdp: {
|
|
194
|
-
id: "cdp",
|
|
195
|
-
name: "CDP",
|
|
196
|
-
displayName: "Direct CDP",
|
|
197
|
-
type: "browser" as const,
|
|
198
|
-
envVar: "CDP_URL",
|
|
199
|
-
docsUrl: "",
|
|
200
|
-
description: "Connect directly to any browser via Chrome DevTools Protocol",
|
|
201
|
-
isLocal: true,
|
|
202
|
-
models: [],
|
|
203
|
-
},
|
|
204
|
-
// Voice Providers
|
|
205
|
-
elevenlabs: {
|
|
206
|
-
id: "elevenlabs",
|
|
207
|
-
name: "ElevenLabs",
|
|
208
|
-
displayName: "ElevenLabs",
|
|
209
|
-
type: "voice" as const,
|
|
210
|
-
envVar: "ELEVENLABS_API_KEY",
|
|
211
|
-
docsUrl: "https://elevenlabs.io/app/settings/api-keys",
|
|
212
|
-
description: "Speech-to-text and text-to-speech for voice conversations",
|
|
213
|
-
models: [],
|
|
214
|
-
},
|
|
215
|
-
deepgram: {
|
|
216
|
-
id: "deepgram",
|
|
217
|
-
name: "Deepgram",
|
|
218
|
-
displayName: "Deepgram",
|
|
219
|
-
type: "voice" as const,
|
|
220
|
-
envVar: "DEEPGRAM_API_KEY",
|
|
221
|
-
docsUrl: "https://console.deepgram.com/",
|
|
222
|
-
description: "Fast speech-to-text and text-to-speech with low latency",
|
|
223
|
-
models: [],
|
|
224
|
-
},
|
|
225
|
-
// Local Voice Providers
|
|
226
|
-
speaches: {
|
|
227
|
-
id: "speaches",
|
|
228
|
-
name: "Speaches",
|
|
229
|
-
displayName: "Speaches (Local)",
|
|
230
|
-
type: "voice" as const,
|
|
231
|
-
voiceSubtype: "both" as const,
|
|
232
|
-
envVar: "SPEACHES_BASE_URL",
|
|
233
|
-
docsUrl: "https://github.com/speaches-ai/speaches",
|
|
234
|
-
description: "Local STT + TTS server with OpenAI-compatible API",
|
|
235
|
-
isLocal: true,
|
|
236
|
-
defaultBaseUrl: "http://localhost:8000",
|
|
237
|
-
models: [
|
|
238
|
-
{ value: "Systran/faster-whisper-large-v3", label: "Whisper Large V3 (STT)", recommended: true, input_cost: 0, output_cost: 0 },
|
|
239
|
-
{ value: "Systran/faster-whisper-medium", label: "Whisper Medium (STT)", input_cost: 0, output_cost: 0 },
|
|
240
|
-
{ value: "hexgrad/Kokoro-82M", label: "Kokoro 82M (TTS)", recommended: true, input_cost: 0, output_cost: 0 },
|
|
241
|
-
],
|
|
242
|
-
},
|
|
243
|
-
whisper_cpp: {
|
|
244
|
-
id: "whisper_cpp",
|
|
245
|
-
name: "Whisper.cpp",
|
|
246
|
-
displayName: "Whisper.cpp (Local)",
|
|
247
|
-
type: "voice" as const,
|
|
248
|
-
voiceSubtype: "stt" as const,
|
|
249
|
-
envVar: "WHISPER_CPP_BASE_URL",
|
|
250
|
-
docsUrl: "https://github.com/ggerganov/whisper.cpp",
|
|
251
|
-
description: "High-performance local speech-to-text",
|
|
252
|
-
isLocal: true,
|
|
253
|
-
defaultBaseUrl: "http://localhost:8080",
|
|
254
|
-
models: [
|
|
255
|
-
{ value: "large-v3", label: "Large V3", recommended: true, input_cost: 0, output_cost: 0 },
|
|
256
|
-
{ value: "large-v3-turbo", label: "Large V3 Turbo (Fast)", input_cost: 0, output_cost: 0 },
|
|
257
|
-
{ value: "medium", label: "Medium", input_cost: 0, output_cost: 0 },
|
|
258
|
-
{ value: "small", label: "Small (Fast)", input_cost: 0, output_cost: 0 },
|
|
259
|
-
{ value: "base", label: "Base (Fastest)", input_cost: 0, output_cost: 0 },
|
|
260
|
-
],
|
|
261
|
-
},
|
|
262
|
-
kokoro: {
|
|
263
|
-
id: "kokoro",
|
|
264
|
-
name: "Kokoro",
|
|
265
|
-
displayName: "Kokoro (Local)",
|
|
266
|
-
type: "voice" as const,
|
|
267
|
-
voiceSubtype: "tts" as const,
|
|
268
|
-
envVar: "KOKORO_BASE_URL",
|
|
269
|
-
docsUrl: "https://github.com/remsky/Kokoro-FastAPI",
|
|
270
|
-
description: "High-quality local text-to-speech, CPU-only, 82M params",
|
|
271
|
-
isLocal: true,
|
|
272
|
-
defaultBaseUrl: "http://localhost:8880",
|
|
273
|
-
models: [
|
|
274
|
-
{ value: "kokoro", label: "Kokoro 82M", recommended: true, input_cost: 0, output_cost: 0 },
|
|
275
|
-
],
|
|
276
|
-
},
|
|
277
|
-
piper: {
|
|
278
|
-
id: "piper",
|
|
279
|
-
name: "Piper",
|
|
280
|
-
displayName: "Piper (Local)",
|
|
281
|
-
type: "voice" as const,
|
|
282
|
-
voiceSubtype: "tts" as const,
|
|
283
|
-
envVar: "PIPER_BASE_URL",
|
|
284
|
-
docsUrl: "https://github.com/rhasspy/piper",
|
|
285
|
-
description: "Fast local text-to-speech, runs on any hardware",
|
|
286
|
-
isLocal: true,
|
|
287
|
-
defaultBaseUrl: "http://localhost:5000",
|
|
288
|
-
models: [
|
|
289
|
-
{ value: "en_US-amy-medium", label: "Amy (Medium)", recommended: true, input_cost: 0, output_cost: 0 },
|
|
290
|
-
{ value: "en_US-lessac-medium", label: "Lessac (Medium)", input_cost: 0, output_cost: 0 },
|
|
291
|
-
],
|
|
292
|
-
},
|
|
293
|
-
fish_speech: {
|
|
294
|
-
id: "fish_speech",
|
|
295
|
-
name: "Fish Speech",
|
|
296
|
-
displayName: "Fish Speech (Local)",
|
|
297
|
-
type: "voice" as const,
|
|
298
|
-
voiceSubtype: "tts" as const,
|
|
299
|
-
envVar: "FISH_SPEECH_BASE_URL",
|
|
300
|
-
docsUrl: "https://github.com/fishaudio/fish-speech",
|
|
301
|
-
description: "High-quality local TTS with voice cloning",
|
|
302
|
-
isLocal: true,
|
|
303
|
-
defaultBaseUrl: "http://localhost:8180",
|
|
304
|
-
models: [
|
|
305
|
-
{ value: "fish-speech-1.5", label: "Fish Speech 1.5", recommended: true, input_cost: 0, output_cost: 0 },
|
|
306
|
-
],
|
|
307
|
-
},
|
|
308
|
-
// MCP Integrations
|
|
309
|
-
composio: {
|
|
310
|
-
id: "composio",
|
|
311
|
-
name: "Composio",
|
|
312
|
-
displayName: "Composio",
|
|
313
|
-
type: "integration" as const,
|
|
314
|
-
envVar: "COMPOSIO_API_KEY",
|
|
315
|
-
docsUrl: "https://app.composio.dev/settings",
|
|
316
|
-
description: "500+ app integrations via MCP gateway",
|
|
317
|
-
models: [],
|
|
318
|
-
},
|
|
319
|
-
smithery: {
|
|
320
|
-
id: "smithery",
|
|
321
|
-
name: "Smithery",
|
|
322
|
-
displayName: "Smithery",
|
|
323
|
-
type: "integration" as const,
|
|
324
|
-
envVar: "SMITHERY_API_KEY",
|
|
325
|
-
docsUrl: "https://smithery.ai/settings",
|
|
326
|
-
description: "MCP server registry and hosting",
|
|
327
|
-
models: [],
|
|
328
|
-
},
|
|
329
|
-
agentdojo: {
|
|
330
|
-
id: "agentdojo",
|
|
331
|
-
name: "AgentDojo",
|
|
332
|
-
displayName: "AgentDojo",
|
|
333
|
-
type: "integration" as const,
|
|
334
|
-
envVar: "AGENTDOJO_API_KEY",
|
|
335
|
-
docsUrl: "https://agentdojo.com/settings",
|
|
336
|
-
description: "Hosted MCP tools and agent capabilities",
|
|
337
|
-
models: [],
|
|
338
|
-
},
|
|
339
|
-
// Skills Integrations
|
|
340
|
-
skillsmp: {
|
|
341
|
-
id: "skillsmp",
|
|
342
|
-
name: "SkillsMP",
|
|
343
|
-
displayName: "SkillsMP",
|
|
344
|
-
type: "integration" as const,
|
|
345
|
-
envVar: "SKILLSMP_API_KEY",
|
|
346
|
-
docsUrl: "https://skillsmp.com/settings",
|
|
347
|
-
description: "Agent skills marketplace (optional - public registry available without key)",
|
|
348
|
-
models: [],
|
|
349
|
-
},
|
|
350
|
-
} as const;
|
|
351
|
-
|
|
352
|
-
export type ProviderId = keyof typeof PROVIDERS;
|
|
353
|
-
|
|
354
|
-
/** Get cost per 1M tokens for a given provider + model. Returns { input_cost, output_cost, cache_creation_cost, cache_read_cost } in USD. */
|
|
355
|
-
export function getModelCost(provider: string, model: string): { input_cost: number; output_cost: number; cache_creation_cost: number; cache_read_cost: number } {
|
|
356
|
-
const providerDef = PROVIDERS[provider as ProviderId];
|
|
357
|
-
if (!providerDef || !("models" in providerDef)) return { input_cost: 0, output_cost: 0, cache_creation_cost: 0, cache_read_cost: 0 };
|
|
358
|
-
const modelDef = (providerDef.models as ReadonlyArray<{ value: string; input_cost?: number; output_cost?: number; cache_creation_cost?: number; cache_read_cost?: number }>)
|
|
359
|
-
.find(m => m.value === model);
|
|
360
|
-
if (!modelDef) return { input_cost: 0, output_cost: 0, cache_creation_cost: 0, cache_read_cost: 0 };
|
|
361
|
-
return {
|
|
362
|
-
input_cost: modelDef.input_cost ?? 0,
|
|
363
|
-
output_cost: modelDef.output_cost ?? 0,
|
|
364
|
-
cache_creation_cost: modelDef.cache_creation_cost ?? 0,
|
|
365
|
-
cache_read_cost: modelDef.cache_read_cost ?? 0,
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// Provider Keys Management
|
|
370
|
-
export const ProviderKeys = {
|
|
371
|
-
// Save an API key (encrypts before storing)
|
|
372
|
-
// projectId: null = global key, string = project-scoped key
|
|
373
|
-
async save(
|
|
374
|
-
providerId: string,
|
|
375
|
-
apiKey: string,
|
|
376
|
-
projectId: string | null = null,
|
|
377
|
-
name: string | null = null
|
|
378
|
-
): Promise<{ success: boolean; error?: string; id?: string }> {
|
|
379
|
-
// Validate format
|
|
380
|
-
const validation = validateKeyFormat(providerId, apiKey);
|
|
381
|
-
if (!validation.valid) {
|
|
382
|
-
return { success: false, error: validation.error };
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
try {
|
|
386
|
-
const encryptedKey = encrypt(apiKey.trim());
|
|
387
|
-
// For multi-field JSON keys (e.g. browserbase), use the api_key field for the hint
|
|
388
|
-
let hintSource = apiKey.trim();
|
|
389
|
-
if (providerId === "browserbase") {
|
|
390
|
-
try {
|
|
391
|
-
const parsed = JSON.parse(hintSource);
|
|
392
|
-
if (parsed.api_key) hintSource = parsed.api_key;
|
|
393
|
-
} catch {}
|
|
394
|
-
}
|
|
395
|
-
const keyHint = createKeyHint(hintSource);
|
|
396
|
-
const record = ProviderKeysDB.save(providerId, encryptedKey, keyHint, projectId, name);
|
|
397
|
-
return { success: true, id: record.id };
|
|
398
|
-
} catch (err) {
|
|
399
|
-
return { success: false, error: `Failed to save key: ${err}` };
|
|
400
|
-
}
|
|
401
|
-
},
|
|
402
|
-
|
|
403
|
-
// Get decrypted API key for a provider (global key, falls back to env var)
|
|
404
|
-
getDecrypted(providerId: string): string | null {
|
|
405
|
-
const record = ProviderKeysDB.findByProvider(providerId);
|
|
406
|
-
if (record) {
|
|
407
|
-
try {
|
|
408
|
-
return decrypt(record.encrypted_key);
|
|
409
|
-
} catch (err) {
|
|
410
|
-
console.error(`Failed to decrypt key for ${providerId}:`, err);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// Fall back to environment variable
|
|
415
|
-
const provider = PROVIDERS[providerId as ProviderId];
|
|
416
|
-
if (provider?.envVar) {
|
|
417
|
-
const envVal = process.env[provider.envVar];
|
|
418
|
-
if (envVal) return envVal;
|
|
419
|
-
}
|
|
420
|
-
return null;
|
|
421
|
-
},
|
|
422
|
-
|
|
423
|
-
// Get decrypted API key for a provider and project
|
|
424
|
-
// Falls back to global key if no project-specific key exists
|
|
425
|
-
getDecryptedForProject(providerId: string, projectId: string | null): string | null {
|
|
426
|
-
console.log(`[ProviderKeys.getDecryptedForProject] providerId=${providerId}, projectId=${projectId}`);
|
|
427
|
-
// Try project-specific key first
|
|
428
|
-
if (projectId) {
|
|
429
|
-
const projectRecord = ProviderKeysDB.findByProviderAndProject(providerId, projectId);
|
|
430
|
-
console.log(`[ProviderKeys.getDecryptedForProject] project record found: ${!!projectRecord}`);
|
|
431
|
-
if (projectRecord) {
|
|
432
|
-
try {
|
|
433
|
-
const key = decrypt(projectRecord.encrypted_key);
|
|
434
|
-
console.log(`[ProviderKeys.getDecryptedForProject] decrypted project key OK, length=${key?.length}`);
|
|
435
|
-
return key;
|
|
436
|
-
} catch (err) {
|
|
437
|
-
console.error(`Failed to decrypt project key for ${providerId}/${projectId}:`, err);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
// Fall back to global key
|
|
442
|
-
const globalKey = this.getDecrypted(providerId);
|
|
443
|
-
console.log(`[ProviderKeys.getDecryptedForProject] global fallback: found=${!!globalKey}, length=${globalKey?.length || 0}`);
|
|
444
|
-
return globalKey;
|
|
445
|
-
},
|
|
446
|
-
|
|
447
|
-
// Check if a provider has a key configured (global)
|
|
448
|
-
hasKey(providerId: string): boolean {
|
|
449
|
-
return ProviderKeysDB.findByProvider(providerId) !== null;
|
|
450
|
-
},
|
|
451
|
-
|
|
452
|
-
// Check if a provider has a key for a specific project (or global)
|
|
453
|
-
hasKeyForProject(providerId: string, projectId: string | null): boolean {
|
|
454
|
-
if (projectId && ProviderKeysDB.findByProviderAndProject(providerId, projectId)) {
|
|
455
|
-
return true;
|
|
456
|
-
}
|
|
457
|
-
return ProviderKeysDB.findByProvider(providerId) !== null;
|
|
458
|
-
},
|
|
459
|
-
|
|
460
|
-
// Get all configured providers with their status (without exposing keys)
|
|
461
|
-
getAll(): Array<{
|
|
462
|
-
id: string;
|
|
463
|
-
provider_id: string;
|
|
464
|
-
key_hint: string;
|
|
465
|
-
is_valid: boolean;
|
|
466
|
-
last_tested_at: string | null;
|
|
467
|
-
created_at: string;
|
|
468
|
-
project_id: string | null;
|
|
469
|
-
name: string | null;
|
|
470
|
-
}> {
|
|
471
|
-
return ProviderKeysDB.findAll().map(k => ({
|
|
472
|
-
id: k.id,
|
|
473
|
-
provider_id: k.provider_id,
|
|
474
|
-
key_hint: k.key_hint,
|
|
475
|
-
is_valid: k.is_valid,
|
|
476
|
-
last_tested_at: k.last_tested_at,
|
|
477
|
-
created_at: k.created_at,
|
|
478
|
-
project_id: k.project_id,
|
|
479
|
-
name: k.name,
|
|
480
|
-
}));
|
|
481
|
-
},
|
|
482
|
-
|
|
483
|
-
// Get all keys for a specific provider
|
|
484
|
-
getAllByProvider(providerId: string): Array<{
|
|
485
|
-
id: string;
|
|
486
|
-
provider_id: string;
|
|
487
|
-
key_hint: string;
|
|
488
|
-
is_valid: boolean;
|
|
489
|
-
last_tested_at: string | null;
|
|
490
|
-
created_at: string;
|
|
491
|
-
project_id: string | null;
|
|
492
|
-
name: string | null;
|
|
493
|
-
}> {
|
|
494
|
-
return ProviderKeysDB.findAllByProvider(providerId).map(k => ({
|
|
495
|
-
id: k.id,
|
|
496
|
-
provider_id: k.provider_id,
|
|
497
|
-
key_hint: k.key_hint,
|
|
498
|
-
is_valid: k.is_valid,
|
|
499
|
-
last_tested_at: k.last_tested_at,
|
|
500
|
-
created_at: k.created_at,
|
|
501
|
-
project_id: k.project_id,
|
|
502
|
-
name: k.name,
|
|
503
|
-
}));
|
|
504
|
-
},
|
|
505
|
-
|
|
506
|
-
// Delete a provider key (global)
|
|
507
|
-
delete(providerId: string): boolean {
|
|
508
|
-
return ProviderKeysDB.delete(providerId);
|
|
509
|
-
},
|
|
510
|
-
|
|
511
|
-
// Delete a provider key by ID
|
|
512
|
-
deleteById(id: string): boolean {
|
|
513
|
-
return ProviderKeysDB.deleteById(id);
|
|
514
|
-
},
|
|
515
|
-
|
|
516
|
-
// Test if an API key is valid by making a test request
|
|
517
|
-
// TODO: Implement actual API testing per provider (Anthropic needs POST, others GET)
|
|
518
|
-
async test(providerId: string, apiKey?: string): Promise<{ valid: boolean; error?: string }> {
|
|
519
|
-
const key = apiKey || this.getDecrypted(providerId);
|
|
520
|
-
if (!key) {
|
|
521
|
-
return { valid: false, error: "No API key available" };
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
const provider = PROVIDERS[providerId as ProviderId];
|
|
525
|
-
if (!provider) {
|
|
526
|
-
return { valid: false, error: "Unknown provider" };
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// For now, just validate format - actual API testing to be implemented later
|
|
530
|
-
const validation = validateKeyFormat(providerId, key);
|
|
531
|
-
if (!validation.valid) {
|
|
532
|
-
return { valid: false, error: validation.error };
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
return { valid: true };
|
|
536
|
-
},
|
|
537
|
-
|
|
538
|
-
// Get list of provider IDs that have valid keys (global only)
|
|
539
|
-
getConfiguredProviders(): string[] {
|
|
540
|
-
return ProviderKeysDB.getConfiguredProviders();
|
|
541
|
-
},
|
|
542
|
-
|
|
543
|
-
// Get list of all provider IDs that have keys (including project-scoped)
|
|
544
|
-
getAllConfiguredProviders(): string[] {
|
|
545
|
-
return ProviderKeysDB.getAllConfiguredProviders();
|
|
546
|
-
},
|
|
547
|
-
};
|
|
548
|
-
|
|
549
|
-
// Onboarding status management
|
|
550
|
-
export const Onboarding = {
|
|
551
|
-
isComplete(): boolean {
|
|
552
|
-
return SettingsDB.get("onboarding_completed") === "true";
|
|
553
|
-
},
|
|
554
|
-
|
|
555
|
-
complete(): void {
|
|
556
|
-
SettingsDB.set("onboarding_completed", "true");
|
|
557
|
-
},
|
|
558
|
-
|
|
559
|
-
reset(): void {
|
|
560
|
-
SettingsDB.delete("onboarding_completed");
|
|
561
|
-
},
|
|
562
|
-
|
|
563
|
-
getStatus(): {
|
|
564
|
-
completed: boolean;
|
|
565
|
-
providers_configured: string[];
|
|
566
|
-
has_any_keys: boolean;
|
|
567
|
-
} {
|
|
568
|
-
return {
|
|
569
|
-
completed: this.isComplete(),
|
|
570
|
-
providers_configured: ProviderKeys.getConfiguredProviders(),
|
|
571
|
-
has_any_keys: ProviderKeysDB.hasAnyKeys(),
|
|
572
|
-
};
|
|
573
|
-
},
|
|
574
|
-
};
|
|
575
|
-
|
|
576
|
-
// Get provider list with configuration status for frontend
|
|
577
|
-
export function getProvidersWithStatus() {
|
|
578
|
-
const configuredProviders = new Set(ProviderKeysDB.getAllConfiguredProviders());
|
|
579
|
-
const keyStatuses = new Map(
|
|
580
|
-
ProviderKeys.getAll().map(k => [k.provider_id, k])
|
|
581
|
-
);
|
|
582
|
-
|
|
583
|
-
return Object.values(PROVIDERS).map(provider => ({
|
|
584
|
-
id: provider.id,
|
|
585
|
-
name: provider.displayName,
|
|
586
|
-
type: provider.type,
|
|
587
|
-
docsUrl: provider.docsUrl,
|
|
588
|
-
description: "description" in provider ? provider.description : undefined,
|
|
589
|
-
models: provider.models,
|
|
590
|
-
hasKey: configuredProviders.has(provider.id),
|
|
591
|
-
keyHint: keyStatuses.get(provider.id)?.key_hint || null,
|
|
592
|
-
isValid: keyStatuses.get(provider.id)?.is_valid ?? null,
|
|
593
|
-
isLocal: "isLocal" in provider ? provider.isLocal : undefined,
|
|
594
|
-
voiceSubtype: "voiceSubtype" in provider ? provider.voiceSubtype : undefined,
|
|
595
|
-
defaultBaseUrl: "defaultBaseUrl" in provider ? provider.defaultBaseUrl : undefined,
|
|
596
|
-
}));
|
|
597
|
-
}
|