ai-consultants 3.3.0 → 3.4.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/.env.example +14 -2
- package/CLAUDE.md +23 -6
- package/README.md +5 -5
- package/SKILL.md +2 -2
- package/docs/COST_RATES.md +13 -13
- package/docs/RECIPES.md +17 -7
- package/docs/cost_rates.json +52 -23
- package/docs/releases/v3.4.0.md +102 -0
- package/package.json +1 -1
- package/references/configuration.md +1 -1
- package/scripts/config.sh +9 -9
- package/scripts/configure.sh +9 -0
- package/scripts/doctor.sh +8 -2
- package/scripts/lib/api.sh +3 -3
- package/scripts/lib/common.sh +28 -3
- package/scripts/query_claude.sh +30 -9
- package/scripts/query_codex.sh +116 -18
- package/scripts/query_gemini.sh +32 -7
- package/scripts/update_clis.sh +7 -1
package/.env.example
CHANGED
|
@@ -122,11 +122,19 @@ GEMINI_TIMEOUT=180
|
|
|
122
122
|
GEMINI_CMD=agy
|
|
123
123
|
# API-mode model ID (only used when GEMINI_USE_API=true)
|
|
124
124
|
GEMINI_API_MODEL=gemini-3.1-pro-preview
|
|
125
|
+
# Reasoning effort for the agy CLI. Passed as --effort <value>. Accepts only
|
|
126
|
+
# low|medium|high; anything else is rejected by the provider and surfaces as a
|
|
127
|
+
# diagnosed error (provider owns the enum — same stance as QWEN3_REASONING_EFFORT).
|
|
128
|
+
# GEMINI_REASONING_EFFORT=
|
|
125
129
|
|
|
126
130
|
# Codex - The Pragmatist
|
|
127
|
-
CODEX_MODEL=gpt-5.
|
|
131
|
+
CODEX_MODEL=gpt-5.6-sol
|
|
128
132
|
CODEX_TIMEOUT=180
|
|
129
133
|
CODEX_CMD=codex
|
|
134
|
+
# Reasoning effort for the codex CLI (and API mode). Passed as
|
|
135
|
+
# -c model_reasoning_effort=<value>. The provider owns the accepted enum;
|
|
136
|
+
# an unsupported value is rejected rather than silently ignored.
|
|
137
|
+
# CODEX_REASONING_EFFORT=
|
|
130
138
|
|
|
131
139
|
# Mistral Vibe - The Devil's Advocate
|
|
132
140
|
MISTRAL_MODEL=mistral-large-3
|
|
@@ -148,6 +156,10 @@ CLAUDE_MODEL=claude-opus-5 # ai-consultants:default
|
|
|
148
156
|
CLAUDE_TIMEOUT=240
|
|
149
157
|
CLAUDE_CMD=claude
|
|
150
158
|
CLAUDE_API_MAX_TOKENS=16384
|
|
159
|
+
# Reasoning effort for the claude CLI (and API mode). Passed as --effort <value>.
|
|
160
|
+
# The provider owns the accepted enum; an unsupported value is rejected rather
|
|
161
|
+
# than silently ignored.
|
|
162
|
+
# CLAUDE_REASONING_EFFORT=
|
|
151
163
|
|
|
152
164
|
# Qwen3 - The Analyst (CLI/API switchable v2.7)
|
|
153
165
|
QWEN3_MODEL=qwen3.7-max
|
|
@@ -157,7 +169,7 @@ QWEN3_CMD=qwen
|
|
|
157
169
|
# mode this is ignored (with a warning); set model.reasoningEffort in
|
|
158
170
|
# ~/.qwen/settings.json instead. Accepted: none|minimal|low|medium|high|xhigh|max
|
|
159
171
|
# (the provider's own enum). The valid subset depends on the model:
|
|
160
|
-
# qwen3.8-max
|
|
172
|
+
# qwen3.8-max takes all of them EXCEPT 'none' - thinking cannot be
|
|
161
173
|
# disabled on it - and defaults to xhigh. An unsupported combination is
|
|
162
174
|
# rejected by the provider with a 400, not silently ignored.
|
|
163
175
|
# QWEN3_REASONING_EFFORT=
|
package/CLAUDE.md
CHANGED
|
@@ -6,7 +6,7 @@ AI Consultants is a multi-model coverage system that queries up to 11 AI consult
|
|
|
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**: 3.
|
|
9
|
+
**Version**: 3.4.0
|
|
10
10
|
|
|
11
11
|
## Distribution
|
|
12
12
|
|
|
@@ -368,9 +368,9 @@ Three tiers of models are available for each consultant, configurable via `apply
|
|
|
368
368
|
|
|
369
369
|
| Tier | Description | Example Models |
|
|
370
370
|
|------|-------------|----------------|
|
|
371
|
-
| **premium** | Latest flagship models | claude-opus-5, Gemini 3.1 Pro (High), gpt-5.
|
|
372
|
-
| **standard** | Good quality at reasonable cost | claude-sonnet-
|
|
373
|
-
| **economy** | Optimized for speed and low cost | claude-haiku-4-5, Gemini 3.
|
|
371
|
+
| **premium** | Latest flagship models | claude-opus-5, Gemini 3.1 Pro (High), gpt-5.6-sol |
|
|
372
|
+
| **standard** | Good quality at reasonable cost | claude-sonnet-5, Gemini 3.6 Flash (High), gpt-5.6-terra |
|
|
373
|
+
| **economy** | Optimized for speed and low cost | claude-haiku-4-5, Gemini 3.6 Flash (Low), gpt-5.6-luna |
|
|
374
374
|
|
|
375
375
|
**Default models are now premium tier** for maximum quality.
|
|
376
376
|
|
|
@@ -407,7 +407,7 @@ All consultants now use premium models by default:
|
|
|
407
407
|
|------------|---------------|
|
|
408
408
|
| Claude | claude-opus-5 |
|
|
409
409
|
| Gemini | Gemini 3.1 Pro (High) (via agy CLI) |
|
|
410
|
-
| Codex | gpt-5.
|
|
410
|
+
| Codex | gpt-5.6-sol |
|
|
411
411
|
| Mistral | mistral-large-3 |
|
|
412
412
|
| Cursor | composer-2.5 |
|
|
413
413
|
| DeepSeek | deepseek-v4-pro |
|
|
@@ -617,7 +617,7 @@ for f in scripts/*.sh scripts/lib/*.sh; do bash -n "$f" && echo "OK: $f"; done
|
|
|
617
617
|
| `CLAUDE_API_MAX_TOKENS` | 16384 | Claude API thinking + visible-output budget |
|
|
618
618
|
| `GEMINI_MODEL` | Gemini 3.1 Pro (High) | Gemini agy CLI model (v2.15) |
|
|
619
619
|
| `GEMINI_API_MODEL` | gemini-3.1-pro-preview | Gemini API-mode model ID (v2.15) |
|
|
620
|
-
| `CODEX_MODEL` | gpt-5.
|
|
620
|
+
| `CODEX_MODEL` | gpt-5.6-sol | Codex model (v2.5) |
|
|
621
621
|
| `MISTRAL_MODEL` | mistral-large-3 | Mistral model (v2.5) |
|
|
622
622
|
| `SYNTHESIS_STRATEGY` | coverage | Synthesis strategy (coverage=union of distinct points) |
|
|
623
623
|
| `ENABLE_SEMANTIC_CACHE` | true | Semantic response caching (v2.3) |
|
|
@@ -787,6 +787,23 @@ curl -fsSL https://raw.githubusercontent.com/matteoscurati/ai-consultants/main/s
|
|
|
787
787
|
|
|
788
788
|
## Changelog
|
|
789
789
|
|
|
790
|
+
### v3.4.0
|
|
791
|
+
- **Gemini was unreachable from an SSH session, and no amount of re-authenticating helped.** `agy` picks its credential store from the environment: seeing `SSH_CLIENT`, `SSH_CONNECTION`, or `SSH_TTY` it switches to a file-based token store and never consults the macOS Keychain. A user who signed in locally therefore lost Gemini entirely over SSH, and signing in again landed the new credential in the Keychain the CLI had already decided to ignore. Reproduced live before fixing (`agy models` → "Please sign in"; the same command under `env -u SSH_CLIENT -u SSH_CONNECTION -u SSH_TTY` → full inventory), and confirmed again end to end after. Found by reading delegation-kit's 0.13.1 fix and checking whether the same failure applied here — it did, in the very session doing the work.
|
|
792
|
+
- **The fix ships in two shapes on purpose** (`lib/common.sh:163-164`). `AGY_ENV_PREFIX` is an array of `env -u …` for anything that reaches `agy` through `run_with_timeout`, because GNU `timeout` execs a binary and **cannot invoke a shell function**; `agy_env` is the same-shell wrapper, defined *from* that array so the two cannot drift. Applied at every executing call site — `query_gemini.sh`, `doctor.sh`, `update_clis.sh`, and `build_synthesis_args` (which is executed directly by `synthesize.sh:304`, not through timeout, so either shape would work there — it uses the array for consistency). The remaining `${GEMINI_CMD:-agy}` hits are `command -v` probes and config-dump strings, which execute nothing.
|
|
793
|
+
- **The Codex adapter was the least isolated in the panel, contradicting our own v3.1.0 policy.** That release isolated Grok specifically so "local plugins, hooks, skills, memories, and project instructions stay outside the consultation", then left Codex running `codex exec --skip-git-repo-check -m … "$FULL_QUERY"` in the ambient environment: the user's `~/.codex/config.toml`, the repo's `AGENTS.md`, their hooks, MCP servers, and execpolicy rules all reached an advisory consultation, the sandbox was unpinned, and the prompt rode in argv — the same `ARG_MAX` and process-list exposure v3.1.0 had already fixed once. CLI mode now uses an ephemeral mode-700 HOME/CWD with `--ephemeral --ignore-user-config --ignore-rules -s read-only`, prompt on stdin, answer from a private `-o` payload (`query_codex.sh:86-160`).
|
|
794
|
+
- **`CODEX_HOME` is resolved before HOME is overridden** (`query_codex.sh:89`) and passed through unchanged: `--ignore-user-config` skips `config.toml` but auth still resolves through `CODEX_HOME`, so repointing it at the isolated home would break authentication outright. Note the coupling recorded at `query_codex.sh:123`: `--ignore-user-config` is safe **only** because `-m` pins the model — it also makes Codex ignore any `-p <profile>`, so a profile must never be added here.
|
|
795
|
+
- **Review caught the `-o` payload rewriting real failures into successes.** The first implementation adopted the payload whenever it was non-empty, *regardless of how `run_query` finished* — so a timeout (124), an auth error, or exhausted retries that left a partial answer on disk all became `exit_code=0` and entered synthesis as a healthy consultation. That is strictly worse than the bug it replaced and defeats the v2.18/v2.19 diagnosed-failure machinery. Adoption is now gated on success; exit 0 with an empty payload remains a failure. Both directions are regression-tested, and both tests were confirmed non-vacuous by reintroducing the defect and watching them fail.
|
|
796
|
+
- **Correction, on the record: the justification for that override was measured and found false.** It was defended as avoiding "false empty-stdout failures", since `run_query` treats an empty stdout as a failure *and retries* — which would have meant every Codex consultation making `MAX_RETRIES` billable calls. Measured against the real CLI, stdout carries the answer (11 bytes), the `-o` file mirrors it, and only token telemetry goes to stderr. There was never a retry storm. `-o` is kept as defence in depth — and the isolation is what makes stdout clean in the first place, since `--ignore-user-config` plus an ephemeral HOME leaves no hooks to emit chatter.
|
|
797
|
+
- **`*_REASONING_EFFORT` had been a documented no-op on the default path.** `warn_effort_ignored_in_cli` announced the setting as API-mode only, but CLI-first transport has been mandatory since v2.21 — so in the shipped configuration the knob did nothing at all, while three CLIs did expose the control. Now wired: Codex `-c model_reasoning_effort=` (`query_codex.sh:148`), Claude `--effort` (`query_claude.sh:78-86`), Gemini `--effort` (`query_gemini.sh:97-105`). This is not cosmetic — cheap models do not degrade gracefully, so a consultant silently inheriting an unknown effort is not a controlled panel member.
|
|
798
|
+
- **Deliberately no per-CLI effort allowlist.** `agy` accepts only `low|medium|high`, but the accepted enum is a provider fact, not ours; an unsupported value comes back as a diagnosed 400 rather than being pre-empted by a table in shell. Same stance v2.25.0 took for Qwen, and for the same reason: hardcoding per-model facts is what produced the stale `MODEL_USED` bugs.
|
|
799
|
+
- **The parameter-contract test did its job on code it knew nothing about.** `test_configure.sh:91-121` scans every non-test `*.sh` for `${VAR:-}` and requires each name to be accepted by `configure --set`; the three new effort reads and then `CODEX_HOME` each failed it in turn. The effort variables are now declared in `.env.example` (commented out, matching the `QWEN3_REASONING_EFFORT` convention). `CODEX_HOME` went to the **exclusion list** instead (`test_configure.sh:105-107`), because it is owned by the Codex CLI: we read it to locate the user's auth store and must never persist it — declaring it would advertise `configure --set CODEX_HOME=…`, writing another tool's private auth path into our config. It joins `HOME`, `TMPDIR`, `XDG_CONFIG_HOME`, and `XAI_API_KEY`, and the distinction is now stated inline so nobody "fixes" it by moving it into `.env.example`.
|
|
800
|
+
- **The model catalog refresh would have been invisible to every existing installation — and only a live smoke test caught it.** The full gate was green (19/19, shellcheck clean, both new regression tests proven non-vacuous) and a real consultation still reported `model=gpt-5.5`. `init` copies `.env.example` verbatim, so the then-current Codex default was persisted as an ordinary unmarked value, and `configure` reads any unmarked value as a deliberate user pin. The proof sits side by side in an installed config: `CODEX_MODEL=gpt-5.5` beside `CLAUDE_MODEL=claude-opus-5 # ai-consultants:default`, where only the marked line can migrate. Fixed with the direct analogue of v3.2.0's Claude migration (`configure.sh:288-295`) — one exact historical value, one target, skipped on the pin marker, rewritten with the default marker. Verified against real config files: unmarked `gpt-5.5` migrates, a pin recorded via `--set` survives, an unrelated `gpt-5.4` is untouched.
|
|
801
|
+
- **Deliberately not generalised.** A table-driven "upgrade anything that looks old" rule would silently rewrite genuine user pins. Two adjacent narrow blocks is the intended shape; a third model needs a third block.
|
|
802
|
+
- **Model ids were verified by querying the installed binaries, never from documentation.** `agy models` (with the SSH markers cleared) returns slugs — `gemini-3.6-flash-high`, `gemini-3.1-pro-high` — but the display names we ship still resolve, checked by round-tripping both forms. Gemini premium stays `Gemini 3.1 Pro (High)` because the inventory has **no 3.6 Pro**; only standard/economy move to 3.6 Flash. Codex `gpt-5.6-sol|terra|luna` and `claude-sonnet-5` each answered a live probe.
|
|
803
|
+
- **Cost rates ship with the ids, not after them.** `calculate_session_cost` never calls `resolve_model_for_cost`, so a model absent from the catalog falls to the `*)` arm of `get_input_cost_per_1k` at 0.005/0.015 and is reported as a confident, wrong number — the trap documented at v2.25.0. Sonnet 5 is entered at its standard $3/$15 rate rather than the introductory $2/$10, which expires 2026-08-31; that slightly overstates for a few weeks and is exactly right afterwards.
|
|
804
|
+
- **Qwen: two ids, two deployments, not a rename.** delegation-kit's snapshot said `GET /models` lists both `qwen3.8-max` and `qwen3.8-max-preview`. Verified live against a real Token Plan account: both are served **and each completion reports its own requested id back in `.model`**, so `-preview` is not an alias and is not silently served by `qwen3.8-max`. Both stay catalogued and both stay in `unpriced_models` — removing the preview entry is precisely what would drop an existing pin onto `default_rate`. Recorded in `docs/RECIPES.md`; the shipped premium Qwen model remains `qwen3.7-max` and the negative assertion in `test_suite.sh` keeps that contract self-documenting.
|
|
805
|
+
- **Process note for the next stacked release.** `ci.yml` triggers on `pull_request: branches: [main]` with the default activity types, and a base-branch change fires `edited`, which is not among them — so a PR stacked on another branch never gets a server-side check until it is retargeted *and* reopened. Separately, `gh pr merge --delete-branch` on a stack base **closes** the child PR rather than retargeting it, and GitHub will neither retarget a closed PR nor reopen one whose base is gone; recovery meant pushing the base ref back from a commit still reachable in `main`. Adding `edited` to the workflow's activity types would close the first hole.
|
|
806
|
+
|
|
790
807
|
### v3.3.0
|
|
791
808
|
- **Grok and Kimi compatibility is now established from capabilities, not inferred from an installed binary or its version string.** `grok_cli_supports_required_interface` validates the complete headless parser surface inside the same isolated HOME/CWD boundary used for dispatch, while `grok_cli_exposes_requested_model` verifies both usable authentication and the exact `GROK_MODEL` in the CLI inventory (`scripts/query_grok.sh:85-154`). Kimi similarly checks prompt mode, `stream-json`, the provider inventory, and `KIMI_MODEL` before any request (`scripts/query_kimi.sh:45-79`). Compatible future and vendor-custom versions therefore continue to work without a release-specific allowlist; an interface that cannot enforce the adapter's contract fails before a model call.
|
|
792
809
|
- **The observed CLI version is provenance only.** Successful Grok and Kimi responses add `metadata.cli_version` and `metadata.cli_compatibility="capability-probed"`; the shared schema documents both fields without making either required for other transports (`scripts/query_grok.sh:319-336`, `scripts/query_kimi.sh:126-138`, `scripts/lib/schema.json:169-180`). This deliberately does not introduce a blessed-version range: the version is useful for diagnosis, while compatibility is decided by the exercised command, output, and model surfaces.
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# AI Consultants v3.
|
|
1
|
+
# AI Consultants v3.4.0
|
|
2
2
|
|
|
3
3
|
> **Coverage, not a single guess.** A panel of up to 11 frontier models from different vendors fans out on your question in parallel and hands you the *union* of what they collectively see — the risks, edge cases, and approaches a single model misses.
|
|
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)
|
|
@@ -447,9 +447,9 @@ parallel and returns the coverage union.
|
|
|
447
447
|
|
|
448
448
|
| Consultant | Premium | Standard | Economy |
|
|
449
449
|
|------------|---------|----------|---------|
|
|
450
|
-
| Claude | claude-opus-5 | claude-sonnet-
|
|
451
|
-
| Gemini | Gemini 3.1 Pro (High) | Gemini 3.
|
|
452
|
-
| Codex | gpt-5.
|
|
450
|
+
| Claude | claude-opus-5 | claude-sonnet-5 | claude-haiku-4-5 |
|
|
451
|
+
| Gemini | Gemini 3.1 Pro (High) | Gemini 3.6 Flash (High) | Gemini 3.6 Flash (Low) |
|
|
452
|
+
| Codex | gpt-5.6-sol | gpt-5.6-terra | gpt-5.6-luna |
|
|
453
453
|
| Mistral | mistral-large-3 | mistral-medium-latest | devstral-small-2 |
|
|
454
454
|
| Cursor | composer-2.5 | composer-2 | gemini-3-flash |
|
|
455
455
|
| DeepSeek | deepseek-v4-pro | deepseek-v4-flash | deepseek-v4-flash |
|
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: 3.
|
|
8
|
+
version: 3.4.0
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
# AI Consultants v3.
|
|
11
|
+
# AI Consultants v3.4.0 - AI Expert Panel
|
|
12
12
|
|
|
13
13
|
**Coverage, not a single guess.** Convene a panel of AI "consultants" from different vendors for coding questions: they fan out in parallel and you get the *union* of what they collectively see — the risks, edge cases, and approaches a single model misses. Each consultant has a **configurable persona** that decorrelates its analysis.
|
|
14
14
|
|
package/docs/COST_RATES.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Cost Rates - AI Consultants v3.
|
|
1
|
+
# Cost Rates - AI Consultants v3.4.0
|
|
2
2
|
|
|
3
3
|
This page documents the per-token rates used by the cost tracking system.
|
|
4
4
|
|
|
@@ -21,13 +21,13 @@ Since v2.5, models are organized into three tiers. Use `apply_model_tier()` or `
|
|
|
21
21
|
| Model | Tier | Cost/1K | Consultant |
|
|
22
22
|
|-------|------|---------|------------|
|
|
23
23
|
| Gemini 3.1 Pro (High) | Premium | $0.002 | Gemini (agy CLI) |
|
|
24
|
-
| Gemini 3.
|
|
25
|
-
| Gemini 3.
|
|
26
|
-
| gpt-5.
|
|
27
|
-
| gpt-5.
|
|
28
|
-
| gpt-5.
|
|
24
|
+
| Gemini 3.6 Flash (High) | Standard | $0.0015 | Gemini (agy CLI) |
|
|
25
|
+
| Gemini 3.6 Flash (Low) | Economy | $0.0015 | Gemini (agy CLI) |
|
|
26
|
+
| gpt-5.6-sol | Premium | $0.005 | Codex |
|
|
27
|
+
| gpt-5.6-terra | Standard | $0.002 | Codex |
|
|
28
|
+
| gpt-5.6-luna | Economy | $0.0002 | Codex |
|
|
29
29
|
| claude-opus-5 | Premium | $0.005 | Claude |
|
|
30
|
-
| claude-sonnet-
|
|
30
|
+
| claude-sonnet-5 | Standard | $0.003 | Claude |
|
|
31
31
|
| claude-haiku-4-5 | Economy | $0.001 | Claude |
|
|
32
32
|
| mistral-large-3 | Premium | $0.002 | Mistral |
|
|
33
33
|
| mistral-medium-latest | Standard | $0.001 | Mistral |
|
|
@@ -54,13 +54,13 @@ Since v2.5, models are organized into three tiers. Use `apply_model_tier()` or `
|
|
|
54
54
|
| Model | Tier | Cost/1K | Consultant |
|
|
55
55
|
|-------|------|---------|------------|
|
|
56
56
|
| Gemini 3.1 Pro (High) | Premium | $0.012 | Gemini (agy CLI) |
|
|
57
|
-
| Gemini 3.
|
|
58
|
-
| Gemini 3.
|
|
59
|
-
| gpt-5.
|
|
60
|
-
| gpt-5.
|
|
61
|
-
| gpt-5.
|
|
57
|
+
| Gemini 3.6 Flash (High) | Standard | $0.0075 | Gemini (agy CLI) |
|
|
58
|
+
| Gemini 3.6 Flash (Low) | Economy | $0.0075 | Gemini (agy CLI) |
|
|
59
|
+
| gpt-5.6-sol | Premium | $0.030 | Codex |
|
|
60
|
+
| gpt-5.6-terra | Standard | $0.012 | Codex |
|
|
61
|
+
| gpt-5.6-luna | Economy | $0.0012 | Codex |
|
|
62
62
|
| claude-opus-5 | Premium | $0.025 | Claude |
|
|
63
|
-
| claude-sonnet-
|
|
63
|
+
| claude-sonnet-5 | Standard | $0.015 | Claude |
|
|
64
64
|
| claude-haiku-4-5 | Economy | $0.005 | Claude |
|
|
65
65
|
| mistral-large-3 | Premium | $0.006 | Mistral |
|
|
66
66
|
| mistral-medium-latest | Standard | $0.003 | Mistral |
|
package/docs/RECIPES.md
CHANGED
|
@@ -190,28 +190,38 @@ For every available variable and its default, see
|
|
|
190
190
|
[`references/configuration.md`](../references/configuration.md). The executable
|
|
191
191
|
source of truth is [`scripts/config.sh`](../scripts/config.sh).
|
|
192
192
|
|
|
193
|
-
## Qwen via Qwen Cloud Token Plan (opt-in
|
|
193
|
+
## Qwen via Qwen Cloud Token Plan (opt-in)
|
|
194
194
|
|
|
195
|
-
`qwen3.8-max
|
|
195
|
+
`qwen3.8-max` is **not** served by DashScope/ModelStudio. It is reachable
|
|
196
196
|
only through a Qwen Cloud **Token Plan** subscription, which has its own base URL
|
|
197
197
|
and its own API key. This is opt-in: nothing below is a default, and the panel's
|
|
198
198
|
premium Qwen model remains `qwen3.7-max`.
|
|
199
199
|
|
|
200
200
|
Understand the tradeoffs before enabling it:
|
|
201
201
|
|
|
202
|
-
- **
|
|
203
|
-
|
|
202
|
+
- **Token Plan only.** No open weights, no published benchmarks, no stable
|
|
203
|
+
per-token price.
|
|
204
204
|
- **Billed in prepaid credits**, not per token — and credit consumption varies
|
|
205
205
|
with reasoning depth. Cost reports therefore exclude it and say so explicitly
|
|
206
206
|
rather than estimating a figure.
|
|
207
207
|
|
|
208
|
+
Both `qwen3.8-max` and `qwen3.8-max-preview` are served by Token Plan and are
|
|
209
|
+
**separate deployments**, not an alias or rename: each completion reports its
|
|
210
|
+
own requested id back in `.model`. Verified against the live endpoint on
|
|
211
|
+
2026-08-05. Prefer `qwen3.8-max`; `qwen3.8-max-preview` is the older
|
|
212
|
+
deployment and the natural candidate for eventual retirement. An existing
|
|
213
|
+
`qwen3.8-max-preview` pin keeps working and stays correctly catalogued — both
|
|
214
|
+
ids are listed in `unpriced_models`, so the session report continues to
|
|
215
|
+
disclose them as credit-billed and excluded from the total rather than falling
|
|
216
|
+
through to `default_rate`.
|
|
217
|
+
|
|
208
218
|
### API mode (the effort knob works here)
|
|
209
219
|
|
|
210
220
|
```bash
|
|
211
221
|
QWEN3_USE_API=true
|
|
212
222
|
QWEN3_FORMAT=openai # Token Plan is OpenAI-compatible; DashScope is not
|
|
213
223
|
QWEN3_API_URL=https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions
|
|
214
|
-
QWEN3_MODEL=qwen3.8-max
|
|
224
|
+
QWEN3_MODEL=qwen3.8-max
|
|
215
225
|
QWEN3_API_KEY=<your Token Plan key>
|
|
216
226
|
QWEN3_REASONING_EFFORT=high # none|minimal|low|medium|high|xhigh|max; default xhigh
|
|
217
227
|
```
|
|
@@ -240,8 +250,8 @@ ai-consultants cannot deliver it per call and warns if you set
|
|
|
240
250
|
"modelProviders": {
|
|
241
251
|
"openai": [
|
|
242
252
|
{
|
|
243
|
-
"id": "qwen3.8-max
|
|
244
|
-
"name": "[Token Plan] qwen3.8-max
|
|
253
|
+
"id": "qwen3.8-max",
|
|
254
|
+
"name": "[Token Plan] qwen3.8-max",
|
|
245
255
|
"baseUrl": "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
|
|
246
256
|
"envKey": "BAILIAN_TOKEN_PLAN_API_KEY",
|
|
247
257
|
"generationConfig": { "reasoning": { "effort": "high" } }
|
package/docs/cost_rates.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.
|
|
2
|
+
"version": "3.4.0",
|
|
3
3
|
"updated": "2026-07-25",
|
|
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.",
|
|
@@ -17,18 +17,26 @@
|
|
|
17
17
|
"input": 0.002,
|
|
18
18
|
"output": 0.012
|
|
19
19
|
},
|
|
20
|
-
"Gemini 3.
|
|
20
|
+
"Gemini 3.6 Flash (High)": {
|
|
21
21
|
"input": 0.0015,
|
|
22
|
-
"output": 0.
|
|
22
|
+
"output": 0.0075
|
|
23
23
|
},
|
|
24
|
-
"Gemini 3.
|
|
24
|
+
"Gemini 3.6 Flash (Low)": {
|
|
25
25
|
"input": 0.0015,
|
|
26
|
-
"output": 0.
|
|
26
|
+
"output": 0.0075
|
|
27
27
|
},
|
|
28
|
-
"gpt-5.
|
|
28
|
+
"gpt-5.6-sol": {
|
|
29
29
|
"input": 0.005,
|
|
30
30
|
"output": 0.030
|
|
31
31
|
},
|
|
32
|
+
"gpt-5.6-terra": {
|
|
33
|
+
"input": 0.002,
|
|
34
|
+
"output": 0.012
|
|
35
|
+
},
|
|
36
|
+
"gpt-5.6-luna": {
|
|
37
|
+
"input": 0.0002,
|
|
38
|
+
"output": 0.0012
|
|
39
|
+
},
|
|
32
40
|
"mistral-large-3": {
|
|
33
41
|
"input": 0.002,
|
|
34
42
|
"output": 0.006
|
|
@@ -75,7 +83,7 @@
|
|
|
75
83
|
"output": 0.00
|
|
76
84
|
},
|
|
77
85
|
"_comment_standard": "Standard tier models",
|
|
78
|
-
"claude-sonnet-
|
|
86
|
+
"claude-sonnet-5": {
|
|
79
87
|
"input": 0.003,
|
|
80
88
|
"output": 0.015
|
|
81
89
|
},
|
|
@@ -137,6 +145,30 @@
|
|
|
137
145
|
"output": 0.001
|
|
138
146
|
},
|
|
139
147
|
"_comment_legacy": "Legacy models for backwards compatibility",
|
|
148
|
+
"Gemini 3.5 Flash (High)": {
|
|
149
|
+
"input": 0.0015,
|
|
150
|
+
"output": 0.009
|
|
151
|
+
},
|
|
152
|
+
"Gemini 3.5 Flash (Low)": {
|
|
153
|
+
"input": 0.0015,
|
|
154
|
+
"output": 0.009
|
|
155
|
+
},
|
|
156
|
+
"gpt-5.5": {
|
|
157
|
+
"input": 0.005,
|
|
158
|
+
"output": 0.030
|
|
159
|
+
},
|
|
160
|
+
"gpt-5.4": {
|
|
161
|
+
"input": 0.0025,
|
|
162
|
+
"output": 0.015
|
|
163
|
+
},
|
|
164
|
+
"gpt-5.4-nano": {
|
|
165
|
+
"input": 0.0002,
|
|
166
|
+
"output": 0.00125
|
|
167
|
+
},
|
|
168
|
+
"claude-sonnet-4-6": {
|
|
169
|
+
"input": 0.003,
|
|
170
|
+
"output": 0.015
|
|
171
|
+
},
|
|
140
172
|
"claude-opus-4-8": {
|
|
141
173
|
"input": 0.005,
|
|
142
174
|
"output": 0.025
|
|
@@ -289,14 +321,6 @@
|
|
|
289
321
|
"input": 0.0003,
|
|
290
322
|
"output": 0.0015
|
|
291
323
|
},
|
|
292
|
-
"gpt-5.4": {
|
|
293
|
-
"input": 0.0025,
|
|
294
|
-
"output": 0.015
|
|
295
|
-
},
|
|
296
|
-
"gpt-5.4-nano": {
|
|
297
|
-
"input": 0.0002,
|
|
298
|
-
"output": 0.00125
|
|
299
|
-
},
|
|
300
324
|
"composer-2.5": {
|
|
301
325
|
"input": 0.0005,
|
|
302
326
|
"output": 0.0025
|
|
@@ -326,19 +350,24 @@
|
|
|
326
350
|
"output": 0.0025
|
|
327
351
|
},
|
|
328
352
|
"_comment_unpriced": "Credit-billed models: drawn from a prepaid subscription pool, with no published per-token price. Rated 0 so the estimator does not fabricate a figure - an absent model would otherwise fall through to default_rate (0.005/0.015) and be reported as a confident, wrong number. Every entry here must also be listed in unpriced_models, which is what makes the session report disclose the exclusion instead of implying the model was free.",
|
|
353
|
+
"qwen3.8-max": {
|
|
354
|
+
"input": 0,
|
|
355
|
+
"output": 0
|
|
356
|
+
},
|
|
329
357
|
"qwen3.8-max-preview": {
|
|
330
358
|
"input": 0,
|
|
331
359
|
"output": 0
|
|
332
360
|
}
|
|
333
361
|
},
|
|
334
362
|
"unpriced_models": [
|
|
363
|
+
"qwen3.8-max",
|
|
335
364
|
"qwen3.8-max-preview"
|
|
336
365
|
],
|
|
337
366
|
"consultant_fallbacks": {
|
|
338
|
-
"_comment": "Premium defaults - Updated
|
|
367
|
+
"_comment": "Premium defaults - Updated Aug 2026",
|
|
339
368
|
"claude": "claude-opus-5",
|
|
340
369
|
"gemini": "Gemini 3.1 Pro (High)",
|
|
341
|
-
"codex": "gpt-5.
|
|
370
|
+
"codex": "gpt-5.6-sol",
|
|
342
371
|
"mistral": "mistral-large-3",
|
|
343
372
|
"deepseek": "deepseek-v4-pro",
|
|
344
373
|
"glm": "glm-5.2",
|
|
@@ -353,7 +382,7 @@
|
|
|
353
382
|
"premium": {
|
|
354
383
|
"claude": "claude-opus-5",
|
|
355
384
|
"gemini": "Gemini 3.1 Pro (High)",
|
|
356
|
-
"codex": "gpt-5.
|
|
385
|
+
"codex": "gpt-5.6-sol",
|
|
357
386
|
"mistral": "mistral-large-3",
|
|
358
387
|
"deepseek": "deepseek-v4-pro",
|
|
359
388
|
"glm": "glm-5.2",
|
|
@@ -364,9 +393,9 @@
|
|
|
364
393
|
"minimax": "minimax-m2.7"
|
|
365
394
|
},
|
|
366
395
|
"standard": {
|
|
367
|
-
"claude": "claude-sonnet-
|
|
368
|
-
"gemini": "Gemini 3.
|
|
369
|
-
"codex": "gpt-5.
|
|
396
|
+
"claude": "claude-sonnet-5",
|
|
397
|
+
"gemini": "Gemini 3.6 Flash (High)",
|
|
398
|
+
"codex": "gpt-5.6-terra",
|
|
370
399
|
"mistral": "mistral-medium-latest",
|
|
371
400
|
"deepseek": "deepseek-v4-flash",
|
|
372
401
|
"glm": "glm-5.2",
|
|
@@ -378,8 +407,8 @@
|
|
|
378
407
|
},
|
|
379
408
|
"economy": {
|
|
380
409
|
"claude": "claude-haiku-4-5",
|
|
381
|
-
"gemini": "Gemini 3.
|
|
382
|
-
"codex": "gpt-5.
|
|
410
|
+
"gemini": "Gemini 3.6 Flash (Low)",
|
|
411
|
+
"codex": "gpt-5.6-luna",
|
|
383
412
|
"mistral": "devstral-small-2",
|
|
384
413
|
"deepseek": "deepseek-v4-flash",
|
|
385
414
|
"glm": "glm-4-flash",
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Release v3.4.0
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-08-05
|
|
4
|
+
**Type:** Minor — Gemini works over SSH again, the Codex consultant is isolated, and the model catalog moves to the current generation
|
|
5
|
+
**Previous:** v3.3.0
|
|
6
|
+
|
|
7
|
+
## Highlights
|
|
8
|
+
|
|
9
|
+
- **Gemini consultations from an SSH session were failing authentication, and re-signing-in could not fix it.** Now fixed at every `agy` call site.
|
|
10
|
+
- **The Codex consultant no longer inherits your local Codex environment** — no `config.toml`, no `AGENTS.md`, no hooks, no MCP servers, and a read-only sandbox.
|
|
11
|
+
- **Model catalog refreshed** to `gpt-5.6-sol/terra/luna`, `claude-sonnet-5`, and Gemini 3.6 Flash, every id verified against the installed CLIs rather than documentation.
|
|
12
|
+
- **`*_REASONING_EFFORT` actually works now.** It was honored in API mode only, which meant it did nothing in the default CLI-first configuration.
|
|
13
|
+
- **Existing installations receive the new Codex model.** Without the migration added here, they would have kept querying `gpt-5.5` indefinitely while every doc claimed otherwise.
|
|
14
|
+
|
|
15
|
+
## What's New
|
|
16
|
+
|
|
17
|
+
### Gemini authentication over SSH
|
|
18
|
+
|
|
19
|
+
The Antigravity CLI picks its credential store from the environment. When it sees any of `SSH_CLIENT`, `SSH_CONNECTION`, or `SSH_TTY`, it switches to a file-based token store and never consults the macOS Keychain. If you signed in locally — as almost everyone does — the credential lives in the Keychain, so every Gemini consultation over SSH failed to authenticate. Signing in again did not help: the new login also landed in the store the CLI had already decided to ignore.
|
|
20
|
+
|
|
21
|
+
Those three markers are now stripped for every `agy` invocation: consultations, `doctor`, `update-clis`, and synthesis. On a local session they are already unset, so this changes nothing there. It grants no additional tools and no filesystem access — only which credential store the CLI consults.
|
|
22
|
+
|
|
23
|
+
If you drive ai-consultants over SSH, this is the release that makes Gemini work.
|
|
24
|
+
|
|
25
|
+
### The Codex consultant runs isolated
|
|
26
|
+
|
|
27
|
+
Previously the Codex adapter ran `codex exec` in your ambient environment. That meant your `~/.codex/config.toml`, the repository's `AGENTS.md`, your hooks, your MCP servers, and your execpolicy rules all shaped what is supposed to be an independent second opinion — and the sandbox was unpinned.
|
|
28
|
+
|
|
29
|
+
CLI mode now runs under an ephemeral HOME and working directory with `--ephemeral`, `--ignore-user-config`, `--ignore-rules`, and `-s read-only`. **Authentication is unaffected**: `CODEX_HOME` still resolves to your real Codex auth store.
|
|
30
|
+
|
|
31
|
+
Two side effects worth knowing:
|
|
32
|
+
|
|
33
|
+
- **Large contexts no longer break it.** The prompt is delivered on stdin rather than argv, which removes both the `ARG_MAX` ceiling and the exposure of your prompt in the process list.
|
|
34
|
+
- **Failures are reported as failures.** A timeout, authentication error, or exhausted retry is never rewritten into a success, even when a partial answer reached disk.
|
|
35
|
+
|
|
36
|
+
### Reasoning effort works in CLI mode
|
|
37
|
+
|
|
38
|
+
`*_REASONING_EFFORT` was documented as API-mode only. Since CLI-first transport became mandatory in v2.21, that meant the setting did nothing at all in the default configuration — while three consultant CLIs did expose the control.
|
|
39
|
+
|
|
40
|
+
| Consultant | Variable | Passed as |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| Codex | `CODEX_REASONING_EFFORT` | `-c model_reasoning_effort=<value>` |
|
|
43
|
+
| Claude | `CLAUDE_REASONING_EFFORT` | `--effort <value>` |
|
|
44
|
+
| Gemini | `GEMINI_REASONING_EFFORT` | `--effort <value>` |
|
|
45
|
+
|
|
46
|
+
There is deliberately no local allowlist of accepted values. The enum belongs to the provider — `agy`, for instance, accepts only `low|medium|high` — and an unsupported value comes back as a diagnosed error rather than being silently pre-empted. Consultants whose CLI has no such flag still warn, as before.
|
|
47
|
+
|
|
48
|
+
All three are optional. Leave them unset and each CLI keeps its own default.
|
|
49
|
+
|
|
50
|
+
### Model catalog
|
|
51
|
+
|
|
52
|
+
Every replacement id was verified live against the installed CLIs:
|
|
53
|
+
|
|
54
|
+
| Consultant | Premium | Standard | Economy |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| Codex | `gpt-5.6-sol` | `gpt-5.6-terra` | `gpt-5.6-luna` |
|
|
57
|
+
| Claude | `claude-opus-5` *(unchanged)* | `claude-sonnet-5` | `claude-haiku-4-5` *(unchanged)* |
|
|
58
|
+
| Gemini | `Gemini 3.1 Pro (High)` *(unchanged)* | `Gemini 3.6 Flash (High)` | `Gemini 3.6 Flash (Low)` |
|
|
59
|
+
|
|
60
|
+
Gemini's premium tier stays on 3.1 Pro because the live model inventory has no 3.6 Pro. Cost rates ship alongside the new ids — a model missing from the catalog would otherwise be billed at the fallback rate and reported as a confident, wrong figure. Superseded ids remain catalogued so pinned configurations and historical responses still resolve.
|
|
61
|
+
|
|
62
|
+
The opt-in Qwen Token Plan model is referenced as `qwen3.8-max`. Both it and `qwen3.8-max-preview` are still served by Token Plan, and they are separate deployments rather than aliases — each reports its own id back. Both stay catalogued, so an existing `-preview` pin keeps working and keeps its credit-billed cost disclosure. The shipped premium Qwen model remains `qwen3.7-max`.
|
|
63
|
+
|
|
64
|
+
### Existing installations get the new Codex model
|
|
65
|
+
|
|
66
|
+
`init` copies `.env.example` verbatim, so the then-current Codex default was written into your config as an ordinary value — and `configure` reads any unmarked value as a deliberate pin. A catalog refresh alone would therefore never have reached you: your panel would have kept querying `gpt-5.5` while the docs, tier tables, and cost catalog all said `gpt-5.6-sol`.
|
|
67
|
+
|
|
68
|
+
`configure` now migrates that one exact historical value and marks it as managed, so future refreshes can reach it too. **An explicit pin is preserved** — if you deliberately want `gpt-5.5`, record it with `--set CODEX_MODEL=gpt-5.5` and it will survive.
|
|
69
|
+
|
|
70
|
+
## Breaking Changes
|
|
71
|
+
|
|
72
|
+
None. All new parameters are additive, existing configurations migrate, and no consultant is added or removed.
|
|
73
|
+
|
|
74
|
+
Two behavior changes are worth noting even though nothing breaks:
|
|
75
|
+
|
|
76
|
+
- **Codex answers may differ**, because it no longer sees your local Codex configuration. That is the intent — an advisory consultation shaped by your own hooks and project instructions is not an independent opinion.
|
|
77
|
+
- **Codex and Gemini tier models changed.** Pin `CODEX_MODEL` / `GEMINI_MODEL` explicitly if you need the previous ones.
|
|
78
|
+
|
|
79
|
+
## Upgrade Guide
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# If installed via npx, nothing to do — npx resolves the published version
|
|
83
|
+
npx ai-consultants "your question"
|
|
84
|
+
|
|
85
|
+
# If installed via git clone
|
|
86
|
+
cd ~/.claude/skills/ai-consultants && git pull
|
|
87
|
+
|
|
88
|
+
# If installed via curl | bash
|
|
89
|
+
curl -fsSL https://raw.githubusercontent.com/matteoscurati/ai-consultants/main/scripts/install.sh | bash
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Then, to pick up the new Codex default in an existing configuration:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
ai-consultants configure
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
No other configuration changes are required. Run `ai-consultants doctor --live` afterwards to confirm each consultant actually answers — the static check only verifies that CLIs are installed and keys are present.
|
|
99
|
+
|
|
100
|
+
## Contributors
|
|
101
|
+
|
|
102
|
+
- @matteoscurati
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-consultants",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "A harness for every question - a panel of up to 11 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"
|
|
@@ -239,7 +239,7 @@ ENABLE_DEEPSEEK=false
|
|
|
239
239
|
|
|
240
240
|
```bash
|
|
241
241
|
GEMINI_MODEL=Gemini 3.1 Pro (High) # agy CLI display name; API mode uses GEMINI_API_MODEL
|
|
242
|
-
CODEX_MODEL=gpt-5.
|
|
242
|
+
CODEX_MODEL=gpt-5.6-sol
|
|
243
243
|
CLAUDE_MODEL=claude-opus-5
|
|
244
244
|
CLAUDE_API_MAX_TOKENS=16384 # API only: adaptive thinking + visible output
|
|
245
245
|
MISTRAL_MODEL=mistral-large-3
|
package/scripts/config.sh
CHANGED
|
@@ -144,8 +144,8 @@ export GEMINI_USE_API
|
|
|
144
144
|
# CODEX CONFIGURATION - The Pragmatist
|
|
145
145
|
# =============================================================================
|
|
146
146
|
|
|
147
|
-
# Model: "gpt-5.
|
|
148
|
-
CODEX_MODEL="${CODEX_MODEL:-gpt-5.
|
|
147
|
+
# Model: "gpt-5.6-sol" (default), "gpt-5.6-terra", "gpt-5.6-luna", etc.
|
|
148
|
+
CODEX_MODEL="${CODEX_MODEL:-gpt-5.6-sol}"
|
|
149
149
|
CODEX_TIMEOUT_SECONDS="${CODEX_TIMEOUT:-180}"
|
|
150
150
|
CODEX_CMD="${CODEX_CMD:-codex}"
|
|
151
151
|
|
|
@@ -584,7 +584,7 @@ get_model_for_tier() {
|
|
|
584
584
|
case "$consultant" in
|
|
585
585
|
claude) echo "claude-opus-5" ;;
|
|
586
586
|
gemini) echo "Gemini 3.1 Pro (High)" ;;
|
|
587
|
-
codex) echo "gpt-5.
|
|
587
|
+
codex) echo "gpt-5.6-sol" ;;
|
|
588
588
|
mistral) echo "mistral-large-3" ;;
|
|
589
589
|
cursor) echo "composer-2.5" ;;
|
|
590
590
|
deepseek) echo "deepseek-v4-pro" ;;
|
|
@@ -598,9 +598,9 @@ get_model_for_tier() {
|
|
|
598
598
|
;;
|
|
599
599
|
standard|medium|balanced)
|
|
600
600
|
case "$consultant" in
|
|
601
|
-
claude) echo "claude-sonnet-
|
|
602
|
-
gemini) echo "Gemini 3.
|
|
603
|
-
codex) echo "gpt-5.
|
|
601
|
+
claude) echo "claude-sonnet-5" ;;
|
|
602
|
+
gemini) echo "Gemini 3.6 Flash (High)" ;;
|
|
603
|
+
codex) echo "gpt-5.6-terra" ;;
|
|
604
604
|
mistral) echo "mistral-medium-latest" ;;
|
|
605
605
|
cursor) echo "composer-2" ;;
|
|
606
606
|
deepseek) echo "deepseek-v4-flash" ;;
|
|
@@ -615,8 +615,8 @@ get_model_for_tier() {
|
|
|
615
615
|
economy|fast|quick)
|
|
616
616
|
case "$consultant" in
|
|
617
617
|
claude) echo "claude-haiku-4-5" ;;
|
|
618
|
-
gemini) echo "Gemini 3.
|
|
619
|
-
codex) echo "gpt-5.
|
|
618
|
+
gemini) echo "Gemini 3.6 Flash (Low)" ;;
|
|
619
|
+
codex) echo "gpt-5.6-luna" ;;
|
|
620
620
|
mistral) echo "devstral-small-2" ;;
|
|
621
621
|
cursor) echo "gemini-3-flash" ;;
|
|
622
622
|
deepseek) echo "deepseek-v4-flash" ;;
|
|
@@ -779,4 +779,4 @@ EOF
|
|
|
779
779
|
# VERSION
|
|
780
780
|
# =============================================================================
|
|
781
781
|
|
|
782
|
-
AI_CONSULTANTS_VERSION="3.
|
|
782
|
+
AI_CONSULTANTS_VERSION="3.4.0"
|
package/scripts/configure.sh
CHANGED
|
@@ -285,6 +285,15 @@ if [[ "$(read_value "$WORK_FILE" CLAUDE_MODEL 2>/dev/null || true)" == "claude-o
|
|
|
285
285
|
echo "Migrated managed Claude default: claude-opus-4-8 -> claude-opus-5" >&2
|
|
286
286
|
fi
|
|
287
287
|
|
|
288
|
+
# Same shape for Codex: `init` once wrote gpt-5.5 as an unmarked value, so
|
|
289
|
+
# configure treated it as a deliberate pin and never reached gpt-5.6-sol. A
|
|
290
|
+
# real pin is preserved by `--set CODEX_MODEL=gpt-5.5`.
|
|
291
|
+
if [[ "$(read_value "$WORK_FILE" CODEX_MODEL 2>/dev/null || true)" == "gpt-5.5" ]] \
|
|
292
|
+
&& ! has_value_marker "$WORK_FILE" CODEX_MODEL "$PIN_MARKER"; then
|
|
293
|
+
set_value CODEX_MODEL "gpt-5.6-sol $DEFAULT_MARKER"
|
|
294
|
+
echo "Migrated managed Codex default: gpt-5.5 -> gpt-5.6-sol" >&2
|
|
295
|
+
fi
|
|
296
|
+
|
|
288
297
|
configure_cli_only() {
|
|
289
298
|
local enable_key="$1" cmd_key="$2" cmd enabled=false
|
|
290
299
|
cmd=$(effective_input_value "$cmd_key")
|
package/scripts/doctor.sh
CHANGED
|
@@ -242,9 +242,15 @@ check_cli_consultant() {
|
|
|
242
242
|
return 0
|
|
243
243
|
fi
|
|
244
244
|
|
|
245
|
-
# Get version (--version is standard and fast, no timeout needed)
|
|
245
|
+
# Get version (--version is standard and fast, no timeout needed).
|
|
246
|
+
# Gemini/agy must run under agy_env so an SSH session still reaches the
|
|
247
|
+
# Keychain credential store (see agy_env in lib/common.sh).
|
|
246
248
|
local version
|
|
247
|
-
|
|
249
|
+
if [[ "$name" == "Gemini" ]]; then
|
|
250
|
+
version=$(agy_env "$cmd" --version 2>/dev/null | head -1 || echo "")
|
|
251
|
+
else
|
|
252
|
+
version=$("$cmd" --version 2>/dev/null | head -1 || echo "")
|
|
253
|
+
fi
|
|
248
254
|
|
|
249
255
|
if [[ -n "$version" ]]; then
|
|
250
256
|
_print " ✓ $name: $version"
|
package/scripts/lib/api.sh
CHANGED
|
@@ -188,7 +188,7 @@ build_qwen_request() {
|
|
|
188
188
|
# 'reasoning_effort' must be one of: 'none', 'minimal', 'low', 'medium',
|
|
189
189
|
# 'high', 'xhigh', 'max'
|
|
190
190
|
# Note this is WIDER than the low|high|xhigh that the public write-ups for
|
|
191
|
-
# qwen3.8-max
|
|
191
|
+
# qwen3.8-max all reported — 'minimal', 'medium' and 'max' are accepted
|
|
192
192
|
# by the model too. Taken from the API rather than from documentation for
|
|
193
193
|
# exactly that reason.
|
|
194
194
|
#
|
|
@@ -196,7 +196,7 @@ build_qwen_request() {
|
|
|
196
196
|
# facts in shell is what produced the stale-model bugs this release also fixes,
|
|
197
197
|
# and the same builder serves GLM/Grok/DeepSeek/MiniMax. An unsupported
|
|
198
198
|
# combination is rejected by the provider with a 400 that run_api_query
|
|
199
|
-
# surfaces without retrying — e.g. 'none' on qwen3.8-max
|
|
199
|
+
# surfaces without retrying — e.g. 'none' on qwen3.8-max returns "The
|
|
200
200
|
# value of the enable_thinking parameter is restricted to True", which is a
|
|
201
201
|
# model fact, not a syntax error.
|
|
202
202
|
validate_reasoning_effort() {
|
|
@@ -248,7 +248,7 @@ build_openai_request() {
|
|
|
248
248
|
# Usage: build_anthropic_request <prompt> <model> [max_tokens]
|
|
249
249
|
build_anthropic_request() {
|
|
250
250
|
local prompt="$1"
|
|
251
|
-
local model="${2:-claude-sonnet-
|
|
251
|
+
local model="${2:-claude-sonnet-5}"
|
|
252
252
|
local max_tokens="${3:-16384}"
|
|
253
253
|
|
|
254
254
|
jq -n \
|
package/scripts/lib/common.sh
CHANGED
|
@@ -140,6 +140,29 @@ check_command() {
|
|
|
140
140
|
return 0
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
# Run a command with SSH session markers stripped from the environment.
|
|
144
|
+
#
|
|
145
|
+
# WHY (do not "simplify" this away): the Antigravity CLI (`agy`, our Gemini
|
|
146
|
+
# transport) picks its credential store from the environment. When it sees any
|
|
147
|
+
# of SSH_CLIENT, SSH_CONNECTION, or SSH_TTY it switches to a file-based token
|
|
148
|
+
# store and never consults the macOS Keychain. A user who signed in locally has
|
|
149
|
+
# credentials only in the Keychain, so every `agy` call from an SSH session
|
|
150
|
+
# fails auth — and re-signing-in does not help, because the new login also lands
|
|
151
|
+
# in the Keychain the CLI has already decided to ignore. Clearing the three
|
|
152
|
+
# markers for the `agy` process restores Keychain lookup. On a local (non-SSH)
|
|
153
|
+
# session they are already unset, so this is a pure no-op there. It grants no
|
|
154
|
+
# extra tools or filesystem access; it only changes which credential store the
|
|
155
|
+
# CLI consults.
|
|
156
|
+
#
|
|
157
|
+
# AGY_ENV_PREFIX is the exec-safe form (external `env` binary) for use under
|
|
158
|
+
# run_with_timeout / GNU timeout, which cannot invoke shell functions. agy_env
|
|
159
|
+
# is the same-shell convenience wrapper. Keep both in lockstep via this array.
|
|
160
|
+
#
|
|
161
|
+
# Usage (same shell): agy_env <command> [args...]
|
|
162
|
+
# Usage (under timeout / command arrays): "${AGY_ENV_PREFIX[@]}" <command> [args...]
|
|
163
|
+
AGY_ENV_PREFIX=(env -u SSH_CLIENT -u SSH_CONNECTION -u SSH_TTY)
|
|
164
|
+
agy_env() { "${AGY_ENV_PREFIX[@]}" "$@"; }
|
|
165
|
+
|
|
143
166
|
# =============================================================================
|
|
144
167
|
# MAIN QUERY EXECUTION FUNCTION
|
|
145
168
|
# =============================================================================
|
|
@@ -149,8 +172,9 @@ check_command() {
|
|
|
149
172
|
# Usage: run_query <consultant_name> <output_file> <timeout_sec> <command...>
|
|
150
173
|
#
|
|
151
174
|
# The query is passed via stdin to the command.
|
|
175
|
+
# Use the exec-safe array form under run_query (agy_env is same-shell only).
|
|
152
176
|
# Example:
|
|
153
|
-
# echo "$QUERY" | run_query "Gemini" "/tmp/out.json" 120 agy -p
|
|
177
|
+
# echo "$QUERY" | run_query "Gemini" "/tmp/out.json" 120 "${AGY_ENV_PREFIX[@]}" agy -p "..." --model "Gemini 3.1 Pro (High)"
|
|
154
178
|
#
|
|
155
179
|
run_query() {
|
|
156
180
|
local consultant_name="$1"
|
|
@@ -485,7 +509,7 @@ warn_effort_ignored_in_cli() {
|
|
|
485
509
|
if is_api_mode "$agent"; then
|
|
486
510
|
return 0
|
|
487
511
|
fi
|
|
488
|
-
log_warn "[$agent] $var is ignored in CLI mode -
|
|
512
|
+
log_warn "[$agent] $var is ignored in CLI mode - this consultant's CLI does not expose a reasoning-effort flag. Set it in the CLI's own configuration, or switch this consultant to API mode."
|
|
489
513
|
}
|
|
490
514
|
|
|
491
515
|
# Log API mode status for debugging
|
|
@@ -1311,7 +1335,8 @@ build_synthesis_args() {
|
|
|
1311
1335
|
# stdin and "-" is not a stdin sentinel. A prior `-p -` made agy answer
|
|
1312
1336
|
# a literal "-" with a generic greeting -> unparseable synthesis ->
|
|
1313
1337
|
# manual_review. Pass the prompt directly, mirroring query_gemini.sh.
|
|
1314
|
-
|
|
1338
|
+
# AGY_ENV_PREFIX is exec-safe under timeout (see agy_env above).
|
|
1339
|
+
SYNTHESIS_ARGS=("${AGY_ENV_PREFIX[@]}" "${GEMINI_CMD:-agy}" "-p" "$prompt")
|
|
1315
1340
|
local model="${SYNTHESIS_MODEL:-${GEMINI_MODEL:-}}"
|
|
1316
1341
|
[[ -n "$model" ]] && SYNTHESIS_ARGS+=("--model" "$model")
|
|
1317
1342
|
;;
|
package/scripts/query_claude.sh
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
# CLAUDE_USE_API - Use API mode instead of CLI (default: false)
|
|
10
10
|
# CLAUDE_API_MAX_TOKENS - API thinking + visible-output budget (default: 16384)
|
|
11
11
|
# ANTHROPIC_API_KEY - API key for API mode
|
|
12
|
+
# CLAUDE_REASONING_EFFORT - Optional CLI/API reasoning effort
|
|
12
13
|
# ENABLE_PERSONA - Enable "The Synthesizer" persona (default: true)
|
|
13
14
|
|
|
14
15
|
set -euo pipefail
|
|
@@ -64,21 +65,41 @@ if is_api_mode "claude"; then
|
|
|
64
65
|
else
|
|
65
66
|
exit_code=$?
|
|
66
67
|
fi
|
|
67
|
-
warn_effort_ignored_in_cli "Claude"
|
|
68
68
|
else
|
|
69
69
|
# --- CLI Mode ---
|
|
70
70
|
log_api_mode_status "claude"
|
|
71
71
|
check_command "$CLAUDE_CMD" "Claude CLI" "Visit https://docs.anthropic.com/en/docs/claude-code" || exit 1
|
|
72
72
|
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
# Optional CLI effort control. Unset leaves the CLI's own default alone;
|
|
74
|
+
# when set, pass --effort through after the shared validation gate. Do not
|
|
75
|
+
# invent a local allowlist — the provider rejects what it does not accept.
|
|
76
|
+
CLAUDE_ARGS=("$CLAUDE_CMD" --print --model "$MODEL_USED" --output-format json)
|
|
77
|
+
effort_ok=true
|
|
78
|
+
if [[ -n "${CLAUDE_REASONING_EFFORT:-}" ]]; then
|
|
79
|
+
source "$SCRIPT_DIR/lib/api.sh"
|
|
80
|
+
if ! cli_effort=$(validate_reasoning_effort "$CLAUDE_REASONING_EFFORT" "$CONSULTANT_NAME"); then
|
|
81
|
+
effort_ok=false
|
|
82
|
+
exit_code=1
|
|
83
|
+
else
|
|
84
|
+
CLAUDE_ARGS+=(--effort "$cli_effort")
|
|
85
|
+
fi
|
|
86
|
+
fi
|
|
80
87
|
|
|
81
|
-
|
|
88
|
+
if [[ "$effort_ok" == "true" ]]; then
|
|
89
|
+
# JSON output exposes provider-measured usage and cost. In particular,
|
|
90
|
+
# output_tokens includes adaptive thinking that is absent from .result.
|
|
91
|
+
# Keep failures inside an explicit conditional so `set -e` cannot skip
|
|
92
|
+
# exit_code assignment (same guard as the API branch).
|
|
93
|
+
if echo "$FULL_QUERY" | run_query \
|
|
94
|
+
"Claude" \
|
|
95
|
+
"$TEMP_OUTPUT" \
|
|
96
|
+
"$CLAUDE_TIMEOUT_SECONDS" \
|
|
97
|
+
"${CLAUDE_ARGS[@]}"; then
|
|
98
|
+
exit_code=0
|
|
99
|
+
else
|
|
100
|
+
exit_code=$?
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
82
103
|
fi
|
|
83
104
|
|
|
84
105
|
# --- Calculate latency ---
|
package/scripts/query_codex.sh
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# query_codex.sh - Query OpenAI Codex CLI or API (
|
|
2
|
+
# query_codex.sh - Query OpenAI Codex CLI or API (isolated CLI runtime)
|
|
3
3
|
#
|
|
4
4
|
# Usage: ./query_codex.sh "question" [context_file] [output_file]
|
|
5
5
|
#
|
|
6
6
|
# Environment variables:
|
|
7
|
-
# CODEX_MODEL - Model to use (default: gpt-5.
|
|
7
|
+
# CODEX_MODEL - Model to use (default: gpt-5.6-sol)
|
|
8
8
|
# CODEX_TIMEOUT - Timeout in seconds (default: 180)
|
|
9
9
|
# CODEX_USE_API - Use API mode instead of CLI (default: false)
|
|
10
10
|
# OPENAI_API_KEY - API key for API mode
|
|
11
|
+
# CODEX_REASONING_EFFORT - Optional CLI/API reasoning effort
|
|
11
12
|
# ENABLE_PERSONA - Enable "The Pragmatist" persona (default: true)
|
|
12
13
|
|
|
13
14
|
set -euo pipefail
|
|
@@ -39,6 +40,22 @@ START_TIME=$(get_timestamp_ms)
|
|
|
39
40
|
|
|
40
41
|
# --- Execution (CLI or API mode) ---
|
|
41
42
|
TEMP_OUTPUT=$(mktemp)
|
|
43
|
+
CODEX_RUNTIME_DIR=""
|
|
44
|
+
exit_code=1
|
|
45
|
+
|
|
46
|
+
cleanup() {
|
|
47
|
+
rm -f "$TEMP_OUTPUT" "${TEMP_OUTPUT}.err"
|
|
48
|
+
|
|
49
|
+
# CODEX_RUNTIME_DIR is always created by this script under the system temp
|
|
50
|
+
# directory. Validate the prefix before recursive cleanup so an unexpected
|
|
51
|
+
# empty or overridden value can never widen the deletion target.
|
|
52
|
+
local temp_prefix="${TMPDIR:-/tmp}"
|
|
53
|
+
temp_prefix="${temp_prefix%/}/ai-consultants-codex."
|
|
54
|
+
if [[ -n "$CODEX_RUNTIME_DIR" && "$CODEX_RUNTIME_DIR" == "$temp_prefix"* ]]; then
|
|
55
|
+
rm -rf -- "$CODEX_RUNTIME_DIR"
|
|
56
|
+
fi
|
|
57
|
+
}
|
|
58
|
+
trap cleanup EXIT
|
|
42
59
|
|
|
43
60
|
if is_api_mode "codex"; then
|
|
44
61
|
# --- API Mode ---
|
|
@@ -61,26 +78,104 @@ if is_api_mode "codex"; then
|
|
|
61
78
|
else
|
|
62
79
|
exit_code=$?
|
|
63
80
|
fi
|
|
64
|
-
warn_effort_ignored_in_cli "Codex"
|
|
65
81
|
else
|
|
66
|
-
# --- CLI Mode ---
|
|
82
|
+
# --- CLI Mode (isolated HOME/CWD; auth via real CODEX_HOME) ---
|
|
67
83
|
log_api_mode_status "codex"
|
|
68
84
|
check_command "$CODEX_CMD" "Codex CLI" "npm install -g @openai/codex" || exit 1
|
|
69
85
|
|
|
70
|
-
#
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
86
|
+
# Resolve the real Codex home BEFORE overriding HOME. --ignore-user-config
|
|
87
|
+
# skips config.toml but auth still resolves through CODEX_HOME; repointing
|
|
88
|
+
# it at the isolated home would break authentication.
|
|
89
|
+
real_codex_home="${CODEX_HOME:-${HOME}/.codex}"
|
|
90
|
+
|
|
91
|
+
runtime_base="${TMPDIR:-/tmp}"
|
|
92
|
+
runtime_base="${runtime_base%/}"
|
|
93
|
+
CODEX_RUNTIME_DIR=$(mktemp -d "$runtime_base/ai-consultants-codex.XXXXXX")
|
|
94
|
+
chmod 700 "$CODEX_RUNTIME_DIR"
|
|
95
|
+
|
|
96
|
+
isolated_home="$CODEX_RUNTIME_DIR/home"
|
|
97
|
+
isolated_cwd="$CODEX_RUNTIME_DIR/workspace"
|
|
98
|
+
prompt_file="$CODEX_RUNTIME_DIR/prompt.txt"
|
|
99
|
+
payload_file="$CODEX_RUNTIME_DIR/payload.txt"
|
|
100
|
+
mkdir -p "$isolated_home" "$isolated_cwd"
|
|
101
|
+
chmod 700 "$isolated_home" "$isolated_cwd"
|
|
102
|
+
printf '%s' "$FULL_QUERY" > "$prompt_file"
|
|
103
|
+
: > "$payload_file"
|
|
104
|
+
chmod 600 "$prompt_file" "$payload_file"
|
|
105
|
+
|
|
106
|
+
cli_effort=""
|
|
107
|
+
effort_ok=true
|
|
108
|
+
if [[ -n "${CODEX_REASONING_EFFORT:-}" ]]; then
|
|
109
|
+
# Keep the existing validate_reasoning_effort gate; pass the value
|
|
110
|
+
# through and let the CLI reject what it does not accept.
|
|
111
|
+
source "$SCRIPT_DIR/lib/api.sh"
|
|
112
|
+
if ! cli_effort=$(validate_reasoning_effort "$CODEX_REASONING_EFFORT" "$CONSULTANT_NAME"); then
|
|
113
|
+
effort_ok=false
|
|
114
|
+
exit_code=1
|
|
115
|
+
fi
|
|
74
116
|
fi
|
|
75
117
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
118
|
+
if [[ "$effort_ok" == "true" ]]; then
|
|
119
|
+
# Isolated Codex headless contract (verified against codex-cli 0.146.0):
|
|
120
|
+
# HOME is ephemeral so ambient ~/.codex config, hooks, MCP, and
|
|
121
|
+
# project instructions stay outside the consultation.
|
|
122
|
+
# CODEX_HOME stays on the real auth store.
|
|
123
|
+
# --ignore-user-config is safe here only because we pin the model with
|
|
124
|
+
# -m. It also makes Codex ignore any -p <profile>, which is why we
|
|
125
|
+
# must not add -p.
|
|
126
|
+
# -s read-only: the consultant answers; it never edits.
|
|
127
|
+
# -C points at an empty temp dir so the host repo's AGENTS.md stays out
|
|
128
|
+
# (build_context.sh already inlined the relevant files into FULL_QUERY).
|
|
129
|
+
# trailing - reads the prompt from stdin (no ARG_MAX / process-list).
|
|
130
|
+
# -o writes the final agent message to a private payload file.
|
|
131
|
+
CMD_ARGS=(
|
|
132
|
+
env
|
|
133
|
+
HOME="$isolated_home"
|
|
134
|
+
CODEX_HOME="$real_codex_home"
|
|
135
|
+
"$CODEX_CMD"
|
|
136
|
+
exec
|
|
137
|
+
--ephemeral
|
|
138
|
+
--ignore-user-config
|
|
139
|
+
--ignore-rules
|
|
140
|
+
--skip-git-repo-check
|
|
141
|
+
-m "$CODEX_MODEL"
|
|
142
|
+
-s read-only
|
|
143
|
+
-C "$isolated_cwd"
|
|
144
|
+
-o "$payload_file"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
if [[ -n "$cli_effort" ]]; then
|
|
148
|
+
CMD_ARGS+=("-c" "model_reasoning_effort=${cli_effort}")
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
CMD_ARGS+=("-")
|
|
152
|
+
|
|
153
|
+
# run_query buffers stdin once and replays it on each retry.
|
|
154
|
+
if run_query \
|
|
155
|
+
"Codex" \
|
|
156
|
+
"$TEMP_OUTPUT" \
|
|
157
|
+
"$CODEX_TIMEOUT_SECONDS" \
|
|
158
|
+
"${CMD_ARGS[@]}" < "$prompt_file"; then
|
|
159
|
+
exit_code=0
|
|
160
|
+
else
|
|
161
|
+
exit_code=$?
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# Prefer the -o payload over stdout only when the run succeeded.
|
|
165
|
+
# A non-empty payload must never rewrite a timeout, auth error, or
|
|
166
|
+
# exhausted-retry into success — a partial answer would enter synthesis
|
|
167
|
+
# as a healthy consultation. Exit 0 with an empty payload remains a
|
|
168
|
+
# diagnosed failure.
|
|
169
|
+
if [[ $exit_code -eq 0 ]]; then
|
|
170
|
+
if [[ -s "$payload_file" ]]; then
|
|
171
|
+
cp "$payload_file" "$TEMP_OUTPUT"
|
|
172
|
+
else
|
|
173
|
+
exit_code=1
|
|
174
|
+
log_warn "[$CONSULTANT_NAME] Codex wrote an empty last-message payload"
|
|
175
|
+
printf 'Codex wrote an empty last-message payload\n' > "${TEMP_OUTPUT}.err"
|
|
176
|
+
fi
|
|
177
|
+
fi
|
|
178
|
+
fi
|
|
84
179
|
fi
|
|
85
180
|
|
|
86
181
|
# --- Calculate latency ---
|
|
@@ -88,12 +183,15 @@ END_TIME=$(get_timestamp_ms)
|
|
|
88
183
|
LATENCY_MS=$((END_TIME - START_TIME))
|
|
89
184
|
|
|
90
185
|
# --- Configuration for response building ---
|
|
91
|
-
MODEL_USED="${CODEX_MODEL:-gpt-5.
|
|
186
|
+
MODEL_USED="${CODEX_MODEL:-gpt-5.6-sol}"
|
|
92
187
|
PERSONA_NAME=$(get_persona_name "$CONSULTANT_NAME")
|
|
93
188
|
|
|
94
189
|
# --- Post-processing: use shared helper ---
|
|
190
|
+
# process_consultant_response returns the consultant exit code. Guard the call
|
|
191
|
+
# so a non-zero return does not abort under set -e before we cat the output
|
|
192
|
+
# file and exit with that code.
|
|
95
193
|
process_consultant_response "$CONSULTANT_NAME" "$MODEL_USED" "$PERSONA_NAME" \
|
|
96
|
-
"$TEMP_OUTPUT" "$OUTPUT_FILE" "$exit_code" "$LATENCY_MS" "" "$FULL_QUERY"
|
|
194
|
+
"$TEMP_OUTPUT" "$OUTPUT_FILE" "$exit_code" "$LATENCY_MS" "" "$FULL_QUERY" || true
|
|
97
195
|
|
|
98
196
|
cat "$OUTPUT_FILE"
|
|
99
197
|
exit $exit_code
|
package/scripts/query_gemini.sh
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# GEMINI_USE_API - Use Google AI API mode instead of the agy CLI (default: false)
|
|
14
14
|
# GEMINI_API_MODEL - API model ID for API mode (default: gemini-3.1-pro-preview)
|
|
15
15
|
# GEMINI_API_KEY - API key for API mode
|
|
16
|
+
# GEMINI_REASONING_EFFORT - Optional CLI reasoning effort
|
|
16
17
|
# ENABLE_PERSONA - Enable "The Architect" persona (default: true)
|
|
17
18
|
|
|
18
19
|
set -euo pipefail
|
|
@@ -68,7 +69,6 @@ if is_api_mode "gemini"; then
|
|
|
68
69
|
else
|
|
69
70
|
exit_code=$?
|
|
70
71
|
fi
|
|
71
|
-
warn_effort_ignored_in_cli "Gemini"
|
|
72
72
|
else
|
|
73
73
|
# --- CLI Mode (Antigravity CLI: agy) ---
|
|
74
74
|
log_api_mode_status "gemini"
|
|
@@ -85,13 +85,38 @@ else
|
|
|
85
85
|
# -p argument. agy has --model (no -m alias) and no read-from-file flag, so a
|
|
86
86
|
# very large FULL_QUERY goes through argv (ARG_MAX-bounded; fine for normal
|
|
87
87
|
# contexts). stdin is /dev/null (agy ignores it; run_query's cat needs an EOF).
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
# Strip SSH_* markers so agy consults the macOS Keychain (see agy_env /
|
|
89
|
+
# AGY_ENV_PREFIX in lib/common.sh). Use the exec-safe prefix array — not the
|
|
90
|
+
# agy_env function — because run_query dispatches through GNU timeout.
|
|
91
|
+
#
|
|
92
|
+
# Optional CLI effort: when GEMINI_REASONING_EFFORT is set, pass --effort.
|
|
93
|
+
# agy accepts only a subset (e.g. low|medium|high); unsupported values fail
|
|
94
|
+
# at the provider and surface as diagnosed errors — no local allowlist.
|
|
95
|
+
GEMINI_ARGS=("${AGY_ENV_PREFIX[@]}" "$GEMINI_CMD" -p "$FULL_QUERY" --model "$GEMINI_MODEL")
|
|
96
|
+
effort_ok=true
|
|
97
|
+
if [[ -n "${GEMINI_REASONING_EFFORT:-}" ]]; then
|
|
98
|
+
source "$SCRIPT_DIR/lib/api.sh"
|
|
99
|
+
if ! cli_effort=$(validate_reasoning_effort "$GEMINI_REASONING_EFFORT" "$CONSULTANT_NAME"); then
|
|
100
|
+
effort_ok=false
|
|
101
|
+
exit_code=1
|
|
102
|
+
else
|
|
103
|
+
GEMINI_ARGS+=(--effort "$cli_effort")
|
|
104
|
+
fi
|
|
105
|
+
fi
|
|
93
106
|
|
|
94
|
-
|
|
107
|
+
if [[ "$effort_ok" == "true" ]]; then
|
|
108
|
+
# Keep failures inside an explicit conditional so `set -e` cannot skip
|
|
109
|
+
# exit_code assignment (same guard as the API branch).
|
|
110
|
+
if run_query \
|
|
111
|
+
"Gemini" \
|
|
112
|
+
"$TEMP_OUTPUT" \
|
|
113
|
+
"$GEMINI_TIMEOUT_SECONDS" \
|
|
114
|
+
"${GEMINI_ARGS[@]}" </dev/null; then
|
|
115
|
+
exit_code=0
|
|
116
|
+
else
|
|
117
|
+
exit_code=$?
|
|
118
|
+
fi
|
|
119
|
+
fi
|
|
95
120
|
fi
|
|
96
121
|
|
|
97
122
|
# --- Calculate latency ---
|
package/scripts/update_clis.sh
CHANGED
|
@@ -200,7 +200,13 @@ main() {
|
|
|
200
200
|
continue
|
|
201
201
|
fi
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
# agy under SSH must not see SSH_* markers (Keychain credential store).
|
|
204
|
+
# AGY_ENV_PREFIX is exec-safe under GNU timeout (see lib/common.sh).
|
|
205
|
+
if [[ "$default_bin" == "agy" ]]; then
|
|
206
|
+
ver="$(run_with_timeout 8 "${AGY_ENV_PREFIX[@]}" "$cmd" --version </dev/null 2>/dev/null | head -1 || true)"
|
|
207
|
+
else
|
|
208
|
+
ver="$(run_with_timeout 8 "$cmd" --version </dev/null 2>/dev/null | head -1 || true)"
|
|
209
|
+
fi
|
|
204
210
|
detect_method "$default_bin" "$cmd"
|
|
205
211
|
log_info "$display ($cmd): installed [${ver:-version n/a}] -- install method: $DETECT_METHOD"
|
|
206
212
|
|