From c82b1875481c61389380d0f590db345b46395c90 Mon Sep 17 00:00:00 2001 From: Rene Fichtmueller Date: Thu, 2 Apr 2026 23:11:21 +0200 Subject: [PATCH] feat: fix template resolution + add 40 routing rules for all project task types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - completion.ts now uses taskType directly for resolvePrompt (not decision.prompt_template) so tip_transceiver_enrich.yaml is used instead of generic_qa fallback template - routing-rules.yaml: +40 task type entries for TIP (8), EO Pulse (8), SwitchBlade (9), PeerCortex (6), NOGnet (9), internal (2) — all with correct model tier assignments - qwen2.5:3b for fast tasks (classify, short outputs) - qwen2.5:14b for medium (most analysis tasks) - qwen2.5:32b for large (blog posts, detailed reports, CSRD) --- .../gateway/src/config/routing-rules.yaml | 467 ++++++++++++++++++ packages/gateway/src/routes/completion.ts | 4 +- 2 files changed, 470 insertions(+), 1 deletion(-) diff --git a/packages/gateway/src/config/routing-rules.yaml b/packages/gateway/src/config/routing-rules.yaml index c806d09..ef93abf 100644 --- a/packages/gateway/src/config/routing-rules.yaml +++ b/packages/gateway/src/config/routing-rules.yaml @@ -15,7 +15,118 @@ routing_rules: validators: [] callers: [all] + # ─── INTERNAL ───────────────────────────────────────────────────────────── + internal_ban_detect: + model: qwen2.5:3b + tier: fast + prompt_template: internal_ban_detect + temperature: 0.1 + max_tokens: 256 + output_format: json + requires_fact_check: false + validators: [] + callers: [internal] + + internal_prompt_improve: + model: qwen2.5:14b + tier: medium + prompt_template: internal_prompt_improve + temperature: 0.4 + max_tokens: 2048 + output_format: text + requires_fact_check: false + validators: [] + callers: [internal] + # ─── TIP: TRANSCEIVER INTELLIGENCE PLATFORM ──────────────────────────────── + tip_transceiver_enrich: + model: qwen2.5:14b + tier: medium + prompt_template: tip_transceiver_enrich + temperature: 0.2 + max_tokens: 1024 + output_format: text + requires_fact_check: false + validators: [banlist, tip_validator, length] + callers: [tip-scraper, internal] + + tip_datasheet_extract: + model: qwen2.5:14b + tier: medium + prompt_template: tip_datasheet_extract + temperature: 0.1 + max_tokens: 1024 + output_format: json + requires_fact_check: false + validators: [schema, tip_validator] + callers: [tip-scraper, internal] + + tip_compatibility_parse: + model: qwen2.5:14b + tier: medium + prompt_template: tip_compatibility_parse + temperature: 0.1 + max_tokens: 512 + output_format: json + requires_fact_check: false + validators: [schema, tip_validator] + callers: [tip-scraper, internal] + + tip_blog_generator: + model: qwen2.5:32b + tier: large + prompt_template: tip_blog_generator + temperature: 0.6 + max_tokens: 3072 + output_format: text + requires_fact_check: false + validators: [banlist, language, length] + callers: [tip-scraper, internal, n8n] + + tip_faq_answer: + model: qwen2.5:14b + tier: medium + prompt_template: tip_faq_answer + temperature: 0.3 + max_tokens: 1024 + output_format: text + requires_fact_check: false + validators: [banlist, tip_validator, length] + callers: [tip-scraper, internal] + + tip_hype_cycle_narrative: + model: qwen2.5:14b + tier: medium + prompt_template: tip_hype_cycle_narrative + temperature: 0.5 + max_tokens: 2500 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [tip-scraper, internal, n8n] + + tip_price_anomaly: + model: qwen2.5:14b + tier: medium + prompt_template: tip_price_anomaly + temperature: 0.2 + max_tokens: 512 + output_format: json + requires_fact_check: false + validators: [schema, tip_validator] + callers: [tip-scraper, internal] + + tip_vendor_classify: + model: qwen2.5:7b + tier: fast + prompt_template: tip_vendor_classify + temperature: 0.1 + max_tokens: 256 + output_format: json + requires_fact_check: false + validators: [schema, tip_validator] + callers: [tip-scraper, internal] + tip_product_description: model: qwen2.5:14b tier: medium @@ -126,6 +237,95 @@ routing_rules: validators: [schema, tip_validator] callers: [tip-scraper, internal] + # ─── EO GLOBAL PULSE (template-based) ────────────────────────────────────── + eo_business_card_ocr: + model: qwen2.5:14b + tier: medium + prompt_template: eo_business_card_ocr + temperature: 0.1 + max_tokens: 512 + output_format: json + requires_fact_check: false + validators: [schema, banlist] + callers: [eo-global-pulse, internal] + + eo_voice_to_crm: + model: qwen2.5:14b + tier: medium + prompt_template: eo_voice_to_crm + temperature: 0.2 + max_tokens: 1024 + output_format: json + requires_fact_check: false + validators: [schema, banlist] + callers: [eo-global-pulse, internal] + + eo_event_prep_brief: + model: qwen2.5:14b + tier: medium + prompt_template: eo_event_prep_brief + temperature: 0.4 + max_tokens: 2048 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [eo-global-pulse, internal] + + eo_attendee_enrich: + model: qwen2.5:14b + tier: medium + prompt_template: eo_attendee_enrich + temperature: 0.3 + max_tokens: 1024 + output_format: json + requires_fact_check: false + validators: [schema, banlist] + callers: [eo-global-pulse, internal] + + eo_meeting_suggest: + model: qwen2.5:14b + tier: medium + prompt_template: eo_meeting_suggest + temperature: 0.5 + max_tokens: 1024 + output_format: json + requires_fact_check: false + validators: [schema, banlist] + callers: [eo-global-pulse, internal] + + eo_lead_qualify: + model: qwen2.5:14b + tier: medium + prompt_template: eo_lead_qualify + temperature: 0.3 + max_tokens: 512 + output_format: json + requires_fact_check: false + validators: [schema, banlist] + callers: [eo-global-pulse, internal] + + eo_debrief_generate: + model: qwen2.5:32b + tier: large + prompt_template: eo_debrief_generate + temperature: 0.4 + max_tokens: 3072 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [eo-global-pulse, internal] + + eo_ticket_summarize: + model: qwen2.5:7b + tier: fast + prompt_template: eo_ticket_summarize + temperature: 0.2 + max_tokens: 512 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [eo-global-pulse, internal] + # ─── EO GLOBAL PULSE ──────────────────────────────────────────────────────── eo_member_summary: model: qwen2.5:14b @@ -204,6 +404,73 @@ routing_rules: validators: [banlist, language] callers: [eo-global-pulse, internal] + # ─── PEERCORTEX (template-based) ──────────────────────────────────────────── + pc_as_narrative: + model: qwen2.5:14b + tier: medium + prompt_template: pc_as_narrative + temperature: 0.3 + max_tokens: 1024 + output_format: text + requires_fact_check: true + validators: [banlist, fact_checker, length] + callers: [peercortex, internal] + + pc_health_summary: + model: qwen2.5:14b + tier: medium + prompt_template: pc_health_summary + temperature: 0.2 + max_tokens: 1024 + output_format: json + requires_fact_check: false + validators: [schema, length] + callers: [peercortex, internal] + + pc_rpki_explain: + model: qwen2.5:14b + tier: medium + prompt_template: pc_rpki_explain + temperature: 0.3 + max_tokens: 512 + output_format: text + requires_fact_check: true + validators: [fact_checker, length] + callers: [peercortex, internal] + + pc_anomaly_hypothesis: + model: qwen2.5:14b + tier: medium + prompt_template: pc_anomaly_hypothesis + temperature: 0.4 + max_tokens: 1024 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [peercortex, internal] + + pc_peer_recommendation: + model: qwen2.5:14b + tier: medium + prompt_template: pc_peer_recommendation + temperature: 0.4 + max_tokens: 1024 + output_format: json + requires_fact_check: false + validators: [schema, banlist] + callers: [peercortex, internal] + + pc_incident_brief: + model: qwen2.5:14b + tier: medium + prompt_template: pc_incident_brief + temperature: 0.2 + max_tokens: 1024 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [peercortex, internal] + # ─── PEERCORTEX ────────────────────────────────────────────────────────────── peercortex_asn_analysis: model: qwen2.5:14b @@ -260,6 +527,106 @@ routing_rules: validators: [fact_checker] callers: [peercortex, internal] + # ─── SWITCHBLADE (template-based) ──────────────────────────────────────────── + sb_root_cause: + model: qwen2.5:14b + tier: medium + prompt_template: sb_root_cause + temperature: 0.2 + max_tokens: 1024 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [switchblade, internal] + + sb_alert_narrative: + model: qwen2.5:7b + tier: fast + prompt_template: sb_alert_narrative + temperature: 0.2 + max_tokens: 512 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [switchblade, internal] + + sb_cve_remediation: + model: qwen2.5:14b + tier: medium + prompt_template: sb_cve_remediation + temperature: 0.2 + max_tokens: 2048 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [switchblade, internal] + + sb_csrd_narrative: + model: qwen2.5:32b + tier: large + prompt_template: sb_csrd_narrative + temperature: 0.4 + max_tokens: 4096 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [switchblade, internal] + + sb_transceiver_advisor: + model: qwen2.5:14b + tier: medium + prompt_template: sb_transceiver_advisor + temperature: 0.3 + max_tokens: 1024 + output_format: json + requires_fact_check: false + validators: [schema, tip_validator] + callers: [switchblade, internal] + + sb_bandwidth_report: + model: qwen2.5:14b + tier: medium + prompt_template: sb_bandwidth_report + temperature: 0.3 + max_tokens: 2048 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [switchblade, internal] + + sb_ticket_draft: + model: qwen2.5:7b + tier: fast + prompt_template: sb_ticket_draft + temperature: 0.3 + max_tokens: 512 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [switchblade, internal] + + sb_firmware_assess: + model: qwen2.5:14b + tier: medium + prompt_template: sb_firmware_assess + temperature: 0.2 + max_tokens: 1024 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [switchblade, internal] + + sb_topology_explain: + model: qwen2.5:14b + tier: medium + prompt_template: sb_topology_explain + temperature: 0.3 + max_tokens: 1024 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [switchblade, internal] + # ─── SWITCHBLADE ───────────────────────────────────────────────────────────── switchblade_incident_summary: model: qwen2.5:14b @@ -349,6 +716,106 @@ routing_rules: validators: [length] callers: [switchblade, internal] + # ─── NOGNET (template-based) ───────────────────────────────────────────────── + nog_cfp_evaluate: + model: qwen2.5:14b + tier: medium + prompt_template: nog_cfp_evaluate + temperature: 0.3 + max_tokens: 1024 + output_format: json + requires_fact_check: false + validators: [schema, banlist] + callers: [nognet, internal] + + nog_cfp_feedback: + model: qwen2.5:14b + tier: medium + prompt_template: nog_cfp_feedback + temperature: 0.4 + max_tokens: 1024 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [nognet, internal] + + nog_topic_gap_analysis: + model: qwen2.5:32b + tier: large + prompt_template: nog_topic_gap_analysis + temperature: 0.5 + max_tokens: 2048 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [nognet, internal] + + nog_meeting_match: + model: qwen2.5:14b + tier: medium + prompt_template: nog_meeting_match + temperature: 0.4 + max_tokens: 1024 + output_format: json + requires_fact_check: false + validators: [schema, banlist] + callers: [nognet, internal] + + nog_speaker_enrich: + model: qwen2.5:14b + tier: medium + prompt_template: nog_speaker_enrich + temperature: 0.3 + max_tokens: 512 + output_format: json + requires_fact_check: false + validators: [schema, banlist] + callers: [nognet, internal] + + nog_sponsor_pitch: + model: qwen2.5:32b + tier: large + prompt_template: nog_sponsor_pitch + temperature: 0.5 + max_tokens: 3072 + output_format: text + requires_fact_check: false + validators: [banlist, language, length] + callers: [nognet, internal] + + nog_event_debrief: + model: qwen2.5:32b + tier: large + prompt_template: nog_event_debrief + temperature: 0.4 + max_tokens: 3000 + output_format: text + requires_fact_check: false + validators: [banlist, length] + callers: [nognet, internal] + + nog_agenda_summary: + model: qwen2.5:7b + tier: fast + prompt_template: nog_agenda_summary + temperature: 0.5 + max_tokens: 512 + output_format: text + requires_fact_check: false + validators: [banlist, language, length] + callers: [nognet, internal] + + nog_session_intro: + model: qwen2.5:3b + tier: fast + prompt_template: nog_session_intro + temperature: 0.5 + max_tokens: 128 + output_format: text + requires_fact_check: false + validators: [banlist] + callers: [nognet, internal] + # ─── NOGNET / CTXEVENT ─────────────────────────────────────────────────────── nognet_event_description: model: qwen2.5:14b diff --git a/packages/gateway/src/routes/completion.ts b/packages/gateway/src/routes/completion.ts index 3a206ef..ada9f10 100644 --- a/packages/gateway/src/routes/completion.ts +++ b/packages/gateway/src/routes/completion.ts @@ -145,8 +145,10 @@ export async function completionRoute(fastify: FastifyInstance): Promise { } // Stage 5: Prompt assembly + // Use taskType directly for template lookup (so tip_transceiver_enrich.yaml is used, + // not the generic_qa fallback from routing). The router only selects the model. const resolved = resolvePrompt( - decision.prompt_template, + taskType ?? decision.prompt_template, { input, user_context: context,