neuronix-node 0.8.0 → 0.9.0

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.
Files changed (2) hide show
  1. package/dist/handlers/chat.js +126 -49
  2. package/package.json +1 -1
@@ -134,28 +134,12 @@ async function handleChat(task) {
134
134
  }
135
135
  }
136
136
  }
137
- // Step 2: No action detected — regular conversation
138
- // Try LLM for conversational response
139
- const modelIds = ["llama3-8b", "mistral-7b", "phi-2", "tinyllama-1.1b"];
140
- const loadedModel = modelIds.find((id) => (0, inference_js_1.isModelLoaded)(id));
141
- if (!loadedModel) {
142
- // No model loaded — provide a helpful static response
143
- const helpText = generateHelpResponse(messages);
144
- return {
145
- text: helpText,
146
- content: helpText,
147
- conversation_id: input.conversation_id,
148
- deployment_id: input.deployment_id,
149
- duration_ms: Date.now() - start,
150
- };
151
- }
152
- try {
153
- const prompt = formatConversation(messages);
154
- const { text, durationMs } = await (0, inference_js_1.runInference)(loadedModel, prompt, input.max_tokens || 512);
155
- const cleanedText = cleanResponse(text);
156
- // Check for preference updates
137
+ // Step 2: No action detected — try smart static responses FIRST
138
+ // Static responses are reliable and instant; LLM is unreliable with small models
139
+ const staticResponse = generateSmartResponse(messages);
140
+ if (staticResponse) {
157
141
  const memoryUpdates = detectPreferences(messages);
158
- let finalText = cleanedText;
142
+ let finalText = staticResponse;
159
143
  if (memoryUpdates.length > 0) {
160
144
  finalText += "\n" + memoryUpdates.map(m => `[MEMORY_UPDATE]${m.key}: ${m.value}[/MEMORY_UPDATE]`).join("\n");
161
145
  }
@@ -164,20 +148,40 @@ async function handleChat(task) {
164
148
  content: finalText,
165
149
  conversation_id: input.conversation_id,
166
150
  deployment_id: input.deployment_id,
167
- model: loadedModel,
168
- duration_ms: durationMs,
169
- };
170
- }
171
- catch {
172
- const helpText = generateHelpResponse(messages);
173
- return {
174
- text: helpText,
175
- content: helpText,
176
- conversation_id: input.conversation_id,
177
- deployment_id: input.deployment_id,
178
151
  duration_ms: Date.now() - start,
179
152
  };
180
153
  }
154
+ // Step 3: No static match — try LLM as last resort (may produce bad output)
155
+ const modelIds = ["llama3-8b", "mistral-7b", "phi-2", "tinyllama-1.1b"];
156
+ const loadedModel = modelIds.find((id) => (0, inference_js_1.isModelLoaded)(id));
157
+ if (loadedModel) {
158
+ try {
159
+ const prompt = formatConversation(messages);
160
+ const { text, durationMs } = await (0, inference_js_1.runInference)(loadedModel, prompt, input.max_tokens || 256);
161
+ const cleanedText = cleanResponse(text);
162
+ // Verify the LLM response is reasonable (not hallucinated garbage)
163
+ if (cleanedText.length > 10 && cleanedText.length < 2000 && !isGarbage(cleanedText)) {
164
+ return {
165
+ text: cleanedText,
166
+ content: cleanedText,
167
+ conversation_id: input.conversation_id,
168
+ deployment_id: input.deployment_id,
169
+ model: loadedModel,
170
+ duration_ms: durationMs,
171
+ };
172
+ }
173
+ }
174
+ catch { }
175
+ }
176
+ // Final fallback — always returns something useful
177
+ const fallback = "I'm not sure how to help with that specifically. Here are some things I can do:\n\n• Process expense reports, payroll, invoices\n• Generate P&L statements, cash flow, budget comparisons\n• Run AR/AP aging reports\n• Create charts from your data\n\nTry asking me something like \"run my expense report\" or type \"help\" for the full list.";
178
+ return {
179
+ text: fallback,
180
+ content: fallback,
181
+ conversation_id: input.conversation_id,
182
+ deployment_id: input.deployment_id,
183
+ duration_ms: Date.now() - start,
184
+ };
181
185
  }
182
186
  /**
183
187
  * Build a natural language response after running an action.
@@ -257,34 +261,107 @@ function buildActionResponse(intent, result) {
257
261
  /**
258
262
  * Generate a helpful response when no LLM is available.
259
263
  */
260
- function generateHelpResponse(messages) {
264
+ /**
265
+ * Smart static response generator — covers common questions without needing the LLM.
266
+ * Returns null if no pattern matches (falls through to LLM).
267
+ */
268
+ function generateSmartResponse(messages) {
261
269
  const lastUser = [...messages].reverse().find(m => m.role === "user");
262
- const userText = lastUser?.content.toLowerCase() || "";
263
- if (/help|what can you do|capabilities/.test(userText)) {
264
- return `Here's what I can do for you. Just ask in plain English:
265
-
270
+ if (!lastUser)
271
+ return null;
272
+ const text = lastUser.content.toLowerCase().trim();
273
+ // Greetings
274
+ if (/^(hi|hello|hey|howdy|good morning|good afternoon|good evening|sup|yo|what's up)[\s!?.]*$/i.test(text)) {
275
+ return "Hi! I'm your accounting bot. I can run reports, process files, calculate payroll, and more.\n\nJust tell me what you need — for example:\n• \"Run my expense report\"\n• \"Show me who owes us money\"\n• \"Run payroll\"\n\nOr type \"help\" to see everything I can do.";
276
+ }
277
+ // Help / capabilities
278
+ if (/help|what can you do|what do you do|capabilities|features|commands|options|menu/i.test(text)) {
279
+ return `Here's everything I can do. Just ask in plain English:\n
280
+ 📊 REPORTS
266
281
  • "Run my expense report" — categorize and summarize expenses
267
282
  • "Generate a P&L" — Profit & Loss statement
268
- • "Create an invoice" — generate a formatted invoice
269
- • "Run payroll" — calculate gross, taxes, deductions, net pay
270
- • "Show me AR aging" — who owes money and how overdue
271
- • "Show me AP aging" — what we owe vendors
272
- "Reconcile the bank" — match bank vs book transactions
283
+ • "Cash flow statement" — operating, investing, financing
284
+ • "Department spending report" — spending by team/department
285
+ • "Variance analysis" — find where you're over/under budget
286
+
287
+ 💰 ACCOUNTING
288
+ • "Run payroll" — gross pay, taxes, deductions, net pay
289
+ • "Show me AR aging" — who owes you money and how overdue
290
+ • "Show me AP aging" — what you owe vendors
291
+ • "Reconcile the bank" — match bank statement to your books
273
292
  • "Budget vs actuals" — compare spending to budget
293
+
294
+ 📋 TAX & COMPLIANCE
274
295
  • "Calculate sales tax" — multi-state tax tracking
275
296
  • "Depreciation schedule" — fixed asset depreciation
276
- • "Cash flow statement" — operating/investing/financing
277
- • "Department spending" — spending by department
278
- "Variance analysis" — find significant budget variances
279
- • "W-2 and 1099 prep" — year-end tax form compilation
297
+ • "W-2 and 1099 prep" — year-end tax form data
298
+
299
+ 📈 OTHER
300
+ • "Create an invoice" — generate a formatted invoice
280
301
  • "Make a chart" — visualize any data
302
+ • "Process my files" — upload files and I'll figure out what to do
281
303
 
282
304
  Just tell me what you need!`;
283
305
  }
284
- if (/hi|hello|hey/.test(userText)) {
285
- return "Hi! I'm your accounting bot. I can run reports, calculate payroll, reconcile accounts, and more. Just tell me what you need — for example, \"run my expense report\" or \"show me the P&L.\"";
306
+ // Thanks / acknowledgment
307
+ if (/^(thanks|thank you|thx|ty|appreciate|perfect|great|awesome|nice|cool|got it|ok|okay)[\s!?.]*$/i.test(text)) {
308
+ return "You're welcome! Let me know if you need anything else.";
309
+ }
310
+ // Goodbye
311
+ if (/^(bye|goodbye|see you|later|good night|gn|cya|ttyl)[\s!?.]*$/i.test(text)) {
312
+ return "Goodbye! I'll be here whenever you need me.";
313
+ }
314
+ // Status / what's happening
315
+ if (/status|what.*happening|what.*going on|update/i.test(text)) {
316
+ return "Everything is running smoothly. Your workspace is ready for files. Upload CSVs to the inbox and I'll process them automatically, or ask me to run a specific report.";
317
+ }
318
+ // How does it work / how to use
319
+ if (/how.*(work|use|start|begin|get started)|tutorial|guide/i.test(text)) {
320
+ return "Here's how to use me:\n\n1. **Upload files** — drag CSVs into the Files tab (expenses, invoices, bank statements, etc.)\n2. **I auto-detect the file type** and process it with the right handler\n3. **Download the output** — clean formatted reports appear in the outputs folder\n\nOr just tell me what you need in chat:\n• \"Run my expense report\"\n• \"Show me AR aging\"\n• \"Run payroll\"\n\nI work with the data in your workspace. The more files you upload, the more I can do.";
321
+ }
322
+ // Questions about files
323
+ if (/what files|which files|my files|file types|what.*upload|what.*accept/i.test(text)) {
324
+ return "I can process these file types:\n\n• **CSV files** — expenses, invoices, bank statements, payroll, budgets\n• **Excel files** (.xlsx) — same as CSV, I'll parse the data\n• **PDF files** — invoices, receipts, statements\n\nJust upload them to the inbox in the Files tab. I'll automatically detect what they are and process them with the right handler.";
325
+ }
326
+ // Process files
327
+ if (/process.*file|run.*file|handle.*file|analyze.*file/i.test(text) && !/expense|payroll|invoice|budget/i.test(text)) {
328
+ return "To process files:\n\n1. Go to the **📁 Files** tab\n2. Upload your files (drag & drop or click Upload)\n3. Select the files you want processed\n4. Choose **Process Individually** or **Merge & Process**\n\nOr just upload them — if auto-processing is on, I'll handle them automatically.";
329
+ }
330
+ // Pricing / cost questions
331
+ if (/price|cost|how much|pricing|subscription|plan/i.test(text)) {
332
+ return "Neuronix offers three plans:\n\n• **Starter** ($49.99/mo) — 3 bots, 5,000 tasks\n• **Pro** ($149.99/mo) — 5 bots, 25,000 tasks\n• **Enterprise** ($499.99/mo) — 10 bots, 500,000 tasks\n\nVisit neuronix-nu.vercel.app/pricing for full details.";
333
+ }
334
+ // Who are you / what are you
335
+ if (/who are you|what are you|about you|your name/i.test(text)) {
336
+ return "I'm your Neuronix accounting bot. I automate financial tasks like expense reports, payroll, bank reconciliation, and more. I work with the files in your workspace — upload data and I'll process it into clean, formatted reports.\n\nI'm powered by a decentralized GPU network, so your data is processed securely and never stored.";
337
+ }
338
+ // No match — return null to fall through to LLM
339
+ return null;
340
+ }
341
+ /**
342
+ * Check if LLM output is garbage (hallucinated, repetitive, or nonsensical)
343
+ */
344
+ function isGarbage(text) {
345
+ // Contains file paths from the system prompt
346
+ if (/inbox\/|outputs\/|\.csv/i.test(text) && text.split("/").length > 5)
347
+ return true;
348
+ // Contains the system prompt instructions
349
+ if (/CAPABILITIES:|BEHAVIOR:|ACTIONS YOU CAN TRIGGER:/i.test(text))
350
+ return true;
351
+ // Repeating the same phrase
352
+ const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 10);
353
+ if (sentences.length >= 3) {
354
+ const unique = new Set(sentences.map(s => s.trim().toLowerCase()));
355
+ if (unique.size < sentences.length * 0.5)
356
+ return true;
286
357
  }
287
- return "I can help with that. Try asking me to run a specific report like \"expense report\", \"P&L\", \"payroll\", or \"AR aging\". Type \"help\" to see everything I can do.";
358
+ // Contains "User:" or "Assistant:" (prompt leakage)
359
+ if (/\bUser:\s|^Assistant:\s/m.test(text))
360
+ return true;
361
+ // Just safety guidelines or generic advice
362
+ if (/always answer questions as honestly|avoid answering questions that do not make sense/i.test(text))
363
+ return true;
364
+ return false;
288
365
  }
289
366
  function formatConversation(messages) {
290
367
  const parts = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neuronix-node",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Neuronix GPU Provider Node — earn by contributing compute to the Neuronix network",
5
5
  "main": "dist/index.js",
6
6
  "bin": {