ai-consultants 5.1.2 → 5.2.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/commands/ai-consultants:consult.md +21 -5
- package/.env.example +81 -43
- package/CLAUDE.md +67 -34
- package/README.md +112 -55
- package/SKILL.md +44 -24
- package/bin/ai-consultants +62 -1
- package/docs/COST_RATES.md +89 -41
- package/docs/JSON_SCHEMA.md +155 -294
- package/docs/RECIPES.md +60 -33
- package/docs/SETUP.md +108 -58
- package/docs/SMART_ROUTING.md +37 -22
- package/docs/cost_rates.json +61 -21
- package/package.json +2 -2
- package/references/configuration.md +114 -42
- package/references/details.md +10 -5
- package/scripts/build_context.sh +30 -5
- package/scripts/classify_question.sh +30 -9
- package/scripts/config.sh +107 -78
- package/scripts/configure.sh +74 -15
- package/scripts/consult_all.sh +409 -61
- package/scripts/doctor.sh +26 -22
- package/scripts/followup.sh +32 -14
- package/scripts/install.sh +12 -0
- package/scripts/lib/agy_exit_guard.sh +80 -0
- package/scripts/lib/api.sh +123 -57
- package/scripts/lib/api_query.sh +47 -21
- package/scripts/lib/cache.sh +34 -5
- package/scripts/lib/common.sh +354 -40
- package/scripts/lib/costs.sh +67 -9
- package/scripts/lib/json_schema_check.jq +65 -0
- package/scripts/lib/personas.sh +39 -18
- package/scripts/lib/response_canonicalize.jq +97 -0
- package/scripts/lib/schema.json +150 -118
- package/scripts/lib/session.sh +28 -8
- package/scripts/lib/synthesis_canonicalize.jq +90 -0
- package/scripts/lib/user_config.sh +22 -7
- package/scripts/query_claude.sh +3 -2
- package/scripts/query_codex.sh +3 -3
- package/scripts/query_gemini.sh +38 -12
- package/scripts/query_glm.sh +1 -1
- package/scripts/query_kimi.sh +21 -7
- package/scripts/query_minimax.sh +15 -11
- package/scripts/query_mistral.sh +6 -3
- package/scripts/query_qwen3.sh +12 -3
- package/scripts/synthesize.sh +101 -15
- package/templates/consultation_report.md +2 -0
- package/templates/synthesis_prompt.md +2 -0
|
@@ -15,7 +15,7 @@ Query multiple AI models for expert opinions on a coding question.
|
|
|
15
15
|
1. If no question provided in $ARGUMENTS, ask the user what they want to consult about.
|
|
16
16
|
|
|
17
17
|
Separate supported consultation options from the question before running the
|
|
18
|
-
panel. In particular, preserve `--preset <name>` and `--strategy <name>` as
|
|
18
|
+
panel. In particular, preserve `--mode <name>`, `--preset <name>` and `--strategy <name>` as
|
|
19
19
|
CLI arguments placed before the question; they are not part of the question
|
|
20
20
|
text. Reject an incomplete option instead of guessing its value.
|
|
21
21
|
|
|
@@ -39,15 +39,30 @@ Query multiple AI models for expert opinions on a coding question.
|
|
|
39
39
|
- Shell-quote every context-file path as one argument.
|
|
40
40
|
- Install a shell trap that removes only the exact query file when the Bash
|
|
41
41
|
invocation exits; question text must not persist in the temp directory.
|
|
42
|
+
Some harnesses (Codex) reject `rm -f`; `unlink "<file>"` removes it too.
|
|
42
43
|
- Capture `caller_root="$PWD"` before changing directories. Pass it through
|
|
43
44
|
`--context-root` so regular files from the user's project are staged under
|
|
44
45
|
a private temp directory without widening the runtime filesystem allowlist.
|
|
45
46
|
|
|
46
47
|
```bash
|
|
47
|
-
caller_root="$PWD"; cd "${AI_CONSULTANTS_DIR:-$HOME/.claude/skills/ai-consultants}" && INVOKING_AGENT=claude ./scripts/consult_all.sh [--preset <name>] [--strategy <name>] --context-root "$caller_root" --query-file "<private-question-file>" "<file1[@TAG]>" "<file2[@TAG]>" ...
|
|
48
|
+
caller_root="$PWD"; cd "${AI_CONSULTANTS_DIR:-$HOME/.claude/skills/ai-consultants}" && INVOKING_AGENT=claude ./scripts/consult_all.sh [--mode <name> | --preset <name>] [--strategy <name>] --context-root "$caller_root" --query-file "<private-question-file>" "<file1[@TAG]>" "<file2[@TAG]>" ...
|
|
48
49
|
```
|
|
49
50
|
- Each `<fileN>` is a file path, optionally suffixed with `@PRIMARY` or `@CONTEXT`.
|
|
50
|
-
- **Capture the last line of stdout** — it contains the output directory path (e.g.,
|
|
51
|
+
- **Capture the last line of stdout** — it contains the output directory path (e.g., `~/.cache/ai-consultants/consultations/20260315_143022_12345`).
|
|
52
|
+
- **No time limit by default.** Reasoning models can take several minutes.
|
|
53
|
+
If your shell tool can run a command in the background and read its output
|
|
54
|
+
while it runs, do so; otherwise use the longest timeout your tool allows.
|
|
55
|
+
- While waiting, the run logs `Output: <output_dir>` near the start and
|
|
56
|
+
`Still waiting after Ns for: <consultants>` every 30 seconds. You decide
|
|
57
|
+
when to stop waiting:
|
|
58
|
+
- `touch "<output_dir>/.proceed"` continues with the answers already
|
|
59
|
+
received: consultants still running are stopped, then synthesis runs.
|
|
60
|
+
Sent during synthesis, it skips the synthesis.
|
|
61
|
+
- `touch "<output_dir>/.abort"` ends the run and keeps the partial output.
|
|
62
|
+
Stopping does not cancel what a provider already generated and billed, so
|
|
63
|
+
keep waiting unless the user wants results now or a consultant looks stuck
|
|
64
|
+
(for example, far slower than the rest of the panel). Never stop the run
|
|
65
|
+
with SIGKILL: it would leave consultant CLIs running. Use `.abort` or SIGTERM.
|
|
51
66
|
- Keep `INVOKING_AGENT=claude` exactly as shown. Never invoke
|
|
52
67
|
`query_claude.sh` directly and never remove self-exclusion to increase the
|
|
53
68
|
panel count.
|
|
@@ -56,7 +71,7 @@ Query multiple AI models for expert opinions on a coding question.
|
|
|
56
71
|
- Read `<output_dir>/report.md` using the **Read** tool
|
|
57
72
|
- Read `<output_dir>/synthesis.json` using the **Read** tool (may not exist if synthesis was skipped or failed)
|
|
58
73
|
- If neither exists, use the **Glob** tool with pattern `<output_dir>/*.json` to discover individual consultant response files, then read each one
|
|
59
|
-
- `claude.json` must not exist and
|
|
74
|
+
- `claude.json` must not exist and the `synthesis_provider` field of `synthesis.json` must not be
|
|
60
75
|
`claude`. If either appears, report a self-exclusion failure instead of
|
|
61
76
|
presenting the run as valid.
|
|
62
77
|
|
|
@@ -89,7 +104,8 @@ Query multiple AI models for expert opinions on a coding question.
|
|
|
89
104
|
```bash
|
|
90
105
|
cd "${AI_CONSULTANTS_DIR:-$HOME/.claude/skills/ai-consultants}" && ./scripts/doctor.sh
|
|
91
106
|
```
|
|
92
|
-
- **
|
|
107
|
+
- **Consultant timeouts** (`Timeout after …s` in the output): a hard limit was set with `<NAME>_TIMEOUT`. Suggest `0` (no limit, the default) or `--mode fast-check` for quicker results
|
|
108
|
+
- **Stopped consultants** (`Stopped by the host`): present the answers received and name the consultants that were stopped before answering
|
|
93
109
|
- **Partial failures** (some consultants responded, others didn't): Present the successful results normally and note which consultants failed at the end
|
|
94
110
|
- **Empty output directory** (no JSON files produced): Suggest running `doctor.sh` to verify CLI installations and API keys
|
|
95
111
|
|
package/.env.example
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# =============================================================================
|
|
2
2
|
# AI Consultants - Environment Variables
|
|
3
3
|
# =============================================================================
|
|
4
|
-
#
|
|
5
|
-
#
|
|
4
|
+
# Template for the private user configuration, normally
|
|
5
|
+
# ~/.config/ai-consultants/.env (created by `ai-consultants init`, or written
|
|
6
|
+
# with detected values by `ai-consultants configure`). Another private
|
|
7
|
+
# directory can be selected with AI_CONSULTANTS_CONFIG_DIR; a project .env is
|
|
8
|
+
# never read automatically. Keep the file at mode 600: it may hold API keys.
|
|
9
|
+
# All variables have sensible defaults - only override what you need, and
|
|
10
|
+
# exported environment variables take precedence over this file.
|
|
6
11
|
#
|
|
7
12
|
# IMPORTANT: At least 2 consultants must be enabled for the system to work.
|
|
8
13
|
#
|
|
9
|
-
# Export variables before running, or source this file:
|
|
10
|
-
# source .env && ./scripts/consult_all.sh "Your question"
|
|
11
|
-
#
|
|
12
14
|
# For detailed setup instructions, see: docs/SETUP.md
|
|
13
15
|
|
|
14
16
|
# =============================================================================
|
|
@@ -18,7 +20,7 @@
|
|
|
18
20
|
# or use the CLI's built-in auth flow.
|
|
19
21
|
|
|
20
22
|
# Google Gemini API key (only needed for API mode; the agy CLI uses OAuth)
|
|
21
|
-
# Get yours at: https://
|
|
23
|
+
# Get yours at: https://aistudio.google.com/apikey
|
|
22
24
|
# CLI mode uses the Antigravity CLI (agy); sign in by running `agy` once.
|
|
23
25
|
# GEMINI_API_KEY=your-google-api-key
|
|
24
26
|
|
|
@@ -77,9 +79,12 @@ ENABLE_GROK=true
|
|
|
77
79
|
ENABLE_MINIMAX=true
|
|
78
80
|
ENABLE_CLAUDE=true
|
|
79
81
|
|
|
80
|
-
# API-only consultants (default: disabled - require API keys)
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
# API-only consultants (default: disabled - require API keys).
|
|
83
|
+
# Left commented on purpose: an explicit "false" is a durable opt-out that
|
|
84
|
+
# presets (including max_quality) will never override, even once a key is
|
|
85
|
+
# added. Uncomment with "true" after setting the key, or run `configure`.
|
|
86
|
+
# ENABLE_GLM=true
|
|
87
|
+
# ENABLE_DEEPSEEK=true
|
|
83
88
|
|
|
84
89
|
# =============================================================================
|
|
85
90
|
# CLI/API MODE SWITCHING (v2.6+)
|
|
@@ -112,29 +117,33 @@ ENABLE_DEEPSEEK=false
|
|
|
112
117
|
# https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions
|
|
113
118
|
|
|
114
119
|
# =============================================================================
|
|
115
|
-
# MODEL CONFIGURATION (
|
|
120
|
+
# MODEL CONFIGURATION (October 2026 premium defaults)
|
|
116
121
|
# =============================================================================
|
|
117
122
|
|
|
118
123
|
# Gemini - The Architect (CLI mode via Antigravity CLI: agy)
|
|
119
|
-
GEMINI_MODEL="Gemini
|
|
120
|
-
GEMINI_TIMEOUT=
|
|
124
|
+
GEMINI_MODEL="Gemini 4 Argon (High)"
|
|
125
|
+
GEMINI_TIMEOUT=0
|
|
121
126
|
GEMINI_CMD=agy
|
|
122
|
-
# API-mode model ID (only used when GEMINI_USE_API=true)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
#
|
|
126
|
-
|
|
127
|
+
# API-mode model ID (only used when GEMINI_USE_API=true). Gemini 4 Argon needs
|
|
128
|
+
# a paid-tier key: Google excludes it from the Free tier and the AI Pro plan.
|
|
129
|
+
GEMINI_API_MODEL=gemini-4-argon
|
|
130
|
+
# Argon's thinking tokens count toward this output budget (API only).
|
|
131
|
+
GEMINI_API_MAX_TOKENS=32768
|
|
132
|
+
# Pin "Gemini 3.8 Flash (High)" or gemini-3.1-pro-preview to keep the previous
|
|
133
|
+
# targets; Gemini 3.1 Pro and 3.6 Flash remain valid CLI pins. gemini-3.8-flash
|
|
134
|
+
# is an API-only opt-in until that transport completes its own authenticated smoke.
|
|
127
135
|
# Reasoning effort for the agy CLI, passed as --effort <value>. Current agy
|
|
128
|
-
# advertises low|medium|high|max globally, but named Gemini 3.8
|
|
129
|
-
# variants reject --effort: leave GEMINI_REASONING_EFFORT unset
|
|
130
|
-
# targets and choose the level with GEMINI_MODEL. Native Gemini
|
|
131
|
-
# API thinking supports low|medium|high through this
|
|
136
|
+
# advertises low|medium|high|max globally, but named Gemini 4 Argon and 3.8
|
|
137
|
+
# High/Medium/Low variants reject --effort: leave GEMINI_REASONING_EFFORT unset
|
|
138
|
+
# for those CLI targets and choose the level with GEMINI_MODEL. Native Gemini
|
|
139
|
+
# 3.7/3.8 Flash and 4 Argon API thinking supports low|medium|high through this
|
|
140
|
+
# setting; Argon defaults to high, matching its CLI target.
|
|
132
141
|
# GEMINI_REASONING_EFFORT=
|
|
133
142
|
|
|
134
143
|
# Codex - The Pragmatist
|
|
135
|
-
CODEX_MODEL=gpt-6-
|
|
144
|
+
CODEX_MODEL=gpt-6.1-sol
|
|
136
145
|
CODEX_API_MAX_TOKENS=16384
|
|
137
|
-
CODEX_TIMEOUT=
|
|
146
|
+
CODEX_TIMEOUT=0
|
|
138
147
|
CODEX_CMD=codex
|
|
139
148
|
# Reasoning effort for the codex CLI (and API mode). Passed as
|
|
140
149
|
# -c model_reasoning_effort=<value>. The provider owns the accepted enum;
|
|
@@ -142,28 +151,29 @@ CODEX_CMD=codex
|
|
|
142
151
|
# CODEX_REASONING_EFFORT=
|
|
143
152
|
|
|
144
153
|
# Mistral Vibe - The Devil's Advocate
|
|
145
|
-
# API model ID. Vibe uses the separate CLI alias
|
|
146
|
-
#
|
|
147
|
-
|
|
154
|
+
# API model ID (MISTRAL_USE_API=true only). Vibe uses the separate CLI alias
|
|
155
|
+
# below. Mistral Large 4 is a public preview and is absent from GET /v1/models
|
|
156
|
+
# even when the key can call it. Pin mistral-large-3 to keep the previous target.
|
|
157
|
+
MISTRAL_MODEL=mistral-large-4
|
|
148
158
|
MISTRAL_CLI_MODEL=mistral-medium-3.5
|
|
149
|
-
MISTRAL_API_MAX_TOKENS=
|
|
159
|
+
MISTRAL_API_MAX_TOKENS=16384
|
|
150
160
|
# Official API opt-ins: use mistral-medium-3-5, mistral-large-2512, or
|
|
151
161
|
# mistral-small-2603 for MISTRAL_MODEL after an authenticated API smoke.
|
|
152
|
-
MISTRAL_TIMEOUT=
|
|
162
|
+
MISTRAL_TIMEOUT=0
|
|
153
163
|
MISTRAL_CMD=vibe
|
|
154
164
|
MISTRAL_MAX_TURNS=4
|
|
155
165
|
|
|
156
166
|
# Kimi - The Eastern Sage (K3 via Kimi Code CLI)
|
|
157
167
|
KIMI_MODEL=kimi-code/k3
|
|
158
168
|
# max_quality selects the inventory-probed kimi-code/k3-256k target.
|
|
159
|
-
KIMI_TIMEOUT=
|
|
169
|
+
KIMI_TIMEOUT=0
|
|
160
170
|
KIMI_CMD=kimi
|
|
161
171
|
|
|
162
172
|
# Claude - The Synthesizer
|
|
163
173
|
CLAUDE_MODEL=claude-fable-5-1 # ai-consultants:default
|
|
164
174
|
# For the lower-cost standard/medium Claude tier, set CLAUDE_MODEL to
|
|
165
175
|
# claude-opus-5-5 (or apply_model_tier standard for a single run).
|
|
166
|
-
CLAUDE_TIMEOUT=
|
|
176
|
+
CLAUDE_TIMEOUT=0
|
|
167
177
|
CLAUDE_CMD=claude
|
|
168
178
|
CLAUDE_API_MAX_TOKENS=16384
|
|
169
179
|
# Reasoning effort for the claude CLI (and API mode). Passed as --effort <value>.
|
|
@@ -172,14 +182,14 @@ CLAUDE_API_MAX_TOKENS=16384
|
|
|
172
182
|
# CLAUDE_REASONING_EFFORT=
|
|
173
183
|
|
|
174
184
|
# Qwen3 - The Analyst (CLI/API switchable v2.7)
|
|
175
|
-
QWEN3_MODEL=qwen3.
|
|
176
|
-
QWEN3_TIMEOUT=
|
|
177
|
-
QWEN3_MAX_QUALITY_TIMEOUT=
|
|
185
|
+
QWEN3_MODEL=qwen3.8-max
|
|
186
|
+
QWEN3_TIMEOUT=0
|
|
187
|
+
QWEN3_MAX_QUALITY_TIMEOUT=0
|
|
178
188
|
QWEN3_API_MAX_TOKENS=16384
|
|
179
189
|
QWEN3_CMD=qwen
|
|
180
190
|
# Reasoning effort. API mode ONLY - the qwen CLI has no effort flag, so in CLI
|
|
181
|
-
# mode this is ignored (with a warning);
|
|
182
|
-
# ~/.qwen/settings.json instead. Accepted: none|minimal|low|medium|high|xhigh|max
|
|
191
|
+
# mode this is ignored (with a warning); configure the effort in
|
|
192
|
+
# ~/.qwen/settings.json instead (see docs/RECIPES.md). Accepted: none|minimal|low|medium|high|xhigh|max
|
|
183
193
|
# (the provider's own enum). The valid subset depends on the model:
|
|
184
194
|
# qwen3.8-max takes all of them EXCEPT 'none' - thinking cannot be
|
|
185
195
|
# disabled on it - and defaults to xhigh. An unsupported combination is
|
|
@@ -201,7 +211,7 @@ QWEN3_CMD=qwen
|
|
|
201
211
|
|
|
202
212
|
# GLM - The Methodologist
|
|
203
213
|
GLM_MODEL=glm-5.3-flash
|
|
204
|
-
GLM_TIMEOUT=
|
|
214
|
+
GLM_TIMEOUT=0
|
|
205
215
|
GLM_API_MAX_TOKENS=16384
|
|
206
216
|
GLM_API_URL=https://api.z.ai/api/coding/paas/v4/chat/completions
|
|
207
217
|
# GLM_REASONING_EFFORT= # max_quality sets max
|
|
@@ -209,7 +219,7 @@ GLM_API_URL=https://api.z.ai/api/coding/paas/v4/chat/completions
|
|
|
209
219
|
# Grok Build CLI + xAI API fallback - The Provocateur
|
|
210
220
|
GROK_CMD=grok
|
|
211
221
|
GROK_MODEL=grok-4.7
|
|
212
|
-
GROK_TIMEOUT=
|
|
222
|
+
GROK_TIMEOUT=0
|
|
213
223
|
GROK_MAX_TURNS=4
|
|
214
224
|
GROK_OAUTH_MODE=shared
|
|
215
225
|
GROK_API_MAX_TOKENS=4096
|
|
@@ -218,8 +228,8 @@ GROK_API_URL=https://api.x.ai/v1/chat/completions
|
|
|
218
228
|
|
|
219
229
|
# DeepSeek - The Code Specialist
|
|
220
230
|
DEEPSEEK_MODEL=deepseek-flash
|
|
221
|
-
DEEPSEEK_TIMEOUT=
|
|
222
|
-
DEEPSEEK_MAX_QUALITY_TIMEOUT=
|
|
231
|
+
DEEPSEEK_TIMEOUT=0
|
|
232
|
+
DEEPSEEK_MAX_QUALITY_TIMEOUT=0
|
|
223
233
|
DEEPSEEK_API_MAX_TOKENS=16384
|
|
224
234
|
DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions
|
|
225
235
|
# DEEPSEEK_REASONING_EFFORT= # max_quality sets max
|
|
@@ -228,7 +238,7 @@ DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions
|
|
|
228
238
|
MINIMAX_CMD=mmx
|
|
229
239
|
MINIMAX_MODEL=MiniMax-M2.7
|
|
230
240
|
# max_quality selects the smoke-tested MiniMax-M3 target.
|
|
231
|
-
MINIMAX_TIMEOUT=
|
|
241
|
+
MINIMAX_TIMEOUT=0
|
|
232
242
|
MINIMAX_API_MAX_TOKENS=4096
|
|
233
243
|
MINIMAX_MAX_TOKENS=4096
|
|
234
244
|
MINIMAX_MAX_QUALITY_TOKENS=16384
|
|
@@ -269,8 +279,8 @@ SYNTHESIS_MODEL=
|
|
|
269
279
|
SYNTHESIS_EXTRACT_FIELDS=true
|
|
270
280
|
SYNTH_MAX=10
|
|
271
281
|
SYNTH_DETAIL_MAX_CHARS=4000
|
|
272
|
-
SYNTHESIS_TIMEOUT=
|
|
273
|
-
SYNTHESIS_TOTAL_TIMEOUT=
|
|
282
|
+
SYNTHESIS_TIMEOUT=0
|
|
283
|
+
SYNTHESIS_TOTAL_TIMEOUT=0
|
|
274
284
|
|
|
275
285
|
# Health gate and quorum: validate the live panel before spending on a full run
|
|
276
286
|
ENABLE_HEALTH_GATE=false # Adds one small ping per selected consultant
|
|
@@ -291,7 +301,8 @@ API_BASE_BACKOFF=2
|
|
|
291
301
|
API_MAX_BACKOFF=60
|
|
292
302
|
API_RATE_LIMIT=30
|
|
293
303
|
|
|
294
|
-
#
|
|
304
|
+
# Deprecated no-op, kept for configuration compatibility: no adapter applies
|
|
305
|
+
# these per-category limits. Use the *_API_MAX_TOKENS settings instead.
|
|
295
306
|
ENABLE_RESPONSE_LIMITS=false
|
|
296
307
|
MAX_RESPONSE_TOKENS_BY_CATEGORY=QUICK_SYNTAX:200,CODE_REVIEW:800,BUG_DEBUG:800,ARCHITECTURE:1000,SECURITY:1000,DATABASE:600,GENERAL:500
|
|
297
308
|
|
|
@@ -310,6 +321,9 @@ MAX_SESSION_COST=1.00
|
|
|
310
321
|
# Question classification (required for smart routing)
|
|
311
322
|
ENABLE_CLASSIFICATION=true
|
|
312
323
|
CLASSIFICATION_MODE=pattern # pattern (fast) or llm (accurate)
|
|
324
|
+
# llm mode asks the Claude CLI (economy model, stateless, tool-free) and is
|
|
325
|
+
# skipped when Claude is the invoking host. Bounded by this timeout (seconds).
|
|
326
|
+
# CLASSIFICATION_TIMEOUT=30
|
|
313
327
|
|
|
314
328
|
# Smart routing: select consultants based on question category
|
|
315
329
|
ENABLE_SMART_ROUTING=false
|
|
@@ -359,6 +373,30 @@ MAX_RETRIES=2 # Max retry attempts on failure
|
|
|
359
373
|
RETRY_DELAY_SECONDS=5 # Pause between retries
|
|
360
374
|
LAUNCH_STAGGER_MAX_SECONDS=2
|
|
361
375
|
|
|
376
|
+
# Every *_TIMEOUT for consultants and synthesis defaults to 0: no time limit.
|
|
377
|
+
# A timed-out call is usually still billed while its answer is lost, so the
|
|
378
|
+
# invoking host decides when to stop waiting. While consult_all.sh waits it
|
|
379
|
+
# logs progress every WAIT_HEARTBEAT_SECONDS (0 = silent) and accepts:
|
|
380
|
+
# touch <output dir>/.proceed continue with the answers received
|
|
381
|
+
# (also: kill -USR1 <pid>, or a first Ctrl-C)
|
|
382
|
+
# touch <output dir>/.abort end the run (also: SIGTERM, or a second Ctrl-C)
|
|
383
|
+
# A positive *_TIMEOUT restores a hard limit for that consultant.
|
|
384
|
+
WAIT_HEARTBEAT_SECONDS=30
|
|
385
|
+
# agy can print its whole answer and then never exit. When its output is one
|
|
386
|
+
# complete JSON object unchanged for this many seconds, the run ends agy and
|
|
387
|
+
# keeps the answer (0 = always wait for agy to exit).
|
|
388
|
+
AGY_EXIT_GRACE_SECONDS=60
|
|
389
|
+
|
|
390
|
+
# Agentic consultant CLIs (agy, qwen, kimi) run from a private empty working
|
|
391
|
+
# directory so they cannot load project instructions or read files beyond the
|
|
392
|
+
# built context. Set to false to run them from the current directory.
|
|
393
|
+
# CLI_WORKSPACE_ISOLATION=true
|
|
394
|
+
|
|
395
|
+
# agy, vibe and kimi accept the prompt only as a command-line argument, which
|
|
396
|
+
# is visible in the process list and size-limited (128 KiB per argument on
|
|
397
|
+
# Linux). Larger prompts fail before dispatch; override the computed limit here.
|
|
398
|
+
# ARGV_PROMPT_MAX_BYTES=
|
|
399
|
+
|
|
362
400
|
# Output directory base
|
|
363
401
|
# DEFAULT_OUTPUT_DIR_BASE=/custom/cache/consultations
|
|
364
402
|
|
package/CLAUDE.md
CHANGED
|
@@ -6,7 +6,7 @@ AI Consultants is a multi-model coverage system that queries up to 10 AI consult
|
|
|
6
6
|
|
|
7
7
|
**Self-Exclusion**: The invoking agent is automatically excluded from both the panel and synthesis. Claude Code won't query or synthesize with Claude, Codex CLI won't query or synthesize with Codex, etc.
|
|
8
8
|
|
|
9
|
-
**Version**: 5.
|
|
9
|
+
**Version**: 5.2.0
|
|
10
10
|
|
|
11
11
|
## Distribution
|
|
12
12
|
|
|
@@ -33,7 +33,6 @@ ai-consultants/
|
|
|
33
33
|
├── bin/
|
|
34
34
|
│ └── ai-consultants # npm/npx entry point (bash wrapper)
|
|
35
35
|
├── package.json # npm distribution metadata (zero dependencies)
|
|
36
|
-
├── .npmignore # Excludes dev artifacts from npm package
|
|
37
36
|
├── scripts/
|
|
38
37
|
│ ├── consult_all.sh # Main orchestrator - entry point
|
|
39
38
|
│ ├── config.sh # Centralized configuration
|
|
@@ -52,9 +51,13 @@ ai-consultants/
|
|
|
52
51
|
│ ├── schema.json # JSON output schema
|
|
53
52
|
│ ├── routing.sh # Smart routing (category affinity) + cost-aware routing
|
|
54
53
|
│ ├── session.sh # Session management
|
|
55
|
-
│ ├── costs.sh # Cost tracking +
|
|
54
|
+
│ ├── costs.sh # Cost tracking + budget enforcement
|
|
56
55
|
│ ├── cache.sh # Semantic caching (v2.3)
|
|
57
56
|
│ ├── api_query.sh # API mode query execution (v2.6)
|
|
57
|
+
│ ├── response_canonicalize.jq # Consultant answer repairs before validation
|
|
58
|
+
│ ├── synthesis_canonicalize.jq # synthesis.json contract
|
|
59
|
+
│ ├── json_schema_check.jq # jq-only schema validator used by tests
|
|
60
|
+
│ ├── agy_exit_guard.sh # Keeps a complete agy answer when agy never exits
|
|
58
61
|
│ └── progress.sh # Progress bars
|
|
59
62
|
├── references/
|
|
60
63
|
│ ├── configuration.md # Full configuration reference
|
|
@@ -67,7 +70,7 @@ ai-consultants/
|
|
|
67
70
|
│ ├── SMART_ROUTING.md # Affinity matrix
|
|
68
71
|
│ └── JSON_SCHEMA.md # Output schema
|
|
69
72
|
└── templates/
|
|
70
|
-
└── synthesis_prompt.md #
|
|
73
|
+
└── synthesis_prompt.md # Reference copy only; the runtime prompt is inline in synthesize.sh
|
|
71
74
|
```
|
|
72
75
|
|
|
73
76
|
## Claude Skills Compliance
|
|
@@ -235,9 +238,9 @@ curl -L code.kimi.com/install.sh | bash
|
|
|
235
238
|
```
|
|
236
239
|
|
|
237
240
|
**Environment Variables:**
|
|
238
|
-
- `ENABLE_KIMI` - Enable Kimi consultant (default:
|
|
241
|
+
- `ENABLE_KIMI` - Enable Kimi consultant (default: true)
|
|
239
242
|
- `KIMI_CMD` - CLI command (default: kimi)
|
|
240
|
-
- `KIMI_TIMEOUT` - Timeout in seconds (default:
|
|
243
|
+
- `KIMI_TIMEOUT` - Timeout in seconds (default: 0, no limit)
|
|
241
244
|
- `KIMI_MODEL` - Kimi CLI model alias (default: kimi-code/k3; passed explicitly with `--model`)
|
|
242
245
|
|
|
243
246
|
**Persona:** The Eastern Sage - Focuses on holistic understanding, balance of perspectives, and wisdom from diverse viewpoints.
|
|
@@ -349,8 +352,8 @@ Three normal tiers plus a `maximum` tier are configurable via `apply_model_tier(
|
|
|
349
352
|
|
|
350
353
|
| Tier | Description | Example Models |
|
|
351
354
|
|------|-------------|----------------|
|
|
352
|
-
| **premium** | Latest flagship models | claude-fable-5-1, Gemini
|
|
353
|
-
| **maximum** | All 10 consultants; maximum targets and highest provider effort | claude-fable-5-1, K3-256k, Qwen3.8-Max, MiniMax M3; Grok xhigh, GLM/DeepSeek max |
|
|
355
|
+
| **premium** | Latest flagship models | claude-fable-5-1, Gemini 4 Argon (High), gpt-6.1-sol |
|
|
356
|
+
| **maximum** | All 10 consultants; maximum targets and highest provider effort | claude-fable-5-1, Gemini 4 Argon (High), K3-256k, Qwen3.8-Max, MiniMax M3; Grok xhigh, GLM/DeepSeek max |
|
|
354
357
|
| **standard** | Good quality at reasonable cost | claude-opus-5-5, Gemini 3.8 Flash (High), gpt-5.6-terra |
|
|
355
358
|
| **economy** | Optimized for speed and low cost | claude-haiku-4-5, Gemini 3.8 Flash (Low), gpt-5.6-luna |
|
|
356
359
|
|
|
@@ -365,7 +368,7 @@ apply_model_tier "standard" # Set all consultants to standard models
|
|
|
365
368
|
apply_model_tier "economy" # Set all consultants to economy models
|
|
366
369
|
|
|
367
370
|
# Get model for a specific consultant and tier (v2.8.1)
|
|
368
|
-
get_model_for_tier "gemini" "premium" # → Gemini
|
|
371
|
+
get_model_for_tier "gemini" "premium" # → Gemini 4 Argon (High) on agy
|
|
369
372
|
get_model_for_tier "claude" "economy" # → claude-haiku-4-5
|
|
370
373
|
```
|
|
371
374
|
|
|
@@ -389,13 +392,13 @@ All consultants now use premium models by default:
|
|
|
389
392
|
| Consultant | Default Model |
|
|
390
393
|
|------------|---------------|
|
|
391
394
|
| Claude | claude-fable-5-1 |
|
|
392
|
-
| Gemini | Gemini
|
|
393
|
-
| Codex | gpt-6-astra |
|
|
394
|
-
| Mistral | CLI: mistral-medium-3.5; API: mistral-large-
|
|
395
|
+
| Gemini | Gemini 4 Argon (High) (via agy CLI); API: gemini-4-argon |
|
|
396
|
+
| Codex | gpt-6.1-sol (max_quality: gpt-6-astra) |
|
|
397
|
+
| Mistral | CLI: mistral-medium-3.5; API: mistral-large-4 (preview) |
|
|
395
398
|
| DeepSeek | deepseek-flash (DeepSeek-V4.1-Flash) |
|
|
396
399
|
| GLM | glm-5.3-flash |
|
|
397
400
|
| Grok | grok-4.7 |
|
|
398
|
-
| Qwen3 | qwen3.
|
|
401
|
+
| Qwen3 | qwen3.8-max (standard/economy: qwen3.8-flash) |
|
|
399
402
|
| Kimi | kimi-code/k3 |
|
|
400
403
|
| MiniMax | MiniMax-M2.7 |
|
|
401
404
|
|
|
@@ -412,10 +415,10 @@ is surfaced and never silently rerouted to the API.
|
|
|
412
415
|
|
|
413
416
|
The live full-panel smoke defines the `max_quality` runtime envelope, not just
|
|
414
417
|
the model names. Mistral and Grok receive four bounded advisory turns plus an
|
|
415
|
-
explicit no-tools/workspace instruction. Qwen3.8-Max
|
|
416
|
-
|
|
417
|
-
GLM gets 16,384; MiniMax M3 gets 16,384
|
|
418
|
-
mmx's native system channel. OpenAI-compatible
|
|
418
|
+
explicit no-tools/workspace instruction. Qwen3.8-Max and DeepSeek get
|
|
419
|
+
`QWEN3_MAX_QUALITY_TIMEOUT`/`DEEPSEEK_MAX_QUALITY_TIMEOUT` (default 0, no limit);
|
|
420
|
+
DeepSeek gets 16,384 completion tokens; GLM gets 16,384; MiniMax M3 gets 16,384
|
|
421
|
+
plus the shared JSON response contract in mmx's native system channel. OpenAI-compatible
|
|
419
422
|
`finish_reason=length` is an error. Every
|
|
420
423
|
response records `metadata.response_quality=structured|fallback|error`:
|
|
421
424
|
malformed JSON-looking output fails closed, while real markdown/prose is kept
|
|
@@ -463,18 +466,20 @@ Reduces redundant API calls by caching responses based on query + context finger
|
|
|
463
466
|
# Configuration in config.sh
|
|
464
467
|
ENABLE_SEMANTIC_CACHE=true # Enable caching (default: true)
|
|
465
468
|
CACHE_TTL_HOURS=24 # Cache expiration
|
|
466
|
-
CACHE_DIR
|
|
469
|
+
CACHE_DIR=~/.cache/ai-consultants/cache # XDG default
|
|
467
470
|
```
|
|
468
471
|
|
|
469
472
|
Functions in `lib/cache.sh`:
|
|
470
|
-
- `generate_fingerprint()` - Creates hash from query + category + context
|
|
473
|
+
- `generate_fingerprint()` - Creates hash from query + category + context + consultant identity (`cache_identity()`: model, transport, effort, persona)
|
|
471
474
|
- `check_cache()` - Returns cached response if valid
|
|
472
475
|
- `store_cache()` - Stores response with metadata
|
|
473
476
|
- `cleanup_cache()` - Removes expired entries
|
|
474
477
|
- `get_cache_stats()` - Returns cache statistics as JSON
|
|
475
478
|
|
|
476
|
-
### Response Length Limits (
|
|
477
|
-
|
|
479
|
+
### Response Length Limits (deprecated no-op)
|
|
480
|
+
**Never applied by any adapter** (most consultant CLIs expose no output cap);
|
|
481
|
+
the settings are accepted for configuration compatibility only. Use the
|
|
482
|
+
`*_API_MAX_TOKENS` settings to bound API responses.
|
|
478
483
|
|
|
479
484
|
```bash
|
|
480
485
|
ENABLE_RESPONSE_LIMITS=false # Default: false (opt-in per quality review)
|
|
@@ -496,7 +501,7 @@ COMPLEXITY_THRESHOLD_MEDIUM=6 # Score 4-6 = medium, 7-10 = complex
|
|
|
496
501
|
```
|
|
497
502
|
|
|
498
503
|
Functions in `lib/routing.sh`:
|
|
499
|
-
- `select_consultants_cost_aware()` - Selects consultants based on complexity
|
|
504
|
+
- `select_consultants_cost_aware()` - Selects consultants based on complexity (used by the smart-routing path)
|
|
500
505
|
- `get_cost_aware_model()` - Returns economic model for simple queries
|
|
501
506
|
- `calculate_query_complexity()` - Scores query 1-10
|
|
502
507
|
|
|
@@ -505,7 +510,12 @@ Functions in `lib/costs.sh`:
|
|
|
505
510
|
- `get_model_tier()` - Returns economy/standard/premium
|
|
506
511
|
|
|
507
512
|
### Fallback Escalation
|
|
508
|
-
|
|
513
|
+
Active only with `ENABLE_COST_AWARE_ROUTING=true`. Re-queries a **structured**
|
|
514
|
+
response whose confidence is below the threshold on the consultant's premium
|
|
515
|
+
model for its active transport (`model_env_var_for`). Error and fallback
|
|
516
|
+
envelopes are never escalated, the same model is never re-asked, a
|
|
517
|
+
maximum-tier target is never "escalated" to premium, and each re-query passes
|
|
518
|
+
`enforce_budget` first.
|
|
509
519
|
|
|
510
520
|
```bash
|
|
511
521
|
FALLBACK_CONFIDENCE_THRESHOLD=7 # Escalate if confidence < 7
|
|
@@ -586,17 +596,18 @@ for f in scripts/*.sh scripts/lib/*.sh; do bash -n "$f" && echo "OK: $f"; done
|
|
|
586
596
|
| `ENABLE_SMART_ROUTING` | false | Intelligent routing by category |
|
|
587
597
|
| `ENABLE_COST_TRACKING` | true | Track costs |
|
|
588
598
|
| `MAX_SESSION_COST` | 1.00 | Max budget ($) |
|
|
589
|
-
| `CLAUDE_MODEL` | claude-fable-5-1 | Claude model (use claude-opus-5 for lower-cost standard) |
|
|
599
|
+
| `CLAUDE_MODEL` | claude-fable-5-1 | Claude model (use claude-opus-5-5 for lower-cost standard) |
|
|
590
600
|
| `CLAUDE_API_MAX_TOKENS` | 16384 | Claude API thinking + visible-output budget |
|
|
591
|
-
| `GEMINI_MODEL` | Gemini
|
|
592
|
-
| `GEMINI_API_MODEL` | gemini-
|
|
593
|
-
| `
|
|
594
|
-
| `
|
|
601
|
+
| `GEMINI_MODEL` | Gemini 4 Argon (High) | Gemini agy CLI model |
|
|
602
|
+
| `GEMINI_API_MODEL` | gemini-4-argon | Gemini API-mode model ID (v2.15) |
|
|
603
|
+
| `GEMINI_API_MAX_TOKENS` | 32768 | Gemini API thinking + visible-output budget |
|
|
604
|
+
| `CODEX_MODEL` | gpt-6.1-sol | Codex model (max_quality: gpt-6-astra) |
|
|
605
|
+
| `MISTRAL_MODEL` | mistral-large-4 | Mistral API model (Vibe uses `MISTRAL_CLI_MODEL`) |
|
|
595
606
|
| `MISTRAL_CLI_MODEL` | mistral-medium-3.5 | Vibe CLI model alias |
|
|
596
607
|
| `SYNTHESIS_STRATEGY` | coverage | Synthesis strategy (coverage=union of distinct points) |
|
|
597
608
|
| `ENABLE_SEMANTIC_CACHE` | true | Semantic response caching (v2.3) |
|
|
598
609
|
| `CACHE_TTL_HOURS` | 24 | Cache expiration in hours (v2.3) |
|
|
599
|
-
| `ENABLE_RESPONSE_LIMITS` | false |
|
|
610
|
+
| `ENABLE_RESPONSE_LIMITS` | false | Deprecated no-op (never applied) |
|
|
600
611
|
| `ENABLE_COST_AWARE_ROUTING` | false | Cost-based model routing (v2.3) |
|
|
601
612
|
| `ENABLE_COMPACT_REPORT` | true | Compact report format (v2.3) |
|
|
602
613
|
| `ENABLE_BUDGET_LIMIT` | false | Budget enforcement (v2.4, opt-in) |
|
|
@@ -629,17 +640,18 @@ The system handles errors with:
|
|
|
629
640
|
|
|
630
641
|
- **Automatic retry**: `MAX_RETRIES` attempts (default: 2)
|
|
631
642
|
- **Delay between retries**: `RETRY_DELAY_SECONDS` (default: 5s)
|
|
632
|
-
- **Cross-platform timeout
|
|
633
|
-
- **Exit codes**: 0 = success, 1 = error, 124 = timeout
|
|
643
|
+
- **Cross-platform timeout** (only when a positive `*_TIMEOUT` is set): Linux (`timeout`), macOS (`gtimeout`), and POSIX fallback
|
|
644
|
+
- **Exit codes**: 0 = success, 1 = error, 124 = timeout; a host abort exits 130 (`.abort`, second Ctrl-C), 143 (SIGTERM) or 129 (SIGHUP)
|
|
634
645
|
|
|
635
646
|
```bash
|
|
636
647
|
# Retry configuration
|
|
637
648
|
MAX_RETRIES=3
|
|
638
649
|
RETRY_DELAY_SECONDS=10
|
|
639
650
|
|
|
640
|
-
# Per-consultant timeout
|
|
641
|
-
|
|
642
|
-
|
|
651
|
+
# Per-consultant timeout: 0 (default) = no limit; the invoking host decides
|
|
652
|
+
# when to stop waiting (touch <output dir>/.proceed or .abort)
|
|
653
|
+
GEMINI_TIMEOUT=0
|
|
654
|
+
CODEX_TIMEOUT=0
|
|
643
655
|
```
|
|
644
656
|
|
|
645
657
|
## Extended Documentation
|
|
@@ -760,6 +772,27 @@ curl -fsSL https://raw.githubusercontent.com/matteoscurati/ai-consultants/main/s
|
|
|
760
772
|
|
|
761
773
|
## Changelog
|
|
762
774
|
|
|
775
|
+
### v5.2.0 (2026-10-19)
|
|
776
|
+
|
|
777
|
+
- **Host context described the wrong project.** Hosts `cd` into the skill root, and `build_context.sh` reported `pwd`/`find .` from there. `consult_all.sh` now runs it from `--context-root` (staged files are absolute temp paths, still admitted by `_is_temp_path`).
|
|
778
|
+
- **API-only consultants never received the response contract.** `run_api_consultant` (GLM, DeepSeek, MiniMax API, custom agents) skipped `build_query_with_persona`, so every answer was prose -> fallback -> never attributable coverage, and `max_quality` could not reach `coverage_integrity=MET`. MiniMax CLI now gets the contract through `--system`. The live GLM smoke then exposed a nested/one-brace-short `confidence`; `normalize_consultant_response_text` lifts/repairs only that exact shape. Rejected payloads keep `metadata.raw_excerpt` so the next failure is diagnosable without a billed re-run.
|
|
779
|
+
- **Cache key ignored the model.** `cache_identity()` (model/API/CLI model, transport, effort, format, URL, budgets, persona) is part of every fingerprint; `CACHE_KEY_VERSION` invalidates old entries once.
|
|
780
|
+
- **Synthesis extraction** used a sed line range that ends at the first `}` line; now `strip_json_fence` then first-`{`..last-`}`. The synthesis call is estimated into `synthesis.json.synthesis_metadata` and billed by `calculate_session_cost` (`_synthesis_estimated_cost`).
|
|
781
|
+
- **Follow-up** history stores the full query, `get_session_by_id` returns the current-session shape, whole-panel follow-ups run with `AI_CONSULTANTS_SKIP_SESSION_SAVE=true` inside the follow-up directory and are recorded on the original session.
|
|
782
|
+
- **Transport privacy/limits.** Questions reach classify/build_context/synthesize via stdin (`-`); the request builders (`lib/api.sh`, `query_minimax.sh`) read the prompt with `jq --rawfile prompt /dev/stdin`, and curl gets headers and body through process substitution (`-H @<(...)`, `--data-binary @<(...)`), so neither the key nor the prompt is in argv or in a temp file a stopped query would leave behind. Process substitution does not survive the POSIX `run_with_timeout` fallback (the background job loses `/dev/fd/63`), so `doctor` bounds its probe with curl's own `-m`. `guard_argv_prompt_size` fails fast for argv-only CLIs (agy/vibe/kimi) and synthesis skips agy above the limit; agy/qwen/kimi run from `make_cli_workspace` directories. The POSIX timeout fallback never reads a TTY.
|
|
783
|
+
- **Test gate hermeticity** now lives in `test_all.sh` (empty `AI_CONSULTANTS_CONFIG_DIR`, documented keys and `_AI_CONSULTANTS_*` markers unset), fixing the root cause of the release-gate leaks recorded in v2.23.0/v2.25.1/v3.0.0. `npm run lint` is the single lint invocation for CI and publish.
|
|
784
|
+
- **JSON contracts.** `lib/response_canonicalize.jq` (consultant answers) and `lib/synthesis_canonicalize.jq` (synthesis.json) apply only deterministic, content-preserving repairs; `summary` is never derived from `detailed` (detailed text is deliberately not atomized) and a string `response` stays fallback prose. `lib/schema.json` v3 describes the real envelopes plus `synthesis_artifact`; `lib/json_schema_check.jq` + `assert_schema_valid` make it executable in tests. Estimates use `model_env_var_for` (tier + transport).
|
|
785
|
+
- **Codex model policy.** `gpt-6.1-sol` is the default/premium Codex target and `gpt-6-astra` stays the maximum target (`get_model_for_tier`, `docs/cost_rates.json` premium tier and fallback). `_codex_frontier_model` in `lib/api.sh` gives both the implicit `high` effort and the none/minimal rejection (provider docs: low|medium|high|xhigh|max, default medium). `configure` migrates unpinned `gpt-6-astra` too and keeps the earliest `migrated-from`. One authorized CLI smoke passed (structured, measured usage, requested-only identity).
|
|
786
|
+
- **Qwen/GLM policy.** `qwen3.8-max` is default/premium/maximum on all Qwen transports (the Token Plan-only gate in `apply_model_tier` is gone; `xhigh` is set only on the OpenAI-compatible wire, `QWEN3_MAX_QUALITY_TIMEOUT` everywhere, default 0); `qwen3.8-flash` serves standard/economy. GLM maximum is `glm-5.3`. Live checks passed for all four. 401/403 failures now carry the provider reason (`provider_error_summary`): a renewed Token Plan issues a new plan key, and DashScope without purchase returns `AccessDenied.Unpurchased`.
|
|
787
|
+
- **Mistral API policy.** `mistral-large-4` (public preview, 2026-10-06) is `MISTRAL_MODEL` and every API tier; `configure` migrates unpinned `mistral-large-3`. Rates use the list price ($1.36/$4.18 per 1M), not the 50% preview price, so budgets fail safe. Evidence: one authorized 1-token chat call (2026-10-15) returned HTTP 200, provider-reported model `mistral-large-4`, `service_tier: standard`. `GET /v1/models` omits the preview (and every Large model) for that key, so listing is not an access check. A first `query_mistral.sh` smoke (same day, HTTP 200, 244 in / 3833 out tokens, ~44 s) failed closed because `message.content` was a chunk array (`thinking` + `text`); `parse_openai_response` now joins only `text` chunks (test in `test_api_transport.sh`). `MISTRAL_API_MAX_TOKENS` default 4096 -> 16384: that smoke spent 3833 of 4096 tokens, mostly thinking. A second authorized smoke after both fixes passed: `response_quality=structured`, provider-reported `mistral-large-4`, Devil's Advocate persona, confidence 9, 244 in / 3296 out measured tokens, ~44 s, schema-valid envelope. Vibe economy moved from the retired `devstral-small-2` to `mistral-medium-3.5`. Vibe stays on `mistral-medium-3.5`.
|
|
788
|
+
- **Gemini policy.** Gemini 4 Argon (GA 2026-10-13; API ID `gemini-4-argon`, generateContent supported) serves maximum and premium/default: `Gemini 4 Argon (High)` on `agy`, `gemini-4-argon` on the API. Standard/economy keep `Gemini 3.8 Flash (High/Low)` on the CLI and `gemini-3.1-pro-preview` on the API (no shutdown announced; `gemini-3.8-flash` API stays opt-in until its own smoke). `configure` migrates unpinned `Gemini 3.8 Flash (High)` (plus the older Pro 3.1 / Flash 3.7 High values) and unpinned `gemini-3.1-pro-preview`. Rates use the list price ($4/$20 per 1M), not the introductory $2/$10 through 2026-11-30. API wire: `GEMINI_API_MAX_TOKENS` (default 32768, Google's minimum advice and per-request non-streaming cap) replaces the fixed 4096 because thinking counts toward `maxOutputTokens`; Argon accepts low|medium|high and defaults to `high` like its CLI target; no sampling parameters are sent (Argon ignores them); `parse_google_ai_response` joins visible text parts and skips `thought` parts. Evidence: `agy models` 1.3.6 lists Argon Low/Medium/High; one authorized `query_gemini.sh` CLI smoke on 2026-10-16 returned `response_quality=structured`, confidence 9, capability-probed identity, ~49 s, schema-valid (agy reports no usage, so tokens are estimated). No authenticated Gemini API smoke was run, so the API transport is offline-tested only. Google excludes Argon from the Free tier and the AI Pro plan. `GEMINI_TIMEOUT` defaults to 0 (no limit, see the timeout policy below), in line with Google's advice to use long client timeouts for hard prompts.
|
|
789
|
+
- **Timeout policy.** Generation has no wall-clock limit by default: every consultant `*_TIMEOUT`, `QWEN3/DEEPSEEK_MAX_QUALITY_TIMEOUT` and `SYNTHESIS_TIMEOUT`/`SYNTHESIS_TOTAL_TIMEOUT` default to 0 (`run_with_timeout 0` runs the command directly; `run_api_query` omits curl `-m`; `format_timeout_label` logs "none"). Reason: a client timeout usually still bills the provider call and loses the answer, and Argon/Large 4 approach the old 180 s limit. The user explicitly rejected a safety ceiling. Instead the host decides: `consult_all.sh` polls children once per second (Bash 3.2 has no `wait -n`), logs a heartbeat every `WAIT_HEARTBEAT_SECONDS` (30), and honors *proceed* (`<dir>/.proceed`, SIGUSR1, first Ctrl-C: stop the current phase, continue with received answers; during synthesis, skip it) and *abort* (`<dir>/.abort`, SIGTERM 143, SIGHUP 129, second Ctrl-C 130). Stopped consultants become `NAME:STOPPED`: partial JSON deleted, counted against quorum, not recorded as a reliability failure, excluded from cost with a billing caveat. `lib/common.sh::kill_process_tree` freezes, terminates and finally kills the whole descendant tree (walked with portable `ps -A -o pid= -o ppid=`), with stderr silenced so Bash job-termination notices stay out of logs. Escalation and synthesis run in the background under `_wait_child_under_host_control`; traps are restored after synthesis. SIGKILL on `consult_all.sh` cannot clean up and would orphan CLIs (documented). Probe limits stay: agy inventory 10-12 s, auth 8-12 s, health gate 30 s, doctor live 45 s, LLM classifier 30 s (falls back to pattern). `configure` migrates unpinned generated 180/240/480/600 values to `0 # ai-consultants:default`; pins and custom values stay limits. Tests: `test_common.sh` Test 15, `test_api_transport.sh` (curl args), `test_configure.sh` (migration), `test_e2e.sh` Tests 6-8 (proceed via file, abort via file, SIGUSR1 during synthesis; all assert no surviving stub process).
|
|
790
|
+
- **Review fixes (`/code-review max` on this branch).** `normalize_consultant_response_text` took its JSON-like probe from `sed`/`cut -c1`, which work line by line, so a pretty-printed truncated answer became a successful fallback instead of failing closed; it now reads the first non-blank character of the whole text, and a canonical result with several JSON values fails closed (it used to reach `build_structured_response --argjson` and leave an empty envelope). `run_api_query` wrote the key-bearing headers to a mktemp file that a stopped or killed query left on disk (reproduced with `kill_process_tree`); headers and body now go through process substitution, and the builders read the prompt from stdin (a 1.2 MB prompt previously produced an empty body via E2BIG). A host proceed during escalation ends the phase (`break`, it used to start the next billed re-query), and `_discard_late_proceed` keeps a request that lands after a phase finished from skipping the next one. The pattern classifier strips dependency/constructor/field/fault injection before the SECURITY check; `build_context.sh` never lists `$HOME` or `/` as the project tree; `provider_error_summary` reads string `error` fields (xAI); `json_schema_check.jq` reports an unknown definition or `$ref`; `kill_process_tree` re-lists the frozen tree until it is stable, from one `ps` snapshot per listing. Regression tests: `test_common.sh` Tests 8, 12, 13, 16; `test_api_transport.sh` (on-disk check, large prompts, xAI reason); `test_context_optimization.sh` Test 18; each failed on the pre-fix tree.
|
|
791
|
+
- **Live verification after the review (2026-10-19).** Default models, `MAX_RETRIES=1`, cache off. `balanced` (Gemini Argon High agy, Sol CLI, Large 4 API): 3/3 structured, 181 s, reported $0.22 incl. synthesis. Every consultant enabled (`DEFAULT_PRESET=` override): 9/10 structured in 172 s, reported $0.59; synthesis represented 83/83 IDs, schema-valid. Kimi failed on an expired Kimi Code OAuth grant (`OAuthUnauthorizedError` in the CLI's session wire; nothing reached the model) and passed a separate single call after `kimi login`. The adapter surfaced only the first stderr line, a `max_retries_per_step` config deprecation warning, as the reason: `run_query` reports the first line, not the first error line (open). No host stop was needed, so `.proceed`/`.abort` remain offline-tested only. The pre-run INFO estimate used to be the generic 4-consultant default-rate figure ($0.063 for both runs); it now logs the refined per-panel estimate.
|
|
792
|
+
- **Host harness check (2026-10-19).** Static: Codex 0.163 has no custom prompts/commands (skills only, from `~/.codex/skills` and `~/.agents/skills`); the Gemini CLI 0.64 `FileCommandLoader` globs `**/*.toml`, so `.gemini/commands/*.md` never registers (and the CLI is Homebrew-deprecated and no longer serves personal OAuth accounts); agy 1.4.2 reads `<workspace>/.agents/skills/<name>/` and `~/.gemini/config/skills/<name>/` (from its built-in instructions); the Gemini CLI shell tool kills a command after 300 s without output (the 30 s heartbeat covers it). `.codex/commands`/`.gemini/commands` stay as host-specific reference text (`test_install.sh` checks them) but are not slash commands. Live, one headless run each against this branch (temporary `~/.agents/skills` symlink and `~/.claude/commands` copies, restored afterwards): Claude Code ran the command in the foreground with a 600 s Bash timeout (it auto-backgrounds past that) and read `.synthesis_provider` as a file name, hence the clearer wording; Codex's first launch was rejected by Codex itself ("rm -f style commands are not permitted"), hence the `unlink` hint, and its memories led it to disable synthesis; agy followed the contract exactly, ran the command async (`WaitMsBeforeAsync` 10 s) and waits at most 30 min for background tasks in print mode. Claude Code host cost $0.59 (Opus 5.5).
|
|
793
|
+
- **Live host control and harnesses (2026-10-19, second pass).** Every stop path ran live (`.proceed`, USR1, `.abort`, SIGTERM, SIGHUP) with no process left. A real terminal Ctrl-C (SIGINT to the whole group) exposed a bug: under `set -e` the interrupted poll `sleep` ended the run with 130 and orphaned the consultant CLIs (they ignore SIGINT as background jobs); fixed with an async poll pause, a Round 1 poll loop without errexit (an interrupted `date`/`jq` would end the run too), `trap '' INT` in every consultant/escalation/synthesis job (Bash 5.2 in CI did not ignore SIGINT in them, so the adapter died and orphaned its CLI; Bash 3.2 does), host-request checks before collecting (a CLI that Ctrl-C ended is `stopped`) and an EXIT safety net; `test_e2e.sh` Tests 9-10 send SIGINT to the process group. agy 1.4.2 printed a complete synthesis and never exited (its log stops after "Stream goroutine exited", without "Language server shutting down"), so the no-timeout run hung for 16 min: `scripts/lib/agy_exit_guard.sh` (`AGY_EXIT_GRACE_SECONDS`). Hosts: Claude Code proceeds on request; agy finds `~/.gemini/config/skills` and aborts on request; Codex `workspace-write` without approvals gets 0/3 (network), and its auto-reviewer refuses the escalation (code to external providers), so the approval must come from the user; the Gemini CLI is rejected for individual accounts (`UNSUPPORTED_CLIENT`). Failure reasons were then fixed against network-denied reproductions (`sandbox-exec` with `(deny network*)`, nothing billed): `pick_error_line` (shared by `run_query` and `get_consultant_error_reason`) skips warnings and stack frames, `describe_curl_exit` names API network failures, agy inventory failures carry agy's message, and `diagnosed_failures_network_hint` flags an all-network failure (sandbox). The user's `~/.kimi-code/config.toml` `max_retries_per_step` was renamed to `max_attempts_per_step` (same value; `kimi doctor` valid).
|
|
794
|
+
- Release 5.2.0 bumps the version surfaces and adds `docs/releases/v5.2.0.md`; the showcase site syncs after npm serves 5.2.0. Frozen benchmark inputs are unchanged. Residual: a non-improving escalation re-query is still not billed (its file is deleted). `history.json` now stores every full question and is never pruned.
|
|
795
|
+
|
|
763
796
|
### v5.1.2 (2026-09-28)
|
|
764
797
|
|
|
765
798
|
- **Model selection remains transport-specific.** Grok 4.7 replaces the premium/maximum default, Opus 5.5 replaces standard Claude, and Gemini 3.8 High/Low replace the respective CLI targets. Fable and API Pro 3.1 remain separate defaults. Native Gemini 3.8 API thinking accepts low/medium/high and rejects incompatible explicit values before dispatch.
|