capsule-ai-cli
Version:
The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing
148 lines ⢠5.87 kB
JavaScript
import React, { useState } from 'react';
import { render, Box, Text, useInput, useApp } from 'ink';
import TextInput from 'ink-text-input';
import Spinner from 'ink-spinner';
import chalk from 'chalk';
import { stateService } from '../services/state.js';
import { contextManager } from '../services/context.js';
import { chatService } from '../services/chat.js';
import { FileHandlerInstance } from '../services/file-handler.js';
const ChatInterface = () => {
const [input, setInput] = useState('');
const [messages, setMessages] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [mode, setMode] = useState(stateService.getMode());
const fileHandler = new FileHandlerInstance();
const { exit } = useApp();
useInput((input, key) => {
if (key.ctrl && input === 'c') {
exit();
}
});
const handleSubmit = async (value) => {
if (!value.trim())
return;
const userMessage = {
role: 'user',
content: value,
timestamp: new Date()
};
setMessages(prev => [...prev, userMessage]);
setInput('');
setIsLoading(true);
try {
if (value.startsWith('/')) {
await handleCommand(value);
}
else {
const response = await chatService.sendMessage(value);
const assistantMessage = {
role: 'assistant',
content: response.content,
timestamp: new Date()
};
setMessages(prev => [...prev, assistantMessage]);
}
}
catch (error) {
const errorMessage = {
role: 'system',
content: `Error: ${error.message}`,
timestamp: new Date()
};
setMessages(prev => [...prev, errorMessage]);
}
finally {
setIsLoading(false);
}
};
const handleCommand = async (command) => {
const [cmd, ...args] = command.slice(1).split(' ');
switch (cmd) {
case 'help':
case 'h':
const helpMessage = {
role: 'system',
content: `Available commands:
/help - Show this help
/mode <chat|agent|plan|fusion> - Switch mode
/new - Start new conversation
/clear - Clear messages
/exit - Exit the app`,
timestamp: new Date()
};
setMessages(prev => [...prev, helpMessage]);
break;
case 'mode':
if (args[0] && ['chat', 'agent', 'plan', 'fusion'].includes(args[0])) {
stateService.setMode(args[0]);
setMode(args[0]);
const modeMessage = {
role: 'system',
content: `Switched to ${args[0]} mode`,
timestamp: new Date()
};
setMessages(prev => [...prev, modeMessage]);
}
break;
case 'new':
contextManager.newContext();
setMessages([]);
break;
case 'clear':
setMessages([]);
break;
case 'exit':
case 'quit':
exit();
break;
default:
const unknownMessage = {
role: 'system',
content: `Unknown command: ${cmd}`,
timestamp: new Date()
};
setMessages(prev => [...prev, unknownMessage]);
}
};
const getModeIcon = () => {
const icons = {
chat: 'š¬',
agent: 'š¤',
plan: 'š',
fusion: 'š®'
};
return icons[mode] || 'š¬';
};
return (React.createElement(Box, { flexDirection: "column", height: "100%" },
React.createElement(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1 },
React.createElement(Text, { color: "cyan", bold: true },
"Capsule CLI - ",
mode,
" mode")),
React.createElement(Box, { flexDirection: "column", flexGrow: 1, paddingY: 1 },
messages.slice(-10).map((msg, i) => (React.createElement(Box, { key: i, marginBottom: 1 },
msg.role === 'user' && (React.createElement(Text, null,
React.createElement(Text, { color: "blue", bold: true }, "You: "),
msg.content)),
msg.role === 'assistant' && (React.createElement(Text, null,
React.createElement(Text, { color: "green", bold: true }, "AI: "),
msg.content)),
msg.role === 'system' && (React.createElement(Text, { color: "yellow", dimColor: true }, msg.content))))),
isLoading && (React.createElement(Box, null,
React.createElement(Text, { color: "green" },
React.createElement(Spinner, { type: "dots" }),
" Thinking...")))),
React.createElement(Box, { borderStyle: "single", borderColor: "gray" },
React.createElement(Box, { marginRight: 1 },
React.createElement(Text, null,
getModeIcon(),
" \u203A ")),
React.createElement(TextInput, { value: input, onChange: setInput, onSubmit: handleSubmit, placeholder: "Type a message or /help for commands..." }))));
};
export async function startReactCLI() {
const { waitUntilExit } = render(React.createElement(ChatInterface, null));
await waitUntilExit();
console.log(chalk.yellow('\nš Goodbye!\n'));
}
//# sourceMappingURL=react-cli.js.map