nothumanallowed 3.3.0 → 3.4.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.
- package/package.json +1 -1
- package/src/commands/ui.mjs +29 -16
- package/src/services/web-ui.mjs +21 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents for security, code, DevOps, data & daily ops. Ask agents directly, plan your day with 5 specialist agents, manage tasks, connect Gmail + Calendar.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -450,11 +450,17 @@ export async function cmdUI(args) {
|
|
|
450
450
|
return;
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
-
// GET /api/calendar
|
|
453
|
+
// GET /api/calendar?date=YYYY-MM-DD
|
|
454
454
|
if (method === 'GET' && pathname === '/api/calendar') {
|
|
455
455
|
try {
|
|
456
|
-
const
|
|
457
|
-
|
|
456
|
+
const dateParam = url.searchParams.get('date');
|
|
457
|
+
let events;
|
|
458
|
+
if (dateParam && dateParam !== new Date().toISOString().split('T')[0]) {
|
|
459
|
+
events = await getEventsForDate(config, new Date(dateParam));
|
|
460
|
+
} else {
|
|
461
|
+
events = await getTodayEvents(config);
|
|
462
|
+
}
|
|
463
|
+
sendJSON(res, 200, { events, date: dateParam || new Date().toISOString().split('T')[0] });
|
|
458
464
|
} catch (e) {
|
|
459
465
|
sendJSON(res, 200, { events: [], error: e.message });
|
|
460
466
|
}
|
|
@@ -550,26 +556,33 @@ export async function cmdUI(args) {
|
|
|
550
556
|
const { textParts, actions } = parseActions(response);
|
|
551
557
|
const textResponse = textParts.join('\n\n');
|
|
552
558
|
|
|
553
|
-
// Execute tool actions
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
if (actions.length > 0) {
|
|
557
|
-
const { action, params } = actions[0];
|
|
558
|
-
executedAction = action;
|
|
559
|
+
// Execute ALL tool actions and collect results
|
|
560
|
+
const toolResults = [];
|
|
561
|
+
for (const { action, params } of actions) {
|
|
559
562
|
try {
|
|
560
|
-
|
|
563
|
+
const result = await executeTool(action, params, config);
|
|
564
|
+
toolResults.push({ action, result: typeof result === 'object' ? JSON.stringify(result) : String(result) });
|
|
561
565
|
} catch (e) {
|
|
562
|
-
|
|
566
|
+
toolResults.push({ action, result: `Error: ${e.message}` });
|
|
563
567
|
}
|
|
564
568
|
}
|
|
565
569
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
+
let fullResponse;
|
|
571
|
+
if (toolResults.length > 0) {
|
|
572
|
+
// Second LLM call with real tool results — forces the LLM to use actual data
|
|
573
|
+
const toolContext = toolResults.map(t => `[${t.action} result]: ${t.result}`).join('\n\n');
|
|
574
|
+
const followUp = `The user asked: "${body.message}"\n\nI executed these tools and got REAL results:\n\n${toolContext}\n\nNow respond to the user based ONLY on the REAL data above. Do NOT invent or fabricate any information. Present the actual results clearly.`;
|
|
575
|
+
try {
|
|
576
|
+
fullResponse = await callLLM(config, chatSystemPrompt, followUp);
|
|
577
|
+
} catch {
|
|
578
|
+
// Fallback: show raw results
|
|
579
|
+
fullResponse = toolResults.map(t => `${t.action}: ${t.result}`).join('\n\n');
|
|
580
|
+
}
|
|
581
|
+
} else {
|
|
582
|
+
fullResponse = textResponse;
|
|
570
583
|
}
|
|
571
584
|
|
|
572
|
-
sendJSON(res, 200, { response: fullResponse,
|
|
585
|
+
sendJSON(res, 200, { response: fullResponse, toolResults, actions });
|
|
573
586
|
} catch (e) {
|
|
574
587
|
sendJSON(res, 200, { response: null, error: e.message });
|
|
575
588
|
}
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -343,13 +343,29 @@ function renderEmails(el){
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
// ---- CALENDAR ----
|
|
346
|
+
var calDate = new Date().toISOString().split('T')[0];
|
|
346
347
|
function renderCalendar(el){
|
|
347
|
-
var
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
348
|
+
var h='<div style="display:flex;gap:8px;align-items:center;margin-bottom:12px">'+
|
|
349
|
+
'<button class="btn btn--secondary" onclick="calNav(-1)"><</button>'+
|
|
350
|
+
'<span style="flex:1;text-align:center;font-weight:700;color:var(--bright)">'+calDate+(calDate===new Date().toISOString().split('T')[0]?' (today)':'')+'</span>'+
|
|
351
|
+
'<button class="btn btn--secondary" onclick="calNav(1)">></button>'+
|
|
352
|
+
'<button class="btn btn--secondary" onclick="calDate=new Date().toISOString().split(\\x27T\\x27)[0];renderCalendar(document.getElementById(\\x27content\\x27))">Today</button>'+
|
|
353
|
+
'</div><div id="calEvents"><div style="text-align:center;padding:20px"><div class="spinner"></div></div></div>';
|
|
352
354
|
el.innerHTML=h;
|
|
355
|
+
apiGet('/api/calendar?date='+calDate).then(function(r){
|
|
356
|
+
var ev=(r&&r.events)||[];
|
|
357
|
+
var ce=document.getElementById('calEvents');if(!ce)return;
|
|
358
|
+
if(ev.length===0){ce.innerHTML='<div class="card" style="text-align:center;color:var(--dim);padding:20px">No events on '+calDate+'</div>';return}
|
|
359
|
+
var out='';ev.forEach(function(x){
|
|
360
|
+
out+='<div class="card event"><span class="event__time">'+(x.isAllDay?'All day':fmtTime(x.start)+' - '+fmtTime(x.end))+'</span><span class="event__title">'+esc(x.summary)+'</span>'+(x.location?'<span class="event__location">'+esc(x.location)+'</span>':'')+'</div>';
|
|
361
|
+
});
|
|
362
|
+
ce.innerHTML=out;
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
function calNav(dir){
|
|
366
|
+
var d=new Date(calDate);d.setDate(d.getDate()+dir);
|
|
367
|
+
calDate=d.toISOString().split('T')[0];
|
|
368
|
+
renderCalendar(document.getElementById('content'));
|
|
353
369
|
}
|
|
354
370
|
|
|
355
371
|
// ---- AGENTS ----
|