fix: non-blocking Claude calls, validate directory exists before start

This commit is contained in:
neken
2026-04-10 15:58:47 +05:00
parent 737bc4b8d7
commit 0f8b6a347c
3 changed files with 30 additions and 25 deletions
+6 -7
View File
@@ -54,16 +54,15 @@ export function createBot(token: string, ownerId: number): Bot {
await ctx.answerCallbackQuery({ text: `Starting "${resolved.name}"...` }); await ctx.answerCallbackQuery({ text: `Starting "${resolved.name}"...` });
await ctx.reply(`Starting session "${resolved.name}" in ${resolved.path}...`); await ctx.reply(`Starting session "${resolved.name}" in ${resolved.path}...`);
try { claude.createSession(
const { sessionId, result } = await claude.createSession(
"You are now connected via Telegram. Briefly confirm you're ready and state the project directory.", "You are now connected via Telegram. Briefly confirm you're ready and state the project directory.",
resolved.path, resolved.path,
); ).then(({ sessionId, result }) => {
manager.createSession(resolved.name, resolved.path, sessionId); manager.createSession(resolved.name, resolved.path, sessionId);
await ctx.reply(`Session "${resolved.name}" created.\n\n${result}`); ctx.reply(`Session "${resolved.name}" created.\n\n${result}`);
} catch (err) { }).catch((err) => {
await ctx.reply(`Failed to create session: ${err}`); ctx.reply(`Failed to create session: ${err}`);
} });
} }
}); });
+14 -7
View File
@@ -1,4 +1,5 @@
import { type Context, InlineKeyboard } from "grammy"; import { type Context, InlineKeyboard } from "grammy";
import { existsSync } from "fs";
import { SessionManager } from "../services/session-manager.js"; import { SessionManager } from "../services/session-manager.js";
import { ClaudeService } from "../services/claude.js"; import { ClaudeService } from "../services/claude.js";
@@ -20,6 +21,12 @@ export function registerCommands(
return; return;
} }
// Validate that directory exists (skip for bookmarks — already validated on save)
if (!existsSync(resolved.path)) {
await ctx.reply(`Directory not found: ${resolved.path}`);
return;
}
if (manager.getAllSessions()[resolved.name]) { if (manager.getAllSessions()[resolved.name]) {
await ctx.reply( await ctx.reply(
`Session "${resolved.name}" already exists. Use /switch ${resolved.name}`, `Session "${resolved.name}" already exists. Use /switch ${resolved.name}`,
@@ -29,16 +36,16 @@ export function registerCommands(
await ctx.reply(`Starting session "${resolved.name}" in ${resolved.path}...`); await ctx.reply(`Starting session "${resolved.name}" in ${resolved.path}...`);
try { // Run Claude session creation without blocking the bot
const { sessionId, result } = await claude.createSession( claude.createSession(
"You are now connected via Telegram. Briefly confirm you're ready and state the project directory.", "You are now connected via Telegram. Briefly confirm you're ready and state the project directory.",
resolved.path, resolved.path,
); ).then(({ sessionId, result }) => {
manager.createSession(resolved.name, resolved.path, sessionId); manager.createSession(resolved.name, resolved.path, sessionId);
await ctx.reply(`Session "${resolved.name}" created.\n\n${result}`); ctx.reply(`Session "${resolved.name}" created.\n\n${result}`);
} catch (err) { }).catch((err) => {
await ctx.reply(`Failed to create session: ${err}`); ctx.reply(`Failed to create session: ${err}`);
} });
}; };
onCommand["stop"] = async (ctx) => { onCommand["stop"] = async (ctx) => {
+6 -7
View File
@@ -28,18 +28,17 @@ export function createMessageHandler(
manager.setStatus(activeName, "busy"); manager.setStatus(activeName, "busy");
await ctx.replyWithChatAction("typing"); await ctx.replyWithChatAction("typing");
try { // Run Claude call without blocking the bot's event loop
const result = await claude.sendMessage(text, session.sessionId); claude.sendMessage(text, session.sessionId).then(async (result) => {
const response = result || "(empty response)"; const response = result || "(empty response)";
const chunks = splitMessage(response); const chunks = splitMessage(response);
for (const chunk of chunks) { for (const chunk of chunks) {
await ctx.reply(chunk); await ctx.reply(chunk);
} }
} catch (err) { }).catch((err) => {
await ctx.reply(`Error: ${err}`); ctx.reply(`Error: ${err}`);
} finally { }).finally(() => {
manager.setStatus(activeName, "idle"); manager.setStatus(activeName, "idle");
} });
}; };
} }