nothumanallowed 14.1.70 → 14.1.71
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/constants.mjs +1 -1
- package/src/server/routes/studio.mjs +211 -99
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "14.1.
|
|
3
|
+
"version": "14.1.71",
|
|
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/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 = '14.1.
|
|
8
|
+
export const VERSION = '14.1.71';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -15,9 +15,67 @@ import { webSearch, fetchUrl } from '../../services/web-tools.mjs';
|
|
|
15
15
|
const WEB_TOOL_AGENTS = new Set([
|
|
16
16
|
'WebSearchAgent', 'TravelAgent', 'mercury', 'MERCURY',
|
|
17
17
|
'athena', 'ATHENA', 'oracle', 'ORACLE', 'cassandra', 'CASSANDRA',
|
|
18
|
-
'HERALD', 'DataAnalystAgent',
|
|
18
|
+
'HERALD', 'DataAnalystAgent', 'herald', 'tempest', 'TEMPEST',
|
|
19
|
+
'epicure', 'EPICURE', 'cartographer', 'CARTOGRAPHER',
|
|
19
20
|
]);
|
|
20
21
|
|
|
22
|
+
// ── Complete Agent Registry ─────────────────────────────────────────────────
|
|
23
|
+
// Each entry: [emoji, name, short description for the planner]
|
|
24
|
+
const AGENT_REGISTRY = [
|
|
25
|
+
['🔍','WebSearchAgent', 'Web search and real-time data retrieval. Use for any task needing current web information.'],
|
|
26
|
+
['🍽','TravelAgent', 'Restaurant, hotel, B&B, travel recommendations. Searches web for real venues with reviews and prices.'],
|
|
27
|
+
['📄','DocumentReaderAgent','Extract data from attached PDFs: specs, tables, model numbers, technical details.'],
|
|
28
|
+
['📧','EmailAgent', 'Read/analyze inbox emails, identify urgent items and deadlines.'],
|
|
29
|
+
['📅','CalendarAgent', 'Review calendar events, find scheduling conflicts, plan meetings.'],
|
|
30
|
+
['💻','GitHubAgent', 'Analyze GitHub repos, issues, PRs, code quality metrics.'],
|
|
31
|
+
['💬','SlackAgent', 'Read Slack channels/messages, identify important conversations.'],
|
|
32
|
+
['📝','NotionAgent', 'Search and read Notion pages, databases, wikis.'],
|
|
33
|
+
['📰','HERALD', 'OSINT intelligence analyst. Synthesizes all collected data into executive briefings with sourced claims and bias flags. Best used as final synthesizer after other agents.'],
|
|
34
|
+
['🔭','ORACLE', 'Senior data scientist. Statistical inference, pattern recognition, decision science. Transforms raw data into actionable intelligence.'],
|
|
35
|
+
['♟','ATHENA', 'Technology research analyst. Evaluates frameworks, approaches, techniques with scientific rigor. Strategic technology recommendations.'],
|
|
36
|
+
['⚠','CASSANDRA', 'Risk analyst and predictive consequence engineer. Systematic risk assessment, threat modeling, scenario planning.'],
|
|
37
|
+
['💰','MERCURY', 'CFA-level financial market analyst. Equity research, technical analysis, quantitative risk. Real-time market data interpretation.'],
|
|
38
|
+
['🖊','QUILL', 'Conversion copywriter. Micro-content, headlines, CTAs, landing pages, email campaigns. Direct response copywriting.'],
|
|
39
|
+
['📊','DataAnalystAgent', 'Data analysis, statistics, pattern extraction, trend identification from datasets.'],
|
|
40
|
+
['🌐','polyglot', 'Computational linguist and translator. Cross-lingual NLP, localization, contrastive linguistics. Professional translation.'],
|
|
41
|
+
['🎨','CanvasAgent', 'HTML dashboard/report generator. Creates visual canvas with charts and tables. USE ONLY AS LAST STEP.'],
|
|
42
|
+
// ── Specialist agents (not in old planner) ─────────
|
|
43
|
+
['🗡','ADE', 'Offensive security specialist (red team). Penetration testing methodology, attack surface analysis, vulnerability exploitation paths.'],
|
|
44
|
+
['🏗','ATLAS', 'Infrastructure-as-Code engineer. Cloud environments, Terraform, Pulumi, declarative configuration, production infrastructure.'],
|
|
45
|
+
['🔗','BABEL', 'Integration architect and API design. Unifies disparate systems, REST/GraphQL/gRPC design, webhook orchestration.'],
|
|
46
|
+
['🗺','CARTOGRAPHER', 'Geospatial analyst. GIS, geodesy, spatial data, location intelligence, map-based analysis.'],
|
|
47
|
+
['🎼','CONDUCTOR', 'Workflow orchestration architect. Designs complex execution plans, dependency graphs, parallel/sequential coordination.'],
|
|
48
|
+
['⏰','CRON', 'Automation architect and CI/CD engineer. Scheduled tasks, pipelines, fault-tolerant automation, GitHub Actions, cron jobs.'],
|
|
49
|
+
['📢','ECHO', 'Content distribution and cross-channel amplification. Transforms content into multi-platform packages (social, blog, video scripts).'],
|
|
50
|
+
['📐','EDI', 'Statistical modeling engineer. Model selection, validation, interpretation. Regression, time series, Bayesian inference.'],
|
|
51
|
+
['🍳','EPICURE', 'Culinary scientist and gastronomic analyst. Food chemistry, global cuisine, nutrition science, recipe analysis, restaurant evaluation.'],
|
|
52
|
+
['🔄','FLUX', 'Data transformation engineer. ETL algebra, format conversion, data reshaping, schema migration.'],
|
|
53
|
+
['🔧','FORGE', 'Infrastructure architect. Production-grade systems, resilience engineering, system design, code architecture.'],
|
|
54
|
+
['🐛','GLITCH', 'Data quality engineer. ETL/ELT pipelines, data cleaning, format transformation, messy data remediation.'],
|
|
55
|
+
['👁','HEIMDALL', 'SRE and observability architect. Monitoring systems, alerting, SLO/SLA design, incident response, dashboards.'],
|
|
56
|
+
['✉','HERMES', 'Event-driven architecture engineer. Message brokers, async communication, Kafka/RabbitMQ/NATS design.'],
|
|
57
|
+
['📉','JARVIS', 'Data visualization architect. Dashboard design, chart selection, information display, D3/Plotly/Grafana.'],
|
|
58
|
+
['🕸','LINK', 'Social graph analyst and community architect. Network analysis, community design, engagement optimization.'],
|
|
59
|
+
['🧠','LOGOS', 'Formal logic analyst and argument auditor. Evaluates argument structure, consistency, logical validity, fallacy detection.'],
|
|
60
|
+
['⚙','MACRO', 'Process automation engineer. Pattern recognition, template systems, bulk operations, workflow automation.'],
|
|
61
|
+
['📜','MURASAKI', 'Long-form content architect. Whitepapers, research papers, essays, book chapters. Academic rigor + narrative craft.'],
|
|
62
|
+
['🎭','MUSE', 'Visual content director. Art direction, visual communication, design systems, brand aesthetics.'],
|
|
63
|
+
['🧭','NAVI', 'Data quality profiler. Dataset assessment, upstream validation, schema inspection, quality scoring before analysis.'],
|
|
64
|
+
['🔌','PIPE', 'Data pipeline architect. Reliable data flows, stream processing, zero-loss record transport.'],
|
|
65
|
+
['🔥','PROMETHEUS', 'Software evolution architect. System analysis, structural weakness identification, evolutionary improvement design, refactoring strategy.'],
|
|
66
|
+
['🛡','SABER', 'Security auditor. Application security, infrastructure hardening, SSDLC, compliance, OWASP, pentest reports.'],
|
|
67
|
+
['👁🗨','SAURON', 'Deep diagnostics and root cause analysis. Goes beyond symptoms to find true origins of system failures.'],
|
|
68
|
+
['📖','SCHEHERAZADE', 'Content strategist and narrative architect. Storytelling, content that captivates, persuades, and converts.'],
|
|
69
|
+
['🖥','SHELL', 'CLI tool architect. Command-line interface design, shell scripting, terminal UX, CLI frameworks.'],
|
|
70
|
+
['⚔','SHOGUN', 'Kubernetes platform engineer. Container orchestration, pod strategy, resource placement, cluster management.'],
|
|
71
|
+
['🌪','TEMPEST', 'Meteorological intelligence analyst. Weather forecasting, atmospheric data interpretation, climate analysis.'],
|
|
72
|
+
['✅','VERITAS', 'Evidence analyst and fact-checker. Determines if claims are supported by evidence, epistemological rigor.'],
|
|
73
|
+
['🎯','ZERO', 'Automated vulnerability scanner. Combines Snyk/Semgrep/Trivy/Nuclei precision with contextual understanding.'],
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
const AGENT_NAMES = AGENT_REGISTRY.map(a => a[1]);
|
|
77
|
+
const AGENT_CATALOG = AGENT_REGISTRY.map(([icon, name, desc]) => `- ${icon} **${name}**: ${desc}`).join('\n');
|
|
78
|
+
|
|
21
79
|
/**
|
|
22
80
|
* Run a web search and return formatted results string.
|
|
23
81
|
*/
|
|
@@ -56,24 +114,22 @@ async function runFetchUrl(url) {
|
|
|
56
114
|
*/
|
|
57
115
|
function extractSearchQueries(task, stepPrompt) {
|
|
58
116
|
const text = (stepPrompt || task).slice(0, 500);
|
|
59
|
-
// Primary query: the full task condensed
|
|
60
117
|
const primary = text.replace(/[^\w\s.,&/-]/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 120);
|
|
61
118
|
const queries = [primary];
|
|
62
119
|
|
|
63
|
-
// Finance: add price + news queries
|
|
64
120
|
if (/gold|silver|oil|stock|bitcoin|crypto|eur|usd|etf|nasdaq|sp500|dow|tesla|apple|nvidia/i.test(text)) {
|
|
65
121
|
const ticker = text.match(/\b([A-Z]{2,5}|gold|silver|oil|bitcoin|ethereum)\b/i)?.[1] || '';
|
|
66
122
|
if (ticker) {
|
|
67
|
-
queries.push(`${ticker} price today
|
|
68
|
-
queries.push(`${ticker} analyst forecast outlook
|
|
123
|
+
queries.push(`${ticker} price today 2026`);
|
|
124
|
+
queries.push(`${ticker} analyst forecast outlook 2026`);
|
|
69
125
|
}
|
|
70
126
|
}
|
|
71
127
|
|
|
72
|
-
// Dedup and cap at 3
|
|
73
128
|
return [...new Set(queries)].slice(0, 3);
|
|
74
129
|
}
|
|
75
130
|
|
|
76
131
|
export function register(router) {
|
|
132
|
+
// ── /api/studio/plan — Intelligent workflow planner ─────────────────
|
|
77
133
|
router.post('/api/studio/plan', async (req, res) => {
|
|
78
134
|
const body = await parseBody(req);
|
|
79
135
|
const task = (body.task || '').trim();
|
|
@@ -82,100 +138,89 @@ export function register(router) {
|
|
|
82
138
|
|
|
83
139
|
const LANG_MAP = {en:'English',it:'Italian',es:'Spanish',fr:'French',de:'German',pt:'Portuguese',zh:'Chinese',ja:'Japanese',ar:'Arabic',hi:'Hindi',ru:'Russian',nl:'Dutch',pl:'Polish',tr:'Turkish',ko:'Korean'};
|
|
84
140
|
const plannerLang = LANG_MAP[(config?.language||'it').slice(0,2)] || 'Italian';
|
|
85
|
-
const
|
|
86
|
-
const taskLow = task.toLowerCase();
|
|
87
|
-
|
|
88
|
-
const hasPdf = !!(body.hasPdf) || /pdf|allegat|catalogo|scheda\s*tecnic/i.test(taskLow);
|
|
89
|
-
const hasEmail = /email|mail|inbox|posta/i.test(taskLow);
|
|
90
|
-
const hasCalendar = /calendar|agenda|calendari|eventi|schedule/i.test(taskLow);
|
|
91
|
-
const hasSearch = /cerca|search|notizie|news|ultime|latest|web|internet|tendenz|trend|acquista|compra|dove\s+trovare|where\s+to\s+buy|similar|simile/i.test(taskLow);
|
|
92
|
-
const hasCanvas = /html|dashboard|visua|report|grafico|chart/i.test(taskLow);
|
|
93
|
-
const hasGitHub = /github|git\b|issue\b|pull request|\bPR\b/i.test(taskLow);
|
|
94
|
-
const hasSlack = /slack/i.test(taskLow);
|
|
95
|
-
const hasNotion = /\bnotion\b/i.test(taskLow);
|
|
96
|
-
const hasBriefing = /briefing|analisi|analizza|summary|sommario|riassunto|riepiloga|valutazione|valuta/i.test(taskLow);
|
|
97
|
-
const hasFinance = /finance|mercato|market|stock|trading|finanz|investiment|cripto|oro|gold|petrolio|oil|commodit|prezzo|correlazion|macro|inflazion|tassi|borse|etf|bitcoin|nasdaq|sp500/i.test(taskLow);
|
|
98
|
-
const hasSecurity = /security|sicurezza|vulnerabilit|audit|pentest|rischi|dipendenz/i.test(taskLow);
|
|
99
|
-
const hasStrategy = /strateg|competitiv|posizionament|raccomandaz|competitive|positioning/i.test(taskLow);
|
|
100
|
-
const hasReputation = /reputazion|reputation|online|brand|review|recension/i.test(taskLow);
|
|
101
|
-
const hasCode = /codice|code|refactor|debug|bug|sviluppo|software|npm|package/i.test(taskLow);
|
|
102
|
-
const hasWriting = /scrivi|write|articolo|article|blog|testo|text|documento|document/i.test(taskLow);
|
|
103
|
-
const hasData = /dati|data|dataset|csv|json|analizza i dati|pattern|statistich|correlazion|regressione|trend|serie\s+storic/i.test(taskLow);
|
|
104
|
-
const hasTranslate = /traduci|translate|traduzione|translation/i.test(taskLow);
|
|
105
|
-
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);
|
|
106
|
-
|
|
107
|
-
const extractSearchQuery = (t) => {
|
|
108
|
-
const m = t.match(/(?:cerca|search|find|ricerca|notizie su|news about|latest on|aggiornamenti su|ultime su|tendenz|trend)\s+(.{5,80}?)(?:\s+(?:e |and |per |for |poi |then )|[,\n]|$)/i);
|
|
109
|
-
if (m) return m[1].trim();
|
|
110
|
-
const domainMatch = t.match(/(?:https?:\/\/)?(?:www\.)?([a-z0-9-]+\.[a-z]{2,}(?:\.[a-z]{2,})?)/i);
|
|
111
|
-
if (domainMatch) return domainMatch[0].replace(/^https?:\/\//,'');
|
|
112
|
-
return t.replace(/^[^:]+:\s*/,'').split(/[,\n]/)[0].slice(0,100).trim() || t.slice(0,80).trim();
|
|
113
|
-
};
|
|
114
|
-
const searchQuery = extractSearchQuery(task);
|
|
141
|
+
const sanitizedTask = task.replace(/<[^>]*>/g, ' ').replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, '').trim();
|
|
115
142
|
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
if (hasPdf) {
|
|
119
|
-
const pdfName = body.pdfName || 'documento allegato';
|
|
120
|
-
steps.push({icon:'📄',agent:'DocumentReaderAgent',label:it?'Leggi documento':'Read document',reason:it?'Allegato PDF rilevato — estraggo dati tecnici prima di ogni altra operazione':'PDF attachment detected — 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.`});
|
|
121
|
-
}
|
|
122
|
-
if (hasTravel) steps.push({icon:'🍽',agent:'TravelAgent', label:it?'Ricerca ristoranti & hotel':'Search restaurants & hotels', reason:it?'Task di viaggio/prenotazione':'Travel/booking task', prompt:task});
|
|
123
|
-
if (hasEmail) steps.push({icon:'📧',agent:'EmailAgent', label:it?'Controlla email':'Check emails', reason:it?'Parola chiave email rilevata':'Email keyword detected', prompt:'Read the latest unread emails and identify urgent items, deadlines, and required actions'});
|
|
124
|
-
if (hasCalendar) steps.push({icon:'📅',agent:'CalendarAgent',label:it?'Rivedi calendario':'Review calendar',reason:it?'Parola chiave calendario rilevata':'Calendar keyword detected', prompt:"Check today's events and identify any scheduling conflicts or important meetings"});
|
|
125
|
-
if (hasGitHub) steps.push({icon:'💻',agent:'GitHubAgent', label:'GitHub', reason:it?'Parola chiave GitHub rilevata':'GitHub keyword detected', prompt:'Read open issues and pull requests, identify what needs attention'});
|
|
126
|
-
if (hasSlack) steps.push({icon:'💬',agent:'SlackAgent', label:'Slack', reason:it?'Parola chiave Slack rilevata':'Slack keyword detected', prompt:'Check recent Slack messages and identify important conversations'});
|
|
127
|
-
if (hasNotion) steps.push({icon:'📝',agent:'NotionAgent', label:'Notion', reason:it?'Parola chiave Notion rilevata':'Notion keyword detected', prompt:'Search Notion for relevant pages and notes'});
|
|
128
|
-
if (!hasTravel && (hasPdf || hasSearch || hasReputation || (!hasEmail && !hasCalendar && !hasGitHub && !hasSlack))) {
|
|
129
|
-
const sp = hasPdf ? (it?'Usa le specifiche tecniche estratte dal documento per cercare online dove acquistare il prodotto o articoli equivalenti.':'Use the technical specifications extracted from the document to search online for where to buy this product or equivalent alternatives.') : searchQuery;
|
|
130
|
-
steps.push({icon:'🔍',agent:'WebSearchAgent',label:it?'Ricerca web':'Web search',reason:it?'Fonte dati web principale':'Primary web data source',prompt:sp});
|
|
131
|
-
}
|
|
132
|
-
if (hasSecurity) steps.push({icon:'🛡',agent:'cassandra', label:it?'CASSANDRA — Rischi':'CASSANDRA — Risks', reason:it?'Keyword sicurezza rilevata':'Security keyword detected', prompt:'Analyze the collected data and identify security risks, vulnerabilities and concrete recommendations'});
|
|
133
|
-
if (hasFinance) steps.push({icon:'💰',agent:'mercury', label:it?'MERCURY — Mercato':'MERCURY — Market', reason:it?'Keyword finanza rilevata':'Finance keyword detected', prompt:'Analyze the financial data and market trends from the collected information'});
|
|
134
|
-
if (hasStrategy) steps.push({icon:'♟',agent:'athena', label:it?'ATHENA — Strategia':'ATHENA — Strategy', reason:it?'Keyword strategia rilevata':'Strategy keyword detected', prompt:'Based on the collected data, produce strategic analysis with competitive positioning and concrete recommendations'});
|
|
135
|
-
if (hasReputation) steps.push({icon:'🔭',agent:'oracle', label:it?'ORACLE — Reputazione':'ORACLE — Reputation', reason:it?'Keyword reputazione rilevata':'Reputation keyword detected', prompt:'Analyze the online reputation data, sentiment and brand positioning from the collected information'});
|
|
136
|
-
if (hasCode) steps.push({icon:'🔧',agent:'forge', label:it?'FORGE — Codice':'FORGE — Code', reason:it?'Keyword codice rilevata':'Code keyword detected', prompt:'Analyze the code, dependencies and technical issues identified in the data'});
|
|
137
|
-
if (hasWriting) steps.push({icon:'🖊',agent:'quill', label:it?'QUILL — Redazione':'QUILL — Writing', reason:it?'Keyword scrittura rilevata':'Writing keyword detected', prompt:'Write a polished, professional document based on all the collected information'});
|
|
138
|
-
if (hasData) steps.push({icon:'📊',agent:'DataAnalystAgent',label:it?'Analisi dati':'Data analysis', reason:it?'Keyword dati rilevata':'Data keyword detected', prompt:'Analyze the data and extract key patterns, trends and insights'});
|
|
139
|
-
if (hasTranslate) steps.push({icon:'🌐',agent:'polyglot', label:it?'POLYGLOT — Traduzione':'POLYGLOT — Translation',reason:it?'Keyword traduzione rilevata':'Translation keyword detected', prompt:'Translate the content as requested, maintaining meaning and style'});
|
|
140
|
-
const hasSpecialist = hasSecurity || hasFinance || hasStrategy || hasReputation || hasCode || hasWriting || hasData || hasTranslate;
|
|
141
|
-
if (!hasSpecialist && (hasBriefing || steps.length > 0)) {
|
|
142
|
-
steps.push({icon:'📰',agent:'HERALD',label:it?'HERALD — Briefing':'HERALD — Briefing',reason:it?'HERALD sintetizza tutti i dati':'HERALD synthesizes all data',prompt:'Based on ALL the data collected by the previous steps, write a complete executive briefing with priorities, findings, and strategic recommendations. Do NOT invent data — only use what was provided.'});
|
|
143
|
-
}
|
|
144
|
-
const specialistCount = [hasSecurity,hasFinance,hasStrategy,hasReputation,hasCode,hasWriting,hasData].filter(Boolean).length;
|
|
145
|
-
if (hasCanvas || specialistCount >= 2 || (hasSpecialist && hasBriefing)) {
|
|
146
|
-
steps.push({icon:'📊',agent:'CanvasAgent',label:it?'Dashboard HTML':'HTML Dashboard',reason:it?'Analisi complessa — dashboard visuale':'Complex analysis — visual dashboard',prompt:'Create a professional HTML dashboard report summarizing all findings from the previous agents'});
|
|
147
|
-
}
|
|
148
|
-
return steps;
|
|
149
|
-
};
|
|
143
|
+
const hasPdf = !!(body.hasPdf) || /pdf|allegat|catalogo|scheda\s*tecnic/i.test(task);
|
|
144
|
+
const pdfName = body.pdfName || 'documento allegato';
|
|
150
145
|
|
|
151
|
-
const keywordSteps = buildKeywordPlan();
|
|
152
|
-
const hasKeywordPlan = keywordSteps.length > 0;
|
|
153
|
-
const sanitizedTask = task.replace(/<[^>]*>/g, ' ').replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, '').trim();
|
|
154
|
-
const keywordPlanJson = hasKeywordPlan ? JSON.stringify(keywordSteps.map(s => ({ agent: s.agent, label: s.label, reason: s.reason || '' }))) : '[]';
|
|
155
146
|
const planConfig = Object.assign({}, config, { thinking: 'off' });
|
|
156
147
|
|
|
157
148
|
try {
|
|
158
|
-
let steps =
|
|
149
|
+
let steps = [];
|
|
150
|
+
|
|
151
|
+
const plannerSystem = `You are CONDUCTOR, the master workflow orchestrator for NHA Studio.
|
|
152
|
+
Your job: analyze the user's task and select the OPTIMAL sequence of specialist agents to accomplish it.
|
|
153
|
+
|
|
154
|
+
## COMPLETE AGENT CATALOG (${AGENT_REGISTRY.length} agents available):
|
|
155
|
+
|
|
156
|
+
${AGENT_CATALOG}
|
|
157
|
+
|
|
158
|
+
## ORCHESTRATION RULES:
|
|
159
|
+
|
|
160
|
+
1. **Select 2-7 agents** depending on task complexity. Simple tasks = 2-3 agents. Complex analysis = 4-7.
|
|
161
|
+
2. **Order matters**: agents execute sequentially. Each agent receives the output of ALL previous agents as context.
|
|
162
|
+
3. **WebSearchAgent or TravelAgent FIRST** when real-time data is needed (prices, news, reviews, weather, venues).
|
|
163
|
+
4. **DocumentReaderAgent FIRST** when a PDF is attached — extract data before anything else.
|
|
164
|
+
5. **HERALD as synthesizer** — place near the end to produce an executive briefing from all collected data.
|
|
165
|
+
6. **CanvasAgent ALWAYS LAST** (and only if visual output is requested or >=3 specialists are used).
|
|
166
|
+
7. **Match agent expertise to task domain**:
|
|
167
|
+
- Finance/markets/crypto → MERCURY (+ WebSearchAgent for live data)
|
|
168
|
+
- Security/audit/vulns → SABER, ADE, ZERO, CASSANDRA (pick the right ones)
|
|
169
|
+
- Code/architecture → FORGE, PROMETHEUS, SAURON
|
|
170
|
+
- Data/statistics → ORACLE, EDI, NAVI (NAVI for quality check first), DataAnalystAgent
|
|
171
|
+
- Writing/content → QUILL (short copy), MURASAKI (long-form), SCHEHERAZADE (narrative), ECHO (multi-platform)
|
|
172
|
+
- Translation → polyglot
|
|
173
|
+
- Infrastructure/cloud → ATLAS, SHOGUN, HEIMDALL, CRON
|
|
174
|
+
- API/integrations → BABEL, HERMES, PIPE
|
|
175
|
+
- Visual/design → MUSE, JARVIS
|
|
176
|
+
- Logic/verification → LOGOS, VERITAS
|
|
177
|
+
- Food/restaurants → EPICURE (+ TravelAgent for search)
|
|
178
|
+
- Weather → TEMPEST
|
|
179
|
+
- Geospatial → CARTOGRAPHER
|
|
180
|
+
- Social/community → LINK
|
|
181
|
+
- Automation → MACRO, CRON
|
|
182
|
+
- Strategy/competitive → ATHENA
|
|
183
|
+
- Risk analysis → CASSANDRA
|
|
184
|
+
8. **Write detailed prompts**: each agent's \`prompt\` field should be a specific instruction telling the agent EXACTLY what to analyze, produce, or investigate. Not just the task repeated — a targeted instruction leveraging that agent's specialty.
|
|
185
|
+
9. **Labels in ${plannerLang}**.
|
|
186
|
+
10. **Never use agents that don't match the task**. A cooking task doesn't need SABER. A security audit doesn't need EPICURE.
|
|
187
|
+
${hasPdf ? `\n11. **PDF ATTACHED**: "${pdfName}" — DocumentReaderAgent MUST be step 1.` : ''}
|
|
188
|
+
|
|
189
|
+
## OUTPUT FORMAT (STRICT — output ONLY this JSON, nothing else):
|
|
190
|
+
|
|
191
|
+
{"steps":[{"icon":"EMOJI","agent":"AGENT_NAME","label":"LABEL_IN_${plannerLang.toUpperCase()}","reason":"WHY_THIS_AGENT","prompt":"DETAILED_INSTRUCTION_FOR_THE_AGENT"}]}`;
|
|
192
|
+
|
|
193
|
+
const plannerUser = `TASK: ${sanitizedTask}
|
|
194
|
+
|
|
195
|
+
Select the optimal agent pipeline. Output ONLY the JSON.`;
|
|
196
|
+
|
|
159
197
|
if (config && (config.llm?.provider || config.llm?.apiKey)) {
|
|
160
198
|
try {
|
|
161
|
-
const
|
|
162
|
-
const planPrompt = hasKeywordPlan
|
|
163
|
-
? `Task: ${sanitizedTask}\n\nKeyword-detected plan (JSON):\n${keywordPlanJson}\n\nLanguage for labels: ${plannerLang}.\n\nReview the plan. You may ADD missing steps, REMOVE wrong ones, REORDER, ADJUST prompts. Keep existing reasons where step is unchanged.\n\nAvailable agents: TravelAgent, WebSearchAgent, DocumentReaderAgent, EmailAgent, CalendarAgent, GitHubAgent, SlackAgent, NotionAgent, HERALD, ORACLE, ATHENA, CASSANDRA, MERCURY, QUILL, DataAnalystAgent, polyglot, CanvasAgent (last only).\n\nOutput ONLY:\n{"steps":[{"icon":"EMOJI","agent":"AGENT_NAME","label":"LABEL","reason":"WHY","prompt":"INSTRUCTION"}]}\n\nMax 6 steps.`
|
|
164
|
-
: `Task: ${sanitizedTask}\n\nLanguage for labels: ${plannerLang}.\n\nBuild a workflow plan. Available agents: TravelAgent, WebSearchAgent, DocumentReaderAgent, EmailAgent, CalendarAgent, GitHubAgent, SlackAgent, NotionAgent, HERALD, ORACLE, ATHENA, CASSANDRA, MERCURY, QUILL, DataAnalystAgent, polyglot, CanvasAgent.\n\nOutput ONLY:\n{"steps":[{"icon":"EMOJI","agent":"AGENT_NAME","label":"LABEL","reason":"WHY","prompt":"INSTRUCTION"}]}\n\n2-5 steps.`;
|
|
165
|
-
const planRaw = await callLLM(planConfig, planSys, planPrompt, { max_tokens: 900 });
|
|
199
|
+
const planRaw = await callLLM(planConfig, plannerSystem, plannerUser, { max_tokens: 2000 });
|
|
166
200
|
let clean = planRaw.replace(/<think>[\s\S]*?<\/think>/g, '').trim().replace(/^```[\w]*\r?\n?/, '').replace(/\r?\n?```$/, '').trim();
|
|
167
201
|
const jm = clean.match(/\{[\s\S]*\}/);
|
|
168
202
|
const parsed = JSON.parse(jm ? jm[0] : clean);
|
|
169
203
|
if (Array.isArray(parsed.steps) && parsed.steps.length > 0) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
204
|
+
steps = parsed.steps
|
|
205
|
+
.filter(s => AGENT_NAMES.includes(s.agent))
|
|
206
|
+
.map(s => {
|
|
207
|
+
const reg = AGENT_REGISTRY.find(r => r[1] === s.agent);
|
|
208
|
+
return { icon: s.icon || (reg ? reg[0] : '🤖'), agent: s.agent, label: s.label, reason: s.reason || '', prompt: s.prompt };
|
|
209
|
+
});
|
|
173
210
|
}
|
|
174
|
-
} catch {}
|
|
211
|
+
} catch { /* LLM failed, fall through to keyword fallback */ }
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Keyword fallback if LLM planner failed or no LLM configured
|
|
215
|
+
if (!steps.length) {
|
|
216
|
+
steps = buildKeywordFallback(task, sanitizedTask, hasPdf, pdfName, plannerLang === 'Italian');
|
|
175
217
|
}
|
|
176
|
-
|
|
218
|
+
|
|
219
|
+
if (!steps.length) {
|
|
220
|
+
const it = plannerLang === 'Italian';
|
|
177
221
|
steps = [{ icon: '🔍', agent: 'WebSearchAgent', label: it ? 'Ricerca web' : 'Web search', reason: 'Fallback', prompt: sanitizedTask }];
|
|
178
222
|
}
|
|
223
|
+
|
|
179
224
|
sendJSON(res, 200, { steps });
|
|
180
225
|
} catch (e) { sendError(res, 500, e.message); }
|
|
181
226
|
});
|
|
@@ -212,19 +257,20 @@ export function register(router) {
|
|
|
212
257
|
} catch {}
|
|
213
258
|
}
|
|
214
259
|
|
|
215
|
-
const contextBlock = context ? `\n\n## CONTEXT FROM PREVIOUS STEPS:\n${context.slice(0,
|
|
216
|
-
const proposalContextBlock = body.proposalContext ? `\n\n## OTHER AGENTS' PROPOSALS (CROSS-READING):\n${body.proposalContext.slice(0,
|
|
260
|
+
const contextBlock = context ? `\n\n## CONTEXT FROM PREVIOUS STEPS:\n${context.slice(0, 12000)}` : '';
|
|
261
|
+
const proposalContextBlock = body.proposalContext ? `\n\n## OTHER AGENTS' PROPOSALS (CROSS-READING):\n${body.proposalContext.slice(0, 8000)}` : '';
|
|
217
262
|
|
|
218
263
|
const formatInstructions = `\n\nFORMATTING RULES (CRITICAL — your output will be rendered as HTML):
|
|
219
264
|
- Use MARKDOWN TABLES with | pipes | for ALL tabular data. Example:
|
|
220
265
|
| Header 1 | Header 2 | Header 3 |
|
|
221
266
|
|----------|----------|----------|
|
|
222
267
|
| data | data | data |
|
|
223
|
-
- NEVER use ASCII art boxes
|
|
224
|
-
- NEVER use ASCII art charts/graphs (├─●──┤). Describe data in tables instead.
|
|
268
|
+
- NEVER use ASCII art boxes or box-drawing characters. They render as ugly monospace blocks.
|
|
225
269
|
- Use **bold**, *italic*, headers (## ##), bullet points, numbered lists, blockquotes (>).
|
|
226
270
|
- For emphasis boxes, use blockquotes: > **Key insight:** text here
|
|
227
|
-
- Write COMPLETE content under every heading — never leave a section empty
|
|
271
|
+
- Write COMPLETE, EXHAUSTIVE content under every heading — never leave a section empty or superficial.
|
|
272
|
+
- Provide DEEP ANALYSIS with specific data points, numbers, percentages, and concrete examples.
|
|
273
|
+
- Minimum 800 words of substantive content. Be thorough, not brief.`;
|
|
228
274
|
|
|
229
275
|
const sysParts = [
|
|
230
276
|
agentSysDef || `You are ${agent}, a specialist AI agent in NHA Studio. Respond entirely in ${language}. Today is ${today}.`,
|
|
@@ -289,7 +335,7 @@ export function register(router) {
|
|
|
289
335
|
output += tok;
|
|
290
336
|
tokensOut += Math.ceil(tok.length / 4);
|
|
291
337
|
sse({ token: tok });
|
|
292
|
-
}, { max_tokens:
|
|
338
|
+
}, { max_tokens: 16384 });
|
|
293
339
|
|
|
294
340
|
clearInterval(keepalive);
|
|
295
341
|
sse({ done: true, output, tokensOut });
|
|
@@ -351,18 +397,18 @@ export function register(router) {
|
|
|
351
397
|
|
|
352
398
|
const crossCtx = (excludeAgent) => eligible
|
|
353
399
|
.filter(p => p.agent !== excludeAgent)
|
|
354
|
-
.map(p => `## ${p.label || p.agent} (Round 1):\n${p.output.slice(0,
|
|
400
|
+
.map(p => `## ${p.label || p.agent} (Round 1):\n${p.output.slice(0,6000)}`)
|
|
355
401
|
.join('\n\n---\n\n');
|
|
356
402
|
|
|
357
403
|
tok('[Parlamento — Round 2: Cross-Reading & Refinamento] ');
|
|
358
404
|
const r2Results = [];
|
|
359
405
|
for (const proposal of eligible) {
|
|
360
406
|
tok(`[Round 2: ${proposal.label || proposal.agent}] `);
|
|
361
|
-
const r2Sys = `You are ${proposal.agent}, a specialist AI agent in NHA Studio Parliament. Today is ${today}. Respond entirely in ${language}.\n\n## WORKFLOW GOAL: ${task}\n\n## YOUR ROUND 1 RESPONSE:\n${proposal.output.slice(0,
|
|
407
|
+
const r2Sys = `You are ${proposal.agent}, a specialist AI agent in NHA Studio Parliament. Today is ${today}. Respond entirely in ${language}.\n\n## WORKFLOW GOAL: ${task}\n\n## YOUR ROUND 1 RESPONSE:\n${proposal.output.slice(0,3000)}\n\n## OTHER AGENTS' ROUND 1 PROPOSALS:\n${crossCtx(proposal.agent)}\n\nDELIBERATION ROUND 2 — REFINEMENT:\n1. Review the other agents' proposals carefully\n2. Incorporate valid points where you AGREE — mark with [AGREE]\n3. Flag genuine disagreements with [CONTRADICTION] and explain your reasoning with evidence\n4. Produce your COMPLETE REFINED response — thorough and exhaustive\n5. Keep analysis focused on: ${task}\n\nBe THOROUGH. Minimum 600 words of substantive refined analysis.`;
|
|
362
408
|
let r2Out = '';
|
|
363
409
|
try {
|
|
364
410
|
await callLLMStream(config, r2Sys, 'Produce your refined Round 2 response. Write complete content under every heading — never leave a section title without body text.',
|
|
365
|
-
(t) => { r2Out += t; }, { max_tokens:
|
|
411
|
+
(t) => { r2Out += t; }, { max_tokens: 16384 });
|
|
366
412
|
} catch { r2Out = proposal.output; }
|
|
367
413
|
r2Results.push({ agent: proposal.agent, label: proposal.label, icon: proposal.icon, output: r2Out });
|
|
368
414
|
sse({ deliberation_r2: { agent: proposal.agent, label: proposal.label, icon: proposal.icon, output: r2Out } });
|
|
@@ -372,7 +418,7 @@ export function register(router) {
|
|
|
372
418
|
tok(`[Parlamento — Round 2 convergenza: ${(r2Conv*100).toFixed(0)}%] `);
|
|
373
419
|
const converged = r2Conv >= 0.30;
|
|
374
420
|
|
|
375
|
-
const allR2Ctx = r2Results.map(r => `## ${r.label || r.agent}:\n${r.output.slice(0,
|
|
421
|
+
const allR2Ctx = r2Results.map(r => `## ${r.label || r.agent}:\n${r.output.slice(0,4000)}`).join('\n\n---\n\n');
|
|
376
422
|
const contradictions = [];
|
|
377
423
|
for (const r of r2Results) {
|
|
378
424
|
const matches = r.output.match(/\[CONTRADICTION\][^\n]*/g) || [];
|
|
@@ -383,14 +429,14 @@ export function register(router) {
|
|
|
383
429
|
tok(converged ? '[Parlamento — Round 3: Sintesi finale HERALD...] ' : '[Parlamento — Round 3: Mediazione HERALD...] ');
|
|
384
430
|
|
|
385
431
|
const medTask = converged
|
|
386
|
-
? `SYNTHESIS TASK (convergenza ${(r2Conv*100).toFixed(0)}%):\n1. Presenta il CONSENSO raggiunto\n2. Segnala ogni sfumatura o punto di divergenza residua\n3. Produci un executive summary unificato con azioni concrete per: ${task}\n4. Sezione "Voci dissonanti" se esistono posizioni che meritano attenzione`
|
|
387
|
-
: `MEDIATION TASK (convergenza ${(r2Conv*100).toFixed(0)}% — divergenza significativa):\n1. Identifica i punti di ACCORDO tra tutti gli agenti\n2. Per ogni disaccordo: valuta quale posizione ha evidenze
|
|
432
|
+
? `SYNTHESIS TASK (convergenza ${(r2Conv*100).toFixed(0)}%):\n1. Presenta il CONSENSO raggiunto tra tutti gli agenti\n2. Segnala ogni sfumatura o punto di divergenza residua\n3. Produci un executive summary unificato con azioni concrete per: ${task}\n4. Sezione "Voci dissonanti" se esistono posizioni che meritano attenzione\n5. SENZA ALCUN LIMITE DI LUNGHEZZA — sii esaustivo e completo`
|
|
433
|
+
: `MEDIATION TASK (convergenza ${(r2Conv*100).toFixed(0)}% — divergenza significativa):\n1. Identifica i punti di ACCORDO tra tutti gli agenti\n2. Per ogni disaccordo: valuta quale posizione ha evidenze piu solide, NOMINA l'agente e spiega perche e stata accolta o scartata\n3. Produci una sintesi UNIFICATA esaustiva\n4. Fai scelte editoriali nette con motivazioni\n5. Executive summary con azioni concrete per: ${task}\n6. SENZA ALCUN LIMITE DI LUNGHEZZA — sii esaustivo e completo`;
|
|
388
434
|
|
|
389
|
-
const medSys = `You are HERALD, the Parliament Mediator in NHA Studio. Today is ${today}. Respond entirely in ${language}.\n\n## WORKFLOW GOAL: ${task}\n\n## ALL AGENTS' REFINED POSITIONS (Round 2):\n${allR2Ctx}${contBlock}\n\n${medTask}\n\nCRITICAL: NEVER write a heading without immediately writing full content below it. Every section MUST have at least
|
|
435
|
+
const medSys = `You are HERALD, the Parliament Mediator in NHA Studio. Today is ${today}. Respond entirely in ${language}.\n\n## WORKFLOW GOAL: ${task}\n\n## ALL AGENTS' REFINED POSITIONS (Round 2):\n${allR2Ctx}${contBlock}\n\n${medTask}\n\nCRITICAL: NEVER write a heading without immediately writing full content below it. Every section MUST have at least 5-8 concrete bullet points or detailed paragraphs. Be EXHAUSTIVE.`;
|
|
390
436
|
|
|
391
437
|
let mediationOutput = '';
|
|
392
438
|
try {
|
|
393
|
-
await callLLMStream(config, medSys, 'Produce the Parliament final synthesis.', (t) => { mediationOutput += t; }, { max_tokens:
|
|
439
|
+
await callLLMStream(config, medSys, 'Produce the Parliament final synthesis. Be thorough and complete.', (t) => { mediationOutput += t; }, { max_tokens: 16384 });
|
|
394
440
|
} catch {}
|
|
395
441
|
sse({ deliberation_r3: { output: mediationOutput, converged } });
|
|
396
442
|
|
|
@@ -406,3 +452,69 @@ export function register(router) {
|
|
|
406
452
|
}
|
|
407
453
|
});
|
|
408
454
|
}
|
|
455
|
+
|
|
456
|
+
// ── Keyword fallback planner (used when LLM is unavailable) ────────────
|
|
457
|
+
|
|
458
|
+
function buildKeywordFallback(task, sanitizedTask, hasPdf, pdfName, it) {
|
|
459
|
+
const taskLow = task.toLowerCase();
|
|
460
|
+
const steps = [];
|
|
461
|
+
|
|
462
|
+
const hasEmail = /email|mail|inbox|posta/i.test(taskLow);
|
|
463
|
+
const hasCalendar = /calendar|agenda|calendari|eventi|schedule/i.test(taskLow);
|
|
464
|
+
const hasSearch = /cerca|search|notizie|news|ultime|latest|web|internet|tendenz|trend|acquista|compra|dove\s+trovare|where\s+to\s+buy|similar|simile/i.test(taskLow);
|
|
465
|
+
const hasCanvas = /html|dashboard|visua|report|grafico|chart/i.test(taskLow);
|
|
466
|
+
const hasGitHub = /github|git\b|issue\b|pull request|\bPR\b/i.test(taskLow);
|
|
467
|
+
const hasSlack = /slack/i.test(taskLow);
|
|
468
|
+
const hasNotion = /\bnotion\b/i.test(taskLow);
|
|
469
|
+
const hasBriefing = /briefing|analisi|analizza|summary|sommario|riassunto|riepiloga|valutazione|valuta/i.test(taskLow);
|
|
470
|
+
const hasFinance = /finance|mercato|market|stock|trading|finanz|investiment|cripto|oro|gold|petrolio|oil|commodit|prezzo|correlazion|macro|inflazion|tassi|borse|etf|bitcoin|nasdaq|sp500/i.test(taskLow);
|
|
471
|
+
const hasSecurity = /security|sicurezza|vulnerabilit|audit|pentest|rischi|dipendenz/i.test(taskLow);
|
|
472
|
+
const hasStrategy = /strateg|competitiv|posizionament|raccomandaz|competitive|positioning/i.test(taskLow);
|
|
473
|
+
const hasReputation = /reputazion|reputation|online|brand|review|recension/i.test(taskLow);
|
|
474
|
+
const hasCode = /codice|code|refactor|debug|bug|sviluppo|software|npm|package|architettur/i.test(taskLow);
|
|
475
|
+
const hasWriting = /scrivi|write|articolo|article|blog|testo|text|documento|document|whitepaper|saggio|essay/i.test(taskLow);
|
|
476
|
+
const hasData = /dati|data|dataset|csv|json|analizza i dati|pattern|statistich|correlazion|regressione|trend|serie\s+storic/i.test(taskLow);
|
|
477
|
+
const hasTranslate = /traduci|translate|traduzione|translation/i.test(taskLow);
|
|
478
|
+
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);
|
|
479
|
+
const hasWeather = /meteo|weather|previsioni|temperatura|clima|pioggia|neve|vento/i.test(taskLow);
|
|
480
|
+
const hasFood = /ricetta|recipe|cucinare|cook|ingredienti|piatto|dish|gastronomia|cucina/i.test(taskLow);
|
|
481
|
+
const hasInfra = /kubernetes|k8s|docker|terraform|cloud|aws|azure|gcp|infrastruttura|infrastructure|deploy|pipeline|ci[\/-]cd/i.test(taskLow);
|
|
482
|
+
const hasApi = /\bapi\b|endpoint|webhook|integrazione|integration|rest|graphql|grpc/i.test(taskLow);
|
|
483
|
+
const hasLogic = /logica|logic|argoment|fallacia|fallacy|ragionamento|reasoning|valid|premessa|premise/i.test(taskLow);
|
|
484
|
+
const hasGeo = /mappa|map|geolocalizzazione|coordinates|latitudine|longitudine|geospatial|gis/i.test(taskLow);
|
|
485
|
+
|
|
486
|
+
if (hasPdf) steps.push({icon:'📄',agent:'DocumentReaderAgent',label:it?'Leggi documento':'Read document',reason:it?'PDF allegato':'PDF attached',prompt:`Extract all technical specifications, data, tables, and key information from the attached document "${pdfName}".`});
|
|
487
|
+
if (hasTravel) steps.push({icon:'🍽',agent:'TravelAgent',label:it?'Ricerca luoghi':'Search venues',reason:it?'Task di viaggio/ristorazione':'Travel/dining task',prompt:sanitizedTask});
|
|
488
|
+
if (hasEmail) steps.push({icon:'📧',agent:'EmailAgent',label:it?'Controlla email':'Check emails',reason:it?'Email rilevata':'Email detected',prompt:'Read the latest unread emails and identify urgent items, deadlines, and required actions'});
|
|
489
|
+
if (hasCalendar) steps.push({icon:'📅',agent:'CalendarAgent',label:it?'Rivedi calendario':'Review calendar',reason:it?'Calendario rilevato':'Calendar detected',prompt:"Check today's events and identify any scheduling conflicts or important meetings"});
|
|
490
|
+
if (hasGitHub) steps.push({icon:'💻',agent:'GitHubAgent',label:'GitHub',reason:it?'GitHub rilevato':'GitHub detected',prompt:'Read open issues and pull requests, identify what needs attention'});
|
|
491
|
+
if (hasSlack) steps.push({icon:'💬',agent:'SlackAgent',label:'Slack',reason:it?'Slack rilevato':'Slack detected',prompt:'Check recent Slack messages and identify important conversations'});
|
|
492
|
+
if (hasNotion) steps.push({icon:'📝',agent:'NotionAgent',label:'Notion',reason:it?'Notion rilevato':'Notion detected',prompt:'Search Notion for relevant pages and notes'});
|
|
493
|
+
if (hasWeather) steps.push({icon:'🌪',agent:'TEMPEST',label:it?'Analisi meteo':'Weather analysis',reason:it?'Meteo rilevato':'Weather detected',prompt:sanitizedTask});
|
|
494
|
+
if (hasFood && !hasTravel) steps.push({icon:'🍳',agent:'EPICURE',label:it?'Analisi culinaria':'Culinary analysis',reason:it?'Cucina rilevata':'Cooking detected',prompt:sanitizedTask});
|
|
495
|
+
if (hasGeo) steps.push({icon:'🗺',agent:'CARTOGRAPHER',label:it?'Analisi geospaziale':'Geospatial analysis',reason:it?'Geolocalizzazione rilevata':'Geo detected',prompt:sanitizedTask});
|
|
496
|
+
if (!hasTravel && (hasPdf || hasSearch || hasReputation || (!hasEmail && !hasCalendar && !hasGitHub && !hasSlack && !hasWeather && !hasFood))) {
|
|
497
|
+
steps.push({icon:'🔍',agent:'WebSearchAgent',label:it?'Ricerca web':'Web search',reason:it?'Fonte dati web':'Web data source',prompt:sanitizedTask});
|
|
498
|
+
}
|
|
499
|
+
if (hasSecurity) steps.push({icon:'🛡',agent:'SABER',label:it?'SABER — Audit sicurezza':'SABER — Security audit',reason:it?'Sicurezza rilevata':'Security detected',prompt:sanitizedTask});
|
|
500
|
+
if (hasFinance) steps.push({icon:'💰',agent:'MERCURY',label:it?'MERCURY — Mercato':'MERCURY — Market',reason:it?'Finanza rilevata':'Finance detected',prompt:sanitizedTask});
|
|
501
|
+
if (hasStrategy) steps.push({icon:'♟',agent:'ATHENA',label:it?'ATHENA — Strategia':'ATHENA — Strategy',reason:it?'Strategia rilevata':'Strategy detected',prompt:sanitizedTask});
|
|
502
|
+
if (hasReputation)steps.push({icon:'🔭',agent:'ORACLE',label:it?'ORACLE — Reputazione':'ORACLE — Reputation',reason:it?'Reputazione rilevata':'Reputation detected',prompt:sanitizedTask});
|
|
503
|
+
if (hasCode) steps.push({icon:'🔧',agent:'FORGE',label:it?'FORGE — Architettura':'FORGE — Architecture',reason:it?'Codice rilevato':'Code detected',prompt:sanitizedTask});
|
|
504
|
+
if (hasWriting) steps.push({icon:'📜',agent:'MURASAKI',label:it?'MURASAKI — Redazione':'MURASAKI — Writing',reason:it?'Scrittura rilevata':'Writing detected',prompt:sanitizedTask});
|
|
505
|
+
if (hasData) steps.push({icon:'📊',agent:'DataAnalystAgent',label:it?'Analisi dati':'Data analysis',reason:it?'Dati rilevati':'Data detected',prompt:sanitizedTask});
|
|
506
|
+
if (hasTranslate) steps.push({icon:'🌐',agent:'polyglot',label:it?'POLYGLOT — Traduzione':'POLYGLOT — Translation',reason:it?'Traduzione rilevata':'Translation detected',prompt:sanitizedTask});
|
|
507
|
+
if (hasInfra) steps.push({icon:'🏗',agent:'ATLAS',label:it?'ATLAS — Infrastruttura':'ATLAS — Infrastructure',reason:it?'Infrastruttura rilevata':'Infrastructure detected',prompt:sanitizedTask});
|
|
508
|
+
if (hasApi) steps.push({icon:'🔗',agent:'BABEL',label:it?'BABEL — Integrazione API':'BABEL — API Integration',reason:it?'API rilevata':'API detected',prompt:sanitizedTask});
|
|
509
|
+
if (hasLogic) steps.push({icon:'🧠',agent:'LOGOS',label:it?'LOGOS — Analisi logica':'LOGOS — Logic analysis',reason:it?'Logica rilevata':'Logic detected',prompt:sanitizedTask});
|
|
510
|
+
|
|
511
|
+
const hasSpecialist = hasSecurity || hasFinance || hasStrategy || hasReputation || hasCode || hasWriting || hasData || hasTranslate || hasInfra || hasApi || hasLogic;
|
|
512
|
+
if (!hasSpecialist && (hasBriefing || steps.length > 0)) {
|
|
513
|
+
steps.push({icon:'📰',agent:'HERALD',label:it?'HERALD — Briefing':'HERALD — Briefing',reason:it?'Sintesi finale':'Final synthesis',prompt:'Based on ALL the data collected by the previous steps, write a complete executive briefing with priorities, findings, and strategic recommendations. Do NOT invent data — only use what was provided.'});
|
|
514
|
+
}
|
|
515
|
+
const specialistCount = [hasSecurity,hasFinance,hasStrategy,hasReputation,hasCode,hasWriting,hasData,hasInfra,hasApi].filter(Boolean).length;
|
|
516
|
+
if (hasCanvas || specialistCount >= 2 || (hasSpecialist && hasBriefing)) {
|
|
517
|
+
steps.push({icon:'📊',agent:'CanvasAgent',label:it?'Dashboard HTML':'HTML Dashboard',reason:it?'Report visuale':'Visual report',prompt:'Create a professional HTML dashboard report summarizing all findings from the previous agents'});
|
|
518
|
+
}
|
|
519
|
+
return steps;
|
|
520
|
+
}
|