capsule-ai-cli
Version:
The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing
143 lines • 7.63 kB
JavaScript
import React, { useState } from 'react';
import { Box, Text, useInput } from 'ink';
import SelectInput from 'ink-select-input';
import TextInput from 'ink-text-input';
import { configManager } from '../../core/config.js';
import { getProviderColor, createProviderColoredItem } from '../utils/provider-colors.js';
import { providerRegistry } from '../../providers/base.js';
import { ProviderFactory } from '../../providers/factory.js';
export const KeyConfiguration = ({ providers, onClose }) => {
const [selectedProvider, setSelectedProvider] = useState(null);
const [apiKey, setApiKey] = useState('');
const [secondaryKey, setSecondaryKey] = useState('');
const [showSuccess, setShowSuccess] = useState(false);
const [currentInput, setCurrentInput] = useState('apiKey');
const providerColor = getProviderColor(selectedProvider || 'google');
useInput((_input, key) => {
if (key.escape) {
onClose();
}
if (key.tab && selectedProvider === 'google-search') {
setCurrentInput(currentInput === 'apiKey' ? 'searchEngineId' : 'apiKey');
}
});
const handleProviderSelect = (item) => {
setSelectedProvider(item.value);
const config = configManager.getConfig();
if (item.value === 'google-search') {
const existingKey = config.services?.googleSearch?.apiKey || '';
const existingEngineId = config.services?.googleSearch?.searchEngineId || '';
setApiKey(existingKey);
setSecondaryKey(existingEngineId);
}
else if (item.value === 'serp-api') {
const existingKey = config.services?.serpApi?.apiKey || '';
setApiKey(existingKey);
}
else {
const existingKey = config.providers?.[item.value]?.apiKey || '';
setApiKey(existingKey);
}
};
const handleKeySubmit = async () => {
if (!selectedProvider || !apiKey.trim())
return;
const config = configManager.getConfig();
if (selectedProvider === 'google-search') {
if (!config.services)
config.services = {};
if (!config.services.googleSearch)
config.services.googleSearch = {};
config.services.googleSearch.apiKey = apiKey.trim();
if (secondaryKey.trim()) {
config.services.googleSearch.searchEngineId = secondaryKey.trim();
}
configManager.setConfig('services', config.services);
}
else if (selectedProvider === 'serp-api') {
if (!config.services)
config.services = {};
if (!config.services.serpApi)
config.services.serpApi = {};
config.services.serpApi.apiKey = apiKey.trim();
configManager.setConfig('services', config.services);
}
else {
if (!config.providers)
config.providers = {};
if (!config.providers[selectedProvider])
config.providers[selectedProvider] = {};
config.providers[selectedProvider].apiKey = apiKey.trim();
configManager.setConfig('providers', config.providers);
if (selectedProvider === 'openrouter') {
providerRegistry.clearAll();
const supportedProviders = ['openai', 'anthropic', 'google', 'xai', 'deepseek', 'moonshot'];
for (const providerName of supportedProviders) {
try {
const provider = await ProviderFactory.create(providerName);
providerRegistry.register(provider);
}
catch (error) {
}
}
}
}
setShowSuccess(true);
setTimeout(() => {
setShowSuccess(false);
setSelectedProvider(null);
setApiKey('');
setSecondaryKey('');
setCurrentInput('apiKey');
}, 1500);
};
if (showSuccess) {
return (React.createElement(Box, { borderStyle: "single", borderColor: "green", paddingX: 1 },
React.createElement(Text, { color: "green" }, "\u2713 API key saved successfully!")));
}
if (!selectedProvider) {
const items = providers.map(provider => {
let label = provider;
if (provider === 'openrouter')
label = 'OpenRouter (All AI Models)';
else if (provider === 'google-search')
label = 'Google Search API';
else if (provider === 'serp-api')
label = 'SerpAPI';
return {
label,
value: provider
};
});
return (React.createElement(Box, { flexDirection: "column", borderStyle: "single", borderColor: "#4285F4", paddingX: 1 },
React.createElement(Box, { marginBottom: 1 },
React.createElement(Text, { color: "#4285F4" }, "\uD83D\uDD11 Configure API Keys")),
React.createElement(Box, null,
React.createElement(Text, { dimColor: true }, "Select a provider to configure:")),
React.createElement(Box, { marginTop: 1 },
React.createElement(SelectInput, { items: items, onSelect: handleProviderSelect, itemComponent: createProviderColoredItem() })),
React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { dimColor: true }, "Press ESC to cancel"))));
}
const displayName = selectedProvider === 'openrouter' ? 'OpenRouter' :
selectedProvider === 'google-search' ? 'Google Search' :
selectedProvider === 'serp-api' ? 'SerpAPI' :
selectedProvider;
return (React.createElement(Box, { flexDirection: "column", borderStyle: "single", borderColor: providerColor, paddingX: 1 },
React.createElement(Box, { marginBottom: 1 },
React.createElement(Text, { color: providerColor },
"\uD83D\uDD11 Configure ",
React.createElement(Text, { color: providerColor }, displayName),
" API Key")),
React.createElement(Box, null,
React.createElement(Text, { color: currentInput === 'apiKey' ? providerColor : 'gray' }, "API Key: "),
selectedProvider === 'google-search' && currentInput !== 'apiKey' ? (React.createElement(Text, { dimColor: true }, apiKey ? '••••••••' : 'Not set')) : (React.createElement(TextInput, { value: apiKey, onChange: setApiKey, onSubmit: selectedProvider === 'google-search' ? () => setCurrentInput('searchEngineId') : handleKeySubmit, placeholder: "Enter your API key", mask: "*" }))),
selectedProvider === 'google-search' && (React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { color: currentInput === 'searchEngineId' ? providerColor : 'gray' }, "Search Engine ID: "),
currentInput === 'searchEngineId' ? (React.createElement(TextInput, { value: secondaryKey, onChange: setSecondaryKey, onSubmit: handleKeySubmit, placeholder: "Enter your Search Engine ID" })) : (React.createElement(Text, { dimColor: true }, secondaryKey || 'Not set')))),
React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { dimColor: true }, selectedProvider === 'google-search' ?
`Press Enter to ${currentInput === 'apiKey' ? 'continue' : 'save'}, Tab to switch fields, ESC to cancel` :
'Press Enter to save, ESC to cancel'))));
};
//# sourceMappingURL=KeyConfiguration.js.map