@llm-dev-ops/agentics-cli 1.4.24 → 1.4.26

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.
@@ -255,82 +255,306 @@ const NL_LOW_CONFIDENCE = 0.5;
255
255
  * Order matters: first match wins — more specific rules go first.
256
256
  */
257
257
  const KEYWORD_RULES = [
258
- // auto-optimizer
259
- { domain: 'auto-optimizer', agent: 'token', keywords: ['token optim', 'optimize token', 'token usage', 'reduce token', 'token cost', 'token waste', 'token efficien', 'token budget'] },
260
- { domain: 'auto-optimizer', agent: 'model-select', keywords: ['select model', 'model select', 'choose model', 'best model', 'which model', 'model recommend', 'model comparison'] },
261
- { domain: 'auto-optimizer', agent: 'self-optimize', keywords: ['self optim', 'auto optim', 'optimize system', 'optimize performance', 'optimize cost', 'reduce cost', 'cost optim', 'optimize spend'] },
262
- // shield
263
- { domain: 'shield', agent: 'prompt-injection', keywords: ['injection', 'prompt attack', 'jailbreak', 'prompt inject'] },
264
- { domain: 'shield', agent: 'pii', keywords: ['pii', 'personal info', 'personally identifiable'] },
265
- { domain: 'shield', agent: 'secrets', keywords: ['secret', 'credential', 'api key', 'password leak'] },
266
- { domain: 'shield', agent: 'toxicity', keywords: ['toxic', 'toxicity', 'harmful', 'offensive'] },
267
- { domain: 'shield', agent: 'moderation', keywords: ['moderat', 'content filter', 'content polic'] },
268
- { domain: 'shield', agent: 'abuse', keywords: ['abuse', 'misuse'] },
269
- { domain: 'shield', agent: 'redaction', keywords: ['redact', 'mask data', 'scrub data'] },
270
- // test-bench
271
- { domain: 'test-bench', agent: 'red-team', keywords: ['red team', 'red-team', 'adversarial test'] },
272
- { domain: 'test-bench', agent: 'benchmark', keywords: ['benchmark', 'bench mark', 'eval score'] },
273
- { domain: 'test-bench', agent: 'hallucination', keywords: ['hallucin', 'fabricat', 'grounding'] },
274
- { domain: 'test-bench', agent: 'quality', keywords: ['quality test', 'test quality', 'quality eval'] },
275
- { domain: 'test-bench', agent: 'bias', keywords: ['bias', 'fairness'] },
276
- // costops
277
- { domain: 'costops', agent: 'attribution', keywords: ['cost attribut', 'cost breakdown', 'spending breakdown', 'how much am i spend', 'cost per', 'spend by'] },
278
- { domain: 'costops', agent: 'forecast', keywords: ['cost forecast', 'spending forecast', 'predict cost', 'future cost', 'budget forecast'] },
279
- { domain: 'costops', agent: 'budget', keywords: ['budget', 'spending limit'] },
280
- { domain: 'costops', agent: 'roi', keywords: ['roi', 'return on invest', 'cost benefit'] },
281
- // observatory
282
- { domain: 'observatory', agent: 'telemetry', keywords: ['telemetry', 'metrics collect'] },
283
- { domain: 'observatory', agent: 'usage-patterns', keywords: ['usage pattern', 'usage trend', 'usage analys'] },
284
- { domain: 'observatory', agent: 'failures', keywords: ['failure analys', 'error rate', 'failure rate'] },
285
- { domain: 'observatory', agent: 'health-check', keywords: ['health check', 'service health', 'system health'] },
286
- { domain: 'observatory', agent: 'slo', keywords: ['slo', 'sli', 'service level'] },
287
- // sentinel
288
- { domain: 'sentinel', agent: 'anomaly', keywords: ['anomal', 'outlier', 'unusual'] },
289
- { domain: 'sentinel', agent: 'drift', keywords: ['drift', 'distribution shift', 'model drift'] },
290
- { domain: 'sentinel', agent: 'rca', keywords: ['root cause', 'rca', 'why did'] },
291
- { domain: 'sentinel', agent: 'alert', keywords: ['alert', 'notify', 'alarm'] },
292
- // memory-graph
293
- { domain: 'memory-graph', agent: 'lineage', keywords: ['lineage', 'decision history', 'decision trail'] },
294
- { domain: 'memory-graph', agent: 'conversation', keywords: ['conversation history', 'chat history', 'previous conversation'] },
295
- { domain: 'memory-graph', agent: 'knowledge-graph', keywords: ['knowledge graph', 'entity relation'] },
296
- // latency-lens
297
- { domain: 'latency-lens', agent: 'latency', keywords: ['latency', 'response time', 'slow response'] },
298
- { domain: 'latency-lens', agent: 'cold-start', keywords: ['cold start', 'cold-start', 'startup time', 'warm up'] },
299
- // orchestrator
300
- { domain: 'orchestrator', agent: 'workflow', keywords: ['workflow', 'pipeline', 'orchestrat'] },
301
- { domain: 'orchestrator', agent: 'scheduler', keywords: ['schedule', 'cron', 'recurring'] },
302
- // incident-manager
303
- { domain: 'incident-manager', agent: 'escalation', keywords: ['escalat', 'page on-call', 'incident'] },
258
+ // ==========================================================================
259
+ // auto-optimizer (3/3 agents)
260
+ // ==========================================================================
261
+ { domain: 'auto-optimizer', agent: 'token', keywords: ['token optim', 'optimize token', 'token usage', 'reduce token', 'token cost', 'token waste', 'token efficien', 'token budget', 'token count', 'token spend', 'token saving'] },
262
+ { domain: 'auto-optimizer', agent: 'model-select', keywords: ['select model', 'model select', 'choose model', 'best model', 'which model', 'model recommend', 'model comparison', 'cheapest model', 'fastest model', 'model picker'] },
263
+ { domain: 'auto-optimizer', agent: 'self-optimize', keywords: ['self optim', 'auto optim', 'optimize system', 'optimize performance', 'optimize cost', 'reduce cost', 'cost optim', 'optimize spend', 'optimize prompt', 'tune prompt', 'prompt optim'] },
264
+ // ==========================================================================
265
+ // shield (9/9 agents)
266
+ // ==========================================================================
267
+ { domain: 'shield', agent: 'prompt-injection', keywords: ['injection', 'prompt attack', 'jailbreak', 'prompt inject', 'inject attack', 'prompt hack'] },
268
+ { domain: 'shield', agent: 'pii', keywords: ['pii', 'personal info', 'personally identifiable', 'personal data', 'phone number', 'social security', 'ssn detect'] },
269
+ { domain: 'shield', agent: 'secrets', keywords: ['secret scan', 'credential leak', 'api key leak', 'password leak', 'leaked secret', 'exposed key', 'secret detect'] },
270
+ { domain: 'shield', agent: 'toxicity', keywords: ['toxic', 'toxicity', 'harmful content', 'offensive', 'hate speech', 'harmful output'] },
271
+ { domain: 'shield', agent: 'moderation', keywords: ['moderat', 'content filter', 'content polic', 'content review', 'flag content'] },
272
+ { domain: 'shield', agent: 'abuse', keywords: ['abuse detect', 'misuse detect', 'abuse pattern', 'bad actor', 'malicious use'] },
273
+ { domain: 'shield', agent: 'redaction', keywords: ['redact', 'mask data', 'scrub data', 'censor output', 'remove sensitiv'] },
274
+ { domain: 'shield', agent: 'safety-boundary', keywords: ['safety boundar', 'safety limit', 'safety check', 'safe to show', 'is it safe', 'safety gate', 'crosses boundar'] },
275
+ { domain: 'shield', agent: 'credential-exposure', keywords: ['credential expos', 'exposed credential', 'leaked credential', 'key exposure', 'password expos', 'api key expos'] },
276
+ // ==========================================================================
277
+ // test-bench (14/14 agents)
278
+ // ==========================================================================
279
+ { domain: 'test-bench', agent: 'red-team', keywords: ['red team', 'red-team', 'red team exercise'] },
280
+ { domain: 'test-bench', agent: 'adversarial', keywords: ['adversarial', 'adversary', 'attack surface', 'adversarial input'] },
281
+ { domain: 'test-bench', agent: 'benchmark', keywords: ['benchmark', 'bench mark', 'eval score', 'model benchmark'] },
282
+ { domain: 'test-bench', agent: 'compare', keywords: ['compare model', 'model a vs', 'model b vs', 'side by side', 'head to head'] },
283
+ { domain: 'test-bench', agent: 'regression', keywords: ['regression test', 'regression check', 'regression suite', 'regressed', 'performance regress'] },
284
+ { domain: 'test-bench', agent: 'quality', keywords: ['quality test', 'test quality', 'quality eval', 'output quality', 'quality score'] },
285
+ { domain: 'test-bench', agent: 'hallucination', keywords: ['hallucin', 'fabricat', 'grounding', 'made up fact', 'invented fact'] },
286
+ { domain: 'test-bench', agent: 'faithfulness', keywords: ['faithful', 'faithfulness', 'grounded in source', 'source faithful', 'accurate to source'] },
287
+ { domain: 'test-bench', agent: 'bias', keywords: ['bias', 'fairness', 'biased output', 'unfair', 'discriminat'] },
288
+ { domain: 'test-bench', agent: 'prompt-sensitivity', keywords: ['prompt sensitiv', 'sensitivity test', 'prompt variation', 'prompt robust', 'input sensitiv'] },
289
+ { domain: 'test-bench', agent: 'consistency', keywords: ['consistency test', 'consistent output', 'output consistenc', 'reproducib', 'deterministic'] },
290
+ { domain: 'test-bench', agent: 'stress', keywords: ['stress test', 'load test', 'high concurrency', 'throughput test', '10k request', '1000 request'] },
291
+ { domain: 'test-bench', agent: 'golden-dataset', keywords: ['golden dataset', 'golden set', 'gold standard', 'reference dataset', 'evaluation dataset', 'eval set'] },
292
+ { domain: 'test-bench', agent: 'synthetic-data', keywords: ['synthetic data', 'generate data', 'fake data', 'test data generat', 'data augment', 'artificial data'] },
293
+ // ==========================================================================
294
+ // costops (5/5 agents)
295
+ // ==========================================================================
296
+ { domain: 'costops', agent: 'attribution', keywords: ['cost attribut', 'cost breakdown', 'spending breakdown', 'how much am i spend', 'cost per', 'spend by', 'spending by team', 'cost by project'] },
297
+ { domain: 'costops', agent: 'forecast', keywords: ['cost forecast', 'spending forecast', 'predict cost', 'future cost', 'budget forecast', 'next quarter cost', 'project spending'] },
298
+ { domain: 'costops', agent: 'budget', keywords: ['budget', 'spending limit', 'within budget', 'over budget', 'budget alert', 'budget threshold'] },
299
+ { domain: 'costops', agent: 'roi', keywords: ['roi', 'return on invest', 'cost benefit', 'value delivered', 'payback period'] },
300
+ { domain: 'costops', agent: 'tradeoff', keywords: ['tradeoff', 'trade-off', 'cost quality', 'cost vs quality', 'build or buy', 'build vs buy', 'price performance', 'bang for buck'] },
301
+ // ==========================================================================
302
+ // observatory (7/7 agents)
303
+ // ==========================================================================
304
+ { domain: 'observatory', agent: 'telemetry', keywords: ['telemetry', 'metrics collect', 'emit metric', 'telemetry data'] },
305
+ { domain: 'observatory', agent: 'usage-patterns', keywords: ['usage pattern', 'usage trend', 'usage analys', 'usage over time', 'adoption metric'] },
306
+ { domain: 'observatory', agent: 'failures', keywords: ['failure analys', 'error rate', 'failure rate', 'failure trend', 'error trend', 'failing request'] },
307
+ { domain: 'observatory', agent: 'health-check', keywords: ['health check', 'service health', 'system health', 'is it up', 'service status', 'uptime'] },
308
+ { domain: 'observatory', agent: 'slo', keywords: ['slo', 'sli', 'service level', 'error budget', 'nines of availability'] },
309
+ { domain: 'observatory', agent: 'post-mortem', keywords: ['outage review', 'blameless review'] },
310
+ { domain: 'observatory', agent: 'visualization', keywords: ['visualiz', 'dashboard', 'chart', 'graph metric', 'plot data', 'show me a graph'] },
311
+ // ==========================================================================
312
+ // sentinel (5/5 agents)
313
+ // ==========================================================================
314
+ { domain: 'sentinel', agent: 'anomaly', keywords: ['anomal', 'outlier', 'unusual', 'unexpected spike'] },
315
+ { domain: 'sentinel', agent: 'drift', keywords: ['drift', 'distribution shift', 'model drift', 'data drift', 'concept drift', 'feature drift'] },
316
+ { domain: 'sentinel', agent: 'rca', keywords: ['root cause', 'rca', 'why did', 'root-cause', 'diagnos'] },
317
+ { domain: 'sentinel', agent: 'alert', keywords: ['set up alert', 'alert rule', 'alert config', 'pager', 'notify when'] },
318
+ { domain: 'sentinel', agent: 'correlation', keywords: ['correlat', 'correlated event', 'event correlation', 'pattern correlation', 'cross-signal'] },
319
+ // ==========================================================================
320
+ // memory-graph (6/6 agents)
321
+ // ==========================================================================
322
+ { domain: 'memory-graph', agent: 'lineage', keywords: ['lineage', 'decision history', 'decision trail', 'provenance'] },
323
+ { domain: 'memory-graph', agent: 'conversation', keywords: ['conversation history', 'chat history', 'previous conversation', 'session history'] },
324
+ { domain: 'memory-graph', agent: 'decisions', keywords: ['decision log', 'decision record', 'past decision', 'decision made', 'track decision'] },
325
+ { domain: 'memory-graph', agent: 'knowledge-graph', keywords: ['knowledge graph', 'entity relation', 'knowledge base', 'entity map'] },
326
+ { domain: 'memory-graph', agent: 'retrieval', keywords: ['retriev from memory', 'fetch context', 'recall from', 'find in memory', 'search memory'] },
327
+ { domain: 'memory-graph', agent: 'patterns', keywords: ['learned pattern', 'pattern detect', 'recurring pattern', 'behavior pattern', 'pattern histor'] },
328
+ // ==========================================================================
329
+ // latency-lens (2/2 agents)
330
+ // ==========================================================================
331
+ { domain: 'latency-lens', agent: 'latency', keywords: ['latency', 'response time', 'slow response', 'how fast', 'p99', 'p95', 'p50', 'tail latency', 'time to first token', 'ttft'] },
332
+ { domain: 'latency-lens', agent: 'cold-start', keywords: ['cold start', 'cold-start', 'startup time', 'warm up', 'warm-up', 'first request slow', 'initialization time'] },
333
+ // ==========================================================================
334
+ // forge (4/4 agents)
335
+ // ==========================================================================
336
+ { domain: 'forge', agent: 'sdk', keywords: ['generate sdk', 'sdk generat', 'client library', 'sdk build', 'create sdk'] },
337
+ { domain: 'forge', agent: 'cli', keywords: ['generate cli', 'cli generat', 'cli wrapper', 'cli tool generat', 'build cli'] },
338
+ { domain: 'forge', agent: 'api-translation', keywords: ['api translat', 'convert api', 'openapi', 'swagger', 'api convert', 'api transform'] },
339
+ { domain: 'forge', agent: 'version-compat', keywords: ['version compat', 'backward compat', 'breaking change', 'api version', 'version check', 'deprecated api'] },
340
+ // ==========================================================================
341
+ // edge (5/5 agents)
342
+ // ==========================================================================
343
+ { domain: 'edge', agent: 'tool-invoke', keywords: ['tool invoke', 'invoke tool', 'call tool', 'tool call', 'function call agent'] },
344
+ { domain: 'edge', agent: 'circuit-breaker', keywords: ['circuit break', 'circuit-break', 'open circuit', 'trip circuit', 'breaker pattern'] },
345
+ { domain: 'edge', agent: 'failover', keywords: ['failover', 'fail over', 'fallback endpoint', 'backup endpoint', 'failover config'] },
346
+ { domain: 'edge', agent: 'execution-guard', keywords: ['execution guard', 'exec guard', 'execution limit', 'run guard', 'execution boundar'] },
347
+ { domain: 'edge', agent: 'caching', keywords: ['cache layer', 'cache config', 'response cache', 'cache hit', 'cache miss', 'invalidate cache', 'cache ttl'] },
348
+ // ==========================================================================
349
+ // incident-manager (3/3 agents)
350
+ // ==========================================================================
351
+ { domain: 'incident-manager', agent: 'escalation', keywords: ['escalat', 'page on-call', 'page sre', 'critical incident', 'incident escalat'] },
304
352
  { domain: 'incident-manager', agent: 'post-mortem', keywords: ['post-mortem', 'postmortem', 'post mortem', 'incident review'] },
305
- // governance-dashboard
306
- { domain: 'governance-dashboard', agent: 'audit', keywords: ['audit trail', 'audit log', 'governance audit'] },
307
- { domain: 'governance-dashboard', agent: 'impact', keywords: ['impact analys', 'blast radius'] },
308
- // policy-engine
309
- { domain: 'policy-engine', agent: 'enforce', keywords: ['enforce policy', 'policy enforce', 'apply policy'] },
310
- { domain: 'policy-engine', agent: 'constraints', keywords: ['constraint', 'guardrail', 'limit'] },
311
- { domain: 'policy-engine', agent: 'approval', keywords: ['approval', 'approve', 'sign-off'] },
312
- // platform
313
- { domain: 'platform', agent: 'executive-summary', keywords: ['executive summary', 'exec summary', 'summary report'] },
314
- { domain: 'platform', agent: 'decision-memo', keywords: ['decision memo', 'decision document'] },
315
- { domain: 'platform', agent: 'risk-score', keywords: ['risk score', 'risk assess', 'risk analys', 'risk evaluat'] },
316
- // forge
317
- { domain: 'forge', agent: 'sdk', keywords: ['generate sdk', 'sdk generat', 'client library'] },
318
- { domain: 'forge', agent: 'api-translation', keywords: ['api translat', 'convert api', 'openapi'] },
319
- // connector-hub
320
- { domain: 'connector-hub', agent: 'database-query', keywords: ['query database', 'database query', 'sql query', 'db query'] },
321
- { domain: 'connector-hub', agent: 'webhook-ingest', keywords: ['webhook', 'ingest event'] },
322
- { domain: 'connector-hub', agent: 'erp-surface', keywords: ['erp', 'enterprise resource'] },
323
- // data-vault
324
- { domain: 'data-vault', agent: 'anonymize', keywords: ['anonymize', 'anonymis', 'de-identify', 'deidentif'] },
325
- { domain: 'data-vault', agent: 'access-control', keywords: ['access control', 'permission', 'authorizat'] },
326
- // research-lab
327
- { domain: 'research-lab', agent: 'hypothesis', keywords: ['hypothesis', 'experiment', 'a/b test'] },
328
- { domain: 'research-lab', agent: 'metrics', keywords: ['metrics analys', 'analyze metrics', 'kpi'] },
329
- // simulator
330
- { domain: 'simulator', agent: 'what-if', keywords: ['what-if', 'what if', 'simulat', 'scenario'] },
331
- // compliance
332
- { domain: 'governance-dashboard', agent: 'audit', keywords: ['compliance', 'compliant', 'regulat', 'data residency', 'gdpr', 'hipaa', 'consent'] },
353
+ { domain: 'incident-manager', agent: 'hitl', keywords: ['human in the loop', 'hitl', 'human review', 'manual review', 'human approval', 'human oversight', 'manual override'] },
354
+ // ==========================================================================
355
+ // orchestrator (7/7 agents)
356
+ // ==========================================================================
357
+ { domain: 'orchestrator', agent: 'workflow', keywords: ['workflow', 'pipeline', 'orchestrat', 'flow builder', 'agent pipeline'] },
358
+ { domain: 'orchestrator', agent: 'scheduler', keywords: ['schedule', 'cron', 'recurring', 'nightly job', 'scheduled task', 'periodic'] },
359
+ { domain: 'orchestrator', agent: 'dependencies', keywords: ['dependenc', 'dependency graph', 'task depend', 'depends on', 'prerequisit', 'blocked by'] },
360
+ { domain: 'orchestrator', agent: 'retry', keywords: ['retry polic', 'retry config', 'retry strateg', 'backoff', 'exponential retry'] },
361
+ { domain: 'orchestrator', agent: 'parallel', keywords: ['parallel exec', 'run parallel', 'run concurrent', 'fan out', 'fan-out', 'run simultaneously'] },
362
+ { domain: 'orchestrator', agent: 'state-machine', keywords: ['state machine', 'state-machine', 'state transition', 'finite state', 'fsm'] },
363
+ { domain: 'orchestrator', agent: 'swarm', keywords: ['swarm orchestrat', 'agent swarm', 'swarm status', 'multi-agent swarm'] },
364
+ // ==========================================================================
365
+ // governance-dashboard (3/3 agents)
366
+ // ==========================================================================
367
+ { domain: 'governance-dashboard', agent: 'audit', keywords: ['audit trail', 'audit log', 'governance audit', 'compliance', 'compliant', 'regulat', 'data residency', 'gdpr', 'hipaa', 'consent', 'sox', 'pci'] },
368
+ { domain: 'governance-dashboard', agent: 'impact', keywords: ['impact analys', 'blast radius', 'change impact', 'downstream impact', 'affected service'] },
369
+ { domain: 'governance-dashboard', agent: 'oversight', keywords: ['oversight', 'governance oversight', 'ai oversight', 'oversight board', 'governance review', 'supervision'] },
370
+ // ==========================================================================
371
+ // policy-engine (3/3 agents)
372
+ // ==========================================================================
373
+ { domain: 'policy-engine', agent: 'enforce', keywords: ['enforce policy', 'policy enforce', 'apply policy', 'enforce rule', 'policy check', 'policy gate'] },
374
+ { domain: 'policy-engine', agent: 'constraints', keywords: ['constraint', 'guardrail', 'rate limit', 'usage limit', 'policy constraint'] },
375
+ { domain: 'policy-engine', agent: 'approval', keywords: ['approval', 'approve', 'sign-off', 'sign off', 'require approval', 'pending approval', 'approval workflow'] },
376
+ // ==========================================================================
377
+ // registry (3/3 agents)
378
+ // ==========================================================================
379
+ { domain: 'registry', agent: 'index', keywords: ['agent index', 'agent registry', 'registered agent', 'agent catalog', 'discover agent'] },
380
+ { domain: 'registry', agent: 'reputation', keywords: ['reputation', 'agent rating', 'trust score', 'reliability score', 'agent reputation'] },
381
+ { domain: 'registry', agent: 'bootstrap', keywords: ['bootstrap agent', 'agent bootstrap', 'scaffold agent', 'onboard agent'] },
382
+ // ==========================================================================
383
+ // marketplace (2/2 agents)
384
+ // ==========================================================================
385
+ { domain: 'marketplace', agent: 'package', keywords: ['marketplace', 'install agent', 'agent package', 'marketplace search', 'agent plugin'] },
386
+ { domain: 'marketplace', agent: 'deprecation', keywords: ['deprecat', 'end of life', 'sunset', 'eol', 'phase out', 'removal notice'] },
387
+ // ==========================================================================
388
+ // analytics-hub (2/2 agents)
389
+ // ==========================================================================
390
+ { domain: 'analytics-hub', agent: 'consensus', keywords: ['consensus build', 'group decision', 'collective opinion', 'consensus view'] },
391
+ { domain: 'analytics-hub', agent: 'recommendation', keywords: ['recommendation report', 'what should i', 'recommend', 'best practice report'] },
392
+ // ==========================================================================
393
+ // config-manager (1/1 agents)
394
+ // ==========================================================================
395
+ { domain: 'config-manager', agent: 'validate', keywords: ['validate config', 'config valid', 'check config', 'configuration check', 'config error'] },
396
+ // ==========================================================================
397
+ // schema-registry (1/1 agents)
398
+ // ==========================================================================
399
+ { domain: 'schema-registry', agent: 'validate', keywords: ['schema valid', 'validate schema', 'json schema', 'schema check', 'schema error'] },
400
+ // ==========================================================================
401
+ // connector-hub (5/5 agents)
402
+ // ==========================================================================
403
+ { domain: 'connector-hub', agent: 'erp-surface', keywords: ['erp', 'enterprise resource', 'sap', 'salesforce', 'erp integrat'] },
404
+ { domain: 'connector-hub', agent: 'database-query', keywords: ['query database', 'database query', 'sql query', 'db query', 'run query', 'select from'] },
405
+ { domain: 'connector-hub', agent: 'webhook-ingest', keywords: ['webhook', 'ingest event', 'webhook endpoint', 'receive webhook', 'webhook setup'] },
406
+ { domain: 'connector-hub', agent: 'event-normalize', keywords: ['event normaliz', 'normalize event', 'event transform', 'standardize event', 'event format'] },
407
+ { domain: 'connector-hub', agent: 'auth-identity', keywords: ['auth identity', 'identity provider', 'idp', 'sso', 'oauth', 'saml', 'identity federation'] },
408
+ // ==========================================================================
409
+ // copilot (7/7 agents)
410
+ // ==========================================================================
411
+ { domain: 'copilot', agent: 'planner', keywords: ['plan task', 'create plan', 'task plan', 'action plan', 'project plan'] },
412
+ { domain: 'copilot', agent: 'config', keywords: ['copilot config', 'configure copilot', 'agent config setup'] },
413
+ { domain: 'copilot', agent: 'decomposer', keywords: ['decompose', 'break down task', 'split task', 'subtask', 'task decompos'] },
414
+ { domain: 'copilot', agent: 'clarifier', keywords: ['clarif', 'what do you mean', 'ambiguous request', 'unclear request', 'refine request'] },
415
+ { domain: 'copilot', agent: 'intent', keywords: ['classify intent', 'detect intent', 'intent classif', 'user intent'] },
416
+ { domain: 'copilot', agent: 'reflection', keywords: ['reflect on', 'self assess', 'self-assess', 'introspect', 'how did i do'] },
417
+ { domain: 'copilot', agent: 'meta-reasoner', keywords: ['meta reason', 'meta-reason', 'reasoning chain', 'chain of thought', 'reasoning trace'] },
418
+ // ==========================================================================
419
+ // simulator (2/2 agents)
420
+ // ==========================================================================
421
+ { domain: 'simulator', agent: 'what-if', keywords: ['what-if', 'what if', 'simulat', 'hypothetical'] },
422
+ { domain: 'simulator', agent: 'scenario', keywords: ['scenario plan', 'scenario test', 'scenario analys', 'deployment scenario', 'failure scenario'] },
423
+ // ==========================================================================
424
+ // benchmark-exchange (1/1 agents)
425
+ // ==========================================================================
426
+ { domain: 'benchmark-exchange', agent: 'publish', keywords: ['publish benchmark', 'share benchmark', 'benchmark exchange', 'submit benchmark', 'benchmark leaderboard'] },
427
+ // ==========================================================================
428
+ // inference-gateway (1/1 agents)
429
+ // ==========================================================================
430
+ { domain: 'inference-gateway', agent: 'route', keywords: ['inference route', 'route request', 'gateway route', 'load balance model', 'model route', 'inference gateway'] },
431
+ // ==========================================================================
432
+ // data-vault (2/2 agents)
433
+ // ==========================================================================
434
+ { domain: 'data-vault', agent: 'anonymize', keywords: ['anonymize', 'anonymis', 'de-identify', 'deidentif', 'mask identit', 'strip pii'] },
435
+ { domain: 'data-vault', agent: 'access-control', keywords: ['access control', 'who has access', 'rbac', 'role based access', 'data access'] },
436
+ // ==========================================================================
437
+ // research-lab (2/2 agents)
438
+ // ==========================================================================
439
+ { domain: 'research-lab', agent: 'hypothesis', keywords: ['hypothesis', 'experiment', 'a/b test', 'ab test', 'hypothesis test', 'statistical test'] },
440
+ { domain: 'research-lab', agent: 'metrics', keywords: ['metrics analys', 'analyze metrics', 'kpi', 'key performance', 'metric trend'] },
441
+ // ==========================================================================
442
+ // platform (4/4 agents)
443
+ // ==========================================================================
444
+ { domain: 'platform', agent: 'decision', keywords: ['make decision', 'go no-go', 'go/no-go', 'decision support', 'decision framework', 'should we'] },
445
+ { domain: 'platform', agent: 'executive-summary', keywords: ['executive summary', 'exec summary', 'summary report', 'tldr', 'tl;dr', 'overview report', 'board summary'] },
446
+ { domain: 'platform', agent: 'decision-memo', keywords: ['decision memo', 'decision document', 'memo for', 'write memo', 'decision paper'] },
447
+ { domain: 'platform', agent: 'risk-score', keywords: ['risk score', 'risk assess', 'risk analys', 'risk evaluat', 'risk level', 'risk rating', 'how risky'] },
333
448
  ];
449
+ /**
450
+ * Multi-agent combos for complex queries. Checked BEFORE single-agent keywords.
451
+ * Each combo maps a query pattern to 2-5 agents that should all be invoked in parallel.
452
+ */
453
+ const MULTI_AGENT_COMBOS = [
454
+ // === Cost & Optimization ===
455
+ { id: 'cost-analysis', keywords: ['how much am i spend', 'cost analysis', 'spending report', 'cost review', 'what are we spend', 'spending on ai', 'ai cost', 'ai spend', 'total cost', 'monthly cost'],
456
+ agents: [{ domain: 'costops', agent: 'attribution' }, { domain: 'costops', agent: 'forecast' }, { domain: 'costops', agent: 'roi' }] },
457
+ { id: 'token-optimization', keywords: ['optimize token', 'token optim', 'reduce token', 'token usage for', 'token cost'],
458
+ agents: [{ domain: 'auto-optimizer', agent: 'token' }, { domain: 'auto-optimizer', agent: 'model-select' }, { domain: 'costops', agent: 'attribution' }] },
459
+ { id: 'full-optimization', keywords: ['optimize everything', 'full system optim', 'comprehensive optim'],
460
+ agents: [{ domain: 'auto-optimizer', agent: 'self-optimize' }, { domain: 'auto-optimizer', agent: 'token' }, { domain: 'auto-optimizer', agent: 'model-select' }, { domain: 'costops', agent: 'tradeoff' }, { domain: 'latency-lens', agent: 'latency' }] },
461
+ { id: 'cost-quality-tradeoff', keywords: ['cost vs quality', 'cost quality tradeoff', 'cheapest good', 'bang for buck'],
462
+ agents: [{ domain: 'costops', agent: 'tradeoff' }, { domain: 'costops', agent: 'roi' }, { domain: 'auto-optimizer', agent: 'model-select' }] },
463
+ // === Security ===
464
+ { id: 'security-scan', keywords: ['security scan', 'scan for security', 'security issue', 'security check', 'is this safe', 'safety scan', 'check security', 'vulnerability scan', 'secure enough'],
465
+ agents: [{ domain: 'shield', agent: 'prompt-injection' }, { domain: 'shield', agent: 'pii' }, { domain: 'shield', agent: 'secrets' }, { domain: 'shield', agent: 'toxicity' }, { domain: 'shield', agent: 'credential-exposure' }] },
466
+ { id: 'red-team', keywords: ['red team', 'red-team', 'adversarial exercise'],
467
+ agents: [{ domain: 'test-bench', agent: 'red-team' }, { domain: 'test-bench', agent: 'adversarial' }, { domain: 'shield', agent: 'prompt-injection' }, { domain: 'shield', agent: 'safety-boundary' }] },
468
+ { id: 'data-protection', keywords: ['protect data', 'data protect', 'anonymize and redact', 'redact pii'],
469
+ agents: [{ domain: 'data-vault', agent: 'anonymize' }, { domain: 'shield', agent: 'pii' }, { domain: 'shield', agent: 'redaction' }, { domain: 'data-vault', agent: 'access-control' }] },
470
+ { id: 'abuse-detection', keywords: ['detect abuse', 'misusing the api', 'abuse pattern', 'bad actor'],
471
+ agents: [{ domain: 'shield', agent: 'abuse' }, { domain: 'observatory', agent: 'usage-patterns' }, { domain: 'sentinel', agent: 'anomaly' }, { domain: 'sentinel', agent: 'alert' }] },
472
+ { id: 'safety-policies', keywords: ['safety polic', 'content rule', 'moderation polic', 'content safet'],
473
+ agents: [{ domain: 'policy-engine', agent: 'enforce' }, { domain: 'policy-engine', agent: 'constraints' }, { domain: 'shield', agent: 'moderation' }, { domain: 'shield', agent: 'safety-boundary' }] },
474
+ // === Model Evaluation ===
475
+ { id: 'model-evaluation', keywords: ['evaluate model', 'model evaluation', 'model quality', 'benchmark model', 'eval my model', 'test my model', 'model perform', 'how good is the model'],
476
+ agents: [{ domain: 'test-bench', agent: 'benchmark' }, { domain: 'test-bench', agent: 'quality' }, { domain: 'test-bench', agent: 'hallucination' }, { domain: 'test-bench', agent: 'faithfulness' }] },
477
+ { id: 'full-model-eval', keywords: ['comprehensive eval', 'full eval', 'complete model test'],
478
+ agents: [{ domain: 'test-bench', agent: 'benchmark' }, { domain: 'test-bench', agent: 'bias' }, { domain: 'test-bench', agent: 'hallucination' }, { domain: 'test-bench', agent: 'consistency' }, { domain: 'test-bench', agent: 'faithfulness' }] },
479
+ { id: 'model-switch', keywords: ['switch model', 'model migration', 'what if we switch', 'migrate model'],
480
+ agents: [{ domain: 'simulator', agent: 'what-if' }, { domain: 'auto-optimizer', agent: 'model-select' }, { domain: 'costops', agent: 'tradeoff' }, { domain: 'test-bench', agent: 'compare' }] },
481
+ { id: 'drift-detection', keywords: ['detect drift', 'model degrad', 'drift in production'],
482
+ agents: [{ domain: 'sentinel', agent: 'drift' }, { domain: 'sentinel', agent: 'anomaly' }, { domain: 'test-bench', agent: 'regression' }, { domain: 'observatory', agent: 'telemetry' }] },
483
+ // === SRE & Operations ===
484
+ { id: 'anomaly-investigation', keywords: ['detect anomal', 'something looks wrong', 'investigate anomal', 'unusual pattern', 'anomal detect', 'check for anomal', 'weird pattern'],
485
+ agents: [{ domain: 'sentinel', agent: 'anomaly' }, { domain: 'sentinel', agent: 'drift' }, { domain: 'sentinel', agent: 'correlation' }, { domain: 'observatory', agent: 'telemetry' }] },
486
+ { id: 'latency-debug', keywords: ['why is it slow', 'latency issue', 'latency problem', 'slow request', 'high latency', 'latency so high', 'too slow', 'why so slow', 'response too slow', 'latency spike'],
487
+ agents: [{ domain: 'latency-lens', agent: 'latency' }, { domain: 'latency-lens', agent: 'cold-start' }, { domain: 'sentinel', agent: 'anomaly' }, { domain: 'sentinel', agent: 'rca' }] },
488
+ { id: 'incident-response', keywords: ['service down', 'outage', 'incident happen', 'went down', 'service failure', 'things are broken', 'production down', 'everything is down'],
489
+ agents: [{ domain: 'incident-manager', agent: 'escalation' }, { domain: 'incident-manager', agent: 'post-mortem' }, { domain: 'sentinel', agent: 'rca' }, { domain: 'observatory', agent: 'failures' }] },
490
+ { id: 'observability-review', keywords: ['observability', 'system status', 'platform health', 'monitoring overview'],
491
+ agents: [{ domain: 'observatory', agent: 'telemetry' }, { domain: 'observatory', agent: 'health-check' }, { domain: 'observatory', agent: 'slo' }, { domain: 'observatory', agent: 'visualization' }] },
492
+ { id: 'resilience-check', keywords: ['make resilient', 'handle failure', 'failure handling', 'fault toleran'],
493
+ agents: [{ domain: 'edge', agent: 'circuit-breaker' }, { domain: 'edge', agent: 'failover' }, { domain: 'edge', agent: 'execution-guard' }, { domain: 'orchestrator', agent: 'retry' }] },
494
+ // === Pipeline & Integration ===
495
+ { id: 'build-pipeline', keywords: ['build pipeline', 'create pipeline', 'orchestrate task', 'set up workflow'],
496
+ agents: [{ domain: 'orchestrator', agent: 'workflow' }, { domain: 'orchestrator', agent: 'scheduler' }, { domain: 'orchestrator', agent: 'dependencies' }, { domain: 'orchestrator', agent: 'parallel' }] },
497
+ { id: 'integration-setup', keywords: ['wire up webhook', 'integrate service', 'connect webhook', 'webhook pipeline'],
498
+ agents: [{ domain: 'connector-hub', agent: 'webhook-ingest' }, { domain: 'connector-hub', agent: 'event-normalize' }, { domain: 'orchestrator', agent: 'workflow' }] },
499
+ { id: 'enterprise-data', keywords: ['query sap', 'erp data', 'enterprise data', 'get records from'],
500
+ agents: [{ domain: 'connector-hub', agent: 'database-query' }, { domain: 'connector-hub', agent: 'erp-surface' }, { domain: 'connector-hub', agent: 'auth-identity' }] },
501
+ { id: 'smart-routing', keywords: ['smart routing', 'route inference optimal', 'intelligent routing'],
502
+ agents: [{ domain: 'inference-gateway', agent: 'route' }, { domain: 'auto-optimizer', agent: 'model-select' }, { domain: 'costops', agent: 'tradeoff' }] },
503
+ // === Executive & Governance ===
504
+ { id: 'executive-brief', keywords: ['executive summary', 'board report', 'platform summary', 'executive overview'],
505
+ agents: [{ domain: 'platform', agent: 'executive-summary' }, { domain: 'costops', agent: 'attribution' }, { domain: 'observatory', agent: 'slo' }, { domain: 'research-lab', agent: 'metrics' }] },
506
+ { id: 'decision-package', keywords: ['go no-go', 'go/no-go', 'decision package', 'decision memo'],
507
+ agents: [{ domain: 'platform', agent: 'decision' }, { domain: 'platform', agent: 'decision-memo' }, { domain: 'platform', agent: 'risk-score' }, { domain: 'costops', agent: 'roi' }] },
508
+ { id: 'risk-assessment', keywords: ['risk assess', 'how risky', 'risk evaluat', 'risk analys'],
509
+ agents: [{ domain: 'platform', agent: 'risk-score' }, { domain: 'governance-dashboard', agent: 'impact' }, { domain: 'simulator', agent: 'scenario' }] },
510
+ { id: 'compliance-review', keywords: ['compliance check', 'are we compliant', 'gdpr complian', 'hipaa complian', 'governance review', 'gdpr', 'hipaa', 'compliance', 'are we compliant', 'regulatory'],
511
+ agents: [{ domain: 'governance-dashboard', agent: 'audit' }, { domain: 'governance-dashboard', agent: 'oversight' }, { domain: 'policy-engine', agent: 'enforce' }, { domain: 'data-vault', agent: 'access-control' }] },
512
+ { id: 'impact-analysis', keywords: ['impact analys', 'blast radius', 'change impact'],
513
+ agents: [{ domain: 'governance-dashboard', agent: 'impact' }, { domain: 'platform', agent: 'risk-score' }, { domain: 'simulator', agent: 'scenario' }, { domain: 'sentinel', agent: 'correlation' }] },
514
+ { id: 'decision-audit', keywords: ['decision audit', 'trace decision', 'decision trail'],
515
+ agents: [{ domain: 'memory-graph', agent: 'decisions' }, { domain: 'memory-graph', agent: 'lineage' }, { domain: 'governance-dashboard', agent: 'audit' }, { domain: 'memory-graph', agent: 'knowledge-graph' }] },
516
+ { id: 'value-assessment', keywords: ['delivering value', 'ai team roi', 'are we delivering', 'value assessment'],
517
+ agents: [{ domain: 'costops', agent: 'roi' }, { domain: 'research-lab', agent: 'metrics' }, { domain: 'observatory', agent: 'usage-patterns' }, { domain: 'platform', agent: 'executive-summary' }] },
518
+ { id: 'recommendation-report', keywords: ['recommendation report', 'generate recommendation', 'board recommendation'],
519
+ agents: [{ domain: 'analytics-hub', agent: 'recommendation' }, { domain: 'analytics-hub', agent: 'consensus' }, { domain: 'platform', agent: 'executive-summary' }] },
520
+ // === Planning ===
521
+ { id: 'task-planning', keywords: ['help me plan', 'break down this', 'plan this task', 'decompose this'],
522
+ agents: [{ domain: 'copilot', agent: 'planner' }, { domain: 'copilot', agent: 'decomposer' }, { domain: 'copilot', agent: 'clarifier' }] },
523
+ { id: 'scenario-simulation', keywords: ['simulate scenario', 'test scenario', 'deployment scenario'],
524
+ agents: [{ domain: 'simulator', agent: 'scenario' }, { domain: 'simulator', agent: 'what-if' }, { domain: 'platform', agent: 'risk-score' }] },
525
+ { id: 'version-health', keywords: ['version compat', 'is this deprecated', 'api still supported'],
526
+ agents: [{ domain: 'forge', agent: 'version-compat' }, { domain: 'marketplace', agent: 'deprecation' }, { domain: 'registry', agent: 'index' }] },
527
+ { id: 'agent-onboarding', keywords: ['onboard agent', 'register new agent', 'new agent setup'],
528
+ agents: [{ domain: 'registry', agent: 'bootstrap' }, { domain: 'registry', agent: 'index' }, { domain: 'config-manager', agent: 'validate' }] },
529
+ ];
530
+ /**
531
+ * Classify a query against multi-agent combos.
532
+ * Returns an array of intents if a combo matches, or null.
533
+ */
534
+ function classifyMultiAgent(query) {
535
+ const q = query.toLowerCase();
536
+ for (const combo of MULTI_AGENT_COMBOS) {
537
+ for (const kw of combo.keywords) {
538
+ if (q.includes(kw)) {
539
+ // Verify all agents exist in registry
540
+ const validAgents = combo.agents.filter(({ domain, agent }) => {
541
+ const dc = AGENT_DOMAINS[domain];
542
+ return dc && dc.agents.includes(agent);
543
+ });
544
+ if (validAgents.length >= 2) {
545
+ return validAgents.map(({ domain, agent }) => ({
546
+ domain,
547
+ agent,
548
+ confidence: 0.75,
549
+ suggested_payload: {},
550
+ reasoning: `Multi-agent combo "${combo.id}" keyword: "${kw}"`,
551
+ }));
552
+ }
553
+ }
554
+ }
555
+ }
556
+ return null;
557
+ }
334
558
  /**
335
559
  * Classify a query using keyword matching against the static rule table.
336
560
  * Returns the best match or null if no keywords match.
@@ -362,21 +586,65 @@ function classifyByKeywords(query) {
362
586
  export async function executeNaturalLanguageRoute(query, options) {
363
587
  const start = Date.now();
364
588
  const correlationId = options.trace_id ?? crypto.randomUUID();
365
- // Try LLM-based classification first (if API key available)
366
- let intent = null;
589
+ // Priority 1: Try multi-agent combo keywords (complex queries 2-5 agents in parallel)
590
+ {
591
+ const multiIntents = classifyMultiAgent(query);
592
+ if (multiIntents) {
593
+ // Multi-agent combo matched — dispatch all agents in parallel
594
+ const agentLabels = multiIntents.map(i => `${i.domain}/${i.agent}`).join(', ');
595
+ console.error(`Multi-agent routing: ${agentLabels}`);
596
+ const dispatchPromises = multiIntents.map(async (intent) => {
597
+ const payload = {
598
+ execution_ref: correlationId,
599
+ text: query,
600
+ ...intent.suggested_payload,
601
+ };
602
+ try {
603
+ const result = await executeAgentsInvokeCommand(intent.domain, intent.agent, payload, options);
604
+ return { intent, result: result };
605
+ }
606
+ catch (err) {
607
+ const errMsg = err instanceof Error ? err.message : String(err);
608
+ return { intent, result: { error: errMsg } };
609
+ }
610
+ });
611
+ const invocations = await Promise.allSettled(dispatchPromises);
612
+ const results = invocations.map((settled, idx) => {
613
+ if (settled.status === 'fulfilled') {
614
+ return settled.value;
615
+ }
616
+ // Shouldn't happen since we catch inside, but handle anyway
617
+ return {
618
+ intent: multiIntents[idx],
619
+ result: { error: settled.reason instanceof Error ? settled.reason.message : String(settled.reason) },
620
+ };
621
+ });
622
+ return {
623
+ kind: 'multi',
624
+ result: {
625
+ query,
626
+ intents: multiIntents,
627
+ invocations: results,
628
+ timing: Date.now() - start,
629
+ },
630
+ };
631
+ }
632
+ }
633
+ // Priority 2: Try LLM-based classification (if API key available)
634
+ let singleIntent = null;
367
635
  const anthropicKey = await getAnthropicApiKey();
368
636
  if (anthropicKey) {
369
- intent = await tryLlmClassification(query, anthropicKey, correlationId);
637
+ singleIntent = await tryLlmClassification(query, anthropicKey, correlationId);
370
638
  }
371
- // Fall back to keyword-based classification
372
- if (!intent) {
373
- intent = classifyByKeywords(query);
374
- if (intent) {
375
- console.error(`Routing to ${intent.domain}/${intent.agent} (keyword match)`);
639
+ // Priority 3: Fall back to single-agent keyword classification
640
+ if (!singleIntent) {
641
+ singleIntent = classifyByKeywords(query);
642
+ if (singleIntent) {
643
+ console.error(`Routing to ${singleIntent.domain}/${singleIntent.agent} (keyword match)`);
376
644
  }
377
645
  }
378
- // If neither method matched, throw a helpful error
379
- if (!intent) {
646
+ // If no method matched, throw a helpful error
647
+ if (!singleIntent) {
380
648
  throw new Error(`Could not determine intent from: "${query}"\n` +
381
649
  `\n` +
382
650
  ` No matching agent domain found. Try being more specific, or use explicit invocation:\n` +
@@ -387,12 +655,12 @@ export async function executeNaturalLanguageRoute(query, options) {
387
655
  const dispatchPayload = {
388
656
  execution_ref: correlationId,
389
657
  text: query,
390
- ...intent.suggested_payload,
658
+ ...singleIntent.suggested_payload,
391
659
  };
392
660
  // Dispatch to the target agent
393
661
  let invocation;
394
662
  try {
395
- invocation = await executeAgentsInvokeCommand(intent.domain, intent.agent, dispatchPayload, options);
663
+ invocation = await executeAgentsInvokeCommand(singleIntent.domain, singleIntent.agent, dispatchPayload, options);
396
664
  }
397
665
  catch (dispatchError) {
398
666
  const errStr = dispatchError instanceof Error ? dispatchError.message : String(dispatchError);
@@ -400,22 +668,25 @@ export async function executeNaturalLanguageRoute(query, options) {
400
668
  const fieldAfter = errStr.match(/missing required field\W*'?(\w+)/i);
401
669
  const fieldName = fieldBefore?.[1] || fieldAfter?.[1];
402
670
  if (fieldName) {
403
- throw new Error(`Routed to ${intent.domain}/${intent.agent} (${(intent.confidence * 100).toFixed(0)}% confidence)\n` +
404
- (intent.reasoning ? ` Reason: ${intent.reasoning}\n` : '') +
671
+ throw new Error(`Routed to ${singleIntent.domain}/${singleIntent.agent} (${(singleIntent.confidence * 100).toFixed(0)}% confidence)\n` +
672
+ (singleIntent.reasoning ? ` Reason: ${singleIntent.reasoning}\n` : '') +
405
673
  `\n` +
406
674
  ` This agent requires structured input that cannot be inferred\n` +
407
675
  ` from a natural language query.\n` +
408
676
  ` Missing field: ${fieldName}\n` +
409
677
  `\n` +
410
678
  ` Use explicit invocation with the required payload:\n` +
411
- ` agentics agents invoke ${intent.domain} ${intent.agent} '{"execution_ref":"...","${fieldName}":"..."}'`);
679
+ ` agentics agents invoke ${singleIntent.domain} ${singleIntent.agent} '{"execution_ref":"...","${fieldName}":"..."}'`);
412
680
  }
413
681
  throw dispatchError;
414
682
  }
415
683
  return {
416
- intent,
417
- invocation,
418
- timing: Date.now() - start,
684
+ kind: 'single',
685
+ result: {
686
+ intent: singleIntent,
687
+ invocation,
688
+ timing: Date.now() - start,
689
+ },
419
690
  };
420
691
  }
421
692
  /**
@@ -507,4 +778,56 @@ export function formatNaturalLanguageRouteForDisplay(result) {
507
778
  lines.push(JSON.stringify(result.invocation.response, null, 2));
508
779
  return lines.join('\n');
509
780
  }
781
+ export function formatMultiAgentRouteForDisplay(result) {
782
+ const lines = [];
783
+ const agentCount = result.invocations.length;
784
+ const succeeded = result.invocations.filter(i => !('error' in i.result)).length;
785
+ const failed = agentCount - succeeded;
786
+ lines.push(`Multi-agent query: "${result.query}"`);
787
+ lines.push(`Agents invoked: ${agentCount} (${succeeded} succeeded${failed > 0 ? `, ${failed} failed` : ''})`);
788
+ lines.push(`Total Timing: ${result.timing}ms`);
789
+ lines.push('');
790
+ for (const inv of result.invocations) {
791
+ const label = `[${inv.intent.domain}/${inv.intent.agent}]`;
792
+ if ('error' in inv.result) {
793
+ lines.push(`${label} ERROR: ${inv.result.error}`);
794
+ }
795
+ else {
796
+ const agentResult = inv.result;
797
+ lines.push(`${label} Status: ${agentResult.status} (${agentResult.timing}ms)`);
798
+ lines.push(JSON.stringify(agentResult.response, null, 2));
799
+ }
800
+ lines.push('');
801
+ }
802
+ return lines.join('\n');
803
+ }
804
+ export function formatRouteResultForDisplay(routeResult) {
805
+ if (routeResult.kind === 'multi') {
806
+ return formatMultiAgentRouteForDisplay(routeResult.result);
807
+ }
808
+ return formatNaturalLanguageRouteForDisplay(routeResult.result);
809
+ }
810
+ export function routeResultToJson(routeResult, query) {
811
+ if (routeResult.kind === 'multi') {
812
+ return {
813
+ kind: 'multi',
814
+ query: routeResult.result.query,
815
+ agents: routeResult.result.invocations.map(i => ({
816
+ domain: i.intent.domain,
817
+ agent: i.intent.agent,
818
+ confidence: i.intent.confidence,
819
+ reasoning: i.intent.reasoning,
820
+ result: 'error' in i.result ? { error: i.result.error } : i.result,
821
+ })),
822
+ timing: routeResult.result.timing,
823
+ };
824
+ }
825
+ return {
826
+ kind: 'single',
827
+ query,
828
+ intent: routeResult.result.intent,
829
+ result: routeResult.result.invocation,
830
+ timing: routeResult.result.timing,
831
+ };
832
+ }
510
833
  //# sourceMappingURL=agents.js.map