feat: integrate model router, session persistence, and hook engine
- NativeAgent now loads/saves messages to SessionStore - Daemon creates ModelRouter with fallback chain support - Telegram bot handles confirmation callbacks from HookEngine - Session data stored in ~/.local/share/flynn/sessions.db Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
import { Bot, Context } from 'grammy';
|
||||
import { Bot } from 'grammy';
|
||||
import type { NativeAgent } from '../../backends/index.js';
|
||||
import type { TelegramConfig } from '../../config/index.js';
|
||||
import type { HookEngine } from '../../hooks/index.js';
|
||||
import { isAllowedChat, createMessageHandler, createResetHandler } from './handlers.js';
|
||||
import { parseConfirmationCallback } from './confirmations.js';
|
||||
|
||||
export interface TelegramBotConfig {
|
||||
telegram: TelegramConfig;
|
||||
agent: NativeAgent;
|
||||
hookEngine?: HookEngine;
|
||||
}
|
||||
|
||||
export function createTelegramBot(config: TelegramBotConfig): Bot {
|
||||
@@ -13,6 +16,7 @@ export function createTelegramBot(config: TelegramBotConfig): Bot {
|
||||
const handleMessage = createMessageHandler(config.agent);
|
||||
const handleReset = createResetHandler(config.agent);
|
||||
const allowedChatIds = config.telegram.allowed_chat_ids;
|
||||
const hookEngine = config.hookEngine;
|
||||
|
||||
// Middleware to check chat ID
|
||||
bot.use(async (ctx, next) => {
|
||||
@@ -24,6 +28,34 @@ export function createTelegramBot(config: TelegramBotConfig): Bot {
|
||||
await next();
|
||||
});
|
||||
|
||||
// Handle confirmation callbacks
|
||||
bot.on('callback_query:data', async (ctx) => {
|
||||
const data = ctx.callbackQuery.data;
|
||||
const parsed = parseConfirmationCallback(data);
|
||||
|
||||
if (!parsed || !hookEngine) {
|
||||
await ctx.answerCallbackQuery({ text: 'Invalid action' });
|
||||
return;
|
||||
}
|
||||
|
||||
const resolved = hookEngine.resolveConfirmation(parsed.id, {
|
||||
approved: parsed.approved,
|
||||
reason: parsed.approved ? undefined : 'Denied by user',
|
||||
});
|
||||
|
||||
if (resolved) {
|
||||
await ctx.answerCallbackQuery({
|
||||
text: parsed.approved ? '✅ Approved' : '❌ Denied',
|
||||
});
|
||||
await ctx.editMessageText(
|
||||
ctx.callbackQuery.message?.text + `\n\n${parsed.approved ? '✅ Approved' : '❌ Denied'}`,
|
||||
{ parse_mode: 'Markdown' }
|
||||
);
|
||||
} else {
|
||||
await ctx.answerCallbackQuery({ text: 'Confirmation expired or not found' });
|
||||
}
|
||||
});
|
||||
|
||||
// Command handlers
|
||||
bot.command('start', async (ctx) => {
|
||||
await ctx.reply('Flynn is ready. Send me a message!');
|
||||
@@ -35,7 +67,9 @@ export function createTelegramBot(config: TelegramBotConfig): Bot {
|
||||
});
|
||||
|
||||
bot.command('status', async (ctx) => {
|
||||
await ctx.reply('Flynn is running.');
|
||||
const pending = hookEngine?.getPendingConfirmations() ?? [];
|
||||
const statusMsg = `Flynn is running.\nPending confirmations: ${pending.length}`;
|
||||
await ctx.reply(statusMsg);
|
||||
});
|
||||
|
||||
// Message handler
|
||||
|
||||
Reference in New Issue
Block a user