profclaw 0.0.1-beta.3 → 2.0.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/CHANGELOG.md +21 -38
- package/CONTRIBUTING.md +3 -5
- package/README.md +128 -63
- package/dist/chat/execution/tools/index.d.ts +1 -1
- package/dist/chat/execution/tools/index.js +41 -2
- package/dist/chat/providers/slack/index.d.ts +2 -2
- package/dist/cli/commands/models.js +39 -26
- package/dist/cli/commands/onboard.js +64 -79
- package/dist/cli/commands/setup.js +293 -90
- package/dist/cli/index.js +0 -6
- package/dist/cli/providers.d.ts +15 -0
- package/dist/cli/providers.js +41 -0
- package/dist/core/deployment.js +2 -0
- package/dist/providers/ai-sdk.js +26 -6
- package/dist/routes/channels.d.ts +12 -0
- package/dist/routes/channels.js +166 -0
- package/dist/server/route-loader.js +1 -0
- package/dist/server.js +115 -109
- package/package.json +1 -1
- package/skills/git-workflow/SKILL.md +3 -3
- package/ui/dist/assets/{ActivityView-DIPQSJ_d.js → ActivityView-BeshZXmE.js} +1 -1
- package/ui/dist/assets/{AgentList-CqyaYrcq.js → AgentList-QVHeldPi.js} +1 -1
- package/ui/dist/assets/{AnalyticsDashboard-C-mjuGHT.js → AnalyticsDashboard-C9R97dXE.js} +1 -1
- package/ui/dist/assets/{AreaChart-CfYWmbtr.js → AreaChart-B73gaiVQ.js} +1 -1
- package/ui/dist/assets/{CartesianChart-BaQ3It0c.js → CartesianChart-CXYL2R-A.js} +1 -1
- package/ui/dist/assets/{ChatView-DxxQy6pl.js → ChatView-qjZErlrp.js} +1 -1
- package/ui/dist/assets/{CostsDashboard-CDBBcGkg.js → CostsDashboard-O4DCLy1i.js} +1 -1
- package/ui/dist/assets/{EstimateSelect-CDjf5qKl.js → EstimateSelect-1hQf4Osk.js} +1 -1
- package/ui/dist/assets/{FloatingChatbot-CZHjvJIe.js → FloatingChatbot-BZBzrJxd.js} +1 -1
- package/ui/dist/assets/{InviteCodeManagement-DTm-IPTm.js → InviteCodeManagement-LEoGqYeA.js} +1 -1
- package/ui/dist/assets/{ProjectDetail-DlYUcOss.js → ProjectDetail--gPfvATB.js} +1 -1
- package/ui/dist/assets/{ProjectIcon-BMRpnM04.js → ProjectIcon-Chd_ofsw.js} +1 -1
- package/ui/dist/assets/{ProjectList-D85TN0i0.js → ProjectList-BvUfVB6c.js} +1 -1
- package/ui/dist/assets/{Settings-CgPqzUvj.js → Settings-1kaf7VHE.js} +1 -1
- package/ui/dist/assets/{StatusIndicator-yig0uZEA.js → StatusIndicator-pRfkNcdV.js} +1 -1
- package/ui/dist/assets/{SummaryDetail-CwLAfHgJ.js → SummaryDetail-DV3AmONk.js} +1 -1
- package/ui/dist/assets/{SummaryList-BvS5Idnu.js → SummaryList-B6kXiTxL.js} +1 -1
- package/ui/dist/assets/{TaskDetail-zarC1fOt.js → TaskDetail-CV6CzbOS.js} +1 -1
- package/ui/dist/assets/{TaskList-CyJq3ANE.js → TaskList-DL7brQKd.js} +1 -1
- package/ui/dist/assets/{TicketBoard-BlWr3-iH.js → TicketBoard-CrkkFj7C.js} +1 -1
- package/ui/dist/assets/{TicketDetail-DmqWKj2W.js → TicketDetail-hnnYclpD.js} +1 -1
- package/ui/dist/assets/{TicketList-Scj4pMWa.js → TicketList-CsDAyQCL.js} +1 -1
- package/ui/dist/assets/{UserManagement-BH7uG7dw.js → UserManagement-BGFQyTSr.js} +1 -1
- package/ui/dist/assets/{ViewSwitcher-3HzZUdWn.js → ViewSwitcher-CnL0OqA8.js} +1 -1
- package/ui/dist/assets/{alert-dialog-DWPb2IfQ.js → alert-dialog-SKM6Gjz4.js} +1 -1
- package/ui/dist/assets/{archive-CGck7gxR.js → archive-BsLa7brF.js} +1 -1
- package/ui/dist/assets/{badge-DEmc3Z_l.js → badge-CVHH1a-v.js} +1 -1
- package/ui/dist/assets/{brain-CfFdLVqb.js → brain-6o_RHVpe.js} +1 -1
- package/ui/dist/assets/{bug-DqSGPUUE.js → bug-CmZI7jqM.js} +1 -1
- package/ui/dist/assets/{calendar-BuZ4zbPW.js → calendar-Bf0t2B82.js} +1 -1
- package/ui/dist/assets/{chevron-up-DcJ4LL_N.js → chevron-up-CoUsOvZj.js} +1 -1
- package/ui/dist/assets/{circle-x-C78PNZjF.js → circle-x-Dgw11LgT.js} +1 -1
- package/ui/dist/assets/{constants-DhDjZe4P.js → constants-Q5Zivl-a.js} +1 -1
- package/ui/dist/assets/{cpu-Ck6AoG8c.js → cpu-DiPMQICV.js} +1 -1
- package/ui/dist/assets/{database-CA2w8Lvt.js → database-BwTfupDi.js} +1 -1
- package/ui/dist/assets/{dialog-BOdGWhgE.js → dialog-BUqN9Psj.js} +1 -1
- package/ui/dist/assets/{ellipsis-FhHKRbfl.js → ellipsis-UJx4Xnf6.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-CO0UqE4-.js → ellipsis-vertical-DoULYEKn.js} +1 -1
- package/ui/dist/assets/{file-code-ChnhYYj1.js → file-code-B2UrJLwi.js} +1 -1
- package/ui/dist/assets/{folder-open-CHwA1-ve.js → folder-open-BJi577JH.js} +1 -1
- package/ui/dist/assets/{funnel-ByEjRFNB.js → funnel-PkaD_HSR.js} +1 -1
- package/ui/dist/assets/{git-branch-GTOPQgU4.js → git-branch-C_K30am0.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-F5M84Kut.js → git-commit-horizontal-IT6ecxWQ.js} +1 -1
- package/ui/dist/assets/{globe-CQWfr7hT.js → globe-f-jjCa_g.js} +1 -1
- package/ui/dist/assets/{hash-nKC9gtLg.js → hash-DNEv8Elo.js} +1 -1
- package/ui/dist/assets/{history-DfFSA9xJ.js → history-BQSBo_1Q.js} +1 -1
- package/ui/dist/assets/{index-DHGvP9mp.js → index-BUmnwPQr.js} +1 -1
- package/ui/dist/assets/{index-Z4-RtZcs.js → index-BfF5G4Cw.js} +1 -1
- package/ui/dist/assets/{index-DeI8lKRR.js → index-C8N375c2.js} +1 -1
- package/ui/dist/assets/index-CuxnqVVz.css +1 -0
- package/ui/dist/assets/{index-Ca3vk7Gq.js → index-CzMM3QOk.js} +1 -1
- package/ui/dist/assets/{index--JkIxVXb.js → index-lJlNPFVJ.js} +3 -3
- package/ui/dist/assets/{index-a4Fxq0Hb.js → index-nS3EErDg.js} +1 -1
- package/ui/dist/assets/{layers-DFeLExSa.js → layers-jFqVrWMD.js} +1 -1
- package/ui/dist/assets/{layout-dashboard-WmgjMhWF.js → layout-dashboard-CcKt1hXw.js} +1 -1
- package/ui/dist/assets/{lightbulb-Bo8hEr7B.js → lightbulb-Jhp7FvbU.js} +1 -1
- package/ui/dist/assets/{link-2-YqrpQXBH.js → link-2-DdO7ostF.js} +1 -1
- package/ui/dist/assets/{markdown-renderer-Croje6Xe.js → markdown-renderer-n1ToC4XQ.js} +1 -1
- package/ui/dist/assets/{message-square-CD0H5hot.js → message-square-CBgH65X7.js} +1 -1
- package/ui/dist/assets/{pencil-DpFnj5dn.js → pencil-CYXCEPQh.js} +1 -1
- package/ui/dist/assets/{play-DVgea_jT.js → play-d1ONaH0-.js} +1 -1
- package/ui/dist/assets/{popover-JXecfWG5.js → popover-CrmZgoWu.js} +1 -1
- package/ui/dist/assets/{progress-C1ghf1Fu.js → progress-uv4SPkL5.js} +1 -1
- package/ui/dist/assets/{rocket-BFxPYGx9.js → rocket-DhvUetsk.js} +1 -1
- package/ui/dist/assets/{select-MADP8m6Q.js → select-CeQ8AHGy.js} +1 -1
- package/ui/dist/assets/{send-eYnW_7n-.js → send-P0r5D7td.js} +1 -1
- package/ui/dist/assets/{server-CPMaysH8.js → server-CVHTZB72.js} +1 -1
- package/ui/dist/assets/{settings-2-scXUOuE_.js → settings-2-ocj5uHGx.js} +1 -1
- package/ui/dist/assets/{sheet-r6NSOxi-.js → sheet-DuQExSho.js} +1 -1
- package/ui/dist/assets/{shield-check-PEr7nmVw.js → shield-check-DfVdE34l.js} +1 -1
- package/ui/dist/assets/{shield-off-CLtXio62.js → shield-off-8l0J6R-8.js} +1 -1
- package/ui/dist/assets/{skeleton-C9oEzNlU.js → skeleton-TFiFJ3nB.js} +1 -1
- package/ui/dist/assets/{smartphone-DusFfY0U.js → smartphone-77_g3SQn.js} +1 -1
- package/ui/dist/assets/{square-e1yxB2eR.js → square-Ckzsr3Rn.js} +1 -1
- package/ui/dist/assets/{switch-tNs0n-kz.js → switch-CAePkd6k.js} +1 -1
- package/ui/dist/assets/{table-CXxtLicg.js → table-ZjAZ7hkt.js} +1 -1
- package/ui/dist/assets/{tag-tAwMmQ9G.js → tag-C35mgoEv.js} +1 -1
- package/ui/dist/assets/{textarea-BjiEeIWh.js → textarea-DsVPnSgR.js} +1 -1
- package/ui/dist/assets/{timer-Vel1N3RP.js → timer-DHJBS2w1.js} +1 -1
- package/ui/dist/assets/{tooltip-ZMwtfr1J.js → tooltip-BYmQ331W.js} +1 -1
- package/ui/dist/assets/{trash-2-eM-CNwsZ.js → trash-2-keO5tKPE.js} +1 -1
- package/ui/dist/assets/{trending-up-BGafmjRo.js → trending-up-BBv8KbrY.js} +1 -1
- package/ui/dist/assets/{wand-sparkles-DPvcd9Pi.js → wand-sparkles-BusQ52ZK.js} +1 -1
- package/ui/dist/assets/{wrench-B8s3zYVV.js → wrench-02YaOSiK.js} +1 -1
- package/ui/dist/index.html +2 -2
- package/dist/chat/auto-reply.d.ts +0 -90
- package/dist/chat/auto-reply.js +0 -272
- package/dist/chat/execution/pty.d.ts +0 -92
- package/dist/chat/execution/pty.js +0 -285
- package/dist/chat/execution/tools/glinr-ops.d.ts +0 -202
- package/dist/chat/execution/tools/glinr-ops.js +0 -694
- package/dist/cli/commands/browser.d.ts +0 -3
- package/dist/cli/commands/browser.js +0 -138
- package/dist/cli/commands/canvas.d.ts +0 -3
- package/dist/cli/commands/canvas.js +0 -155
- package/dist/cli/commands/nodes.d.ts +0 -3
- package/dist/cli/commands/nodes.js +0 -193
- package/dist/diagnostics/exporters.d.ts +0 -21
- package/dist/diagnostics/exporters.js +0 -138
- package/dist/diagnostics/index.d.ts +0 -10
- package/dist/diagnostics/index.js +0 -9
- package/dist/diagnostics/middleware.d.ts +0 -12
- package/dist/diagnostics/middleware.js +0 -58
- package/dist/diagnostics/tracer.d.ts +0 -133
- package/dist/diagnostics/tracer.js +0 -257
- package/dist/discovery/index.d.ts +0 -8
- package/dist/discovery/index.js +0 -7
- package/dist/discovery/mdns.d.ts +0 -40
- package/dist/discovery/mdns.js +0 -249
- package/dist/plugins/registry.d.ts +0 -122
- package/dist/plugins/registry.js +0 -352
- package/dist/plugins/sandbox.d.ts +0 -77
- package/dist/plugins/sandbox.js +0 -287
- package/dist/plugins/search/brave.d.ts +0 -9
- package/dist/plugins/search/brave.js +0 -157
- package/dist/plugins/search/duckduckgo.d.ts +0 -9
- package/dist/plugins/search/duckduckgo.js +0 -171
- package/dist/plugins/search/index.d.ts +0 -13
- package/dist/plugins/search/index.js +0 -23
- package/dist/plugins/search/searxng.d.ts +0 -9
- package/dist/plugins/search/searxng.js +0 -170
- package/dist/plugins/search/serper.d.ts +0 -9
- package/dist/plugins/search/serper.js +0 -135
- package/dist/plugins/search/tavily.d.ts +0 -9
- package/dist/plugins/search/tavily.js +0 -146
- package/dist/providers/adapters/anthropic.d.ts +0 -26
- package/dist/providers/adapters/anthropic.js +0 -306
- package/dist/providers/adapters/base.d.ts +0 -53
- package/dist/providers/adapters/base.js +0 -99
- package/dist/providers/adapters/ollama.d.ts +0 -30
- package/dist/providers/adapters/ollama.js +0 -292
- package/dist/utils/ai-cache.d.ts +0 -72
- package/dist/utils/ai-cache.js +0 -204
- package/dist/utils/file-lock.d.ts +0 -85
- package/dist/utils/file-lock.js +0 -204
- package/ui/dist/assets/index-WclMPci1.css +0 -1
|
@@ -11,14 +11,26 @@
|
|
|
11
11
|
import { Command } from 'commander';
|
|
12
12
|
import chalk from 'chalk';
|
|
13
13
|
import figlet from 'figlet';
|
|
14
|
-
import { select, input, password as passwordPrompt, confirm } from '@inquirer/prompts';
|
|
14
|
+
import { select, search, input, password as passwordPrompt, confirm, Separator } from '@inquirer/prompts';
|
|
15
15
|
import { randomUUID } from 'crypto';
|
|
16
16
|
import { eq } from 'drizzle-orm';
|
|
17
|
-
import {
|
|
17
|
+
import { spawn } from 'child_process';
|
|
18
|
+
import { existsSync, mkdirSync, openSync } from 'node:fs';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { createServer } from 'net';
|
|
21
|
+
import { initStorage, getDb, saveProviderConfig, loadAllProviderConfigs } from '../../storage/index.js';
|
|
18
22
|
import { users, inviteCodes } from '../../storage/schema.js';
|
|
23
|
+
import { PROVIDER_CATALOG } from '../providers.js';
|
|
19
24
|
import { hashPassword, validatePasswordStrength, generateRecoveryCodes, hashRecoveryCodes, generateInviteCode, hashInviteCode, } from '../../auth/password.js';
|
|
20
25
|
import { updateSettings } from '../../settings/index.js';
|
|
21
26
|
import { success, error, info, warn, spinner } from '../utils/output.js';
|
|
27
|
+
/** Render a step header with progress bar. */
|
|
28
|
+
function stepHeader(step, total, title) {
|
|
29
|
+
const barLen = 20;
|
|
30
|
+
const filled = Math.round((step / total) * barLen);
|
|
31
|
+
const bar = chalk.cyan('━'.repeat(filled)) + chalk.dim('━'.repeat(barLen - filled));
|
|
32
|
+
console.log(`\n ${bar} ${chalk.dim(`${step}/${total}`)} ${chalk.bold.white(title)}\n`);
|
|
33
|
+
}
|
|
22
34
|
// Helpers
|
|
23
35
|
function showBanner() {
|
|
24
36
|
const banner = figlet.textSync('profClaw', {
|
|
@@ -122,32 +134,46 @@ function hasEnvKey(key) {
|
|
|
122
134
|
return !!val && val !== '' && !val.startsWith('sk-ant-xxxx') && !val.startsWith('sk-xxxx');
|
|
123
135
|
}
|
|
124
136
|
// Step 1: System Check
|
|
137
|
+
async function detectConfiguredProvider() {
|
|
138
|
+
// Check env vars first
|
|
139
|
+
for (const p of PROVIDER_CATALOG) {
|
|
140
|
+
if (hasEnvKey(p.envVar))
|
|
141
|
+
return p.name;
|
|
142
|
+
}
|
|
143
|
+
// Check database (saved via saveProviderConfig)
|
|
144
|
+
try {
|
|
145
|
+
const saved = await loadAllProviderConfigs();
|
|
146
|
+
const enabled = saved.find(s => s.enabled);
|
|
147
|
+
if (enabled) {
|
|
148
|
+
const match = PROVIDER_CATALOG.find(p => p.key === enabled.type);
|
|
149
|
+
return match ? `${match.name} (saved)` : enabled.type;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch { /* db not ready yet */ }
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
125
155
|
async function stepSystemCheck(db) {
|
|
126
|
-
console.log(chalk.bold.white('\n Step 1: System Check\n'));
|
|
127
156
|
const spin = spinner('Checking system...');
|
|
128
157
|
spin.start();
|
|
129
158
|
const redisOk = await checkRedis();
|
|
130
159
|
const hasAdmin = await checkAdminExists(db);
|
|
131
|
-
const
|
|
132
|
-
const
|
|
160
|
+
const providerName = await detectConfiguredProvider();
|
|
161
|
+
const hasProvider = !!providerName;
|
|
133
162
|
spin.stop();
|
|
134
|
-
const mark = (ok) => (ok ? chalk.green('
|
|
163
|
+
const mark = (ok) => (ok ? chalk.green(' \u2713') : chalk.red(' \u2717'));
|
|
135
164
|
console.log(`${mark(redisOk)} Redis: ${redisOk ? 'connected' : 'not reachable'}`);
|
|
136
165
|
console.log(`${mark(hasAdmin)} Admin account: ${hasAdmin ? 'exists' : 'not created'}`);
|
|
137
|
-
console.log(`${mark(
|
|
138
|
-
hasOpenAIKey ? 'OpenAI key found' :
|
|
139
|
-
'not configured'}`);
|
|
166
|
+
console.log(`${mark(hasProvider)} AI provider: ${providerName || 'not configured'}`);
|
|
140
167
|
if (!redisOk) {
|
|
141
168
|
warn('Redis is required for task processing.');
|
|
142
169
|
info('Start Redis: docker compose up redis -d');
|
|
143
170
|
}
|
|
144
|
-
return { redisOk, hasAdmin,
|
|
171
|
+
return { redisOk, hasAdmin, hasProvider, providerName };
|
|
145
172
|
}
|
|
146
173
|
// Step 2: AI Provider
|
|
147
174
|
async function stepAiProvider(status) {
|
|
148
|
-
if (status.
|
|
149
|
-
|
|
150
|
-
info(`AI provider already configured (${provider} from env).`);
|
|
175
|
+
if (status.hasProvider) {
|
|
176
|
+
info(`AI provider already configured (${status.providerName}).`);
|
|
151
177
|
try {
|
|
152
178
|
const reconfigure = await confirm({
|
|
153
179
|
message: 'Reconfigure AI provider?',
|
|
@@ -155,22 +181,63 @@ async function stepAiProvider(status) {
|
|
|
155
181
|
theme,
|
|
156
182
|
});
|
|
157
183
|
if (!reconfigure)
|
|
158
|
-
return '
|
|
184
|
+
return status.providerName || 'configured';
|
|
159
185
|
}
|
|
160
186
|
catch {
|
|
161
|
-
return '
|
|
187
|
+
return status.providerName || 'configured';
|
|
162
188
|
}
|
|
163
189
|
}
|
|
190
|
+
// Detect which providers already have keys
|
|
191
|
+
const detected = new Set();
|
|
192
|
+
for (const p of PROVIDER_CATALOG) {
|
|
193
|
+
if (process.env[p.envVar])
|
|
194
|
+
detected.add(p.key);
|
|
195
|
+
}
|
|
196
|
+
// Check Ollama service
|
|
197
|
+
const ollamaRunning = await checkOllama(process.env.OLLAMA_BASE_URL || 'http://localhost:11434');
|
|
198
|
+
if (ollamaRunning)
|
|
199
|
+
detected.add('ollama');
|
|
164
200
|
let choice;
|
|
165
201
|
try {
|
|
166
|
-
choice = await
|
|
167
|
-
message: 'Select AI
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
202
|
+
choice = await search({
|
|
203
|
+
message: 'Select AI provider (type to filter, arrows to navigate)',
|
|
204
|
+
pageSize: 15,
|
|
205
|
+
source: (term) => {
|
|
206
|
+
const results = [];
|
|
207
|
+
const filter = (term || '').toLowerCase();
|
|
208
|
+
let lastCategory = '';
|
|
209
|
+
for (const p of PROVIDER_CATALOG) {
|
|
210
|
+
if (filter && ![p.name, p.key, p.models, p.category, p.tag]
|
|
211
|
+
.some(s => s.toLowerCase().includes(filter))) {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (p.category !== lastCategory) {
|
|
215
|
+
if (results.length > 0)
|
|
216
|
+
results.push(new Separator());
|
|
217
|
+
results.push(new Separator(chalk.bold.cyan(` ${p.category} `)));
|
|
218
|
+
lastCategory = p.category;
|
|
219
|
+
}
|
|
220
|
+
const det = detected.has(p.key) ? chalk.green(' *') : '';
|
|
221
|
+
const ollamaTag = p.key === 'ollama' && ollamaRunning ? 'detected' : p.tag;
|
|
222
|
+
const tag = ollamaTag ? ` ${chalk.dim(`[${ollamaTag}]`)}` : '';
|
|
223
|
+
results.push({
|
|
224
|
+
name: `${p.name.padEnd(16)} ${chalk.dim(p.models)}${tag}${det}`,
|
|
225
|
+
value: p.key,
|
|
226
|
+
description: p.envVar,
|
|
227
|
+
short: p.name,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if (!filter || 'skip'.includes(filter)) {
|
|
231
|
+
results.push(new Separator());
|
|
232
|
+
results.push({
|
|
233
|
+
name: chalk.dim('Skip for now'),
|
|
234
|
+
value: 'skip',
|
|
235
|
+
description: 'Configure later in Settings',
|
|
236
|
+
short: 'Skip',
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return results;
|
|
240
|
+
},
|
|
174
241
|
theme,
|
|
175
242
|
});
|
|
176
243
|
}
|
|
@@ -181,58 +248,61 @@ async function stepAiProvider(status) {
|
|
|
181
248
|
info('AI provider skipped. You can configure it later in Settings.');
|
|
182
249
|
return 'skip';
|
|
183
250
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
251
|
+
const chosen = PROVIDER_CATALOG.find(p => p.key === choice);
|
|
252
|
+
if (!chosen)
|
|
253
|
+
return 'skip';
|
|
254
|
+
console.log(`\n ${chalk.bold(chosen.name)} selected`);
|
|
255
|
+
console.log(chalk.dim(` Env var: ${chosen.envVar}`));
|
|
256
|
+
// Ollama special case
|
|
257
|
+
if (chosen.key === 'ollama') {
|
|
258
|
+
const ollamaUrl = process.env.OLLAMA_BASE_URL || 'http://localhost:11434';
|
|
259
|
+
const spin = spinner(`Checking Ollama at ${ollamaUrl}...`);
|
|
260
|
+
spin.start();
|
|
261
|
+
const ollamaOk = await checkOllama(ollamaUrl);
|
|
262
|
+
spin.stop();
|
|
263
|
+
if (ollamaOk) {
|
|
264
|
+
success(`Ollama reachable at ${ollamaUrl}`);
|
|
265
|
+
await saveProviderConfig({ type: 'ollama', apiKey: ollamaUrl, enabled: true });
|
|
266
|
+
await updateSettings({
|
|
267
|
+
integrations: { ollamaEndpoint: ollamaUrl },
|
|
268
|
+
plugins: { ollama: { enabled: true, autoStart: false } },
|
|
269
|
+
});
|
|
270
|
+
success('Ollama provider configured.');
|
|
194
271
|
}
|
|
195
|
-
|
|
196
|
-
|
|
272
|
+
else {
|
|
273
|
+
warn(`Ollama not reachable at ${ollamaUrl}`);
|
|
274
|
+
info('Start Ollama: docker compose --profile ai up -d');
|
|
275
|
+
info('Then re-run: profclaw setup');
|
|
276
|
+
await saveProviderConfig({ type: 'ollama', apiKey: ollamaUrl, enabled: true });
|
|
197
277
|
}
|
|
278
|
+
return 'ollama';
|
|
198
279
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
warn('No key provided, skipping.');
|
|
204
|
-
return 'skip';
|
|
205
|
-
}
|
|
206
|
-
await saveProviderConfig({ type: 'openai', apiKey, enabled: true });
|
|
207
|
-
success('OpenAI provider configured.');
|
|
208
|
-
return 'openai';
|
|
209
|
-
}
|
|
210
|
-
catch {
|
|
211
|
-
return 'skip';
|
|
212
|
-
}
|
|
280
|
+
// Already detected
|
|
281
|
+
if (detected.has(chosen.key)) {
|
|
282
|
+
success(`${chosen.name} already configured from ${chosen.envVar}`);
|
|
283
|
+
return chosen.key;
|
|
213
284
|
}
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const ollamaOk = await checkOllama(ollamaUrl);
|
|
219
|
-
spin.stop();
|
|
220
|
-
if (ollamaOk) {
|
|
221
|
-
success(`Ollama reachable at ${ollamaUrl}`);
|
|
222
|
-
await saveProviderConfig({ type: 'ollama', apiKey: ollamaUrl, enabled: true });
|
|
223
|
-
await updateSettings({
|
|
224
|
-
integrations: { ollamaEndpoint: ollamaUrl },
|
|
225
|
-
plugins: { ollama: { enabled: true, autoStart: false } },
|
|
226
|
-
});
|
|
227
|
-
success('Ollama provider configured.');
|
|
285
|
+
// Prompt for API key
|
|
286
|
+
let apiKey;
|
|
287
|
+
try {
|
|
288
|
+
apiKey = await input({ message: chosen.envVar, theme });
|
|
228
289
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
290
|
+
catch {
|
|
291
|
+
return 'skip';
|
|
292
|
+
}
|
|
293
|
+
if (!apiKey) {
|
|
294
|
+
warn('No key provided, skipping.');
|
|
295
|
+
return 'skip';
|
|
296
|
+
}
|
|
297
|
+
try {
|
|
298
|
+
await saveProviderConfig({ type: chosen.key, apiKey, enabled: true });
|
|
299
|
+
success(`${chosen.name} provider configured.`);
|
|
300
|
+
return chosen.key;
|
|
301
|
+
}
|
|
302
|
+
catch (err) {
|
|
303
|
+
error(`Failed to save: ${err instanceof Error ? err.message : 'unknown'}`);
|
|
304
|
+
return 'skip';
|
|
234
305
|
}
|
|
235
|
-
return 'ollama';
|
|
236
306
|
}
|
|
237
307
|
// Step 3: Admin Account
|
|
238
308
|
async function createAdminUser(db, name, email, password) {
|
|
@@ -267,7 +337,6 @@ async function stepAdminAccount(db) {
|
|
|
267
337
|
error('Database not available. Cannot create admin account.');
|
|
268
338
|
return null;
|
|
269
339
|
}
|
|
270
|
-
console.log(chalk.bold.white('\n Step 3: Admin Account\n'));
|
|
271
340
|
const existingAdmins = await getExistingAdmins(db);
|
|
272
341
|
if (existingAdmins.length > 0) {
|
|
273
342
|
console.log(chalk.dim(' Existing admin accounts:'));
|
|
@@ -414,7 +483,6 @@ async function stepAdminAccount(db) {
|
|
|
414
483
|
}
|
|
415
484
|
// Step 4: Registration Mode
|
|
416
485
|
async function stepRegistrationMode(db) {
|
|
417
|
-
console.log(chalk.bold.white('\n Step 4: Registration Mode\n'));
|
|
418
486
|
let mode;
|
|
419
487
|
try {
|
|
420
488
|
mode = await select({
|
|
@@ -472,7 +540,6 @@ async function stepRegistrationMode(db) {
|
|
|
472
540
|
}
|
|
473
541
|
// Step 5: GitHub OAuth (optional)
|
|
474
542
|
async function stepGitHubOAuth() {
|
|
475
|
-
console.log(chalk.bold.white('\n Step 5: GitHub OAuth (Optional)\n'));
|
|
476
543
|
let configure;
|
|
477
544
|
try {
|
|
478
545
|
configure = await confirm({
|
|
@@ -519,19 +586,111 @@ async function stepGitHubOAuth() {
|
|
|
519
586
|
return true;
|
|
520
587
|
}
|
|
521
588
|
// Step 6: Summary
|
|
522
|
-
function
|
|
523
|
-
|
|
589
|
+
function checkPortAvailable(port) {
|
|
590
|
+
return new Promise((resolve) => {
|
|
591
|
+
const server = createServer();
|
|
592
|
+
server.once('error', () => resolve(false));
|
|
593
|
+
server.once('listening', () => { server.close(); resolve(true); });
|
|
594
|
+
server.listen(port);
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
async function showSummaryAndOffer(results) {
|
|
598
|
+
const port = parseInt(process.env.PORT || '3000', 10);
|
|
524
599
|
console.log(chalk.bold.white('\n Setup Complete!\n'));
|
|
525
|
-
console.log(' ' + '
|
|
526
|
-
const mark = (ok) => (ok ? chalk.green('
|
|
600
|
+
console.log(' ' + '\u2500'.repeat(44));
|
|
601
|
+
const mark = (ok) => (ok ? chalk.green('\u2713') : chalk.yellow('\u2717'));
|
|
527
602
|
console.log(` ${mark(results.redisOk)} Redis: ${results.redisOk ? 'connected' : 'not connected'}`);
|
|
528
603
|
console.log(` ${mark(results.aiProvider !== 'skip')} AI: ${results.aiProvider === 'skip' ? 'not configured' : results.aiProvider}`);
|
|
529
604
|
console.log(` ${mark(!!results.adminEmail)} Admin: ${results.adminEmail || 'not created'}`);
|
|
530
605
|
console.log(` ${mark(true)} Registration: ${results.registrationMode}${results.inviteCodes.length ? ` (${results.inviteCodes.length} codes)` : ''}`);
|
|
531
606
|
console.log(` ${mark(results.githubOAuth)} GitHub OAuth: ${results.githubOAuth ? 'configured' : 'skipped'}`);
|
|
532
|
-
console.log(' ' + '
|
|
607
|
+
console.log(' ' + '\u2500'.repeat(44));
|
|
608
|
+
// Check if server is already running
|
|
609
|
+
const portFree = await checkPortAvailable(port);
|
|
610
|
+
const serverRunning = !portFree;
|
|
611
|
+
if (serverRunning) {
|
|
612
|
+
// Server already running - just show the URL
|
|
613
|
+
console.log('');
|
|
614
|
+
success(`Server already running on port ${port}`);
|
|
615
|
+
console.log(`\n ${chalk.cyan.bold(`http://localhost:${port}`)}\n`);
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
// Offer to start the server
|
|
619
|
+
console.log('');
|
|
620
|
+
let startServer = false;
|
|
621
|
+
try {
|
|
622
|
+
startServer = await confirm({
|
|
623
|
+
message: 'Start the server now?',
|
|
624
|
+
default: true,
|
|
625
|
+
theme,
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
catch { /* Ctrl+C */ }
|
|
629
|
+
if (startServer) {
|
|
630
|
+
console.log('');
|
|
631
|
+
const startSpin = spinner('Starting server...');
|
|
632
|
+
startSpin.start();
|
|
633
|
+
// Determine runtime
|
|
634
|
+
const distPath = 'dist/server.js';
|
|
635
|
+
const useCompiled = existsSync(distPath);
|
|
636
|
+
const cmd = useCompiled ? 'node' : 'npx';
|
|
637
|
+
const args = useCompiled ? [distPath] : ['tsx', 'src/server.ts'];
|
|
638
|
+
// Redirect server output to log file (keep terminal clean)
|
|
639
|
+
const logDir = join(process.cwd(), 'data');
|
|
640
|
+
if (!existsSync(logDir))
|
|
641
|
+
mkdirSync(logDir, { recursive: true });
|
|
642
|
+
const logPath = join(logDir, 'server.log');
|
|
643
|
+
const logFd = openSync(logPath, 'a');
|
|
644
|
+
const child = spawn(cmd, args, {
|
|
645
|
+
stdio: ['ignore', logFd, logFd],
|
|
646
|
+
detached: true,
|
|
647
|
+
env: { ...process.env, PORT: String(port) },
|
|
648
|
+
});
|
|
649
|
+
child.unref();
|
|
650
|
+
// Wait for server to start, polling health check
|
|
651
|
+
let serverOk = false;
|
|
652
|
+
for (let i = 0; i < 5; i++) {
|
|
653
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
654
|
+
try {
|
|
655
|
+
const res = await fetch(`http://localhost:${port}/health`, {
|
|
656
|
+
signal: AbortSignal.timeout(2000),
|
|
657
|
+
});
|
|
658
|
+
if (res.ok) {
|
|
659
|
+
serverOk = true;
|
|
660
|
+
break;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
catch { /* not ready yet */ }
|
|
664
|
+
}
|
|
665
|
+
startSpin.stop();
|
|
666
|
+
if (serverOk) {
|
|
667
|
+
success(`Server running on port ${port}`);
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
warn('Server starting in background (health check pending)');
|
|
671
|
+
}
|
|
672
|
+
console.log(`\n ${chalk.cyan.bold(`http://localhost:${port}`)}`);
|
|
673
|
+
console.log('');
|
|
674
|
+
console.log(chalk.dim(' Server is running in the background.'));
|
|
675
|
+
console.log(chalk.dim(` Stop: ${chalk.white('profclaw daemon stop')} or ${chalk.white(`kill $(lsof -ti :${port})`)}`));
|
|
676
|
+
console.log(chalk.dim(` Logs: ${chalk.white(`tail -f ${logPath}`)}`));
|
|
677
|
+
console.log(chalk.dim(` Status: ${chalk.white('profclaw doctor')}`));
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
console.log('');
|
|
681
|
+
console.log(` Start later with: ${chalk.cyan.bold('profclaw serve')}`);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
// Always show helpful next steps
|
|
533
685
|
console.log('');
|
|
534
|
-
console.log(
|
|
686
|
+
console.log(chalk.bold.white(' Next Steps'));
|
|
687
|
+
console.log(' ' + '\u2500'.repeat(44));
|
|
688
|
+
console.log(` ${chalk.cyan('profclaw doctor')} Health check (12 tests)`);
|
|
689
|
+
console.log(` ${chalk.cyan('profclaw chat quick')} ${chalk.dim('"hi"')} Chat with AI`);
|
|
690
|
+
console.log(` ${chalk.cyan('profclaw task list')} View agent tasks`);
|
|
691
|
+
console.log(` ${chalk.cyan('profclaw tools list')} Available tools`);
|
|
692
|
+
console.log(` ${chalk.cyan('profclaw provider test')} Test AI provider`);
|
|
693
|
+
console.log(` ${chalk.cyan('profclaw --help')} All commands`);
|
|
535
694
|
console.log('');
|
|
536
695
|
}
|
|
537
696
|
// Non-Interactive Mode
|
|
@@ -657,6 +816,7 @@ export function setupCommand() {
|
|
|
657
816
|
.option('--admin-name <name>', 'Admin display name (non-interactive)')
|
|
658
817
|
.option('--ai-provider <provider>', 'AI provider: anthropic, openai, ollama, skip (non-interactive)')
|
|
659
818
|
.option('--registration-mode <mode>', 'Registration mode: invite, open (non-interactive)')
|
|
819
|
+
.option('--from-onboard', 'Called from onboard wizard (skip AI provider)')
|
|
660
820
|
.action(async (options) => {
|
|
661
821
|
try {
|
|
662
822
|
// Non-interactive mode
|
|
@@ -670,36 +830,79 @@ export function setupCommand() {
|
|
|
670
830
|
});
|
|
671
831
|
return;
|
|
672
832
|
}
|
|
833
|
+
const fromOnboard = !!options.fromOnboard;
|
|
673
834
|
// Interactive mode
|
|
674
|
-
|
|
835
|
+
if (!fromOnboard)
|
|
836
|
+
showBanner();
|
|
837
|
+
// Suppress initialization noise ([INFO] Initializing LibSQL storage, etc.)
|
|
838
|
+
const _origLog = console.log;
|
|
839
|
+
console.log = (...args) => {
|
|
840
|
+
const msg = String(args[0] || '');
|
|
841
|
+
if (msg.includes('[INFO]') || msg.includes('[DEBUG]'))
|
|
842
|
+
return;
|
|
843
|
+
_origLog.apply(console, args);
|
|
844
|
+
};
|
|
675
845
|
const spin = spinner('Initializing...');
|
|
676
846
|
spin.start();
|
|
677
847
|
await initStorage();
|
|
678
848
|
const db = getDb();
|
|
679
849
|
spin.stop();
|
|
850
|
+
// Restore console
|
|
851
|
+
console.log = _origLog;
|
|
680
852
|
if (!db) {
|
|
681
853
|
error('Failed to initialize database.');
|
|
682
854
|
process.exit(1);
|
|
683
855
|
}
|
|
684
|
-
//
|
|
685
|
-
|
|
686
|
-
//
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
//
|
|
856
|
+
// Dynamic step numbering
|
|
857
|
+
// Standalone: 5 steps (System Check, AI Provider, Admin, Registration, GitHub OAuth)
|
|
858
|
+
// From onboard: continues at step 5 of 6 (onboard did 1-4)
|
|
859
|
+
const totalSteps = fromOnboard ? 6 : 5;
|
|
860
|
+
let step = fromOnboard ? 4 : 0;
|
|
861
|
+
// System Check (skip if from onboard - already done)
|
|
862
|
+
let status;
|
|
863
|
+
if (fromOnboard) {
|
|
864
|
+
// Quick silent check
|
|
865
|
+
const redisOk = await checkRedis();
|
|
866
|
+
const hasAdmin = await checkAdminExists(db);
|
|
867
|
+
const providerName = await detectConfiguredProvider();
|
|
868
|
+
status = { redisOk, hasAdmin, hasProvider: !!providerName, providerName };
|
|
869
|
+
}
|
|
870
|
+
else {
|
|
871
|
+
step++;
|
|
872
|
+
stepHeader(step, totalSteps, 'System Check');
|
|
873
|
+
status = await stepSystemCheck(db);
|
|
874
|
+
}
|
|
875
|
+
// AI Provider (skip if from onboard - already configured)
|
|
876
|
+
let aiProvider = 'skip';
|
|
877
|
+
if (!fromOnboard) {
|
|
878
|
+
step++;
|
|
879
|
+
stepHeader(step, totalSteps, 'AI Provider');
|
|
880
|
+
aiProvider = await stepAiProvider(status);
|
|
881
|
+
}
|
|
882
|
+
// Admin Account
|
|
883
|
+
step++;
|
|
884
|
+
stepHeader(step, totalSteps, 'Admin Account');
|
|
690
885
|
const adminEmail = await stepAdminAccount(db);
|
|
691
|
-
//
|
|
886
|
+
// Registration Mode
|
|
887
|
+
step++;
|
|
888
|
+
stepHeader(step, totalSteps, 'Registration Mode');
|
|
692
889
|
const regResult = await stepRegistrationMode(db);
|
|
693
|
-
//
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
890
|
+
// GitHub OAuth (skip if from onboard to keep it shorter)
|
|
891
|
+
let githubOAuth = false;
|
|
892
|
+
if (!fromOnboard) {
|
|
893
|
+
step++;
|
|
894
|
+
stepHeader(step, totalSteps, 'GitHub OAuth');
|
|
895
|
+
githubOAuth = await stepGitHubOAuth();
|
|
896
|
+
}
|
|
897
|
+
// Summary + offer to start server
|
|
898
|
+
await showSummaryAndOffer({
|
|
697
899
|
redisOk: status.redisOk,
|
|
698
900
|
aiProvider,
|
|
699
901
|
adminEmail,
|
|
700
902
|
registrationMode: regResult.mode,
|
|
701
903
|
inviteCodes: regResult.codes,
|
|
702
904
|
githubOAuth,
|
|
905
|
+
fromOnboard,
|
|
703
906
|
});
|
|
704
907
|
}
|
|
705
908
|
catch (err) {
|
package/dist/cli/index.js
CHANGED
|
@@ -23,17 +23,14 @@ import { sessionCommands } from './commands/session.js';
|
|
|
23
23
|
import { doctorCommand } from './commands/doctor.js';
|
|
24
24
|
import { providerCommands } from './commands/provider.js';
|
|
25
25
|
import { mcpCommands } from './commands/mcp.js';
|
|
26
|
-
import { browserCommands } from './commands/browser.js';
|
|
27
26
|
import { devicesCommands } from './commands/devices.js';
|
|
28
27
|
import { daemonCommand } from './commands/daemon.js';
|
|
29
28
|
import { completionCommands } from './commands/completion.js';
|
|
30
|
-
import { canvasCommands } from './commands/canvas.js';
|
|
31
29
|
import { webhooksCommands } from './commands/webhooks.js';
|
|
32
30
|
import { channelsCommands } from './commands/channels.js';
|
|
33
31
|
import { securityCommands } from './commands/security.js';
|
|
34
32
|
import { logsCommand } from './commands/logs.js';
|
|
35
33
|
import { modelsCommands } from './commands/models.js';
|
|
36
|
-
import { nodesCommands } from './commands/nodes.js';
|
|
37
34
|
import { tuiCommand } from './commands/tui.js';
|
|
38
35
|
const VERSION = '2.0.0';
|
|
39
36
|
// ASCII Banner
|
|
@@ -77,17 +74,14 @@ program.addCommand(doctorCommand());
|
|
|
77
74
|
program.addCommand(providerCommands());
|
|
78
75
|
program.addCommand(mcpCommands());
|
|
79
76
|
// Phase 9 - OpenClaw parity commands
|
|
80
|
-
program.addCommand(browserCommands());
|
|
81
77
|
program.addCommand(devicesCommands());
|
|
82
78
|
program.addCommand(daemonCommand());
|
|
83
79
|
program.addCommand(completionCommands());
|
|
84
|
-
program.addCommand(canvasCommands());
|
|
85
80
|
program.addCommand(webhooksCommands());
|
|
86
81
|
program.addCommand(channelsCommands());
|
|
87
82
|
program.addCommand(securityCommands());
|
|
88
83
|
program.addCommand(logsCommand());
|
|
89
84
|
program.addCommand(modelsCommands());
|
|
90
|
-
program.addCommand(nodesCommands());
|
|
91
85
|
program.addCommand(tuiCommand());
|
|
92
86
|
// Default action (no command) - show banner and help
|
|
93
87
|
program.action(() => {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared AI provider catalog for CLI wizards (onboard + setup).
|
|
3
|
+
*/
|
|
4
|
+
export interface ProviderEntry {
|
|
5
|
+
key: string;
|
|
6
|
+
name: string;
|
|
7
|
+
models: string;
|
|
8
|
+
envVar: string;
|
|
9
|
+
category: string;
|
|
10
|
+
tag: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const PROVIDER_CATALOG: ProviderEntry[];
|
|
13
|
+
/** All env var keys used by providers (for .env writing). */
|
|
14
|
+
export declare const PROVIDER_ENV_KEYS: string[];
|
|
15
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared AI provider catalog for CLI wizards (onboard + setup).
|
|
3
|
+
*/
|
|
4
|
+
export const PROVIDER_CATALOG = [
|
|
5
|
+
// Popular
|
|
6
|
+
{ key: 'anthropic', name: 'Anthropic', models: 'Claude 4.x, 3.5 Sonnet', envVar: 'ANTHROPIC_API_KEY', category: 'Popular', tag: 'recommended' },
|
|
7
|
+
{ key: 'openai', name: 'OpenAI', models: 'GPT-4o, o1, o3', envVar: 'OPENAI_API_KEY', category: 'Popular', tag: '' },
|
|
8
|
+
{ key: 'google', name: 'Google AI', models: 'Gemini 2.x, Flash', envVar: 'GOOGLE_GENERATIVE_AI_API_KEY', category: 'Popular', tag: '' },
|
|
9
|
+
{ key: 'ollama', name: 'Ollama', models: 'Llama, Mistral, Qwen', envVar: 'OLLAMA_BASE_URL', category: 'Popular', tag: 'free, local' },
|
|
10
|
+
// Fast Inference
|
|
11
|
+
{ key: 'groq', name: 'Groq', models: 'Llama, Mixtral', envVar: 'GROQ_API_KEY', category: 'Fast Inference', tag: 'fast' },
|
|
12
|
+
{ key: 'cerebras', name: 'Cerebras', models: 'Llama 3.3 70B', envVar: 'CEREBRAS_API_KEY', category: 'Fast Inference', tag: 'fast' },
|
|
13
|
+
{ key: 'fireworks', name: 'Fireworks', models: 'Llama, Mixtral', envVar: 'FIREWORKS_API_KEY', category: 'Fast Inference', tag: '' },
|
|
14
|
+
{ key: 'together', name: 'Together', models: 'Open models', envVar: 'TOGETHER_API_KEY', category: 'Fast Inference', tag: '' },
|
|
15
|
+
// Enterprise
|
|
16
|
+
{ key: 'azure', name: 'Azure OpenAI', models: 'GPT-4o', envVar: 'AZURE_OPENAI_API_KEY', category: 'Enterprise', tag: 'enterprise' },
|
|
17
|
+
{ key: 'bedrock', name: 'AWS Bedrock', models: 'Claude, Titan, Llama', envVar: 'AWS_ACCESS_KEY_ID', category: 'Enterprise', tag: 'enterprise' },
|
|
18
|
+
{ key: 'watsonx', name: 'IBM Watsonx', models: 'Granite, Llama', envVar: 'WATSONX_API_KEY', category: 'Enterprise', tag: 'enterprise' },
|
|
19
|
+
// More Providers
|
|
20
|
+
{ key: 'deepseek', name: 'DeepSeek', models: 'V3, R1 (reasoning)', envVar: 'DEEPSEEK_API_KEY', category: 'More Providers', tag: '' },
|
|
21
|
+
{ key: 'mistral', name: 'Mistral', models: 'Large, Codestral', envVar: 'MISTRAL_API_KEY', category: 'More Providers', tag: '' },
|
|
22
|
+
{ key: 'xai', name: 'xAI', models: 'Grok', envVar: 'XAI_API_KEY', category: 'More Providers', tag: '' },
|
|
23
|
+
{ key: 'perplexity', name: 'Perplexity', models: 'Sonar (search)', envVar: 'PERPLEXITY_API_KEY', category: 'More Providers', tag: 'search' },
|
|
24
|
+
{ key: 'cohere', name: 'Cohere', models: 'Command R+', envVar: 'COHERE_API_KEY', category: 'More Providers', tag: '' },
|
|
25
|
+
// Aggregators
|
|
26
|
+
{ key: 'openrouter', name: 'OpenRouter', models: 'Any model (proxy)', envVar: 'OPENROUTER_API_KEY', category: 'Aggregators', tag: 'multi-model' },
|
|
27
|
+
{ key: 'replicate', name: 'Replicate', models: 'Open-source models', envVar: 'REPLICATE_API_TOKEN', category: 'Aggregators', tag: '' },
|
|
28
|
+
{ key: 'github-models', name: 'GitHub Models', models: 'Azure-backed', envVar: 'GITHUB_TOKEN', category: 'Aggregators', tag: '' },
|
|
29
|
+
{ key: 'huggingface', name: 'HuggingFace', models: 'Inference API', envVar: 'HF_TOKEN', category: 'Aggregators', tag: '' },
|
|
30
|
+
{ key: 'nvidia-nim', name: 'NVIDIA NIM', models: 'Llama, Nemotron', envVar: 'NVIDIA_NIM_API_KEY', category: 'Aggregators', tag: '' },
|
|
31
|
+
// Asia
|
|
32
|
+
{ key: 'zhipu', name: 'Zhipu AI', models: 'GLM-4, GLM-5', envVar: 'ZHIPU_API_KEY', category: 'Asia', tag: '' },
|
|
33
|
+
{ key: 'moonshot', name: 'Moonshot', models: 'Kimi (128K context)', envVar: 'MOONSHOT_API_KEY', category: 'Asia', tag: '' },
|
|
34
|
+
{ key: 'qwen', name: 'Qwen', models: 'Qwen Max, Plus', envVar: 'QWEN_API_KEY', category: 'Asia', tag: '' },
|
|
35
|
+
{ key: 'minimax', name: 'MiniMax', models: 'abab series', envVar: 'MINIMAX_API_KEY', category: 'Asia', tag: '' },
|
|
36
|
+
{ key: 'volcengine', name: 'Volcengine', models: 'Doubao (Bytedance)', envVar: 'VOLCENGINE_API_KEY', category: 'Asia', tag: '' },
|
|
37
|
+
{ key: 'qianfan', name: 'Qianfan', models: 'ERNIE (Baidu)', envVar: 'QIANFAN_API_KEY', category: 'Asia', tag: '' },
|
|
38
|
+
];
|
|
39
|
+
/** All env var keys used by providers (for .env writing). */
|
|
40
|
+
export const PROVIDER_ENV_KEYS = PROVIDER_CATALOG.map(p => p.envVar);
|
|
41
|
+
//# sourceMappingURL=providers.js.map
|