this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(bot): sync missing tools to existing agents on startup

Previously, new tools were only attached when creating a new agent.
Now existing agents get any missing tools attached automatically,
preserving agent memory while adding new capabilities.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

alice 0473bc31 d42dfb94

+65 -4
+65 -4
src/bot.ts
··· 26 26 const AGENT_NAME = 'adhd-support-agent'; 27 27 28 28 /** 29 + * Sync any missing tools to an existing agent 30 + * 31 + * Compares registered tools with agent's attached tools and attaches any missing ones. 32 + */ 33 + async function syncToolsToAgent(client: ReturnType<typeof getLettaClient>, agentId: string): Promise<void> { 34 + const registeredToolIds = getRegisteredToolIds(); 35 + if (registeredToolIds.length === 0) { 36 + return; 37 + } 38 + 39 + // Get currently attached tools 40 + const attachedTools = new Set<string>(); 41 + for await (const tool of client.agents.tools.list(agentId)) { 42 + attachedTools.add(tool.id); 43 + } 44 + 45 + // Attach any missing tools 46 + let attached = 0; 47 + for (const toolId of registeredToolIds) { 48 + if (!attachedTools.has(toolId)) { 49 + try { 50 + await client.agents.tools.attach(toolId, { agent_id: agentId }); 51 + attached++; 52 + } catch (err) { 53 + console.warn(`Failed to attach tool ${toolId}:`, err); 54 + } 55 + } 56 + } 57 + 58 + if (attached > 0) { 59 + console.log(`Attached ${String(attached)} new tools to existing agent`); 60 + } 61 + } 62 + 63 + /** 29 64 * Get or create the single ADHD support agent 30 65 * 31 66 * Searches for existing agent by name, creates if not found. ··· 47 82 if (agent.name === AGENT_NAME) { 48 83 console.log(`Found existing agent: ${agent.id}`); 49 84 agentId = agent.id; 85 + 86 + // Sync any missing tools to the existing agent 87 + await syncToolsToAgent(client, agentId); 88 + 50 89 return agentId; 51 90 } 52 91 } ··· 142 181 const msgPreview = message.slice(0, 100) + (message.length > 100 ? '...' : ''); 143 182 console.log(`\n📤 Sending message to agent ${agentId}: "${msgPreview}"`); 144 183 184 + // Inject current date/time so the assistant has a sense of time 185 + const now = new Date(); 186 + const timestamp = now.toLocaleString('en-US', { 187 + weekday: 'long', 188 + year: 'numeric', 189 + month: 'long', 190 + day: 'numeric', 191 + hour: 'numeric', 192 + minute: '2-digit', 193 + hour12: true, 194 + timeZoneName: 'short', 195 + }); 196 + const messageWithTime = `[${timestamp}]\n${message}`; 197 + 145 198 // Send message to agent (non-streaming mode for simplicity in M1) 146 199 const response = await client.agents.messages.create(agentId, { 147 - input: message, 200 + input: messageWithTime, 148 201 streaming: false, 149 202 }); 150 203 ··· 323 376 // Send message to agent and get response 324 377 const response = await sendMessageToAgent(currentAgentId, messageText); 325 378 326 - // Reply to user 327 - await ctx.reply(response); 379 + // Reply to user with Markdown formatting (fallback to plain text if parsing fails) 380 + try { 381 + await ctx.reply(response, { parse_mode: 'Markdown' }); 382 + } catch { 383 + // Markdown parsing failed, send as plain text 384 + await ctx.reply(response); 385 + } 328 386 } catch (err: unknown) { 329 387 console.error('Error handling message:', err); 330 388 ··· 382 440 // Handle Bun hot reload - stop bot before module replacement 383 441 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, @typescript-eslint/strict-boolean-expressions -- import.meta.hot is undefined when not in hot mode 384 442 if (import.meta.hot) { 385 - import.meta.hot.dispose(() => { 443 + import.meta.hot.dispose(async () => { 386 444 console.log('Hot reload: stopping bot...'); 387 445 bot.stop('HOT_RELOAD'); 446 + // bot.stop() is sync but Telegram needs time to release the connection 447 + await new Promise((resolve) => setTimeout(resolve, 500)); 448 + console.log('Hot reload: bot stopped'); 388 449 }); 389 450 }