squidclaw 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/ai/gateway.js CHANGED
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { logger } from '../core/logger.js';
7
+ import { getRouteForTask } from './smart-router.js';
7
8
  import { MODEL_MAP, MODEL_PRICING } from '../core/config.js';
8
9
 
9
10
  export class AIGateway {
@@ -27,7 +28,13 @@ export class AIGateway {
27
28
  * Send a chat completion request with auto-fallback
28
29
  */
29
30
  async chat(messages, options = {}) {
30
- const model = options.model || this.config.ai?.defaultModel;
31
+ // Smart routing: use best model for the task
32
+ let routedModel = options.model;
33
+ if (!routedModel && options.taskHint) {
34
+ const route = getRouteForTask(options.taskHint, options.toolName, this.config);
35
+ if (route) routedModel = route.model;
36
+ }
37
+ const model = routedModel || this.config.ai?.defaultModel;
31
38
  const fallbackChain = options.fallbackChain || this.config.ai?.fallbackChain || [];
32
39
  const modelsToTry = [model, ...fallbackChain].filter(Boolean);
33
40
 
@@ -0,0 +1,77 @@
1
+ /**
2
+ * 🦑 Smart AI Router
3
+ * Routes to the best model based on task type
4
+ *
5
+ * - Creative content (PPT, reports, stories) → Gemini (free + creative)
6
+ * - Conversation, reasoning → Claude (smart)
7
+ * - Quick tasks, translations → Flash models (fast + cheap)
8
+ * - Code, analysis → Claude or GPT-4o
9
+ */
10
+
11
+ import { logger } from '../core/logger.js';
12
+
13
+ const TASK_ROUTES = {
14
+ // Creative content → Gemini
15
+ presentation: { provider: 'google', model: 'gemini-2.5-flash', reason: 'creative content' },
16
+ pptx: { provider: 'google', model: 'gemini-2.5-flash', reason: 'presentation' },
17
+ dashboard: { provider: 'google', model: 'gemini-2.5-flash', reason: 'visual content' },
18
+ report: { provider: 'google', model: 'gemini-2.5-flash', reason: 'report generation' },
19
+ story: { provider: 'google', model: 'gemini-2.5-flash', reason: 'creative writing' },
20
+ article: { provider: 'google', model: 'gemini-2.5-flash', reason: 'article writing' },
21
+ email_draft: { provider: 'google', model: 'gemini-2.5-flash', reason: 'email draft' },
22
+ excel: { provider: 'google', model: 'gemini-2.5-flash', reason: 'data generation' },
23
+ pdf: { provider: 'google', model: 'gemini-2.5-flash', reason: 'document' },
24
+
25
+ // Quick tasks → Flash (fast)
26
+ translate: { provider: 'google', model: 'gemini-2.0-flash', reason: 'translation' },
27
+ summarize: { provider: 'google', model: 'gemini-2.0-flash', reason: 'summarization' },
28
+ weather: { provider: 'google', model: 'gemini-2.0-flash', reason: 'simple lookup' },
29
+
30
+ // Default stays on primary model
31
+ };
32
+
33
+ // Detect task type from message + tool context
34
+ function detectTask(message, toolName) {
35
+ const lower = (message || '').toLowerCase();
36
+
37
+ // Explicit tool-based routing
38
+ if (toolName) {
39
+ if (['pptx', 'pptx_slides', 'pptx_pro', 'presentation', 'powerpoint'].includes(toolName)) return 'presentation';
40
+ if (['dashboard', 'canvas_dashboard'].includes(toolName)) return 'dashboard';
41
+ if (['excel', 'xlsx'].includes(toolName)) return 'excel';
42
+ if (['pdf'].includes(toolName)) return 'pdf';
43
+ if (['translate'].includes(toolName)) return 'translate';
44
+ }
45
+
46
+ // Message-based detection
47
+ if (lower.match(/\b(presentation|ppt|powerpoint|slides|عرض تقديمي|شرائح)\b/)) return 'presentation';
48
+ if (lower.match(/\b(dashboard|لوحة)\b/)) return 'dashboard';
49
+ if (lower.match(/\b(report|تقرير)\b/)) return 'report';
50
+ if (lower.match(/\b(story|قصة|حكاية)\b/)) return 'story';
51
+ if (lower.match(/\b(article|مقال)\b/)) return 'article';
52
+ if (lower.match(/\b(translate|ترجم)\b/)) return 'translate';
53
+ if (lower.match(/\b(summarize|summary|لخص|ملخص)\b/)) return 'summarize';
54
+ if (lower.match(/\b(excel|spreadsheet|جدول)\b/)) return 'excel';
55
+
56
+ return null; // Use default model
57
+ }
58
+
59
+ export function getRouteForTask(message, toolName, config) {
60
+ const task = detectTask(message, toolName);
61
+ if (!task) return null;
62
+
63
+ const route = TASK_ROUTES[task];
64
+ if (!route) return null;
65
+
66
+ // Check if provider is available
67
+ const providers = config?.ai?.providers || {};
68
+ if (!providers[route.provider]?.key) {
69
+ logger.debug('smart-router', `${route.provider} not available for ${task}, using default`);
70
+ return null;
71
+ }
72
+
73
+ logger.info('smart-router', `Routing "${task}" → ${route.provider}/${route.model} (${route.reason})`);
74
+ return { provider: route.provider, model: route.model, task, reason: route.reason };
75
+ }
76
+
77
+ export { detectTask, TASK_ROUTES };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "squidclaw",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "🦑 AI agent platform — human-like agents for WhatsApp, Telegram & more",
5
5
  "main": "lib/engine.js",
6
6
  "bin": {