nothumanallowed 13.5.104 → 13.5.106
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 +200 -4
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.106",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -2731,6 +2731,7 @@ export async function cmdUI(args) {
|
|
|
2731
2731
|
const hasWriting = /scrivi|write|articolo|article|blog|testo|text|documento|document/i.test(taskLow);
|
|
2732
2732
|
const hasData = /dati|data|dataset|csv|json|analizza i dati|pattern|statistich/i.test(taskLow);
|
|
2733
2733
|
const hasTranslate = /traduci|translate|traduzione|translation/i.test(taskLow);
|
|
2734
|
+
const hasTravel = /ristorante|restaurant|b&b|hotel|albergo|agriturismo|locanda|osteria|prenotaz|vacanz|romantico|sushi|giapponese|cinese|pizza|cena|dinner|pranzo|lunch|soggiorno|weekend|pernottament|posto\s+dove\s+mangiare|posto\s+dove\s+dormire|dove\s+mangiare|dove\s+dormire|posto\s+romantico|gita|escursione/i.test(taskLow);
|
|
2734
2735
|
|
|
2735
2736
|
const it = plannerLang === 'Italian';
|
|
2736
2737
|
|
|
@@ -2754,6 +2755,7 @@ export async function cmdUI(args) {
|
|
|
2754
2755
|
const pdfName = body.pdfName || 'documento allegato';
|
|
2755
2756
|
steps.push({icon:'\u{1F4C4}',agent:'DocumentReaderAgent',label:it?'Leggi documento':'Read document',reason:it?'Allegato PDF rilevato \u2014 estraggo dati tecnici prima di ogni altra operazione':'PDF attachment detected \u2014 extracting technical data first',prompt:`Extract all technical specifications, model numbers, part codes, product names, manufacturer, dimensions, ratings, and any other key data from the attached document "${pdfName}". List every technical detail precisely.`});
|
|
2756
2757
|
}
|
|
2758
|
+
if (hasTravel) steps.push({icon:'\u{1F374}',agent:'TravelAgent', label:it?'Ricerca ristoranti & hotel':'Search restaurants & hotels', reason:it?'Task di viaggio/prenotazione: cerco disponibilità reale su TheFork, Booking, TripAdvisor con browser automation':'Travel/booking task: searching real availability on TheFork, Booking, TripAdvisor with browser automation', prompt:task});
|
|
2757
2759
|
if (hasEmail) steps.push({icon:'\u{1F4E7}',agent:'EmailAgent', label:it?'Controlla email':'Check emails', reason:it?'Parola chiave email/mail/posta rilevata nel task':'Keyword email/mail detected in task', prompt:'Read the latest unread emails and identify urgent items, deadlines, and required actions'});
|
|
2758
2760
|
if (hasCalendar) steps.push({icon:'\u{1F4C5}',agent:'CalendarAgent', label:it?'Rivedi calendario':'Review calendar', reason:it?'Parola chiave calendario/agenda/eventi rilevata nel task':'Keyword calendar/agenda/events detected in task', prompt:'Check today\'s events and identify any scheduling conflicts or important meetings'});
|
|
2759
2761
|
if (hasGitHub) steps.push({icon:'\u{1F4BB}',agent:'GitHubAgent', label:'GitHub', reason:it?'Parola chiave GitHub/git/issue/PR rilevata nel task':'Keyword GitHub/git/issue/PR detected in task', prompt:'Read open issues and pull requests, identify what needs attention'});
|
|
@@ -2761,7 +2763,7 @@ export async function cmdUI(args) {
|
|
|
2761
2763
|
if (hasNotion) steps.push({icon:'\u{1F4DD}',agent:'NotionAgent', label:'Notion', reason:it?'Parola chiave Notion/note rilevata nel task':'Keyword Notion/note detected in task', prompt:'Search Notion for relevant pages and notes'});
|
|
2762
2764
|
// When PDF is present: always search web (to find where to buy, similar products etc.)
|
|
2763
2765
|
// The search query will be refined at runtime using the extracted PDF specs as context
|
|
2764
|
-
if (hasPdf || hasSearch || hasReputation || (!hasEmail && !hasCalendar && !hasGitHub && !hasSlack)) {
|
|
2766
|
+
if (!hasTravel && (hasPdf || hasSearch || hasReputation || (!hasEmail && !hasCalendar && !hasGitHub && !hasSlack))) {
|
|
2765
2767
|
const searchPrompt = hasPdf
|
|
2766
2768
|
? (it ? 'Usando le specifiche tecniche estratte dal documento (codice prodotto, modello, costruttore, caratteristiche), cerca online dove acquistare il prodotto o articoli equivalenti. Usa i codici esatti dal documento come query di ricerca.' : 'Using the technical specifications extracted from the document (product code, model, manufacturer, specs), search online for where to buy this product or equivalent alternatives. Use exact codes from the document as search queries.')
|
|
2767
2769
|
: searchQuery;
|
|
@@ -2851,7 +2853,7 @@ Review the plan above. You may:
|
|
|
2851
2853
|
- ADJUST the "prompt" field of any step to better match the task
|
|
2852
2854
|
- KEEP steps that are correct as-is
|
|
2853
2855
|
|
|
2854
|
-
Available agents: WebSearchAgent, DocumentReaderAgent, EmailAgent, CalendarAgent, GitHubAgent, SlackAgent, NotionAgent, HERALD, ORACLE, ATHENA, CASSANDRA, MERCURY, QUILL, DataAnalystAgent, polyglot, CanvasAgent (last, only if visual output needed).
|
|
2856
|
+
Available agents: TravelAgent (restaurants/hotels/bookings with real browser automation on TheFork/Booking/TripAdvisor), WebSearchAgent, DocumentReaderAgent, EmailAgent, CalendarAgent, GitHubAgent, SlackAgent, NotionAgent, HERALD, ORACLE, ATHENA, CASSANDRA, MERCURY, QUILL, DataAnalystAgent, polyglot, CanvasAgent (last, only if visual output needed).
|
|
2855
2857
|
|
|
2856
2858
|
Output ONLY:
|
|
2857
2859
|
{"steps":[{"icon":"EMOJI","agent":"AGENT_NAME","label":"LABEL","reason":"WHY THIS AGENT","prompt":"INSTRUCTION"}]}
|
|
@@ -2869,7 +2871,7 @@ Language for labels: ${plannerLang}.
|
|
|
2869
2871
|
|
|
2870
2872
|
Build a workflow plan for this task.
|
|
2871
2873
|
|
|
2872
|
-
Available agents: WebSearchAgent, DocumentReaderAgent, EmailAgent, CalendarAgent, GitHubAgent, SlackAgent, NotionAgent, HERALD, ORACLE, ATHENA, CASSANDRA, MERCURY, QUILL, DataAnalystAgent, polyglot, CanvasAgent.
|
|
2874
|
+
Available agents: TravelAgent (restaurants/hotels/bookings with real browser automation on TheFork/Booking/TripAdvisor), WebSearchAgent, DocumentReaderAgent, EmailAgent, CalendarAgent, GitHubAgent, SlackAgent, NotionAgent, HERALD, ORACLE, ATHENA, CASSANDRA, MERCURY, QUILL, DataAnalystAgent, polyglot, CanvasAgent.
|
|
2873
2875
|
|
|
2874
2876
|
Output ONLY:
|
|
2875
2877
|
{"steps":[{"icon":"EMOJI","agent":"AGENT_NAME","label":"LABEL","reason":"WHY THIS AGENT","prompt":"INSTRUCTION"}]}
|
|
@@ -3170,6 +3172,200 @@ ${rawText.slice(0, 18000)}`;
|
|
|
3170
3172
|
}
|
|
3171
3173
|
} catch (e) { toolData = toolData || `Web search failed: ${e.message}`; }
|
|
3172
3174
|
|
|
3175
|
+
} else if (agent === 'TravelAgent') {
|
|
3176
|
+
sendToken('[TravelAgent: analyzing your request...] ');
|
|
3177
|
+
try {
|
|
3178
|
+
const be = await import('../services/browser-engine.mjs');
|
|
3179
|
+
const travelTask = stepPrompt || task;
|
|
3180
|
+
|
|
3181
|
+
// ── Extract parameters from task ──
|
|
3182
|
+
// Date: "16 maggio", "16/05", "16-05-2026", "sabato 16", etc.
|
|
3183
|
+
// ── PARAMETER EXTRACTION ──
|
|
3184
|
+
const monthNames = {gennaio:1,febbraio:2,marzo:3,aprile:4,maggio:5,giugno:6,luglio:7,agosto:8,settembre:9,ottobre:10,novembre:11,dicembre:12};
|
|
3185
|
+
const dateMatch = travelTask.match(/(\d{1,2})\s+(gennaio|febbraio|marzo|aprile|maggio|giugno|luglio|agosto|settembre|ottobre|novembre|dicembre)/i)
|
|
3186
|
+
|| travelTask.match(/(\d{1,2})[\/\-](\d{1,2})(?:[\/\-](\d{4}))?/);
|
|
3187
|
+
let targetDate = null;
|
|
3188
|
+
let targetDateStr = null;
|
|
3189
|
+
if (dateMatch) {
|
|
3190
|
+
if (dateMatch[2] && isNaN(Number(dateMatch[2]))) {
|
|
3191
|
+
const day = parseInt(dateMatch[1]);
|
|
3192
|
+
const month = monthNames[(dateMatch[2] || '').toLowerCase()];
|
|
3193
|
+
if (day && month) {
|
|
3194
|
+
const year = new Date().getFullYear();
|
|
3195
|
+
targetDate = new Date(year, month - 1, day);
|
|
3196
|
+
targetDateStr = String(day).padStart(2, '0') + '/' + String(month).padStart(2, '0') + '/' + year;
|
|
3197
|
+
}
|
|
3198
|
+
} else if (dateMatch[1] && dateMatch[2]) {
|
|
3199
|
+
const day = parseInt(dateMatch[1]);
|
|
3200
|
+
const month = parseInt(dateMatch[2]);
|
|
3201
|
+
const year = dateMatch[3] ? parseInt(dateMatch[3]) : new Date().getFullYear();
|
|
3202
|
+
if (day >= 1 && day <= 31 && month >= 1 && month <= 12) {
|
|
3203
|
+
targetDate = new Date(year, month - 1, day);
|
|
3204
|
+
targetDateStr = String(day).padStart(2, '0') + '/' + String(month).padStart(2, '0') + '/' + year;
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
|
|
3209
|
+
// City: "a Mantova", "in Bologna", "near Milan", "vicino a Firenze"
|
|
3210
|
+
const cityMatch = travelTask.match(/\b(?:a|in|near|vicino\s+a|at|around)\s+([A-Za-z][a-zA-Z\s]{2,25}?)(?:\s*[,\.!?\n]|\s+(?:il|la|per|con|un|una|mi|mia|del|della|per\s+la|il\s+|la\s+)|$)/i);
|
|
3211
|
+
const city = cityMatch ? cityMatch[1].trim().replace(/\s+$/, '') : null;
|
|
3212
|
+
|
|
3213
|
+
// Cuisine type → OSM cuisine tag
|
|
3214
|
+
const cuisineMap = {sushi:'sushi',pizza:'pizza',giapponese:'japanese',japanese:'japanese',italiano:'italian',italian:'italian',cinese:'chinese',chinese:'chinese',indiano:'indian',indian:'indian',steakhouse:'steak_house',trattoria:'italian',osteria:'italian'};
|
|
3215
|
+
const cuisineMatch = travelTask.match(/\b(sushi|pizza|giapponese|japanese|italiano|italian|cinese|chinese|indiano|indian|steakhouse|trattoria|osteria)\b/i);
|
|
3216
|
+
const cuisineRaw = cuisineMatch ? cuisineMatch[1].toLowerCase() : null;
|
|
3217
|
+
const cuisineOSM = cuisineRaw ? (cuisineMap[cuisineRaw] || cuisineRaw) : null;
|
|
3218
|
+
|
|
3219
|
+
const hasAccommodation = /b&b|bed\s*(?:&|and)\s*breakfast|hotel|albergo|agriturismo|locanda|ostello|hostel|pernottament|soggiorno/i.test(travelTask);
|
|
3220
|
+
const hasRestaurant = /ristorante|restaurant|sushi|cena|dinner|pranzo|lunch|mangiare|eat/i.test(travelTask);
|
|
3221
|
+
|
|
3222
|
+
const summaryParts = [];
|
|
3223
|
+
if (city) summaryParts.push('city: ' + city);
|
|
3224
|
+
if (targetDateStr) summaryParts.push('date: ' + targetDateStr);
|
|
3225
|
+
if (cuisineRaw) summaryParts.push('cuisine: ' + cuisineRaw);
|
|
3226
|
+
if (hasAccommodation) summaryParts.push('accommodation: yes');
|
|
3227
|
+
if (hasRestaurant) summaryParts.push('restaurant: yes');
|
|
3228
|
+
sendToken('[Extracted — ' + (summaryParts.join(', ') || 'general search') + '] ');
|
|
3229
|
+
|
|
3230
|
+
const UA = 'NHA-TravelAgent/1.0 (nothumanallowed.com)';
|
|
3231
|
+
const portalResults = [];
|
|
3232
|
+
|
|
3233
|
+
// ── TIER 1: Nominatim geocoding → get lat/lon for city ──
|
|
3234
|
+
let lat = null, lon = null;
|
|
3235
|
+
if (city) {
|
|
3236
|
+
sendToken('[Geocoding ' + city + '...] ');
|
|
3237
|
+
try {
|
|
3238
|
+
const geoUrl = 'https://nominatim.openstreetmap.org/search?' + new URLSearchParams({ q: city, format: 'json', limit: '1', addressdetails: '0' }).toString();
|
|
3239
|
+
const geoRes = await withTimeout(fetch(geoUrl, { headers: { 'User-Agent': UA, 'Accept': 'application/json' } }), 8000);
|
|
3240
|
+
if (geoRes.ok) {
|
|
3241
|
+
const geoData = await geoRes.json();
|
|
3242
|
+
if (geoData && geoData[0]) {
|
|
3243
|
+
lat = parseFloat(geoData[0].lat);
|
|
3244
|
+
lon = parseFloat(geoData[0].lon);
|
|
3245
|
+
sendToken('[Found: ' + lat.toFixed(4) + ', ' + lon.toFixed(4) + '] ');
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
} catch {}
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
// ── TIER 1: Overpass API — real OSM data ──
|
|
3252
|
+
if (lat !== null && lon !== null) {
|
|
3253
|
+
const radius = 5000; // 5km radius
|
|
3254
|
+
const formatPlace = (el) => {
|
|
3255
|
+
const t = el.tags || {};
|
|
3256
|
+
const parts = [];
|
|
3257
|
+
if (t.name) parts.push('**' + t.name + '**');
|
|
3258
|
+
if (t['addr:street']) parts.push(t['addr:street'] + (t['addr:housenumber'] ? ' ' + t['addr:housenumber'] : ''));
|
|
3259
|
+
if (t['addr:city']) parts.push(t['addr:city']);
|
|
3260
|
+
if (t.phone || t['contact:phone']) parts.push('Tel: ' + (t.phone || t['contact:phone']));
|
|
3261
|
+
if (t.website || t['contact:website']) parts.push('Web: ' + (t.website || t['contact:website']));
|
|
3262
|
+
if (t.opening_hours) parts.push('Orari: ' + t.opening_hours);
|
|
3263
|
+
if (t.email || t['contact:email']) parts.push('Email: ' + (t.email || t['contact:email']));
|
|
3264
|
+
if (t.cuisine) parts.push('Cucina: ' + t.cuisine);
|
|
3265
|
+
if (t.stars) parts.push('Stelle: ' + t.stars);
|
|
3266
|
+
const coordLat = el.lat || (el.center && el.center.lat);
|
|
3267
|
+
const coordLon = el.lon || (el.center && el.center.lon);
|
|
3268
|
+
if (coordLat && coordLon) parts.push('Maps: https://www.openstreetmap.org/?mlat=' + coordLat + '&mlon=' + coordLon + '&zoom=17');
|
|
3269
|
+
return parts.join(' | ');
|
|
3270
|
+
};
|
|
3271
|
+
|
|
3272
|
+
// Restaurants query
|
|
3273
|
+
if (hasRestaurant) {
|
|
3274
|
+
sendToken('[Overpass: searching restaurants' + (cuisineOSM ? ' (' + cuisineOSM + ')' : '') + '...] ');
|
|
3275
|
+
try {
|
|
3276
|
+
const cuisineFilter = cuisineOSM ? '["cuisine"="' + cuisineOSM + '"]' : '';
|
|
3277
|
+
const restQuery = '[out:json][timeout:20];(node["amenity"="restaurant"]' + cuisineFilter + '(around:' + radius + ',' + lat + ',' + lon + ');way["amenity"="restaurant"]' + cuisineFilter + '(around:' + radius + ',' + lat + ',' + lon + '););out center tags;';
|
|
3278
|
+
const restRes = await withTimeout(fetch('https://overpass.kumi.systems/api/interpreter', {
|
|
3279
|
+
method: 'POST',
|
|
3280
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': UA },
|
|
3281
|
+
body: 'data=' + encodeURIComponent(restQuery)
|
|
3282
|
+
}), 25000);
|
|
3283
|
+
if (restRes.ok) {
|
|
3284
|
+
const restData = await restRes.json();
|
|
3285
|
+
const elements = (restData.elements || []).filter(el => el.tags && el.tags.name);
|
|
3286
|
+
if (elements.length > 0) {
|
|
3287
|
+
const lines = ['## Ristoranti trovati via OpenStreetMap (' + elements.length + ' risultati, raggio ' + (radius/1000) + 'km da ' + city + ')'];
|
|
3288
|
+
elements.slice(0, 15).forEach((el, i) => { lines.push((i+1) + '. ' + formatPlace(el)); });
|
|
3289
|
+
portalResults.push(lines.join('\n'));
|
|
3290
|
+
sendToken('[Found ' + elements.length + ' restaurants] ');
|
|
3291
|
+
} else if (cuisineOSM) {
|
|
3292
|
+
// Retry without cuisine filter — broader search
|
|
3293
|
+
sendToken('[No ' + cuisineOSM + ' found, retrying broader...] ');
|
|
3294
|
+
const broadQuery = '[out:json][timeout:20];(node["amenity"="restaurant"](around:' + radius + ',' + lat + ',' + lon + ');way["amenity"="restaurant"](around:' + radius + ',' + lat + ',' + lon + '););out center tags;';
|
|
3295
|
+
const broadRes = await withTimeout(fetch('https://overpass.kumi.systems/api/interpreter', {
|
|
3296
|
+
method: 'POST',
|
|
3297
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': UA },
|
|
3298
|
+
body: 'data=' + encodeURIComponent(broadQuery)
|
|
3299
|
+
}), 25000);
|
|
3300
|
+
if (broadRes.ok) {
|
|
3301
|
+
const broadData = await broadRes.json();
|
|
3302
|
+
const broadEl = (broadData.elements || []).filter(el => el.tags && el.tags.name);
|
|
3303
|
+
if (broadEl.length > 0) {
|
|
3304
|
+
const lines = ['## Ristoranti a ' + city + ' (tutti i tipi, ' + broadEl.length + ' trovati — nessun ristorante ' + cuisineRaw + ' su OpenStreetMap in questa zona)'];
|
|
3305
|
+
broadEl.slice(0, 10).forEach((el, i) => { lines.push((i+1) + '. ' + formatPlace(el)); });
|
|
3306
|
+
portalResults.push(lines.join('\n'));
|
|
3307
|
+
}
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
} catch (e) { sendToken('[Overpass restaurants error: ' + e.message.slice(0,50) + '] '); }
|
|
3312
|
+
}
|
|
3313
|
+
|
|
3314
|
+
// Accommodation query
|
|
3315
|
+
if (hasAccommodation) {
|
|
3316
|
+
sendToken('[Overpass: searching accommodation...] ');
|
|
3317
|
+
try {
|
|
3318
|
+
const accQuery = '[out:json][timeout:20];(node["tourism"~"hotel|guest_house|bed_and_breakfast|hostel|motel"](around:' + radius + ',' + lat + ',' + lon + ');way["tourism"~"hotel|guest_house|bed_and_breakfast|hostel|motel"](around:' + radius + ',' + lat + ',' + lon + ');node["amenity"="hotel"](around:' + radius + ',' + lat + ',' + lon + '););out center tags;';
|
|
3319
|
+
const accRes = await withTimeout(fetch('https://overpass.kumi.systems/api/interpreter', {
|
|
3320
|
+
method: 'POST',
|
|
3321
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': UA },
|
|
3322
|
+
body: 'data=' + encodeURIComponent(accQuery)
|
|
3323
|
+
}), 25000);
|
|
3324
|
+
if (accRes.ok) {
|
|
3325
|
+
const accData = await accRes.json();
|
|
3326
|
+
const elements = (accData.elements || []).filter(el => el.tags && el.tags.name);
|
|
3327
|
+
if (elements.length > 0) {
|
|
3328
|
+
const lines = ['## Alloggi trovati via OpenStreetMap (' + elements.length + ' risultati, raggio ' + (radius/1000) + 'km da ' + city + ')'];
|
|
3329
|
+
elements.slice(0, 15).forEach((el, i) => {
|
|
3330
|
+
const t = el.tags || {};
|
|
3331
|
+
const type = t.tourism === 'guest_house' ? 'B&B/Guest house' : t.tourism === 'hotel' ? 'Hotel' : t.tourism === 'bed_and_breakfast' ? 'B&B' : (t.tourism || 'Alloggio');
|
|
3332
|
+
lines.push((i+1) + '. [' + type + '] ' + formatPlace(el));
|
|
3333
|
+
});
|
|
3334
|
+
portalResults.push(lines.join('\n'));
|
|
3335
|
+
sendToken('[Found ' + elements.length + ' accommodations] ');
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
} catch (e) { sendToken('[Overpass accommodation error: ' + e.message.slice(0,50) + '] '); }
|
|
3339
|
+
}
|
|
3340
|
+
} else if (city) {
|
|
3341
|
+
sendToken('[Geocoding failed, skipping Overpass] ');
|
|
3342
|
+
}
|
|
3343
|
+
|
|
3344
|
+
// ── TIER 2: Web search fallback — targeted queries ──
|
|
3345
|
+
const dataFound = portalResults.length > 0 && portalResults.some(r => r.includes('trovati') && !r.includes('0 risultati'));
|
|
3346
|
+
if (!dataFound) {
|
|
3347
|
+
sendToken('[Web search fallback...] ');
|
|
3348
|
+
try {
|
|
3349
|
+
const queries = [
|
|
3350
|
+
[cuisineRaw, 'ristorante', city].filter(Boolean).join(' '),
|
|
3351
|
+
hasAccommodation ? ['b&b romantico', city, targetDateStr ? targetDateStr.slice(0,5) : ''].filter(Boolean).join(' ') : null
|
|
3352
|
+
].filter(Boolean);
|
|
3353
|
+
for (const q of queries) {
|
|
3354
|
+
const sr = await withTimeout(executeTool('web_search', { query: q, deep: true }, config), 30000);
|
|
3355
|
+
if (sr && sr.length > 100) portalResults.push('## Web search: "' + q + '"\n' + (typeof sr === 'string' ? sr : JSON.stringify(sr)));
|
|
3356
|
+
}
|
|
3357
|
+
} catch {}
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3360
|
+
// ── Build final output ──
|
|
3361
|
+
if (portalResults.length > 0) {
|
|
3362
|
+
const header = '# TravelAgent — Risultati per: ' + (city || 'zona non specificata') + (targetDateStr ? ' | Data: ' + targetDateStr : '') + (cuisineRaw ? ' | Cucina: ' + cuisineRaw : '') + '\n\n';
|
|
3363
|
+
toolData = header + portalResults.join('\n\n');
|
|
3364
|
+
} else {
|
|
3365
|
+
toolData = '# TravelAgent — Nessun risultato trovato\n\nNon sono stati trovati ristoranti o alloggi per i parametri specificati.\n\n**Parametri cercati:**\n- Città: ' + (city || 'non specificata') + '\n- Data: ' + (targetDateStr || 'non specificata') + '\n- Tipo cucina: ' + (cuisineRaw || 'qualsiasi') + '\n\n**Suggerimento:** Specifica la città esatta (es. "a Mantova") e il tipo di cucina per ottenere risultati migliori.';
|
|
3366
|
+
}
|
|
3367
|
+
} catch (e) { toolData = toolData || 'TravelAgent failed: ' + e.message; }
|
|
3368
|
+
|
|
3173
3369
|
} else if (agent === 'BrowserAgent') {
|
|
3174
3370
|
// Collect all URLs from stepPrompt + task, plus infer subpaths mentioned (e.g. /about, /docs)
|
|
3175
3371
|
const allUrlMatches = [...new Set((stepPrompt + ' ' + task).match(/https?:\/\/[^\s"'<>)]+/g) || [])];
|
|
@@ -3378,7 +3574,7 @@ ${rawText.slice(0, 18000)}`;
|
|
|
3378
3574
|
const today = new Date().toISOString().split('T')[0];
|
|
3379
3575
|
const isCanvasAgent = agent === 'CanvasAgent';
|
|
3380
3576
|
// Tool-data agents: fetch real live data and use buildSystemPrompt (tool calls allowed)
|
|
3381
|
-
const isLiveDataAgent = ['CalendarAgent','EmailAgent','GitHubAgent','NotionAgent','SlackAgent','DriveAgent','BrowserAgent','WebSearchAgent','ResearchAgent','FileReaderAgent','CodeExecutorAgent'].includes(agent);
|
|
3577
|
+
const isLiveDataAgent = ['CalendarAgent','EmailAgent','GitHubAgent','NotionAgent','SlackAgent','DriveAgent','BrowserAgent','WebSearchAgent','ResearchAgent','FileReaderAgent','CodeExecutorAgent','TravelAgent'].includes(agent);
|
|
3382
3578
|
|
|
3383
3579
|
// ── Canvas HTML template — built server-side, guaranteed CSS ─────
|
|
3384
3580
|
// The LLM outputs ONLY the <body> inner HTML (no <html>, no <style>)
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '13.5.
|
|
8
|
+
export const VERSION = '13.5.106';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -6144,6 +6144,7 @@ function renderStudio(el) {
|
|
|
6144
6144
|
|
|
6145
6145
|
// Agent catalog
|
|
6146
6146
|
var STUDIO_AGENTS = [
|
|
6147
|
+
{icon:'🍴',name:'TravelAgent',desc:'Restaurants, hotels & bookings (browser automation)'},
|
|
6147
6148
|
{icon:'🔍',name:'WebSearchAgent',desc:'Search the web'},
|
|
6148
6149
|
{icon:'🌐',name:'BrowserAgent',desc:'Navigate & screenshot pages'},
|
|
6149
6150
|
{icon:'💌',name:'EmailAgent',desc:'Read & summarize emails'},
|