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.
- package/.claude/commands/ai-consultants:consult.md +94 -0
- package/.claude/commands/ai-consultants:debate.md +103 -0
- package/.claude/commands/ai-consultants:help.md +30 -0
- package/CLAUDE.md +839 -0
- package/LICENSE +21 -0
- package/README.md +758 -0
- package/SKILL.md +156 -0
- package/bin/ai-consultants +96 -0
- package/docs/COST_RATES.md +172 -0
- package/docs/JSON_SCHEMA.md +305 -0
- package/docs/SETUP.md +879 -0
- package/docs/SMART_ROUTING.md +219 -0
- package/docs/cost_rates.json +143 -0
- package/package.json +47 -0
- package/references/configuration.md +141 -0
- package/references/details.md +60 -0
- package/scripts/build_context.sh +562 -0
- package/scripts/classify_question.sh +148 -0
- package/scripts/config.sh +753 -0
- package/scripts/configure.sh +1093 -0
- package/scripts/consult_all.sh +934 -0
- package/scripts/debate_round.sh +421 -0
- package/scripts/doctor.sh +642 -0
- package/scripts/followup.sh +197 -0
- package/scripts/install.sh +319 -0
- package/scripts/lib/api.sh +640 -0
- package/scripts/lib/api_query.sh +228 -0
- package/scripts/lib/cache.sh +338 -0
- package/scripts/lib/chunking.sh +880 -0
- package/scripts/lib/code_optimizer.sh +671 -0
- package/scripts/lib/common.sh +1088 -0
- package/scripts/lib/costs.sh +674 -0
- package/scripts/lib/personas.sh +372 -0
- package/scripts/lib/progress.sh +251 -0
- package/scripts/lib/reflection.sh +447 -0
- package/scripts/lib/routing.sh +566 -0
- package/scripts/lib/schema.json +165 -0
- package/scripts/lib/session.sh +327 -0
- package/scripts/lib/symbol_map.sh +445 -0
- package/scripts/lib/voting.sh +495 -0
- package/scripts/peer_review.sh +460 -0
- package/scripts/preflight_check.sh +452 -0
- package/scripts/query_aider.sh +83 -0
- package/scripts/query_amp.sh +67 -0
- package/scripts/query_claude.sh +99 -0
- package/scripts/query_codex.sh +92 -0
- package/scripts/query_cursor.sh +72 -0
- package/scripts/query_deepseek.sh +17 -0
- package/scripts/query_gemini.sh +85 -0
- package/scripts/query_glm.sh +17 -0
- package/scripts/query_grok.sh +17 -0
- package/scripts/query_kilo.sh +140 -0
- package/scripts/query_kimi.sh +67 -0
- package/scripts/query_minimax.sh +17 -0
- package/scripts/query_mistral.sh +97 -0
- package/scripts/query_ollama.sh +328 -0
- package/scripts/query_qwen3.sh +93 -0
- package/scripts/setup_wizard.sh +367 -0
- package/scripts/skillport-install.sh +196 -0
- package/scripts/synthesize.sh +332 -0
- package/templates/consultation_report.md +323 -0
- package/templates/synthesis_prompt.md +120 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# reflection.sh - Self-reflection (Reflexion pattern) for AI Consultants
|
|
3
|
+
#
|
|
4
|
+
# Implements the generate-critique-refine pattern to improve
|
|
5
|
+
# response quality through self-criticism.
|
|
6
|
+
|
|
7
|
+
# =============================================================================
|
|
8
|
+
# REFLECTION PROMPTS
|
|
9
|
+
# =============================================================================
|
|
10
|
+
|
|
11
|
+
# Prompt for self-critique
|
|
12
|
+
CRITIQUE_PROMPT_TEMPLATE='You provided this response to a programming question:
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
%RESPONSE%
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
Now critique your response. Consider:
|
|
19
|
+
1. **Correctness**: Are there logical or technical errors?
|
|
20
|
+
2. **Completeness**: Is anything important missing?
|
|
21
|
+
3. **Clarity**: Is it well explained?
|
|
22
|
+
4. **Edge cases**: Have you considered all edge cases?
|
|
23
|
+
5. **Alternatives**: Are there better approaches not mentioned?
|
|
24
|
+
6. **Risks**: Are there hidden potential problems?
|
|
25
|
+
|
|
26
|
+
Respond in JSON:
|
|
27
|
+
{
|
|
28
|
+
"critique": {
|
|
29
|
+
"strengths": ["<strengths of the response>"],
|
|
30
|
+
"weaknesses": ["<weak points>"],
|
|
31
|
+
"missing_aspects": ["<what is missing>"],
|
|
32
|
+
"errors_found": ["<identified errors>"],
|
|
33
|
+
"improvement_suggestions": ["<how to improve>"]
|
|
34
|
+
},
|
|
35
|
+
"overall_quality": <1-10>,
|
|
36
|
+
"needs_refinement": <true if significant improvement is needed>
|
|
37
|
+
}'
|
|
38
|
+
|
|
39
|
+
# Prompt for refinement
|
|
40
|
+
REFINE_PROMPT_TEMPLATE='Your original response was:
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
%ORIGINAL%
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
Your self-critique identified:
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
%CRITIQUE%
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
Now produce an IMPROVED response that:
|
|
53
|
+
1. Corrects the identified errors
|
|
54
|
+
2. Adds the missing aspects
|
|
55
|
+
3. Strengthens the weak points
|
|
56
|
+
4. Maintains the strengths
|
|
57
|
+
|
|
58
|
+
Respond with the same JSON schema as the original response, but improved.'
|
|
59
|
+
|
|
60
|
+
# =============================================================================
|
|
61
|
+
# REFLECTION FUNCTIONS
|
|
62
|
+
# =============================================================================
|
|
63
|
+
|
|
64
|
+
# Helper: Execute prompt with a specific consultant
|
|
65
|
+
# Usage: _exec_consultant <consultant> <prompt>
|
|
66
|
+
_exec_consultant() {
|
|
67
|
+
local consultant="$1"
|
|
68
|
+
local prompt="$2"
|
|
69
|
+
|
|
70
|
+
case "$consultant" in
|
|
71
|
+
Gemini) echo "$prompt" | "$GEMINI_CMD" -p - -m "$GEMINI_MODEL" 2>/dev/null ;;
|
|
72
|
+
Codex) "$CODEX_CMD" exec --skip-git-repo-check "$prompt" 2>/dev/null ;;
|
|
73
|
+
Mistral) "$MISTRAL_CMD" --prompt "$prompt" --auto-approve 2>/dev/null ;;
|
|
74
|
+
Kilo) "$KILO_CMD" --auto --json "$prompt" 2>/dev/null ;;
|
|
75
|
+
*) return 1 ;;
|
|
76
|
+
esac
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# Generate critique of a response
|
|
80
|
+
# Usage: generate_critique <consultant> <response_content>
|
|
81
|
+
# Output: JSON with the critique
|
|
82
|
+
generate_critique() {
|
|
83
|
+
local consultant="$1"
|
|
84
|
+
local response="$2"
|
|
85
|
+
local prompt="${CRITIQUE_PROMPT_TEMPLATE//%RESPONSE%/$response}"
|
|
86
|
+
|
|
87
|
+
_exec_consultant "$consultant" "$prompt" || \
|
|
88
|
+
echo '{"critique": {"error": "Unknown consultant"}, "needs_refinement": false}'
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
# Refine a response based on critique
|
|
92
|
+
# Usage: refine_response <consultant> <original_response> <critique>
|
|
93
|
+
# Output: refined response
|
|
94
|
+
refine_response() {
|
|
95
|
+
local consultant="$1"
|
|
96
|
+
local original="$2"
|
|
97
|
+
local critique="$3"
|
|
98
|
+
|
|
99
|
+
local prompt="${REFINE_PROMPT_TEMPLATE//%ORIGINAL%/$original}"
|
|
100
|
+
prompt="${prompt//%CRITIQUE%/$critique}"
|
|
101
|
+
|
|
102
|
+
_exec_consultant "$consultant" "$prompt"
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Execute complete reflection cycle
|
|
106
|
+
# Usage: run_reflection_cycle <consultant> <query> <output_file> [cycles]
|
|
107
|
+
run_reflection_cycle() {
|
|
108
|
+
local consultant="$1"
|
|
109
|
+
local query="$2"
|
|
110
|
+
local output_file="$3"
|
|
111
|
+
local cycles="${4:-1}"
|
|
112
|
+
|
|
113
|
+
local current_response=""
|
|
114
|
+
local reflection_history=()
|
|
115
|
+
|
|
116
|
+
# Step 1: Get initial response (already done externally)
|
|
117
|
+
if [[ -f "$output_file" && -s "$output_file" ]]; then
|
|
118
|
+
current_response=$(cat "$output_file")
|
|
119
|
+
else
|
|
120
|
+
log_warn "No initial response found for reflection"
|
|
121
|
+
return 1
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Reflection cycles
|
|
125
|
+
for ((cycle=1; cycle<=cycles; cycle++)); do
|
|
126
|
+
log_debug "[$consultant] Reflection cycle $cycle/$cycles"
|
|
127
|
+
|
|
128
|
+
# Step 2: Self-critique
|
|
129
|
+
local critique=$(generate_critique "$consultant" "$current_response")
|
|
130
|
+
|
|
131
|
+
# Check if refinement is needed
|
|
132
|
+
local needs_refinement=$(echo "$critique" | jq -r '.needs_refinement // false' 2>/dev/null)
|
|
133
|
+
|
|
134
|
+
if [[ "$needs_refinement" == "false" && $cycle -gt 1 ]]; then
|
|
135
|
+
log_debug "[$consultant] No refinement needed, stopping at cycle $cycle"
|
|
136
|
+
break
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
# Save to history
|
|
140
|
+
reflection_history+=("$critique")
|
|
141
|
+
|
|
142
|
+
# Step 3: Refine
|
|
143
|
+
local refined=$(refine_response "$consultant" "$current_response" "$critique")
|
|
144
|
+
|
|
145
|
+
if [[ -n "$refined" ]]; then
|
|
146
|
+
current_response="$refined"
|
|
147
|
+
else
|
|
148
|
+
log_warn "[$consultant] Refinement failed, keeping previous response"
|
|
149
|
+
break
|
|
150
|
+
fi
|
|
151
|
+
done
|
|
152
|
+
|
|
153
|
+
# Add reflection metadata to final result
|
|
154
|
+
if echo "$current_response" | jq -e '.' > /dev/null 2>&1; then
|
|
155
|
+
echo "$current_response" | jq \
|
|
156
|
+
--argjson cycles "$cycles" \
|
|
157
|
+
--argjson history "$(printf '%s\n' ${reflection_history[@]+"${reflection_history[@]}"} | jq -s '.')" \
|
|
158
|
+
'. + {reflection: {cycles_completed: $cycles, history: $history}}' \
|
|
159
|
+
> "$output_file"
|
|
160
|
+
else
|
|
161
|
+
echo "$current_response" > "$output_file"
|
|
162
|
+
fi
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# =============================================================================
|
|
166
|
+
# QUALITY ASSESSMENT
|
|
167
|
+
# =============================================================================
|
|
168
|
+
|
|
169
|
+
# Evaluate if a response would benefit from reflection
|
|
170
|
+
# Usage: should_reflect <response_json>
|
|
171
|
+
# Returns: 0 if yes, 1 if no
|
|
172
|
+
should_reflect() {
|
|
173
|
+
local response="$1"
|
|
174
|
+
|
|
175
|
+
# Check confidence score
|
|
176
|
+
local confidence=$(echo "$response" | jq -r '.confidence.score // 5' 2>/dev/null)
|
|
177
|
+
|
|
178
|
+
# If confidence is low, reflect
|
|
179
|
+
if [[ $confidence -lt 6 ]]; then
|
|
180
|
+
return 0
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
# Check if there are many caveats
|
|
184
|
+
local caveats_count=$(echo "$response" | jq -r '.response.caveats | length // 0' 2>/dev/null)
|
|
185
|
+
if [[ $caveats_count -gt 3 ]]; then
|
|
186
|
+
return 0
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
# Check uncertainty factors
|
|
190
|
+
local uncertainty_count=$(echo "$response" | jq -r '.confidence.uncertainty_factors | length // 0' 2>/dev/null)
|
|
191
|
+
if [[ $uncertainty_count -gt 2 ]]; then
|
|
192
|
+
return 0
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
return 1
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
# Calculate quality score of a response
|
|
199
|
+
# Usage: calculate_quality_score <response_json>
|
|
200
|
+
calculate_quality_score() {
|
|
201
|
+
local response="$1"
|
|
202
|
+
|
|
203
|
+
local confidence=$(echo "$response" | jq -r '.confidence.score // 5' 2>/dev/null)
|
|
204
|
+
local has_code=$(echo "$response" | jq -r '.response.code_snippets | length > 0' 2>/dev/null)
|
|
205
|
+
local has_pros=$(echo "$response" | jq -r '.response.pros | length > 0' 2>/dev/null)
|
|
206
|
+
local has_cons=$(echo "$response" | jq -r '.response.cons | length > 0' 2>/dev/null)
|
|
207
|
+
|
|
208
|
+
local score=$confidence
|
|
209
|
+
|
|
210
|
+
# Bonus for completeness
|
|
211
|
+
[[ "$has_code" == "true" ]] && score=$((score + 1))
|
|
212
|
+
[[ "$has_pros" == "true" ]] && score=$((score + 1))
|
|
213
|
+
[[ "$has_cons" == "true" ]] && score=$((score + 1))
|
|
214
|
+
|
|
215
|
+
# Cap at 10
|
|
216
|
+
if [[ $score -gt 10 ]]; then
|
|
217
|
+
score=10
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
echo $score
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
# =============================================================================
|
|
224
|
+
# JUDGE STEP - OVERCONFIDENCE DETECTION (v2.2)
|
|
225
|
+
# =============================================================================
|
|
226
|
+
|
|
227
|
+
# Prompt template for the judge evaluation
|
|
228
|
+
JUDGE_PROMPT_TEMPLATE='You are an expert meta-evaluator. Your job is to detect OVERCONFIDENCE in AI responses.
|
|
229
|
+
|
|
230
|
+
Analyze this response for overconfidence signals:
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
CONSULTANT: %CONSULTANT%
|
|
234
|
+
CONFIDENCE SCORE: %CONFIDENCE%/10
|
|
235
|
+
|
|
236
|
+
SUMMARY:
|
|
237
|
+
%SUMMARY%
|
|
238
|
+
|
|
239
|
+
DETAILED RESPONSE:
|
|
240
|
+
%DETAILED%
|
|
241
|
+
|
|
242
|
+
REASONING FOR CONFIDENCE:
|
|
243
|
+
%REASONING%
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
Evaluate for overconfidence by checking:
|
|
247
|
+
|
|
248
|
+
1. **Hedging vs Certainty Mismatch**: Does the text use hedging language ("might", "could", "possibly") but claim high confidence?
|
|
249
|
+
2. **Evidence Quality**: Is the confidence score justified by the evidence/reasoning provided?
|
|
250
|
+
3. **Complexity Acknowledgment**: Does a high confidence score acknowledge the complexity of the problem?
|
|
251
|
+
4. **Edge Cases**: Are edge cases mentioned? High confidence without edge case consideration is suspicious.
|
|
252
|
+
5. **Alternative Awareness**: Does the response acknowledge alternative approaches exist?
|
|
253
|
+
|
|
254
|
+
Respond ONLY with valid JSON:
|
|
255
|
+
{
|
|
256
|
+
"consultant": "%CONSULTANT%",
|
|
257
|
+
"original_confidence": %CONFIDENCE%,
|
|
258
|
+
"overconfidence_detected": <true/false>,
|
|
259
|
+
"adjusted_confidence": <1-10>,
|
|
260
|
+
"analysis": {
|
|
261
|
+
"hedging_language_count": <number of hedging phrases found>,
|
|
262
|
+
"certainty_claims_count": <number of certainty claims>,
|
|
263
|
+
"evidence_quality": "<weak|moderate|strong>",
|
|
264
|
+
"complexity_acknowledged": <true/false>,
|
|
265
|
+
"edge_cases_mentioned": <true/false>,
|
|
266
|
+
"alternatives_acknowledged": <true/false>
|
|
267
|
+
},
|
|
268
|
+
"red_flags": ["<specific overconfidence indicators found>"],
|
|
269
|
+
"recommendation": "<keep|adjust_down|flag_for_review>"
|
|
270
|
+
}'
|
|
271
|
+
|
|
272
|
+
# Run judge evaluation on a single response
|
|
273
|
+
# Usage: judge_response <response_file>
|
|
274
|
+
# Output: JSON with judge evaluation
|
|
275
|
+
judge_response() {
|
|
276
|
+
local response_file="$1"
|
|
277
|
+
|
|
278
|
+
if [[ ! -f "$response_file" || ! -s "$response_file" ]]; then
|
|
279
|
+
echo '{"error": "Invalid response file"}'
|
|
280
|
+
return 1
|
|
281
|
+
fi
|
|
282
|
+
|
|
283
|
+
local consultant confidence summary detailed reasoning
|
|
284
|
+
consultant=$(jq -r '.consultant // "unknown"' "$response_file" 2>/dev/null)
|
|
285
|
+
confidence=$(jq -r '.confidence.score // 5' "$response_file" 2>/dev/null)
|
|
286
|
+
summary=$(jq -r '.response.summary // "No summary"' "$response_file" 2>/dev/null)
|
|
287
|
+
detailed=$(jq -r '.response.detailed // "No details"' "$response_file" 2>/dev/null | head -c 2000)
|
|
288
|
+
reasoning=$(jq -r '.confidence.reasoning // "No reasoning provided"' "$response_file" 2>/dev/null)
|
|
289
|
+
|
|
290
|
+
local prompt="${JUDGE_PROMPT_TEMPLATE}"
|
|
291
|
+
prompt="${prompt//%CONSULTANT%/$consultant}"
|
|
292
|
+
prompt="${prompt//%CONFIDENCE%/$confidence}"
|
|
293
|
+
prompt="${prompt//%SUMMARY%/$summary}"
|
|
294
|
+
prompt="${prompt//%DETAILED%/$detailed}"
|
|
295
|
+
prompt="${prompt//%REASONING%/$reasoning}"
|
|
296
|
+
|
|
297
|
+
# Use Claude for judging (most reliable for meta-analysis)
|
|
298
|
+
if command -v claude &> /dev/null; then
|
|
299
|
+
echo "$prompt" | claude --print 2>/dev/null
|
|
300
|
+
else
|
|
301
|
+
# Fallback: heuristic-based detection
|
|
302
|
+
heuristic_overconfidence_check "$response_file"
|
|
303
|
+
fi
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
# Heuristic-based overconfidence detection (no LLM required)
|
|
307
|
+
# Usage: heuristic_overconfidence_check <response_file>
|
|
308
|
+
heuristic_overconfidence_check() {
|
|
309
|
+
local response_file="$1"
|
|
310
|
+
|
|
311
|
+
local consultant confidence text
|
|
312
|
+
consultant=$(jq -r '.consultant // "unknown"' "$response_file" 2>/dev/null)
|
|
313
|
+
confidence=$(jq -r '.confidence.score // 5' "$response_file" 2>/dev/null)
|
|
314
|
+
text=$(jq -r '(.response.summary // "") + " " + (.response.detailed // "") + " " + (.confidence.reasoning // "")' "$response_file" 2>/dev/null | tr '[:upper:]' '[:lower:]')
|
|
315
|
+
|
|
316
|
+
# Count hedging language
|
|
317
|
+
local hedging_words="might|could|possibly|perhaps|maybe|likely|probably|seems|appears|suggest"
|
|
318
|
+
local hedging_count
|
|
319
|
+
hedging_count=$(echo "$text" | grep -oiE "$hedging_words" | wc -l | tr -d ' ')
|
|
320
|
+
|
|
321
|
+
# Count certainty language
|
|
322
|
+
local certainty_words="definitely|certainly|absolutely|always|never|must|clearly|obviously|undoubtedly"
|
|
323
|
+
local certainty_count
|
|
324
|
+
certainty_count=$(echo "$text" | grep -oiE "$certainty_words" | wc -l | tr -d ' ')
|
|
325
|
+
|
|
326
|
+
# Check for edge cases mention
|
|
327
|
+
local edge_case_mentioned=false
|
|
328
|
+
echo "$text" | grep -qiE "edge case|corner case|exception|special case" && edge_case_mentioned=true
|
|
329
|
+
|
|
330
|
+
# Check for alternatives mention
|
|
331
|
+
local alternatives_mentioned=false
|
|
332
|
+
echo "$text" | grep -qiE "alternative|another approach|other option|could also|alternatively" && alternatives_mentioned=true
|
|
333
|
+
|
|
334
|
+
# Calculate overconfidence indicators
|
|
335
|
+
local red_flags=()
|
|
336
|
+
local overconfidence=false
|
|
337
|
+
local adjusted=$confidence
|
|
338
|
+
|
|
339
|
+
# High confidence + lots of hedging = suspicious
|
|
340
|
+
if [[ $confidence -ge 8 && $hedging_count -ge 3 ]]; then
|
|
341
|
+
red_flags+=("High confidence with excessive hedging language")
|
|
342
|
+
overconfidence=true
|
|
343
|
+
adjusted=$((confidence - 2))
|
|
344
|
+
fi
|
|
345
|
+
|
|
346
|
+
# High confidence + no edge cases = suspicious
|
|
347
|
+
if [[ $confidence -ge 8 && "$edge_case_mentioned" == "false" ]]; then
|
|
348
|
+
red_flags+=("High confidence without edge case consideration")
|
|
349
|
+
overconfidence=true
|
|
350
|
+
adjusted=$((adjusted - 1))
|
|
351
|
+
fi
|
|
352
|
+
|
|
353
|
+
# Very high confidence is almost always overconfident
|
|
354
|
+
if [[ $confidence -ge 9 ]]; then
|
|
355
|
+
red_flags+=("Extremely high confidence (9-10) is rarely justified")
|
|
356
|
+
overconfidence=true
|
|
357
|
+
adjusted=$((adjusted - 1))
|
|
358
|
+
fi
|
|
359
|
+
|
|
360
|
+
# Clamp adjusted confidence
|
|
361
|
+
[[ $adjusted -lt 1 ]] && adjusted=1
|
|
362
|
+
[[ $adjusted -gt 10 ]] && adjusted=10
|
|
363
|
+
|
|
364
|
+
local recommendation="keep"
|
|
365
|
+
if [[ "$overconfidence" == "true" ]]; then
|
|
366
|
+
if [[ $((confidence - adjusted)) -ge 2 ]]; then
|
|
367
|
+
recommendation="adjust_down"
|
|
368
|
+
else
|
|
369
|
+
recommendation="flag_for_review"
|
|
370
|
+
fi
|
|
371
|
+
fi
|
|
372
|
+
|
|
373
|
+
jq -n \
|
|
374
|
+
--arg consultant "$consultant" \
|
|
375
|
+
--argjson original "$confidence" \
|
|
376
|
+
--argjson overconfidence "$overconfidence" \
|
|
377
|
+
--argjson adjusted "$adjusted" \
|
|
378
|
+
--argjson hedging "$hedging_count" \
|
|
379
|
+
--argjson certainty "$certainty_count" \
|
|
380
|
+
--argjson edge_cases "$edge_case_mentioned" \
|
|
381
|
+
--argjson alternatives "$alternatives_mentioned" \
|
|
382
|
+
--arg red_flags "$(IFS='|'; echo "${red_flags[*]:-}")" \
|
|
383
|
+
--arg recommendation "$recommendation" \
|
|
384
|
+
'{
|
|
385
|
+
consultant: $consultant,
|
|
386
|
+
original_confidence: $original,
|
|
387
|
+
overconfidence_detected: $overconfidence,
|
|
388
|
+
adjusted_confidence: $adjusted,
|
|
389
|
+
analysis: {
|
|
390
|
+
hedging_language_count: $hedging,
|
|
391
|
+
certainty_claims_count: $certainty,
|
|
392
|
+
evidence_quality: (if $hedging > $certainty then "weak" elif $hedging == $certainty then "moderate" else "strong" end),
|
|
393
|
+
complexity_acknowledged: ($hedging > 0),
|
|
394
|
+
edge_cases_mentioned: $edge_cases,
|
|
395
|
+
alternatives_acknowledged: $alternatives
|
|
396
|
+
},
|
|
397
|
+
red_flags: ($red_flags | split("|") | map(select(. != ""))),
|
|
398
|
+
recommendation: $recommendation
|
|
399
|
+
}'
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
# Run judge evaluation on all responses in a directory
|
|
403
|
+
# Usage: judge_all_responses <responses_dir> <output_file>
|
|
404
|
+
judge_all_responses() {
|
|
405
|
+
local responses_dir="$1"
|
|
406
|
+
local output_file="$2"
|
|
407
|
+
|
|
408
|
+
local results='[]'
|
|
409
|
+
local overconfidence_count=0
|
|
410
|
+
local total_count=0
|
|
411
|
+
|
|
412
|
+
for f in "$responses_dir"/*.json; do
|
|
413
|
+
if [[ -f "$f" && -s "$f" && "$(basename "$f")" != "voting.json" && "$(basename "$f")" != "synthesis.json" && "$(basename "$f")" != "judge_report.json" ]]; then
|
|
414
|
+
local evaluation
|
|
415
|
+
evaluation=$(judge_response "$f")
|
|
416
|
+
|
|
417
|
+
if echo "$evaluation" | jq -e '.' > /dev/null 2>&1; then
|
|
418
|
+
results=$(echo "$results" | jq --argjson eval "$evaluation" '. + [$eval]')
|
|
419
|
+
|
|
420
|
+
local is_overconfident
|
|
421
|
+
is_overconfident=$(echo "$evaluation" | jq -r '.overconfidence_detected // false')
|
|
422
|
+
[[ "$is_overconfident" == "true" ]] && ((overconfidence_count++))
|
|
423
|
+
((total_count++))
|
|
424
|
+
fi
|
|
425
|
+
fi
|
|
426
|
+
done
|
|
427
|
+
|
|
428
|
+
# Generate summary
|
|
429
|
+
jq -n \
|
|
430
|
+
--argjson evaluations "$results" \
|
|
431
|
+
--argjson overconfident "$overconfidence_count" \
|
|
432
|
+
--argjson total "$total_count" \
|
|
433
|
+
'{
|
|
434
|
+
judge_report: {
|
|
435
|
+
timestamp: (now | todate),
|
|
436
|
+
total_evaluated: $total,
|
|
437
|
+
overconfidence_detected: $overconfident,
|
|
438
|
+
evaluations: $evaluations,
|
|
439
|
+
summary: {
|
|
440
|
+
reliability: (if $overconfident == 0 then "high" elif ($overconfident / $total) < 0.3 then "medium" else "low" end),
|
|
441
|
+
action_required: ($overconfident > 0)
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}' > "$output_file"
|
|
445
|
+
|
|
446
|
+
cat "$output_file"
|
|
447
|
+
}
|