feat: add TUI entry point with minimal readline mode
This commit is contained in:
+121
@@ -0,0 +1,121 @@
|
||||
import { loadConfig } from './config/index.js';
|
||||
import { SessionStore, SessionManager } from './session/index.js';
|
||||
import { AnthropicClient, OpenAIClient, OllamaClient, ModelRouter } from './models/index.js';
|
||||
import { MinimalTui } from './frontends/tui/index.js';
|
||||
import type { Config } from './config/index.js';
|
||||
import { resolve } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { existsSync, mkdirSync } from 'fs';
|
||||
|
||||
const CONFIG_PATH = process.env.FLYNN_CONFIG
|
||||
?? resolve(homedir(), '.config/flynn/config.yaml');
|
||||
|
||||
const SYSTEM_PROMPT = `You are Flynn, a helpful personal AI assistant. You are direct, concise, and helpful. You can help with a variety of tasks including answering questions, providing information, and having conversations.
|
||||
|
||||
Keep responses focused and avoid unnecessary verbosity. Use markdown formatting when it improves readability.`;
|
||||
|
||||
function createModelRouter(config: Config): ModelRouter {
|
||||
const models = config.models;
|
||||
|
||||
const defaultClient = new AnthropicClient({
|
||||
model: models.default.model,
|
||||
});
|
||||
|
||||
let fastClient;
|
||||
let complexClient;
|
||||
let localClient;
|
||||
|
||||
if (models.fast) {
|
||||
fastClient = new AnthropicClient({ model: models.fast.model });
|
||||
}
|
||||
|
||||
if (models.complex) {
|
||||
complexClient = new AnthropicClient({ model: models.complex.model });
|
||||
}
|
||||
|
||||
if (models.local) {
|
||||
if (models.local.provider === 'ollama') {
|
||||
localClient = new OllamaClient({
|
||||
model: models.local.model,
|
||||
host: models.local.endpoint,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const fallbackChain = [];
|
||||
for (const providerName of models.fallback_chain) {
|
||||
if (providerName === 'openai') {
|
||||
fallbackChain.push(new OpenAIClient({ model: 'gpt-4o' }));
|
||||
} else if (providerName === 'local' && localClient) {
|
||||
fallbackChain.push(localClient);
|
||||
}
|
||||
}
|
||||
|
||||
return new ModelRouter({
|
||||
default: defaultClient,
|
||||
fast: fastClient,
|
||||
complex: complexClient,
|
||||
local: localClient,
|
||||
fallbackChain,
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('Flynn TUI starting...');
|
||||
|
||||
if (!existsSync(CONFIG_PATH)) {
|
||||
console.error(`Config file not found: ${CONFIG_PATH}`);
|
||||
console.error('Copy config/default.yaml to ~/.config/flynn/config.yaml and configure it.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const config = loadConfig(CONFIG_PATH);
|
||||
|
||||
// Ensure data directory exists
|
||||
const dataDir = resolve(homedir(), '.local/share/flynn');
|
||||
mkdirSync(dataDir, { recursive: true });
|
||||
|
||||
// Initialize components
|
||||
const sessionStore = new SessionStore(resolve(dataDir, 'sessions.db'));
|
||||
const sessionManager = new SessionManager(sessionStore);
|
||||
const modelRouter = createModelRouter(config);
|
||||
|
||||
// Get TUI session
|
||||
const session = sessionManager.getSession('tui', 'local');
|
||||
|
||||
// Create and start minimal TUI
|
||||
const tui = new MinimalTui({
|
||||
session,
|
||||
modelClient: modelRouter,
|
||||
systemPrompt: SYSTEM_PROMPT,
|
||||
onTransfer: (target) => {
|
||||
if (target === 'telegram') {
|
||||
const telegramUserId = String(config.telegram.allowed_chat_ids[0]);
|
||||
sessionManager.transferSession('tui', 'local', 'telegram', telegramUserId);
|
||||
console.log(`Session transferred to Telegram (${telegramUserId})\n`);
|
||||
} else {
|
||||
console.log(`Unknown transfer target: ${target}\n`);
|
||||
}
|
||||
},
|
||||
onFullscreen: () => {
|
||||
console.log('Fullscreen mode not yet implemented.\n');
|
||||
},
|
||||
});
|
||||
|
||||
// Handle shutdown
|
||||
process.on('SIGINT', () => {
|
||||
tui.stop();
|
||||
sessionStore.close();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
await tui.start();
|
||||
|
||||
// Cleanup
|
||||
sessionStore.close();
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Failed to start TUI:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user