diff --git a/package-lock.json b/package-lock.json index 10d31c67..0d17a7ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,13 @@ { "name": "zcode-cli-x", - "version": "1.0.0", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "zcode-cli-x", - "version": "1.0.0", + "version": "2.0.0", + "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.81.0", "@grammyjs/auto-retry": "^2.0.2", @@ -31,8 +32,14 @@ "bin": { "zcode": "bin/zcode.js" }, + "devDependencies": {}, "engines": { - "node": ">=20.0.0" + "node": ">=20.0.0", + "npm": ">=9.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/uroma2" } }, "node_modules/@anthropic-ai/sdk": { diff --git a/src/bot/index.js b/src/bot/index.js index eb75295f..1209d199 100644 --- a/src/bot/index.js +++ b/src/bot/index.js @@ -1256,14 +1256,14 @@ export async function initBot(config, api, tools, skills, agents) { try { // ── Intent detection: bypass AI for simple messages ── const intent = detectIntent(text); - if (intent && intent.bypassAI) { - logger.info(`🎯 Intent: ${intent.type} — bypassing AI`); - const reply = intent.response || 'Got it.'; - await queueRequest(key, text, async () => { - await sendFormatted(ctx, reply); - }); - return; - } + if (intent && intent.bypassAI) { + logger.info(`🎯 Intent: ${intent.type} — bypassing AI`); + clearInterval(typingInterval); + const reply = intent.response || 'Got it.'; + await sendFormatted(ctx, reply); + return; + } + // ── Load conversation history for this chat ── const chatKey = conversation._key(ctx.chat.id, ctx.message?.message_thread_id); diff --git a/src/bot/intent-detector.js b/src/bot/intent-detector.js index 02490962..b3091b23 100644 --- a/src/bot/intent-detector.js +++ b/src/bot/intent-detector.js @@ -18,9 +18,9 @@ const GREETINGS = [ /^(hi|hey|hello|howdy|greetings|sup|yo|what'?s up|what'?s up|how are you|how's it going|how do you do)/i, /^(good morning|good afternoon|good evening|good night)/i, /^(thanks|thank you|thx|ty|appreciate it)/i, - /^(ok|okay|alright|sure|yes|yeah|yep|nope|no)/i, - /^(continue|go ahead|proceed|do it|carry on|keep going)/i, - /^(done|finished|completed|all good|looks good)/i, + /^(?:ok|okay|alright|sure|yes|yeah|yep|nope|no)\b/i, + /^(continue|go ahead|proceed|do it|carry on|keep going)$/i, + /^(done|finished|completed|all good|looks good)$/i, /^(bye|goodbye|see you|later|take care)/i, ]; @@ -76,11 +76,12 @@ export function detectIntent(message) { }; let category = 'greeting'; - if (pattern.test(/^(thanks|thank you|thx|ty)/i)) category = 'thanks'; - else if (pattern.test(/^(bye|goodbye|see you|later)/i)) category = 'goodbye'; - else if (pattern.test(/^(ok|okay|alright|sure|yes|yeah)/i)) category = 'confirmation'; - else if (pattern.test(/^(continue|go ahead|proceed)/i)) category = 'continue'; - else if (pattern.test(/^(good morning|good afternoon|good evening)/i)) category = 'greeting'; + if (/^(thanks|thank you|thx|ty|appreciate it)/i.test(trimmed)) category = 'thanks'; + else if (/^(bye|goodbye|see you|later|take care)/i.test(trimmed)) category = 'goodbye'; + else if (/^(ok|okay|alright|sure|yes|yeah|yep|nope|no)/i.test(trimmed)) category = 'confirmation'; + else if (/^(continue|go ahead|proceed|do it|carry on|keep going)/i.test(trimmed)) category = 'continue'; + else if (/^(done|finished|completed|all good|looks good)/i.test(trimmed)) category = 'completion'; + else if (/^(good morning|good afternoon|good evening)/i.test(trimmed)) category = 'greeting'; const list = responses[category] || responses['greeting']; return { @@ -106,21 +107,21 @@ export function detectIntent(message) { if (pattern.test(trimmed)) { if (type === 'instant') { const now = new Date(); - if (pattern.test(/what time/i)) { + if (/what time/i.test(trimmed)) { return { type: 'instant', response: `🕐 ${now.toLocaleTimeString('en-US', { timeZone: 'Asia/Tbilisi' })} (Tbilisi time)`, bypassAI: true, }; } - if (pattern.test(/what date|what day/i)) { + if (/(what date|what day)/i.test(trimmed)) { return { type: 'instant', response: `📅 ${now.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}`, bypassAI: true, }; } - if (pattern.test(/who are you|what are you/i)) { + if (/(who are you|what are you)/i.test(trimmed)) { return { type: 'instant', response: '⚡ I\'m zCode CLI X — an agentic coding assistant running on Telegram. I can read/write files, run bash commands, manage git repos, search the web, and more.',