feat: fix template resolution + add 40 routing rules for all project task types

- 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)
This commit is contained in:
Rene Fichtmueller 2026-04-02 23:11:21 +02:00
parent 2c5f7f6ebe
commit c82b187548
2 changed files with 470 additions and 1 deletions

View File

@ -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

View File

@ -145,8 +145,10 @@ export async function completionRoute(fastify: FastifyInstance): Promise<void> {
}
// 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,