PageSourceSearch

https://dulcet-rolypoly-07cad3.netlify.app/tux_ai/response-engine.js

js dulcet-rolypoly-07cad3.netlify.app collected 2026-10-03 10:40:17 UTC 10,102 bytes, 214 lines download raw bytes

1/**
2 * Tux AI Advanced Response Engine
3 * Provides intent classification, context tracking, smart response building,
4 * and key message injection for LUR.
5 * This layer sits on top of the base keyword matcher to make Tux feel intelligent.
6 */
7(function() {
8    'use strict';
9
10    if (!window.tuxKnowledge) {
11        console.warn('tuxKnowledge not loaded yet - load knowledge-base.js first.');
12    }
13
14    window.tuxEngine = window.tuxEngine || {};
15
16    // Conversation context for "intelligence"
17    window.tuxEngine.context = {
18        history: [],           // last N questions + intents
19        lastIntent: null,
20        lastTopic: null,
21        repeatCount: {},       // per key
22        sessionStart: Date.now()
23    };
24
25    const MAX_HISTORY = 6;
26
27    function updateContext(question, intent, matchedKey) {
28        const ctx = window.tuxEngine.context;
29        ctx.history.push({ q: question, intent: intent, key: matchedKey, t: Date.now() });
30        if (ctx.history.length > MAX_HISTORY) ctx.history.shift();
31        ctx.lastIntent = intent;
32        ctx.lastTopic = matchedKey || intent;
33        ctx.repeatCount[matchedKey || question] = (ctx.repeatCount[matchedKey || question] || 0) + 1;
34    }
35
36    window.tuxEngine.getContext = function() { return window.tuxEngine.context; };
37
38    // Intent classification - makes it "understand" categories
39    window.tuxEngine.classifyIntent = function(normalizedQuestion, originalInput) {
40        const q = (normalizedQuestion || '').toLowerCase();
41        const orig = (originalInput || '').toLowerCase();
42        const combined = q + ' ' + orig;
43        const intents = [];
44
45        const kw = (window.tuxKnowledge && window.tuxKnowledge.INTENT_KEYWORDS) || {};
46
47        if (kw.greeting && kw.greeting.some(w => combined.includes(w))) intents.push('greeting');
48        if (kw.thanks && kw.thanks.some(w => combined.includes(w))) intents.push('thanks');
49        if (kw.goodbye && kw.goodbye.some(w => combined.includes(w))) intents.push('goodbye');
50
51        if (kw.crypto && kw.crypto.some(w => combined.includes(w))) intents.push('crypto');
52        if (kw.site && kw.site.some(w => combined.includes(w))) intents.push('site');
53        if (kw.tux && kw.tux.some(w => combined.includes(w))) intents.push('tux');
54        if (kw.lucipher && kw.lucipher.some(w => combined.includes(w))) intents.push('lucipher');
55        if (kw.about && kw.about.some(w => combined.includes(w))) intents.push('about');
56        if (kw.gaming && kw.gaming.some(w => combined.includes(w))) intents.push('gaming');
57        if (kw.coding && kw.coding.some(w => combined.includes(w))) intents.push('coding');
58
59        // Specific coin focus
60        if (combined.includes('lucipher live') || combined.includes('live token') || combined.includes('lur') ||
61            (combined.includes('active') && combined.includes('coin')) ||
62            (combined.includes('only') && combined.includes('coin'))) {
63            intents.push('lucipherLiveToken');
64        }
65
66        // Question type
67        if (q.startsWith('what is') || q.includes('what is')) intents.push('definition');
68        if (q.startsWith('who') || q.includes('who is') || q.includes('who created')) intents.push('who');
69        if (q.startsWith('how') || q.includes('how to')) intents.push('howto');
70        if (q.includes('should i') || q.includes('is it safe') || q.includes('recommend')) intents.push('advice');
71
72        if (intents.length === 0) intents.push('general');
73
74        // Dedup
75        return [...new Set(intents)];
76    };
77
78    // Check if any intent should trigger the key promotion
79    window.tuxEngine.shouldInjectKeyMessage = function(intents) {
80        const trigger = ['crypto', 'site', 'tux', 'lucipher', 'lucipherLiveToken'];
81        return intents.some(i => trigger.includes(i));
82    };
83
84    // Build a smart primary response, injecting key fact when appropriate
85    window.tuxEngine.buildSmartResponse = function(baseResponse, intents, question, matchedKey) {
86        const knowledge = window.tuxKnowledge || {};
87        const KEY = knowledge.LUCIPHER_LIVE_TOKEN_MESSAGE || "LUR is the only active coin for this summer.";
88        const templates = knowledge.SMART_TEMPLATES || {};
89        let response = baseResponse || '';
90
91        // If this came from online search / research, preserve the found content + links and only lightly append key if relevant
92        if (response && /Based on current online information|I looked that up online|Here are direct links|Here are the sources\/l
92inks from my previous/i.test(response)) {
93            if (window.tuxEngine.shouldInjectKeyMessage(intents || []) && !response.includes('LUR is the only active')) {
94                response = response.replace(/([.!?]?)\s*$/, ` ${KEY}$1`);
95            }
96            return response;
97        }
98
99        const needsKey = window.tuxEngine.shouldInjectKeyMessage(intents || []);
100
101        // Special high-priority cases - override or augment for intelligence
102        if (intents.includes('lucipherLiveToken') || (matchedKey && matchedKey.includes('lucipher live'))) {
103            const t = knowledge.random(templates.lucipherLiveToken) || "{KEY_MESSAGE}";
104            response = knowledge.fillTemplate(t, { KEY_MESSAGE: KEY });
105            return response;
106        }
107
108        if (intents.includes('site') || (matchedKey && (matchedKey.includes('what is this') || matchedKey.includes('lucipher.dk')))) {
109            const t = knowledge.random(templates.siteIntro) || "This is Lucipher.dk. {KEY_MESSAGE}";
110            response = knowledge.fillTemplate(t, { KEY_MESSAGE: KEY });
111            return response;
112        }
113
114        if (intents.includes('tux') || (matchedKey && (matchedKey.includes('who are you') || matchedKey.includes('tux ai')))) {
115            const t = knowledge.random(templates.tuxIntro) || "I'm Tux Ai. {KEY_MESSAGE}";
116            response = knowledge.fillTemplate(t, { KEY_MESSAGE: KEY });
117            return response;
118        }
119
120        if (intents.includes('lucipher') || (matchedKey && matchedKey.includes('who is lucipher'))) {
121            const t = knowledge.random(templates.aboutLucipher) || "Lucipher created me. {KEY_MESSAGE}";
122            response = knowledge.fillTemplate(t, { KEY_MESSAGE: KEY });
123            return response;
124        }
125
126        if (needsKey && intents.includes('crypto')) {
127            const t = knowledge.random(templates.cryptoGeneral) || "Crypto talk! {KEY_MESSAGE}";
128            // Prepend or weave the smart crypto line + keep some base flavor
129            response = knowledge.fillTemplate(t, { KEY_MESSAGE: KEY }) + (response ? ' ' + response : '');
130            return response;
131        }
132
133        if (needsKey) {
134            // General injection for tux/coin/crypto/site related
135            if (response && !response.includes('LUR')) {
136                // Append naturally
137                response = response.replace(/([.!?]?)$/, ` ${KEY}$1`);
138            } else if (!response) {
139                response = knowledge.fillTemplate(knowledge.random(templates.cryptoGeneral) || "On the topic of coins and projects here: {KEY_MESSAGE}", { KEY_MESSAGE: KEY });
140            }
141        }
142
143        // Add context-aware flavor using history (makes it feel smarter)
144        const ctx = window.tuxEngine.context;
145        if (ctx.history.length > 1 && ctx.lastIntent === 'crypto' && intents.includes('crypto')) {
146            response += " Building on what we talked about earlier, the summer focus stays strong on the active token.";
147        }
148
149        return response;
150    };
151
152    // Smarter fallback that uses knowledge
153    window.tuxEngine.getSmartFallback = function(question, intents, closestKey) {
154        const knowledge = window.tuxKnowledge || {};
155        const KEY = knowledge.LUCIPHER_LIVE_TOKEN_MESSAGE || "";
156        const templates = knowledge.SMART_TEMPLATES || {};
157
158        let fb = knowledge.random(templates.fallbackSmart) || "Sorry, I don't understand that yet. Try the globe icon for online search!";
159
160        if (window.tuxEngine.shouldInjectKeyMessage(intents)) {
161            fb = fb.replace(/(\.)$/, '') + ` ${KEY}`;
162        }
163
164        if (closestKey && closestKey.length > 3) {
165            fb += ` (Closest I know: "${closestKey}")`;
166        }
167
168        return fb;
169    };
170
171    // Main hook: called from improved backend
172    window.tuxEngine.processResponse = function(rawResponse, question, normalizedQ, matchedKey, intents) {
173        let final = rawResponse;
174
175        // Update context first
176        updateContext(question, intents, matchedKey);
177
178        // Apply smart building / injection
179        final = window.tuxEngine.buildSmartResponse(final, intents, question, matchedKey);
180
181        // Personality touches for greetings etc. - keep very light, no info dumps or c
181oin pushes unless user asked a question
182        if (intents.includes('greeting')) {
183            const greetings = [
184                "Hey! ",
185                "Hi there! ",
186                "Waddle up! ",
187                "Yo! "
188            ];
189            // Only lightly flavor if the base response doesn't already look like a greeting
190            const lowerFinal = (final || '').toLowerCase();
191            if (!lowerFinal.startsWith('hello') && !lowerFinal.startsWith('hi') && !lowerFinal.startsWith('hey') && !lowerFinal.startsWith('yo')) {
192                final = (window.tuxKnowledge.random ? window.tuxKnowledge.random(greetings) : "Hello! ") + final;
193            }
194        }
195
196        if (intents.includes('thanks')) {
197            final += " No problem - happy to help spread the Tux and Lucipher vibes!";
198        }
199
200        if (intents.includes('goodbye')) {
201            final = "Catch you on the flip side of the blockchain! Stay cool. 🐧 " + (final || "");
202        }
203
204        // Light anti-repetition: if repeated a lot, vary
205        const repeats = (window.tuxEngine.context.repeatCount[matchedKey] || 0);
206        if (repeats > 2 && final) {
207            final = final + " (We've chatted about this a bit - want the deep dive or something new?)";
208        }
209
210        return final;
211    };
212
213    console.log('tux_ai/response-engine.js loaded - Advanced Tux AI engine ready.');
214})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.