ai-consultants 2.20.0 → 2.21.0
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.md +25 -8
- package/README.md +9 -2
- package/SKILL.md +10 -4
- package/bin/ai-consultants +5 -0
- package/docs/COST_RATES.md +1 -1
- package/docs/SETUP.md +9 -5
- package/docs/cost_rates.json +1 -1
- package/docs/releases/v2.21.0.md +65 -0
- package/package.json +1 -1
- package/references/configuration.md +35 -10
- package/scripts/config.sh +58 -12
- package/scripts/consult_all.sh +31 -0
- package/scripts/doctor.sh +6 -5
- package/scripts/lib/api_query.sh +9 -0
- package/scripts/lib/common.sh +58 -5
- package/scripts/lib/orchestration.sh +33 -5
- package/scripts/lib/personas.sh +10 -3
- package/scripts/lib/reflection.sh +4 -1
- package/scripts/lib/reliability.sh +132 -0
- package/scripts/lib/stance.sh +70 -0
- package/scripts/lib/voting.sh +73 -20
- package/scripts/peer_review.sh +18 -9
- package/scripts/query_gemini.sh +12 -7
- package/scripts/query_kilo.sh +7 -0
- package/scripts/query_kimi.sh +24 -4
- package/scripts/query_minimax.sh +72 -7
- package/scripts/release.sh +220 -0
- package/scripts/roster_calibrate.sh +8 -2
- package/scripts/synthesize.sh +12 -5
- package/scripts/test_e2e.sh +84 -0
- package/scripts/test_fixtures/stub_cli.sh +45 -0
- package/scripts/test_release.sh +220 -0
- package/scripts/test_reliability.sh +83 -0
- package/scripts/test_roster_calibrate.sh +22 -7
- package/scripts/test_stance.sh +67 -0
- package/scripts/test_suite.sh +11 -0
- package/scripts/test_update_clis.sh +79 -0
- package/scripts/test_user_config.sh +45 -1
- package/scripts/test_voting_metadata.sh +69 -0
- package/scripts/update_clis.sh +238 -0
package/CLAUDE.md
CHANGED
|
@@ -6,7 +6,7 @@ AI Consultants is a multi-model AI deliberation system that queries up to 15 AI
|
|
|
6
6
|
|
|
7
7
|
**Self-Exclusion**: The invoking agent is automatically excluded from the panel to prevent self-consultation. Claude Code won't query Claude, Codex CLI won't query Codex, etc.
|
|
8
8
|
|
|
9
|
-
**Version**: 2.
|
|
9
|
+
**Version**: 2.21.0
|
|
10
10
|
|
|
11
11
|
## Distribution
|
|
12
12
|
|
|
@@ -38,6 +38,7 @@ ai-consultants/
|
|
|
38
38
|
│ ├── consult_all.sh # Main orchestrator - entry point
|
|
39
39
|
│ ├── config.sh # Centralized configuration
|
|
40
40
|
│ ├── doctor.sh # Diagnostic and auto-fix tool (v2.2)
|
|
41
|
+
│ ├── update_clis.sh # Check/update installed consultant CLIs (v2.21)
|
|
41
42
|
│ ├── peer_review.sh # Anonymous peer review (v2.2)
|
|
42
43
|
│ ├── roster_audit.sh # Roster uncorrelated-value audit (v2.20)
|
|
43
44
|
│ ├── roster_calibrate.sh # Measured capability calibration, Tier A (v2.20)
|
|
@@ -59,6 +60,7 @@ ai-consultants/
|
|
|
59
60
|
│ ├── voting.sh # Voting/consensus + confidence intervals
|
|
60
61
|
│ ├── routing.sh # Smart routing + cost-aware routing
|
|
61
62
|
│ ├── orchestration.sh # Dynamic orchestration planner + shapes (v2.16)
|
|
63
|
+
│ ├── stance.sh # Stance-based semantic consensus (v2.21, opt-in)
|
|
62
64
|
│ ├── session.sh # Session management
|
|
63
65
|
│ ├── costs.sh # Cost tracking + response limits
|
|
64
66
|
│ ├── cache.sh # Semantic caching (v2.3)
|
|
@@ -285,7 +287,7 @@ curl -fsSL https://ampcode.com/install.sh | bash
|
|
|
285
287
|
```
|
|
286
288
|
|
|
287
289
|
**Environment Variables:**
|
|
288
|
-
- `ENABLE_AMP` - Enable Amp consultant (default:
|
|
290
|
+
- `ENABLE_AMP` - Enable Amp consultant (default: true)
|
|
289
291
|
- `AMP_CMD` - CLI command (default: amp)
|
|
290
292
|
- `AMP_TIMEOUT` - Timeout in seconds (default: 180)
|
|
291
293
|
- `AMP_API_KEY` - API key for authentication
|
|
@@ -326,7 +328,7 @@ Qwen3 now supports CLI/API mode switching using the qwen-code CLI.
|
|
|
326
328
|
export QWEN3_USE_API=false
|
|
327
329
|
./scripts/consult_all.sh "question"
|
|
328
330
|
|
|
329
|
-
# API mode (
|
|
331
|
+
# API mode (opt-in)
|
|
330
332
|
export QWEN3_USE_API=true
|
|
331
333
|
export QWEN3_API_KEY="your-dashscope-key"
|
|
332
334
|
./scripts/consult_all.sh "question"
|
|
@@ -342,7 +344,7 @@ npm install -g @qwen-code/qwen-code@latest
|
|
|
342
344
|
## v2.6 Features
|
|
343
345
|
|
|
344
346
|
### CLI/API Mode Switching
|
|
345
|
-
|
|
347
|
+
Six consultants can now switch between CLI and API mode: **Gemini, Codex, Claude, Mistral, Qwen3, MiniMax**.
|
|
346
348
|
|
|
347
349
|
When API mode is enabled for an agent, CLI mode is disabled (mutual exclusivity).
|
|
348
350
|
|
|
@@ -379,6 +381,7 @@ New environment variables in `config.sh`:
|
|
|
379
381
|
| `CLAUDE_USE_API` | false | Use Anthropic API instead of claude CLI |
|
|
380
382
|
| `MISTRAL_USE_API` | false | Use Mistral API instead of vibe CLI |
|
|
381
383
|
| `QWEN3_USE_API` | false | Use DashScope API instead of qwen CLI (v2.7) |
|
|
384
|
+
| `MINIMAX_USE_API` | false | Use MiniMax API instead of the mmx CLI (v2.21) |
|
|
382
385
|
| `GEMINI_API_URL` | https://generativelanguage.googleapis.com/v1beta/models | Google AI endpoint |
|
|
383
386
|
| `CODEX_API_URL` | https://api.openai.com/v1/chat/completions | OpenAI endpoint |
|
|
384
387
|
| `CLAUDE_API_URL` | https://api.anthropic.com/v1/messages | Anthropic endpoint |
|
|
@@ -649,7 +652,7 @@ for f in scripts/*.sh scripts/lib/*.sh; do bash -n "$f" && echo "OK: $f"; done
|
|
|
649
652
|
| Variable | Default | Description |
|
|
650
653
|
|----------|---------|-------------|
|
|
651
654
|
| `INVOKING_AGENT` | unknown | Agent invoking the skill (for self-exclusion) |
|
|
652
|
-
| `ENABLE_CLAUDE` |
|
|
655
|
+
| `ENABLE_CLAUDE` | true | Enable Claude consultant (auto-excluded under Claude Code) |
|
|
653
656
|
| `ENABLE_DEBATE` | false | Enable Multi-Agent Debate |
|
|
654
657
|
| `DEBATE_ROUNDS` | 1 | Number of debate rounds |
|
|
655
658
|
| `ENABLE_SYNTHESIS` | true | Auto-synthesis of responses |
|
|
@@ -676,15 +679,19 @@ for f in scripts/*.sh scripts/lib/*.sh; do bash -n "$f" && echo "OK: $f"; done
|
|
|
676
679
|
| `ENABLE_CAPABILITY_ROUTING` | false | Capability-aware panel composition (v2.20, opt-in) |
|
|
677
680
|
| `CAPABILITY_WEIGHT_STRENGTH` | 10 | Vote-weight modulation: conf*(S+cap)/S (v2.20) |
|
|
678
681
|
| `CAPABILITY_DEFAULT` | 5 | Fallback capability for a missing consultant/axis (v2.20) |
|
|
682
|
+
| `ENABLE_STANCE_CONSENSUS` | false | Enumerated-stance exact-match consensus (v2.21, opt-in; +1 LLM call/run) |
|
|
683
|
+
| `STANCE_MAX_OPTIONS` | 5 | Max stance options generated per question (v2.21) |
|
|
679
684
|
| `ENABLE_BUDGET_LIMIT` | false | Budget enforcement (v2.4, opt-in) |
|
|
680
685
|
| `BUDGET_ACTION` | warn | Action on budget exceeded: warn/stop (v2.4) |
|
|
681
686
|
| `QWEN3_USE_API` | false | Use DashScope API instead of qwen CLI (v2.7) |
|
|
682
687
|
| `QWEN3_CMD` | qwen | Qwen CLI command (v2.7) |
|
|
683
|
-
| `ENABLE_KIMI` |
|
|
688
|
+
| `ENABLE_KIMI` | true | Enable Kimi consultant (v2.9) |
|
|
684
689
|
| `KIMI_CMD` | kimi | Kimi CLI command (v2.9) |
|
|
685
690
|
| `KIMI_MODEL` | kimi-code/kimi-for-coding | Kimi model (v2.9) |
|
|
686
|
-
| `ENABLE_MINIMAX` |
|
|
687
|
-
| `
|
|
691
|
+
| `ENABLE_MINIMAX` | true | Enable MiniMax consultant (v2.10; CLI via mmx v2.21) |
|
|
692
|
+
| `MINIMAX_USE_API` | false | Use MiniMax API instead of the mmx CLI (v2.21) |
|
|
693
|
+
| `MINIMAX_CMD` | mmx | MiniMax CLI command (v2.21) |
|
|
694
|
+
| `MINIMAX_API_KEY` | - | MiniMax API key (API mode only) (v2.10) |
|
|
688
695
|
| `MINIMAX_MODEL` | MiniMax-M2.7 | MiniMax model (v2.10) |
|
|
689
696
|
|
|
690
697
|
## External Dependencies
|
|
@@ -699,6 +706,7 @@ for f in scripts/*.sh scripts/lib/*.sh; do bash -n "$f" && echo "OK: $f"; done
|
|
|
699
706
|
- `kimi` CLI - Kimi Code (v2.9)
|
|
700
707
|
- `claude` CLI - Claude (v2.2, also used for synthesis)
|
|
701
708
|
- `qwen` CLI - Qwen via qwen-code (v2.7, optional)
|
|
709
|
+
- `mmx` CLI - MiniMax via mmx-cli (v2.21, optional; `npm i -g mmx-cli`, auth `mmx auth login`)
|
|
702
710
|
- `ollama` CLI - Local models (v2.2)
|
|
703
711
|
- `jq` - JSON parsing
|
|
704
712
|
|
|
@@ -834,6 +842,15 @@ curl -fsSL https://raw.githubusercontent.com/matteoscurati/ai-consultants/main/s
|
|
|
834
842
|
|
|
835
843
|
## Changelog
|
|
836
844
|
|
|
845
|
+
### v2.21.0
|
|
846
|
+
- **CLI-first transport (principle).** Every `*_USE_API` defaults `false`; a consultant with a CLI always uses it, API is opt-in (CLI-less model or explicit choice). `ENABLE_AMP`/`ENABLE_CLAUDE` default true.
|
|
847
|
+
- **MiniMax via `mmx` CLI** (was API-only). `query_minimax.sh` runs `mmx text chat --non-interactive …` in CLI mode; `config.sh` adds `MINIMAX_CMD` + auto-resolves `MINIMAX_USE_API` (API iff `MINIMAX_API_KEY` set — back-compat), drops MiniMax from `API_CONSULTANTS`; `doctor.sh` treats it as switchable.
|
|
848
|
+
- **`scripts/update_clis.sh`** (+ `ai-consultants update-clis`): per CLI-backed consultant, `detect_method` (brew formula/cask, npm, uv, pipx, pip, self-update, curl installer) → update. `--dry-run`, `--only`.
|
|
849
|
+
- **Stance consensus** (opt-in, `ENABLE_STANCE_CONSENSUS`): new `lib/stance.sh` (`generate_stance_options` — one synthesizer call wrapped in `run_with_timeout`; `_stance_clean`; `build_stance_prompt`). `consult_all.sh` generates the shared set → `stance_options.json` + exports `STANCE_OPTIONS_PROMPT`; injected via `personas.sh` (CLI) + `api_query.sh` (API). `voting.sh::calculate_consensus_score` scores the plurality stance over the PANEL size (not the count of emitted stances). `STANCE_MAX_OPTIONS`, `STANCE_TIMEOUT`.
|
|
850
|
+
- **Smoke-test reliability**: `query_gemini.sh` (`agy -p "$QUERY"`), `query_kimi.sh` (`stream-json` + `_kimi_extract_content`), `query_kilo.sh` (de-fence). Shared `_is_consultant_response_file` metadata filter in `common.sh`, applied across `voting.sh`/`synthesize.sh`/`peer_review.sh`/`reflection.sh`. `orchestration.sh` stalled→stable relabel (set -e-safe) + debate-round promote validation.
|
|
851
|
+
- **Persona fix**: `_AGENT_DEFAULT_PERSONAS` mapped `GLM|17`/`DEEPSEEK|7` (each got the other's persona) → `GLM|7`/`DEEPSEEK|17`.
|
|
852
|
+
- **Dev/reliability**: reliability tracking + Amp/Claude default-on; offline e2e test; `scripts/release.sh` version-bump automation; calibration fixes (diagnosable peer-review failures + cost-only path); `test_user_config.sh` XDG test made hermetic (unset the exported `_AI_CONSULTANTS_XDG_*` intermediates). `npm test` = 18 suites. Hardened by a `/code-review max` pass.
|
|
853
|
+
|
|
837
854
|
### v2.20.0
|
|
838
855
|
- **Capability axes (borrowed from the delegation-kit cost/intelligence/taste table).** `references/affinity.json` → v1.1: new `capabilities` (per-consultant {intelligence, taste, cost}, 1-10), `category_axis` (category → the quality axis it stresses: taste for API_DESIGN/ARCHITECTURE/CODE_REVIEW/GENERAL, intelligence otherwise), `capability_default`. New `lib/routing.sh::get_capability` / `get_category_axis` (cached like `get_affinity`).
|
|
839
856
|
- **Capability-weighted voting** (`ENABLE_CAPABILITY_WEIGHTING`, opt-in): `lib/voting.sh::_effective_vote_weight` modulates a vote by the consultant's capability on the run's axis — `confidence × (S + cap) / S` (`S = CAPABILITY_WEIGHT_STRENGTH`, default 10). Applied in `calculate_weighted_recommendation` and `calculate_final_score` (normalizer uses the same weight → 1-10 scale preserved). Axis from `QUESTION_CATEGORY`. `cost` never weights a vote (tie-break intelligence > taste > cost).
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# AI Consultants v2.
|
|
1
|
+
# AI Consultants v2.21.0
|
|
2
2
|
|
|
3
3
|
> **A harness for every question.** A panel of up to 15 frontier models that writes its own playbook per question — fan out, debate to convergence, cross-examine under adversarial review, or run a tournament — and checks its work before it reaches you.
|
|
4
4
|
|
|
5
|
-
[](https://github.com/matteoscurati/ai-consultants)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](https://docs.anthropic.com/en/docs/claude-code/skills)
|
|
8
8
|
[](https://github.com/matteoscurati/ai-consultants)
|
|
@@ -580,6 +580,8 @@ ai-consultants doctor --json # JSON for automa
|
|
|
580
580
|
ai-consultants doctor --live # Real ping per consultant — catches installed-but-unauthenticated CLIs
|
|
581
581
|
ai-consultants doctor --suggest-config # Print recommended ENABLE_* based on detected CLIs
|
|
582
582
|
ai-consultants doctor --suggest-preset --question "..." # Recommend preset + strategy for a question
|
|
583
|
+
ai-consultants update-clis # Check & update every installed consultant CLI
|
|
584
|
+
ai-consultants update-clis --dry-run # Preview: each CLI's install method + update command
|
|
583
585
|
```
|
|
584
586
|
|
|
585
587
|
> When a consultant fails mid-consultation, the run surfaces the captured reason (e.g. `CLI not found`, `401 Unauthorized`) instead of a bare "Failed", so you can tell *not installed* from *not authenticated* from *transient*.
|
|
@@ -609,6 +611,11 @@ The **shape** is chosen per question (or pinned via `ORCHESTRATION_MODE`):
|
|
|
609
611
|
|
|
610
612
|
Set `ORCHESTRATION_MODE=fixed` for the classic fixed-round pipeline.
|
|
611
613
|
|
|
614
|
+
Consensus is measured lexically by default; set `ENABLE_STANCE_CONSENSUS=true`
|
|
615
|
+
(opt-in, v2.21) to have the panel pick from a shared set of enumerated stance
|
|
616
|
+
options and score agreement by exact match instead — see
|
|
617
|
+
[references/configuration.md](references/configuration.md#semantic-consensus-v221-opt-in).
|
|
618
|
+
|
|
612
619
|
With peer review:
|
|
613
620
|
```
|
|
614
621
|
Responses -> Anonymize -> Peer Ranking -> De-anonymize -> Peer Scores
|
package/SKILL.md
CHANGED
|
@@ -5,10 +5,10 @@ license: MIT
|
|
|
5
5
|
compatibility: Requires bash, jq, and at least 2 AI CLI tools (agy, codex, vibe, etc.). macOS and Linux.
|
|
6
6
|
metadata:
|
|
7
7
|
author: matteoscurati
|
|
8
|
-
version: 2.
|
|
8
|
+
version: 2.21.0
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
# AI Consultants v2.
|
|
11
|
+
# AI Consultants v2.21.0 - AI Expert Panel
|
|
12
12
|
|
|
13
13
|
**A harness for every question.** Convene a panel of AI "consultants" for coding questions — and let the engine pick *how* they deliberate: a quick read, a convergence loop, an adversarial refutation gate, a tournament, or an exhaustive sweep. Each consultant has a **configurable persona** that shapes its analysis.
|
|
14
14
|
|
|
@@ -42,11 +42,12 @@ Configuration (presets, strategies, features, personas, API keys) can be managed
|
|
|
42
42
|
| **Kimi** | `kimi` | The Eastern Sage | Holistic, balanced perspectives |
|
|
43
43
|
| **Claude** | `claude` | The Synthesizer | Big picture, synthesis |
|
|
44
44
|
| **Qwen** | `qwen` | The Analyst | Data-driven, metrics |
|
|
45
|
+
| **MiniMax** | `mmx` | The Pragmatic Optimizer | Performance, efficiency, pragmatism |
|
|
45
46
|
| **Ollama** | `ollama` | The Local Expert | Privacy-first, zero cost |
|
|
46
47
|
|
|
47
|
-
**API-only consultants**: GLM (The Methodologist), Grok (The Provocateur), DeepSeek (The Code Specialist)
|
|
48
|
+
**API-only consultants**: GLM (The Methodologist), Grok (The Provocateur), DeepSeek (The Code Specialist)
|
|
48
49
|
|
|
49
|
-
**CLI/API Mode**: Gemini, Codex, Claude, Mistral, and
|
|
50
|
+
**CLI/API Mode**: Gemini, Codex, Claude, Mistral, Qwen, and MiniMax can switch between CLI and API mode via `*_USE_API` environment variables. Gemini auto-selects API mode when `GEMINI_API_KEY` is set (no `agy` install needed) and the CLI otherwise.
|
|
50
51
|
|
|
51
52
|
**Self-Exclusion**: The invoking agent is automatically excluded from the panel. When invoked from Claude Code, Claude is excluded; when invoked from Codex CLI, Codex is excluded, etc.
|
|
52
53
|
|
|
@@ -96,6 +97,7 @@ Query is classified, then sent to consultants in parallel. Responses are scored,
|
|
|
96
97
|
| **Smart Routing** | Auto-select best consultants per question type | `ENABLE_SMART_ROUTING` |
|
|
97
98
|
| **Cost Tracking** | Track API usage costs | `ENABLE_COST_TRACKING` |
|
|
98
99
|
| **Panic Mode** | Auto-add rigor when uncertainty detected | `ENABLE_PANIC_MODE` |
|
|
100
|
+
| **Stance Consensus** | Panel picks from enumerated stances; agreement by exact match (opt-in, v2.21) | `ENABLE_STANCE_CONSENSUS` |
|
|
99
101
|
|
|
100
102
|
## Configuration
|
|
101
103
|
|
|
@@ -136,6 +138,10 @@ Diagnose and fix issues:
|
|
|
136
138
|
./scripts/doctor.sh --live # Real ping per consultant — catches installed-but-unauthenticated CLIs
|
|
137
139
|
```
|
|
138
140
|
|
|
141
|
+
Keep the consultant CLIs current with `ai-consultants update-clis` (`--dry-run` to
|
|
142
|
+
preview, `--only <cli>` to target one) — it detects how each CLI was installed
|
|
143
|
+
(brew/npm/uv/pipx/curl/self-update) and updates it.
|
|
144
|
+
|
|
139
145
|
When a consultant fails during a consultation, the run prints the captured reason (e.g. "CLI not found", "401 Unauthorized"). The run is also **graded** MET/DEGRADED/FAILED by how many responded (`QUORUM_MIN`), with a "Diagnosed Failures" section in the report. Set `ENABLE_HEALTH_GATE=true` to ping consultants and drop the dead ones *before* the run.
|
|
140
146
|
|
|
141
147
|
## Interpreting Results
|
package/bin/ai-consultants
CHANGED
|
@@ -55,6 +55,7 @@ Usage:
|
|
|
55
55
|
ai-consultants --preset <name> "question" Use a configuration preset
|
|
56
56
|
ai-consultants --strategy <name> "question" Use a synthesis strategy
|
|
57
57
|
ai-consultants doctor [--fix] [--json] Run diagnostics
|
|
58
|
+
ai-consultants update-clis [--dry-run] Check & update installed consultant CLIs
|
|
58
59
|
ai-consultants init [--force] Scaffold ~/.config/ai-consultants/{config.sh,.env}
|
|
59
60
|
ai-consultants install Install slash commands to ~/.claude/commands/
|
|
60
61
|
ai-consultants version Show version
|
|
@@ -78,6 +79,10 @@ EOF
|
|
|
78
79
|
shift
|
|
79
80
|
exec "$SCRIPTS_DIR/doctor.sh" "$@"
|
|
80
81
|
;;
|
|
82
|
+
update-clis|update)
|
|
83
|
+
shift
|
|
84
|
+
exec "$SCRIPTS_DIR/update_clis.sh" "$@"
|
|
85
|
+
;;
|
|
81
86
|
init)
|
|
82
87
|
shift
|
|
83
88
|
FORCE=false
|
package/docs/COST_RATES.md
CHANGED
package/docs/SETUP.md
CHANGED
|
@@ -358,15 +358,19 @@ curl -L code.kimi.com/install.sh | bash
|
|
|
358
358
|
|
|
359
359
|
Verify: `kimi --version`
|
|
360
360
|
|
|
361
|
-
### MiniMax (
|
|
361
|
+
### MiniMax (CLI via mmx) - v2.21
|
|
362
362
|
|
|
363
|
-
MiniMax
|
|
363
|
+
MiniMax runs via the `mmx` CLI by default (CLI-first, OAuth). Install and sign in:
|
|
364
364
|
|
|
365
365
|
```bash
|
|
366
|
-
|
|
367
|
-
|
|
366
|
+
npm install -g mmx-cli
|
|
367
|
+
mmx auth login # OAuth (browser); or: mmx auth login --api-key <key>
|
|
368
368
|
```
|
|
369
369
|
|
|
370
|
+
API mode is opt-in: set `MINIMAX_USE_API=true` with `MINIMAX_API_KEY`.
|
|
371
|
+
|
|
372
|
+
Verify: `mmx --version`
|
|
373
|
+
|
|
370
374
|
---
|
|
371
375
|
|
|
372
376
|
## Ollama (Local Models) - v2.2
|
|
@@ -521,7 +525,7 @@ INVOKING_AGENT=codex ./scripts/consult_all.sh "Question"
|
|
|
521
525
|
|
|
522
526
|
## CLI/API Mode Switching (v2.6+)
|
|
523
527
|
|
|
524
|
-
|
|
528
|
+
Six consultants can switch between CLI mode (using local CLI tools) and API mode (direct API calls): **Gemini, Codex, Claude, Mistral, Qwen3, and MiniMax**.
|
|
525
529
|
|
|
526
530
|
### Why Use API Mode?
|
|
527
531
|
|
package/docs/cost_rates.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.21.0",
|
|
3
3
|
"updated": "2026-06-24",
|
|
4
4
|
"models": {
|
|
5
5
|
"_comment_units": "All rates are USD per 1,000 tokens (per-1K). lib/costs.sh computes cost as (token_count / 1000) * rate, so every value here MUST be a per-1K rate = (provider $/1M price) / 1000. Do NOT paste $/MTok figures directly.",
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Release v2.21.0
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-07-14
|
|
4
|
+
**Type:** Minor — CLI-first transport, MiniMax on the mmx CLI, `update-clis`, and opt-in stance consensus
|
|
5
|
+
**Previous:** v2.20.0
|
|
6
|
+
|
|
7
|
+
## Highlights
|
|
8
|
+
|
|
9
|
+
- **CLI-first is now the rule.** Any consultant that ships a CLI uses it by default; API mode is opt-in — only for CLI-less models or an explicit `*_USE_API=true`. Amp and Claude are on by default.
|
|
10
|
+
- **MiniMax runs on the `mmx` CLI** (it was API-only). Existing API-only setups keep working: `MINIMAX_USE_API` auto-resolves to API mode only when `MINIMAX_API_KEY` is set.
|
|
11
|
+
- **`ai-consultants update-clis`** keeps every consultant CLI current, detecting how each was installed.
|
|
12
|
+
- **Stance-based semantic consensus** (opt-in): the panel picks from a shared set of enumerated stance options, so agreement is scored by exact match instead of lexical similarity.
|
|
13
|
+
- A batch of smoke-test-surfaced reliability fixes across the Gemini/Kimi/Kilo adapters and the voting/synthesis pipeline, plus a runtime persona fix. Hardened by a multi-agent `/code-review max` pass.
|
|
14
|
+
|
|
15
|
+
## What's New
|
|
16
|
+
|
|
17
|
+
### CLI-first transport
|
|
18
|
+
|
|
19
|
+
Every `*_USE_API` flag now defaults to `false`. A consultant with a CLI always uses it; API mode is reserved for models without a CLI or an explicit opt-in. `ENABLE_AMP` and `ENABLE_CLAUDE` default on.
|
|
20
|
+
|
|
21
|
+
### MiniMax via the `mmx` CLI
|
|
22
|
+
|
|
23
|
+
`query_minimax.sh` runs `mmx text chat --non-interactive --quiet --no-color --output text …` by default. `MINIMAX_CMD` (default `mmx`) sets the binary. To preserve pre-2.21 behavior, `MINIMAX_USE_API` auto-resolves:
|
|
24
|
+
|
|
25
|
+
- `MINIMAX_API_KEY` set → API mode (the only transport before 2.21 — nothing breaks on upgrade).
|
|
26
|
+
- otherwise → the `mmx` CLI.
|
|
27
|
+
|
|
28
|
+
An explicit `MINIMAX_USE_API=true|false` always wins. `doctor` validates the CLI in CLI mode and the key in API mode.
|
|
29
|
+
|
|
30
|
+
### `update-clis`
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ai-consultants update-clis # update every installed consultant CLI
|
|
34
|
+
ai-consultants update-clis --dry-run # show each CLI's install method + the exact update command
|
|
35
|
+
ai-consultants update-clis --only mmx # limit to one CLI (by consultant name or binary)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For each CLI-backed consultant it detects the install method — brew formula/cask, npm, uv, pipx, pip, a self-updating binary, or a curl installer — and updates it via the matching command, best-effort.
|
|
39
|
+
|
|
40
|
+
### Stance-based semantic consensus (opt-in)
|
|
41
|
+
|
|
42
|
+
| Flag (default) | Effect |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `ENABLE_STANCE_CONSENSUS` (false) | One LLM call enumerates 2–`STANCE_MAX_OPTIONS` mutually-exclusive stance options for the question; each consultant picks one verbatim; consensus = the plurality stance's share of the **panel**. |
|
|
45
|
+
| `STANCE_MAX_OPTIONS` (5) | Cap on the generated option set. |
|
|
46
|
+
| `STANCE_TIMEOUT` (60) | Seconds for the stance-generation call (guards a blocking/unauthenticated synthesizer at startup). |
|
|
47
|
+
|
|
48
|
+
The lexical cluster (Jaccard over the free-text `approach`) can't tell that "Commit the lockfile" and "Always keep package-lock in git" agree; the stance signal makes agreement exact-matchable. Every path degrades to the lexical cluster if fewer than two stances are emitted or generation fails, so it is always safe to enable. The generated options are written to `stance_options.json` in the output dir.
|
|
49
|
+
|
|
50
|
+
### Reliability fixes
|
|
51
|
+
|
|
52
|
+
- **CLI adapters** (from a full-panel smoke test): Gemini (`agy -p "$QUERY"`, not the broken `-p -`), Kimi (`--output-format stream-json` + a hardened extractor), and Kilo (strip the ```json fence) return structured responses instead of the unstructured fallback.
|
|
53
|
+
- **Metadata pollution**: a shared `_is_consultant_response_file` filter keeps pipeline files (`voting.json`, `orchestration.json`, `stance_options.json`, …) out of every voting/synthesis/peer-review glob, so they can't become phantom votes, reviewees, or synthesis inputs. Consensus is the largest agreeing cluster (single-linkage over Jaccard).
|
|
54
|
+
- **Orchestration**: a lexical "stalled" is relabeled "stable" when the panel's own per-round signal says positions stopped moving (now `set -e`-safe against a malformed round summary); a debate round's refined stance is validated before it is grafted.
|
|
55
|
+
- **Personas**: GLM and DeepSeek were transposed at runtime — each consultant ran under the other's persona name and prompt. Fixed.
|
|
56
|
+
|
|
57
|
+
### Under the hood
|
|
58
|
+
|
|
59
|
+
Reliability tracking with Amp/Claude default-on; an offline end-to-end integration test; `scripts/release.sh` version-bump automation; calibration fixes (diagnosable peer-review failures + a cost-only path). `npm test` now runs 18 suites.
|
|
60
|
+
|
|
61
|
+
## Upgrade notes
|
|
62
|
+
|
|
63
|
+
- **Fully back-compat.** With the new flags off, behavior matches v2.20.0.
|
|
64
|
+
- **MiniMax users**: if you ran MiniMax via `MINIMAX_API_KEY`, nothing changes — it stays on the API. To switch to the CLI, `npm install -g mmx-cli` and `mmx auth login`, then unset the key (or set `MINIMAX_USE_API=false`).
|
|
65
|
+
- **New opt-in flags**: `ENABLE_STANCE_CONSENSUS`, `STANCE_MAX_OPTIONS`, `STANCE_TIMEOUT`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-consultants",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.0",
|
|
4
4
|
"description": "A harness for every question - a panel of up to 15 AI models that picks its own deliberation strategy per question (convergence, adversarial verification, tournament) and checks its work before answering",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ai-consultants": "bin/ai-consultants"
|
|
@@ -141,9 +141,32 @@ agrees on the first pass.
|
|
|
141
141
|
The convergence trajectory and stop reason are recorded in `orchestration.json` /
|
|
142
142
|
`optimization_metrics.json`. Every round still respects `MAX_SESSION_COST` / budget limits.
|
|
143
143
|
|
|
144
|
+
## Semantic Consensus (v2.21+, opt-in)
|
|
145
|
+
|
|
146
|
+
By default the consensus score (which drives `CONVERGENCE_TARGET_CONSENSUS`) is a
|
|
147
|
+
**lexical cluster**: the largest group of consultants whose free-text `approach`
|
|
148
|
+
fields are similar (single-linkage over Jaccard). That can't tell that two
|
|
149
|
+
differently-phrased answers actually AGREE ("Commit the lockfile" vs "Always keep
|
|
150
|
+
package-lock in git").
|
|
151
|
+
|
|
152
|
+
`ENABLE_STANCE_CONSENSUS=true` adds an exact-matchable signal: one extra LLM call
|
|
153
|
+
enumerates a small set of mutually-exclusive **stance options** for the question,
|
|
154
|
+
each consultant is asked to pick exactly one verbatim, and consensus becomes the
|
|
155
|
+
plurality stance's share of the **panel** (consultants that answered but emitted no
|
|
156
|
+
stance count against agreement). It degrades to the lexical cluster whenever fewer
|
|
157
|
+
than two stances are emitted or generation fails, so it is always safe to enable.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
ENABLE_STANCE_CONSENSUS=false # opt-in; adds ~1 LLM call per run
|
|
161
|
+
STANCE_MAX_OPTIONS=5 # max stance options generated per question
|
|
162
|
+
STANCE_TIMEOUT=60 # seconds for the stance-generation call (guards a hang)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The generated options are written to `stance_options.json` in the output dir.
|
|
166
|
+
|
|
144
167
|
## CLI/API Mode Switching (v2.6+)
|
|
145
168
|
|
|
146
|
-
|
|
169
|
+
Six consultants support switching between CLI and API mode. **The default is the CLI** for every consultant that has one — API mode is opt-in (for CLI-less models or an explicit choice). When API mode is enabled, the CLI is not used.
|
|
147
170
|
|
|
148
171
|
**Gemini auto-resolution (v2.15.1):** leave `GEMINI_USE_API` unset and the mode is chosen for you — API mode when `GEMINI_API_KEY` is present (no `agy` install or OAuth needed; ideal for `npx`), CLI mode (`agy`) otherwise. Set `GEMINI_USE_API` explicitly only to force a mode (an explicit value disables auto-detection).
|
|
149
172
|
|
|
@@ -154,6 +177,7 @@ CODEX_USE_API=false # Use OpenAI API instead of codex CLI
|
|
|
154
177
|
CLAUDE_USE_API=false # Use Anthropic API instead of claude CLI
|
|
155
178
|
MISTRAL_USE_API=false # Use Mistral API instead of vibe CLI
|
|
156
179
|
QWEN3_USE_API=false # Use qwen CLI (default) or DashScope API
|
|
180
|
+
MINIMAX_USE_API=false # Use mmx CLI (default) or MiniMax API
|
|
157
181
|
```
|
|
158
182
|
|
|
159
183
|
### API Keys
|
|
@@ -165,6 +189,7 @@ QWEN3_USE_API=false # Use qwen CLI (default) or DashScope API
|
|
|
165
189
|
| Claude | `ANTHROPIC_API_KEY` | Anthropic API key |
|
|
166
190
|
| Mistral | `MISTRAL_API_KEY` | Mistral API key |
|
|
167
191
|
| Qwen3 | `QWEN3_API_KEY` | DashScope API key |
|
|
192
|
+
| MiniMax | `MINIMAX_API_KEY` | MiniMax API key (API mode only; the mmx CLI uses OAuth) |
|
|
168
193
|
|
|
169
194
|
## Consultant Toggles and Models
|
|
170
195
|
|
|
@@ -175,17 +200,17 @@ ENABLE_CODEX=true
|
|
|
175
200
|
ENABLE_MISTRAL=true
|
|
176
201
|
ENABLE_KILO=true
|
|
177
202
|
ENABLE_CURSOR=true
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
#
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
203
|
+
ENABLE_AMP=true # Amp CLI - The Systems Thinker
|
|
204
|
+
ENABLE_KIMI=true # Kimi CLI - The Eastern Sage
|
|
205
|
+
ENABLE_QWEN3=true # Qwen CLI/API - The Analyst
|
|
206
|
+
ENABLE_MINIMAX=true # MiniMax CLI/API (mmx) - The Pragmatic Optimizer
|
|
207
|
+
ENABLE_CLAUDE=true # Claude CLI - The Synthesizer (auto-excluded under Claude Code)
|
|
208
|
+
|
|
209
|
+
# Off by default
|
|
210
|
+
ENABLE_AIDER=false # Aider CLI - The Pair Programmer
|
|
185
211
|
ENABLE_OLLAMA=false # Ollama - The Local Expert
|
|
186
|
-
ENABLE_MINIMAX=false # MiniMax API - The Pragmatic Optimizer
|
|
187
212
|
|
|
188
|
-
# API-only consultants
|
|
213
|
+
# API-only consultants (off by default - require API keys)
|
|
189
214
|
ENABLE_GLM=false
|
|
190
215
|
ENABLE_GROK=false
|
|
191
216
|
ENABLE_DEEPSEEK=false
|
package/scripts/config.sh
CHANGED
|
@@ -64,9 +64,13 @@ DEFAULT_OUTPUT_DIR_BASE="${DEFAULT_OUTPUT_DIR_BASE:-${_AI_CONSULTANTS_XDG_CACHE}
|
|
|
64
64
|
# =============================================================================
|
|
65
65
|
# For agents that support both CLI and API mode, set USE_API=true to use API mode.
|
|
66
66
|
# When API mode is enabled, CLI mode is automatically disabled (mutual exclusivity).
|
|
67
|
-
#
|
|
67
|
+
# 6 agents support switching: Gemini, Codex, Claude, Mistral, Qwen3, MiniMax
|
|
68
68
|
|
|
69
|
-
# Mode switching (true =
|
|
69
|
+
# Mode switching (true = API, false = CLI). DEFAULT IS CLI — when a consultant
|
|
70
|
+
# has a CLI, the tool uses it; the CLIs are the primary transport (OAuth /
|
|
71
|
+
# subscription, no API key needed). API mode is opt-in only: for CLI-less models
|
|
72
|
+
# (GLM/Grok/DeepSeek are API-only anyway) or an explicit per-run user
|
|
73
|
+
# choice. Set a switch to true (with its API key) to force API for that agent.
|
|
70
74
|
# GEMINI_USE_API is intentionally NOT defaulted here: it is auto-resolved in the
|
|
71
75
|
# Gemini configuration section below (needs GEMINI_API_KEY / GEMINI_CMD), so an
|
|
72
76
|
# explicit unset must remain distinguishable from an explicit "false".
|
|
@@ -74,6 +78,10 @@ CODEX_USE_API="${CODEX_USE_API:-false}"
|
|
|
74
78
|
CLAUDE_USE_API="${CLAUDE_USE_API:-false}"
|
|
75
79
|
MISTRAL_USE_API="${MISTRAL_USE_API:-false}"
|
|
76
80
|
QWEN3_USE_API="${QWEN3_USE_API:-false}" # Default false to use qwen CLI
|
|
81
|
+
# MINIMAX_USE_API is intentionally NOT defaulted here: it is auto-resolved in the
|
|
82
|
+
# MiniMax configuration section below (needs MINIMAX_API_KEY), so an explicit
|
|
83
|
+
# unset stays distinguishable from an explicit "false" (back-compat for pre-v2.21
|
|
84
|
+
# API-only MiniMax users -- see the rationale at the resolve block).
|
|
77
85
|
|
|
78
86
|
# API endpoints for CLI-switchable agents
|
|
79
87
|
GEMINI_API_URL="${GEMINI_API_URL:-https://generativelanguage.googleapis.com/v1beta/models}"
|
|
@@ -215,14 +223,36 @@ DEEPSEEK_FORMAT="${DEEPSEEK_FORMAT:-openai}"
|
|
|
215
223
|
# API key: Set DEEPSEEK_API_KEY environment variable
|
|
216
224
|
|
|
217
225
|
# =============================================================================
|
|
218
|
-
# MINIMAX CONFIGURATION - The Pragmatic Optimizer (API
|
|
226
|
+
# MINIMAX CONFIGURATION - The Pragmatic Optimizer (CLI/API, v2.10; CLI via mmx v2.21)
|
|
219
227
|
# =============================================================================
|
|
220
228
|
|
|
229
|
+
MINIMAX_CMD="${MINIMAX_CMD:-mmx}"
|
|
221
230
|
MINIMAX_MODEL="${MINIMAX_MODEL:-MiniMax-M2.7}"
|
|
222
231
|
MINIMAX_TIMEOUT_SECONDS="${MINIMAX_TIMEOUT:-180}"
|
|
223
232
|
MINIMAX_API_URL="${MINIMAX_API_URL:-https://api.minimax.io/v1/chat/completions}"
|
|
224
233
|
MINIMAX_FORMAT="${MINIMAX_FORMAT:-openai}"
|
|
225
|
-
#
|
|
234
|
+
# CLI mode (default) uses the mmx CLI (npm i -g mmx-cli; auth: mmx auth login).
|
|
235
|
+
# API mode (MINIMAX_USE_API=true) uses MINIMAX_API_KEY against MINIMAX_API_URL.
|
|
236
|
+
#
|
|
237
|
+
# Auto-resolve the MiniMax transport when the user hasn't pinned MINIMAX_USE_API.
|
|
238
|
+
# Unlike Gemini, the mmx CLI IS npm-installable, so CLI is the genuine default
|
|
239
|
+
# (per the CLI-first principle). This block exists purely for BACK-COMPAT: before
|
|
240
|
+
# v2.21 MiniMax was API-only, so a working pre-v2.21 config necessarily had
|
|
241
|
+
# MINIMAX_API_KEY and no mmx. Defaulting such a user to CLI would break MiniMax on
|
|
242
|
+
# upgrade (mmx not found). So when the mode is unset:
|
|
243
|
+
# - MINIMAX_API_KEY present -> API mode (preserves the pre-v2.21 API-only user;
|
|
244
|
+
# a set key is itself the "explicit user choice")
|
|
245
|
+
# - otherwise -> CLI mode (mmx; the new default)
|
|
246
|
+
# An explicit MINIMAX_USE_API=true/false is always honored. Idempotent across
|
|
247
|
+
# re-sourcing via the "${MINIMAX_USE_API+x}" set-vs-unset guard.
|
|
248
|
+
if [[ -z "${MINIMAX_USE_API+x}" ]]; then
|
|
249
|
+
if [[ -n "${MINIMAX_API_KEY:-}" ]]; then
|
|
250
|
+
MINIMAX_USE_API=true
|
|
251
|
+
else
|
|
252
|
+
MINIMAX_USE_API=false
|
|
253
|
+
fi
|
|
254
|
+
fi
|
|
255
|
+
export MINIMAX_USE_API
|
|
226
256
|
|
|
227
257
|
# =============================================================================
|
|
228
258
|
# AMP CONFIGURATION - The Systems Thinker (v2.8)
|
|
@@ -285,7 +315,7 @@ ALL_CONSULTANTS=("Gemini" "Codex" "Mistral" "Kilo" "Cursor" "Aider" "Amp" "Kimi"
|
|
|
285
315
|
CLI_CONSULTANTS=("Gemini" "Codex" "Mistral" "Kilo" "Cursor" "Aider" "Amp" "Kimi" "Claude" "Qwen3" "Ollama")
|
|
286
316
|
|
|
287
317
|
# API-only consultants (use HTTP API directly, no CLI available)
|
|
288
|
-
API_CONSULTANTS=("GLM" "Grok" "DeepSeek"
|
|
318
|
+
API_CONSULTANTS=("GLM" "Grok" "DeepSeek")
|
|
289
319
|
|
|
290
320
|
# =============================================================================
|
|
291
321
|
# ENABLED CONSULTANTS
|
|
@@ -298,17 +328,17 @@ ENABLE_CODEX="${ENABLE_CODEX:-true}"
|
|
|
298
328
|
ENABLE_MISTRAL="${ENABLE_MISTRAL:-true}"
|
|
299
329
|
ENABLE_KILO="${ENABLE_KILO:-true}"
|
|
300
330
|
ENABLE_CURSOR="${ENABLE_CURSOR:-true}"
|
|
301
|
-
|
|
302
|
-
ENABLE_AMP="${ENABLE_AMP:-false}" # Amp Code (v2.8)
|
|
331
|
+
ENABLE_AMP="${ENABLE_AMP:-true}" # Amp Code (v2.8)
|
|
303
332
|
ENABLE_KIMI="${ENABLE_KIMI:-true}" # Kimi Code (v2.9)
|
|
304
|
-
ENABLE_CLAUDE="${ENABLE_CLAUDE:-
|
|
333
|
+
ENABLE_CLAUDE="${ENABLE_CLAUDE:-true}" # Auto-disabled when invoked by Claude Code
|
|
334
|
+
ENABLE_QWEN3="${ENABLE_QWEN3:-true}" # qwen-code CLI (v2.7); API opt-in
|
|
335
|
+
ENABLE_MINIMAX="${ENABLE_MINIMAX:-true}" # mmx CLI (v2.21); API opt-in
|
|
336
|
+
ENABLE_AIDER="${ENABLE_AIDER:-false}" # Aider CLI (off by default)
|
|
305
337
|
|
|
306
|
-
# API-
|
|
307
|
-
ENABLE_QWEN3="${ENABLE_QWEN3:-true}"
|
|
338
|
+
# API-only consultants (disabled by default - require API keys)
|
|
308
339
|
ENABLE_GLM="${ENABLE_GLM:-false}"
|
|
309
340
|
ENABLE_GROK="${ENABLE_GROK:-false}"
|
|
310
341
|
ENABLE_DEEPSEEK="${ENABLE_DEEPSEEK:-false}"
|
|
311
|
-
ENABLE_MINIMAX="${ENABLE_MINIMAX:-false}"
|
|
312
342
|
|
|
313
343
|
# Local model support via Ollama (disabled by default)
|
|
314
344
|
ENABLE_OLLAMA="${ENABLE_OLLAMA:-false}"
|
|
@@ -440,6 +470,13 @@ WARN_AT_COST="${WARN_AT_COST:-0.50}"
|
|
|
440
470
|
# (persistent across reboots; this is user data, not cache).
|
|
441
471
|
COST_TRACKING_FILE="${COST_TRACKING_FILE:-${_AI_CONSULTANTS_XDG_DATA}/costs.json}"
|
|
442
472
|
|
|
473
|
+
# --- Reliability Tracking (foundation for a future self-tuning roster) ---
|
|
474
|
+
# Enable per-consultant success/failure recording (opt-in default: ON)
|
|
475
|
+
ENABLE_RELIABILITY_TRACKING="${ENABLE_RELIABILITY_TRACKING:-true}"
|
|
476
|
+
|
|
477
|
+
# File for cumulative per-consultant reliability tracking (same XDG data dir as costs)
|
|
478
|
+
RELIABILITY_FILE="${RELIABILITY_FILE:-${_AI_CONSULTANTS_XDG_DATA}/reliability.json}"
|
|
479
|
+
|
|
443
480
|
# --- Budget Enforcement (v2.4) ---
|
|
444
481
|
# Enable budget limit enforcement (opt-in, default OFF)
|
|
445
482
|
ENABLE_BUDGET_LIMIT="${ENABLE_BUDGET_LIMIT:-false}"
|
|
@@ -586,6 +623,15 @@ CONVERGENCE_STALL_EPSILON="${CONVERGENCE_STALL_EPSILON:-5}"
|
|
|
586
623
|
# and runs anonymous peer review as a refutation gate before synthesis.
|
|
587
624
|
ENABLE_ADVERSARIAL_VERIFY="${ENABLE_ADVERSARIAL_VERIFY:-true}"
|
|
588
625
|
|
|
626
|
+
# Stance-based semantic consensus (v2.21, opt-in). When true, one LLM call
|
|
627
|
+
# enumerates 2..STANCE_MAX_OPTIONS mutually-exclusive stance options per question
|
|
628
|
+
# and each consultant picks one verbatim, so consensus is an exact-match plurality
|
|
629
|
+
# (robust to paraphrasing) instead of lexical clustering. Adds one serial LLM call
|
|
630
|
+
# per run; degrades gracefully to the cluster consensus if generation fails.
|
|
631
|
+
ENABLE_STANCE_CONSENSUS="${ENABLE_STANCE_CONSENSUS:-false}"
|
|
632
|
+
STANCE_MAX_OPTIONS="${STANCE_MAX_OPTIONS:-5}"
|
|
633
|
+
STANCE_TIMEOUT="${STANCE_TIMEOUT:-60}" # seconds for the stance-generation call (guards a hang)
|
|
634
|
+
|
|
589
635
|
# =============================================================================
|
|
590
636
|
# QUORUM GRADING (v2.19.0)
|
|
591
637
|
# =============================================================================
|
|
@@ -899,4 +945,4 @@ EOF
|
|
|
899
945
|
# VERSION
|
|
900
946
|
# =============================================================================
|
|
901
947
|
|
|
902
|
-
AI_CONSULTANTS_VERSION="2.
|
|
948
|
+
AI_CONSULTANTS_VERSION="2.21.0"
|
package/scripts/consult_all.sh
CHANGED
|
@@ -36,6 +36,7 @@ source "$SCRIPT_DIR/lib/common.sh"
|
|
|
36
36
|
source "$SCRIPT_DIR/lib/session.sh"
|
|
37
37
|
source "$SCRIPT_DIR/lib/progress.sh"
|
|
38
38
|
source "$SCRIPT_DIR/lib/costs.sh"
|
|
39
|
+
source "$SCRIPT_DIR/lib/reliability.sh"
|
|
39
40
|
source "$SCRIPT_DIR/lib/voting.sh"
|
|
40
41
|
source "$SCRIPT_DIR/lib/routing.sh"
|
|
41
42
|
source "$SCRIPT_DIR/lib/cache.sh"
|
|
@@ -298,6 +299,21 @@ chmod 700 "$DEFAULT_OUTPUT_DIR_BASE"
|
|
|
298
299
|
mkdir -p "$OUTPUT_DIR"
|
|
299
300
|
chmod 700 "$OUTPUT_DIR"
|
|
300
301
|
|
|
302
|
+
# --- Stance options (v2.21, opt-in): generate a shared enumerated stance set so
|
|
303
|
+
# every consultant picks the same one -> exact-match consensus. Fully graceful:
|
|
304
|
+
# on any failure STANCE_OPTIONS_PROMPT stays empty and consensus uses the cluster.
|
|
305
|
+
if [[ "${ENABLE_STANCE_CONSENSUS:-false}" == "true" ]]; then
|
|
306
|
+
source "$SCRIPT_DIR/lib/stance.sh"
|
|
307
|
+
STANCE_OPTIONS=$(generate_stance_options "$QUERY" 2>/dev/null || echo "[]")
|
|
308
|
+
echo "$STANCE_OPTIONS" > "$OUTPUT_DIR/stance_options.json" 2>/dev/null || true
|
|
309
|
+
if STANCE_OPTIONS_PROMPT=$(build_stance_prompt "$STANCE_OPTIONS" 2>/dev/null); then
|
|
310
|
+
export STANCE_OPTIONS_PROMPT
|
|
311
|
+
log_info "Stance consensus: $(echo "$STANCE_OPTIONS" | jq -r 'length' 2>/dev/null || echo '?') options generated"
|
|
312
|
+
else
|
|
313
|
+
log_warn "Stance consensus: no usable options — falling back to lexical cluster consensus"
|
|
314
|
+
fi
|
|
315
|
+
fi
|
|
316
|
+
|
|
301
317
|
log_info "Output: $OUTPUT_DIR"
|
|
302
318
|
log_info "Question: ${QUERY:0:80}$([ ${#QUERY} -gt 80 ] && echo '...')"
|
|
303
319
|
if [[ ${#FILES[@]} -gt 0 ]]; then
|
|
@@ -557,9 +573,15 @@ for i in "${!PIDS[@]}"; do
|
|
|
557
573
|
log_success " $name: OK (cached)"
|
|
558
574
|
RESULTS+=("$name:OK")
|
|
559
575
|
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
|
576
|
+
if [[ "${ENABLE_RELIABILITY_TRACKING:-true}" == "true" ]]; then
|
|
577
|
+
record_consultant_outcome "$name" success 2>/dev/null || true
|
|
578
|
+
fi
|
|
560
579
|
else
|
|
561
580
|
log_warn " $name: Cache miss"
|
|
562
581
|
RESULTS+=("$name:EMPTY")
|
|
582
|
+
if [[ "${ENABLE_RELIABILITY_TRACKING:-true}" == "true" ]]; then
|
|
583
|
+
record_consultant_outcome "$name" fail 2>/dev/null || true
|
|
584
|
+
fi
|
|
563
585
|
fi
|
|
564
586
|
continue
|
|
565
587
|
fi
|
|
@@ -570,6 +592,9 @@ for i in "${!PIDS[@]}"; do
|
|
|
570
592
|
RESULTS+=("$name:OK")
|
|
571
593
|
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
|
572
594
|
update_progress "$name" 100 "success"
|
|
595
|
+
if [[ "${ENABLE_RELIABILITY_TRACKING:-true}" == "true" ]]; then
|
|
596
|
+
record_consultant_outcome "$name" success 2>/dev/null || true
|
|
597
|
+
fi
|
|
573
598
|
|
|
574
599
|
# Store in cache (v2.3)
|
|
575
600
|
if is_cache_enabled; then
|
|
@@ -581,12 +606,18 @@ for i in "${!PIDS[@]}"; do
|
|
|
581
606
|
_surface_consultant_error "$name" "$output_file"
|
|
582
607
|
RESULTS+=("$name:EMPTY")
|
|
583
608
|
update_progress "$name" 100 "failed"
|
|
609
|
+
if [[ "${ENABLE_RELIABILITY_TRACKING:-true}" == "true" ]]; then
|
|
610
|
+
record_consultant_outcome "$name" fail 2>/dev/null || true
|
|
611
|
+
fi
|
|
584
612
|
fi
|
|
585
613
|
else
|
|
586
614
|
log_error " $name: Failed"
|
|
587
615
|
_surface_consultant_error "$name" "$output_file"
|
|
588
616
|
RESULTS+=("$name:FAILED")
|
|
589
617
|
update_progress "$name" 100 "failed"
|
|
618
|
+
if [[ "${ENABLE_RELIABILITY_TRACKING:-true}" == "true" ]]; then
|
|
619
|
+
record_consultant_outcome "$name" fail 2>/dev/null || true
|
|
620
|
+
fi
|
|
590
621
|
fi
|
|
591
622
|
done
|
|
592
623
|
|