@elevenlabs/convai-cli
Version:
CLI tool to manage ElevenLabs conversational AI agents
183 lines • 10.4 kB
JavaScript
import React, { useState } from 'react';
import { Box, Text, useApp, useInput } from 'ink';
import SelectInput from 'ink-select-input';
import TextInput from 'ink-text-input';
import App from '../App.js';
import StatusCard from '../components/StatusCard.js';
import ProgressFlow from '../components/ProgressFlow.js';
import theme from '../themes/elevenlabs.js';
import { getTemplateByName, getTemplateOptions } from '../../templates.js';
import { writeAgentConfig } from '../../utils.js';
import { createAgentApi } from '../../elevenlabs-api.js';
import { getElevenLabsClient } from '../../elevenlabs-api.js';
import path from 'path';
import fs from 'fs-extra';
export const AddAgentView = ({ initialName, environment = 'prod', template = 'default', skipUpload = false, onComplete }) => {
const { exit } = useApp();
const [currentStep, setCurrentStep] = useState(initialName ? 'template' : 'name');
const [agentName, setAgentName] = useState(initialName || '');
const [selectedTemplate, setSelectedTemplate] = useState(template);
const [selectedEnvironment, setSelectedEnvironment] = useState(environment);
const [isCreating, setIsCreating] = useState(false);
const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);
const [progress, setProgress] = useState(0);
const [statusMessage, setStatusMessage] = useState('');
const templates = Object.entries(getTemplateOptions()).map(([name, description]) => ({
label: `${name} - ${description}`,
value: name
}));
const environments = [
{ label: 'Production', value: 'prod' },
{ label: 'Staging', value: 'staging' },
{ label: 'Development', value: 'dev' }
];
useInput((_, key) => {
if (key.escape && !isCreating) {
exit();
}
if (key.return) {
if (currentStep === 'name' && agentName.trim()) {
setCurrentStep('template');
}
else if (currentStep === 'confirm') {
handleCreate();
}
}
});
const handleCreate = async () => {
setCurrentStep('creating');
setIsCreating(true);
setError(null);
try {
// Step 1: Generate config
setStatusMessage('Generating agent configuration...');
setProgress(20);
const agentConfig = getTemplateByName(agentName, selectedTemplate);
// Step 2: Create directory
setStatusMessage('Creating agent directory...');
setProgress(40);
const configDir = path.resolve(`agent_configs/${selectedEnvironment}`);
await fs.ensureDir(configDir);
// Step 3: Write config file
setStatusMessage('Writing configuration file...');
setProgress(50);
const configPath = path.join(configDir, `${agentName}.json`);
await writeAgentConfig(configPath, agentConfig);
// Step 4: Update agents.json
setStatusMessage('Updating agents.json...');
setProgress(60);
const agentsConfigPath = path.resolve('agents.json');
const agentsConfig = await fs.readJson(agentsConfigPath);
// Check if agent already exists
let existingAgent = agentsConfig.agents.find((agent) => agent.name === agentName);
const relativeConfigPath = `agent_configs/${selectedEnvironment}/${agentName}.json`;
if (existingAgent) {
// Update existing agent with new environment
if (!existingAgent.environments) {
existingAgent.environments = {};
}
existingAgent.environments[selectedEnvironment] = { config: relativeConfigPath };
}
else {
// Add new agent
agentsConfig.agents.push({
name: agentName,
environments: {
[selectedEnvironment]: { config: relativeConfigPath }
}
});
}
await fs.writeJson(agentsConfigPath, agentsConfig, { spaces: 2 });
// Step 5: Upload to ElevenLabs (if not skipped)
if (!skipUpload) {
setStatusMessage('Uploading to ElevenLabs...');
setProgress(80);
const client = await getElevenLabsClient();
const conversationConfig = agentConfig.conversation_config || {};
const platformSettings = agentConfig.platform_settings;
const tags = agentConfig.tags || [];
const agentId = await createAgentApi(client, agentName, conversationConfig, platformSettings, tags);
if (agentId) {
setStatusMessage(`Agent created with ID: ${agentId}`);
}
}
setProgress(100);
setSuccess(true);
setTimeout(() => {
if (onComplete) {
onComplete();
}
else {
exit();
}
}, 2000);
}
catch (err) {
setError(err instanceof Error ? err.message : 'Failed to create agent');
setIsCreating(false);
}
};
const handleTemplateSelect = (item) => {
setSelectedTemplate(item.value);
setCurrentStep('environment');
};
const handleEnvironmentSelect = (item) => {
setSelectedEnvironment(item.value);
setCurrentStep('confirm');
};
return (React.createElement(App, { title: "ElevenLabs Conversational AI", subtitle: "Create New Agent", showOverlay: !success },
React.createElement(Box, { flexDirection: "column", gap: 1 },
currentStep === 'name' && (React.createElement(Box, { flexDirection: "column", gap: 1 },
React.createElement(Text, { color: theme.colors.text.primary, bold: true }, "Step 1: Agent Name"),
React.createElement(Box, { marginBottom: 1 },
React.createElement(Text, { color: theme.colors.text.secondary }, "Enter a name for your agent:")),
React.createElement(TextInput, { value: agentName, onChange: setAgentName, placeholder: "my-assistant" }),
React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { color: theme.colors.text.muted }, "Press Enter to continue, Escape to cancel")))),
currentStep === 'template' && (React.createElement(Box, { flexDirection: "column", gap: 1 },
React.createElement(Text, { color: theme.colors.text.primary, bold: true }, "Step 2: Select Template"),
React.createElement(Box, { marginBottom: 1 },
React.createElement(Text, { color: theme.colors.text.secondary }, "Choose a template for your agent:")),
React.createElement(SelectInput, { items: templates, onSelect: handleTemplateSelect }))),
currentStep === 'environment' && (React.createElement(Box, { flexDirection: "column", gap: 1 },
React.createElement(Text, { color: theme.colors.text.primary, bold: true }, "Step 3: Select Environment"),
React.createElement(Box, { marginBottom: 1 },
React.createElement(Text, { color: theme.colors.text.secondary }, "Choose the target environment:")),
React.createElement(SelectInput, { items: environments, onSelect: handleEnvironmentSelect }))),
currentStep === 'confirm' && (React.createElement(Box, { flexDirection: "column", gap: 1 },
React.createElement(Text, { color: theme.colors.text.primary, bold: true }, "Review Configuration"),
React.createElement(Box, { flexDirection: "column", marginTop: 1 },
React.createElement(Text, { color: theme.colors.text.secondary },
"\u2022 Name: ",
React.createElement(Text, { color: theme.colors.accent.primary }, agentName)),
React.createElement(Text, { color: theme.colors.text.secondary },
"\u2022 Template: ",
React.createElement(Text, { color: theme.colors.accent.primary }, selectedTemplate)),
React.createElement(Text, { color: theme.colors.text.secondary },
"\u2022 Environment: ",
React.createElement(Text, { color: theme.colors.accent.primary }, selectedEnvironment)),
React.createElement(Text, { color: theme.colors.text.secondary },
"\u2022 Upload to ElevenLabs: ",
React.createElement(Text, { color: theme.colors.accent.primary }, skipUpload ? 'No' : 'Yes'))),
React.createElement(Box, { marginTop: 2 },
React.createElement(Text, { color: theme.colors.success }, "Press Enter to create agent, Escape to cancel")))),
currentStep === 'creating' && (React.createElement(Box, { flexDirection: "column", gap: 1 },
!success ? (React.createElement(React.Fragment, null,
React.createElement(StatusCard, { title: "Creating Agent", status: "loading", message: statusMessage }),
React.createElement(ProgressFlow, { value: progress, label: "Progress", showWave: true }))) : (React.createElement(Box, { flexDirection: "column", gap: 1 },
React.createElement(StatusCard, { title: "Agent Created Successfully", status: "success", message: `Agent '${agentName}' has been created` }),
React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { color: theme.colors.text.secondary },
"Configuration saved to: agent_configs/",
selectedEnvironment,
"/",
agentName,
".json")))),
error && (React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { color: theme.colors.error },
"\u2717 Error: ",
error))))))));
};
export default AddAgentView;
//# sourceMappingURL=AddAgentView.js.map