ai-consultants 2.10.1

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.
Files changed (62) hide show
  1. package/.claude/commands/ai-consultants:consult.md +94 -0
  2. package/.claude/commands/ai-consultants:debate.md +103 -0
  3. package/.claude/commands/ai-consultants:help.md +30 -0
  4. package/CLAUDE.md +839 -0
  5. package/LICENSE +21 -0
  6. package/README.md +758 -0
  7. package/SKILL.md +156 -0
  8. package/bin/ai-consultants +96 -0
  9. package/docs/COST_RATES.md +172 -0
  10. package/docs/JSON_SCHEMA.md +305 -0
  11. package/docs/SETUP.md +879 -0
  12. package/docs/SMART_ROUTING.md +219 -0
  13. package/docs/cost_rates.json +143 -0
  14. package/package.json +47 -0
  15. package/references/configuration.md +141 -0
  16. package/references/details.md +60 -0
  17. package/scripts/build_context.sh +562 -0
  18. package/scripts/classify_question.sh +148 -0
  19. package/scripts/config.sh +753 -0
  20. package/scripts/configure.sh +1093 -0
  21. package/scripts/consult_all.sh +934 -0
  22. package/scripts/debate_round.sh +421 -0
  23. package/scripts/doctor.sh +642 -0
  24. package/scripts/followup.sh +197 -0
  25. package/scripts/install.sh +319 -0
  26. package/scripts/lib/api.sh +640 -0
  27. package/scripts/lib/api_query.sh +228 -0
  28. package/scripts/lib/cache.sh +338 -0
  29. package/scripts/lib/chunking.sh +880 -0
  30. package/scripts/lib/code_optimizer.sh +671 -0
  31. package/scripts/lib/common.sh +1088 -0
  32. package/scripts/lib/costs.sh +674 -0
  33. package/scripts/lib/personas.sh +372 -0
  34. package/scripts/lib/progress.sh +251 -0
  35. package/scripts/lib/reflection.sh +447 -0
  36. package/scripts/lib/routing.sh +566 -0
  37. package/scripts/lib/schema.json +165 -0
  38. package/scripts/lib/session.sh +327 -0
  39. package/scripts/lib/symbol_map.sh +445 -0
  40. package/scripts/lib/voting.sh +495 -0
  41. package/scripts/peer_review.sh +460 -0
  42. package/scripts/preflight_check.sh +452 -0
  43. package/scripts/query_aider.sh +83 -0
  44. package/scripts/query_amp.sh +67 -0
  45. package/scripts/query_claude.sh +99 -0
  46. package/scripts/query_codex.sh +92 -0
  47. package/scripts/query_cursor.sh +72 -0
  48. package/scripts/query_deepseek.sh +17 -0
  49. package/scripts/query_gemini.sh +85 -0
  50. package/scripts/query_glm.sh +17 -0
  51. package/scripts/query_grok.sh +17 -0
  52. package/scripts/query_kilo.sh +140 -0
  53. package/scripts/query_kimi.sh +67 -0
  54. package/scripts/query_minimax.sh +17 -0
  55. package/scripts/query_mistral.sh +97 -0
  56. package/scripts/query_ollama.sh +328 -0
  57. package/scripts/query_qwen3.sh +93 -0
  58. package/scripts/setup_wizard.sh +367 -0
  59. package/scripts/skillport-install.sh +196 -0
  60. package/scripts/synthesize.sh +332 -0
  61. package/templates/consultation_report.md +323 -0
  62. package/templates/synthesis_prompt.md +120 -0
@@ -0,0 +1,566 @@
1
+ #!/bin/bash
2
+ # routing.sh - Smart consultant selection based on question type
3
+ #
4
+ # Selects the most suitable consultants based on the question category.
5
+
6
+ # =============================================================================
7
+ # AFFINITY MATRIX
8
+ # =============================================================================
9
+ # Using case statements for bash 3.2 compatibility (no associative arrays)
10
+ # Affinity scores: 10 = perfect match, 1 = poor match
11
+
12
+ # =============================================================================
13
+ # SELECTION FUNCTIONS
14
+ # =============================================================================
15
+
16
+ # Get affinity for a category-consultant combination
17
+ # Usage: get_affinity <category> <consultant>
18
+ get_affinity() {
19
+ local category="$1"
20
+ local consultant="$2"
21
+
22
+ case "$category" in
23
+ CODE_REVIEW)
24
+ case "$consultant" in
25
+ Gemini) echo 7 ;;
26
+ Codex) echo 10 ;;
27
+ Mistral) echo 8 ;;
28
+ Kilo) echo 9 ;;
29
+ Cursor) echo 9 ;;
30
+ Aider) echo 9 ;;
31
+ Amp) echo 7 ;;
32
+ Kimi) echo 7 ;;
33
+ Claude) echo 8 ;;
34
+ Qwen3) echo 8 ;;
35
+ GLM) echo 8 ;;
36
+ Grok) echo 7 ;;
37
+ DeepSeek) echo 10 ;;
38
+ MiniMax) echo 8 ;;
39
+ *) echo 5 ;;
40
+ esac
41
+ ;;
42
+ BUG_DEBUG)
43
+ case "$consultant" in
44
+ Gemini) echo 7 ;;
45
+ Codex) echo 10 ;;
46
+ Mistral) echo 9 ;;
47
+ Kilo) echo 8 ;;
48
+ Cursor) echo 9 ;;
49
+ Aider) echo 9 ;;
50
+ Amp) echo 8 ;;
51
+ Kimi) echo 6 ;;
52
+ Claude) echo 7 ;;
53
+ Qwen3) echo 8 ;;
54
+ GLM) echo 8 ;;
55
+ Grok) echo 7 ;;
56
+ DeepSeek) echo 9 ;;
57
+ MiniMax) echo 8 ;;
58
+ *) echo 5 ;;
59
+ esac
60
+ ;;
61
+ ARCHITECTURE)
62
+ case "$consultant" in
63
+ Gemini) echo 10 ;;
64
+ Codex) echo 6 ;;
65
+ Mistral) echo 8 ;;
66
+ Kilo) echo 9 ;;
67
+ Cursor) echo 8 ;;
68
+ Aider) echo 6 ;;
69
+ Amp) echo 10 ;;
70
+ Kimi) echo 9 ;;
71
+ Claude) echo 9 ;;
72
+ Qwen3) echo 7 ;;
73
+ GLM) echo 7 ;;
74
+ Grok) echo 9 ;;
75
+ DeepSeek) echo 7 ;;
76
+ MiniMax) echo 7 ;;
77
+ *) echo 5 ;;
78
+ esac
79
+ ;;
80
+ ALGORITHM)
81
+ case "$consultant" in
82
+ Gemini) echo 9 ;;
83
+ Codex) echo 8 ;;
84
+ Mistral) echo 7 ;;
85
+ Kilo) echo 8 ;;
86
+ Cursor) echo 7 ;;
87
+ Aider) echo 7 ;;
88
+ Amp) echo 7 ;;
89
+ Kimi) echo 8 ;;
90
+ Claude) echo 7 ;;
91
+ Qwen3) echo 9 ;;
92
+ GLM) echo 7 ;;
93
+ Grok) echo 8 ;;
94
+ DeepSeek) echo 10 ;;
95
+ MiniMax) echo 8 ;;
96
+ *) echo 5 ;;
97
+ esac
98
+ ;;
99
+ SECURITY)
100
+ case "$consultant" in
101
+ Gemini) echo 9 ;;
102
+ Codex) echo 9 ;;
103
+ Mistral) echo 10 ;;
104
+ Kilo) echo 8 ;;
105
+ Cursor) echo 8 ;;
106
+ Aider) echo 7 ;;
107
+ Amp) echo 8 ;;
108
+ Kimi) echo 7 ;;
109
+ Claude) echo 8 ;;
110
+ Qwen3) echo 7 ;;
111
+ GLM) echo 8 ;;
112
+ Grok) echo 8 ;;
113
+ DeepSeek) echo 8 ;;
114
+ MiniMax) echo 7 ;;
115
+ *) echo 5 ;;
116
+ esac
117
+ ;;
118
+ QUICK_SYNTAX)
119
+ case "$consultant" in
120
+ Gemini) echo 10 ;;
121
+ Codex) echo 8 ;;
122
+ Mistral) echo 5 ;;
123
+ Kilo) echo 6 ;;
124
+ Cursor) echo 7 ;;
125
+ Aider) echo 8 ;;
126
+ Amp) echo 5 ;;
127
+ Kimi) echo 5 ;;
128
+ Claude) echo 6 ;;
129
+ Qwen3) echo 7 ;;
130
+ GLM) echo 6 ;;
131
+ Grok) echo 5 ;;
132
+ DeepSeek) echo 9 ;;
133
+ MiniMax) echo 8 ;;
134
+ *) echo 5 ;;
135
+ esac
136
+ ;;
137
+ DATABASE)
138
+ case "$consultant" in
139
+ Gemini) echo 8 ;;
140
+ Codex) echo 9 ;;
141
+ Mistral) echo 7 ;;
142
+ Kilo) echo 7 ;;
143
+ Cursor) echo 8 ;;
144
+ Aider) echo 7 ;;
145
+ Amp) echo 7 ;;
146
+ Kimi) echo 7 ;;
147
+ Claude) echo 7 ;;
148
+ Qwen3) echo 9 ;;
149
+ GLM) echo 7 ;;
150
+ Grok) echo 6 ;;
151
+ DeepSeek) echo 9 ;;
152
+ MiniMax) echo 8 ;;
153
+ *) echo 5 ;;
154
+ esac
155
+ ;;
156
+ API_DESIGN)
157
+ case "$consultant" in
158
+ Gemini) echo 10 ;;
159
+ Codex) echo 9 ;;
160
+ Mistral) echo 7 ;;
161
+ Kilo) echo 8 ;;
162
+ Cursor) echo 9 ;;
163
+ Aider) echo 7 ;;
164
+ Amp) echo 9 ;;
165
+ Kimi) echo 8 ;;
166
+ Claude) echo 8 ;;
167
+ Qwen3) echo 7 ;;
168
+ GLM) echo 8 ;;
169
+ Grok) echo 8 ;;
170
+ DeepSeek) echo 8 ;;
171
+ MiniMax) echo 8 ;;
172
+ *) echo 5 ;;
173
+ esac
174
+ ;;
175
+ TESTING)
176
+ case "$consultant" in
177
+ Gemini) echo 7 ;;
178
+ Codex) echo 10 ;;
179
+ Mistral) echo 9 ;;
180
+ Kilo) echo 7 ;;
181
+ Cursor) echo 9 ;;
182
+ Aider) echo 9 ;;
183
+ Amp) echo 8 ;;
184
+ Kimi) echo 6 ;;
185
+ Claude) echo 7 ;;
186
+ Qwen3) echo 8 ;;
187
+ GLM) echo 10 ;;
188
+ Grok) echo 7 ;;
189
+ DeepSeek) echo 8 ;;
190
+ MiniMax) echo 7 ;;
191
+ *) echo 5 ;;
192
+ esac
193
+ ;;
194
+ *)
195
+ # GENERAL and unknown categories: all known consultants get score 8
196
+ case "$consultant" in
197
+ Gemini|Codex|Mistral|Kilo|Cursor|Aider|Amp|Kimi|Claude|Qwen3|GLM|Grok|DeepSeek|MiniMax) echo 8 ;;
198
+ *) echo 5 ;;
199
+ esac
200
+ ;;
201
+ esac
202
+ }
203
+
204
+ # Select the best consultants for a category
205
+ # Usage: select_consultants <category> [min_affinity] [max_consultants]
206
+ # Returns: list of consultants sorted by affinity
207
+ select_consultants() {
208
+ local category="$1"
209
+ local min_affinity="${2:-7}"
210
+ local max_consultants="${3:-8}"
211
+
212
+ # Include all consultants (order matches ALL_CONSULTANTS in config.sh)
213
+ local consultants=("Gemini" "Codex" "Mistral" "Kilo" "Cursor" "Aider" "Amp" "Kimi" "Claude" "Qwen3" "GLM" "Grok" "DeepSeek" "MiniMax")
214
+ local selected=()
215
+ local scores=()
216
+
217
+ # Collect affinities
218
+ for c in "${consultants[@]}"; do
219
+ local score=$(get_affinity "$category" "$c")
220
+ if [[ $score -ge $min_affinity ]]; then
221
+ selected+=("$c")
222
+ scores+=("$score")
223
+ fi
224
+ done
225
+
226
+ # Sort by score (simple bubble sort)
227
+ local n=${#selected[@]}
228
+ for ((i=0; i<n-1; i++)); do
229
+ for ((j=0; j<n-i-1; j++)); do
230
+ if [[ ${scores[$j]} -lt ${scores[$((j+1))]} ]]; then
231
+ # Swap
232
+ local tmp="${selected[$j]}"
233
+ selected[$j]="${selected[$((j+1))]}"
234
+ selected[$((j+1))]="$tmp"
235
+
236
+ tmp="${scores[$j]}"
237
+ scores[$j]="${scores[$((j+1))]}"
238
+ scores[$((j+1))]="$tmp"
239
+ fi
240
+ done
241
+ done
242
+
243
+ # Limit to maximum requested
244
+ local count=0
245
+ for c in ${selected[@]+"${selected[@]}"}; do
246
+ if [[ $count -ge $max_consultants ]]; then
247
+ break
248
+ fi
249
+ echo "$c"
250
+ count=$((count + 1))
251
+ done
252
+ }
253
+
254
+ # Get the list of consultants as JSON
255
+ # Usage: get_selected_consultants_json <category> [min_affinity]
256
+ get_selected_consultants_json() {
257
+ local category="$1"
258
+ local min_affinity="${2:-7}"
259
+
260
+ local consultants=$(select_consultants "$category" "$min_affinity")
261
+ local json="["
262
+ local first=true
263
+
264
+ while IFS= read -r c; do
265
+ if [[ -n "$c" ]]; then
266
+ local score=$(get_affinity "$category" "$c")
267
+ if [[ "$first" == "true" ]]; then
268
+ first=false
269
+ else
270
+ json+=","
271
+ fi
272
+ json+="{\"consultant\":\"$c\",\"affinity\":$score}"
273
+ fi
274
+ done <<< "$consultants"
275
+
276
+ json+="]"
277
+ echo "$json"
278
+ }
279
+
280
+ # Check if a consultant is recommended for a category
281
+ # Usage: is_recommended <category> <consultant> [min_affinity]
282
+ is_recommended() {
283
+ local category="$1"
284
+ local consultant="$2"
285
+ local min_affinity="${3:-7}"
286
+
287
+ local score=$(get_affinity "$category" "$consultant")
288
+ if [[ $score -ge $min_affinity ]]; then
289
+ return 0
290
+ fi
291
+ return 1
292
+ }
293
+
294
+ # =============================================================================
295
+ # SMART ROUTING MODES
296
+ # =============================================================================
297
+
298
+ # Determine the routing mode based on the category
299
+ # Usage: get_routing_mode <category>
300
+ # Returns: full|selective|single
301
+ get_routing_mode() {
302
+ local category="$1"
303
+
304
+ case "$category" in
305
+ SECURITY)
306
+ # Security: all consultants (important)
307
+ echo "full"
308
+ ;;
309
+ QUICK_SYNTAX)
310
+ # Syntax: just one needed
311
+ echo "single"
312
+ ;;
313
+ CODE_REVIEW|BUG_DEBUG|ARCHITECTURE)
314
+ # Important: at least 3
315
+ echo "selective"
316
+ ;;
317
+ *)
318
+ # Default: all
319
+ echo "full"
320
+ ;;
321
+ esac
322
+ }
323
+
324
+ # Get the recommended number of consultants
325
+ # Usage: get_recommended_count <category>
326
+ get_recommended_count() {
327
+ local category="$1"
328
+ local mode=$(get_routing_mode "$category")
329
+
330
+ case "$mode" in
331
+ full)
332
+ echo 10 # All consultants (CLI + API)
333
+ ;;
334
+ selective)
335
+ echo 5 # Subset based on affinity
336
+ ;;
337
+ single)
338
+ echo 1
339
+ ;;
340
+ *)
341
+ echo 10
342
+ ;;
343
+ esac
344
+ }
345
+
346
+ # =============================================================================
347
+ # TIMEOUT ADJUSTMENTS
348
+ # =============================================================================
349
+
350
+ # Get recommended timeout for a category
351
+ # Usage: get_category_timeout <category>
352
+ get_category_timeout() {
353
+ local category="$1"
354
+ case "$category" in
355
+ QUICK_SYNTAX) echo 60 ;;
356
+ BUG_DEBUG) echo 180 ;;
357
+ ARCHITECTURE) echo 240 ;;
358
+ SECURITY) echo 240 ;;
359
+ CODE_REVIEW) echo 180 ;;
360
+ ALGORITHM) echo 180 ;;
361
+ DATABASE) echo 120 ;;
362
+ API_DESIGN) echo 180 ;;
363
+ TESTING) echo 120 ;;
364
+ GENERAL|*) echo 180 ;;
365
+ esac
366
+ }
367
+
368
+ # =============================================================================
369
+ # COST-AWARE ROUTING (v2.3)
370
+ # =============================================================================
371
+
372
+ # Ensure costs.sh is sourced (lazy loading helper)
373
+ _ensure_costs_sourced() {
374
+ if ! type get_economic_model &>/dev/null; then
375
+ local script_dir
376
+ script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
377
+ source "$script_dir/costs.sh" 2>/dev/null || true
378
+ fi
379
+ }
380
+
381
+ # Select consultants based on cost efficiency
382
+ # Usage: select_consultants_cost_aware <category> <complexity> [min_affinity]
383
+ # Returns: list of consultants optimized for cost/quality balance
384
+ select_consultants_cost_aware() {
385
+ local category="$1"
386
+ local complexity="${2:-5}"
387
+ local min_affinity="${3:-7}"
388
+
389
+ # Check if cost-aware routing is enabled
390
+ if [[ "${ENABLE_COST_AWARE_ROUTING:-false}" != "true" ]]; then
391
+ # Fall back to standard selection
392
+ select_consultants "$category" "$min_affinity"
393
+ return
394
+ fi
395
+
396
+ _ensure_costs_sourced
397
+
398
+ local simple_threshold="${COMPLEXITY_THRESHOLD_SIMPLE:-3}"
399
+ local medium_threshold="${COMPLEXITY_THRESHOLD_MEDIUM:-6}"
400
+
401
+ # Simple queries: only economic models, fewer consultants
402
+ if [[ $complexity -le $simple_threshold ]]; then
403
+ # For simple queries, use only 2 consultants with economic models
404
+ select_consultants "$category" "$min_affinity" 2
405
+ return
406
+ fi
407
+
408
+ # Medium complexity: balanced selection
409
+ if [[ $complexity -le $medium_threshold ]]; then
410
+ # Use standard selection but limit to 3-4 consultants
411
+ select_consultants "$category" "$min_affinity" 4
412
+ return
413
+ fi
414
+
415
+ # Complex queries: full selection
416
+ select_consultants "$category" "$min_affinity"
417
+ }
418
+
419
+ # Get model override for cost-aware routing
420
+ # Usage: get_cost_aware_model <consultant> <complexity>
421
+ # Returns: model name to use, or empty for default
422
+ get_cost_aware_model() {
423
+ local consultant="$1"
424
+ local complexity="${2:-5}"
425
+
426
+ # Check if cost-aware routing is enabled
427
+ if [[ "${ENABLE_COST_AWARE_ROUTING:-false}" != "true" ]]; then
428
+ echo ""
429
+ return
430
+ fi
431
+
432
+ # Check if we should use economic models for simple queries
433
+ if [[ "${USE_ECONOMIC_MODELS_FOR_SIMPLE:-true}" != "true" ]]; then
434
+ echo ""
435
+ return
436
+ fi
437
+
438
+ local simple_threshold="${COMPLEXITY_THRESHOLD_SIMPLE:-3}"
439
+
440
+ # Simple queries: use economic model
441
+ if [[ $complexity -le $simple_threshold ]]; then
442
+ _ensure_costs_sourced
443
+ local economic_model
444
+ economic_model=$(get_economic_model "$consultant" 2>/dev/null || echo "")
445
+ echo "$economic_model"
446
+ return
447
+ fi
448
+
449
+ # Complex queries: use default model
450
+ echo ""
451
+ }
452
+
453
+ # Check if cost-aware routing is enabled
454
+ # Usage: is_cost_aware_routing_enabled
455
+ is_cost_aware_routing_enabled() {
456
+ [[ "${ENABLE_COST_AWARE_ROUTING:-false}" == "true" ]]
457
+ }
458
+
459
+ # Get routing summary for logging
460
+ # Usage: get_routing_summary <category> <complexity> <num_consultants>
461
+ get_routing_summary() {
462
+ local category="$1"
463
+ local complexity="${2:-5}"
464
+ local num_consultants="${3:-5}"
465
+
466
+ local mode="standard"
467
+ if is_cost_aware_routing_enabled; then
468
+ local simple_threshold="${COMPLEXITY_THRESHOLD_SIMPLE:-3}"
469
+ local medium_threshold="${COMPLEXITY_THRESHOLD_MEDIUM:-6}"
470
+
471
+ if [[ $complexity -le $simple_threshold ]]; then
472
+ mode="economic"
473
+ elif [[ $complexity -le $medium_threshold ]]; then
474
+ mode="balanced"
475
+ else
476
+ mode="comprehensive"
477
+ fi
478
+ fi
479
+
480
+ echo "{\"category\":\"$category\",\"complexity\":$complexity,\"mode\":\"$mode\",\"consultants\":$num_consultants}"
481
+ }
482
+
483
+ # =============================================================================
484
+ # FALLBACK ESCALATION (v2.3 Quality Review)
485
+ # =============================================================================
486
+
487
+ # Fallback escalation threshold - escalate to premium if confidence below this
488
+ FALLBACK_CONFIDENCE_THRESHOLD="${FALLBACK_CONFIDENCE_THRESHOLD:-7}"
489
+
490
+ # Check if response needs escalation based on confidence
491
+ # Usage: needs_escalation <response_file>
492
+ # Returns: 0 if escalation needed, 1 otherwise
493
+ needs_escalation() {
494
+ local response_file="$1"
495
+
496
+ if [[ ! -f "$response_file" || ! -s "$response_file" ]]; then
497
+ return 0 # No response = needs escalation
498
+ fi
499
+
500
+ local confidence
501
+ confidence=$(jq -r '.confidence.score // 5' "$response_file" 2>/dev/null)
502
+
503
+ if [[ ! "$confidence" =~ ^[0-9]+$ ]]; then
504
+ confidence=5
505
+ fi
506
+
507
+ local threshold="${FALLBACK_CONFIDENCE_THRESHOLD:-7}"
508
+
509
+ if [[ $confidence -lt $threshold ]]; then
510
+ return 0 # Needs escalation
511
+ fi
512
+
513
+ return 1 # No escalation needed
514
+ }
515
+
516
+ # Get premium model for escalation
517
+ # Delegates to get_model_for_tier() in config.sh (single source of truth)
518
+ # Usage: get_premium_model <consultant>
519
+ get_premium_model() {
520
+ local consultant="$1"
521
+ if type get_model_for_tier &>/dev/null; then
522
+ get_model_for_tier "$consultant" "premium"
523
+ else
524
+ echo ""
525
+ fi
526
+ }
527
+
528
+ # Check if escalation is enabled
529
+ # Usage: is_escalation_enabled
530
+ is_escalation_enabled() {
531
+ # Escalation is enabled when cost-aware routing is on
532
+ [[ "${ENABLE_COST_AWARE_ROUTING:-false}" == "true" ]]
533
+ }
534
+
535
+ # Get escalation summary for a response
536
+ # Usage: get_escalation_summary <response_file> <consultant>
537
+ get_escalation_summary() {
538
+ local response_file="$1"
539
+ local consultant="$2"
540
+
541
+ local needs_it="false"
542
+ local confidence=0
543
+ local threshold="${FALLBACK_CONFIDENCE_THRESHOLD:-7}"
544
+
545
+ if [[ -f "$response_file" && -s "$response_file" ]]; then
546
+ confidence=$(jq -r '.confidence.score // 5' "$response_file" 2>/dev/null)
547
+ [[ ! "$confidence" =~ ^[0-9]+$ ]] && confidence=5
548
+ fi
549
+
550
+ if [[ $confidence -lt $threshold ]]; then
551
+ needs_it="true"
552
+ fi
553
+
554
+ local premium_model
555
+ premium_model=$(get_premium_model "$consultant")
556
+
557
+ cat << EOF
558
+ {
559
+ "consultant": "$consultant",
560
+ "confidence": $confidence,
561
+ "threshold": $threshold,
562
+ "needs_escalation": $needs_it,
563
+ "premium_model": "$premium_model"
564
+ }
565
+ EOF
566
+ }