Skip to content

feat(xai): detect retired May 15 models in doctor/chat startup + hermes migrate xai#29277

Merged
teknium1 merged 6 commits into
mainfrom
hermes/hermes-4a9379ae
May 20, 2026
Merged

feat(xai): detect retired May 15 models in doctor/chat startup + hermes migrate xai#29277
teknium1 merged 6 commits into
mainfrom
hermes/hermes-4a9379ae

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

xAI is retiring grok-4, grok-4-0709, grok-4-fast{,-reasoning,-non-reasoning}, grok-4-1-fast{,-reasoning,-non-reasoning}, grok-code-fast-1, grok-3, and grok-imagine-image-pro on May 15, 2026. After that date, configs pointing at those names will silently 404 or get rerouted. This PR adds detection at three surfaces and a one-shot migration command so users find out before the cutover, not after.

Changes

  • hermes_cli/xai_retirement.py — single source of truth for retired→replacement mapping with reasoning_effort hints (e.g. *-non-reasoninggrok-4.3 + reasoning_effort="none"). Recursively walks any config dict's provider/model slots.
  • hermes doctor — new "xAI Model Retirement (May 15, 2026)" section. Surfaces each retired ref with its recommended replacement and a link to xAI's migration guide.
  • hermes chat startup — same warning shown at session start so users notice without having to run doctor.
  • hermes migrate xai — new CLI subcommand. Default is dry-run (preview only). --apply rewrites config.yaml in place via ruamel.yaml round-trip (preserves comments/formatting), creating a timestamped .bak-pre-migrate-xai-* backup first. --no-backup skips the backup.
  • hermes_cli/models.py — comment note that the xAI static fallback excludes retired models.

Salvage

Cherry-picked from #23278 + #23320 (both by @Julientalbot). Conflicts in hermes_cli/doctor.py resolved to use the current _section() helper. Duplicate "align toolset defaults and model fallback" commits collapsed since main's wording is already richer.

Validation

  • scripts/run_tests.sh tests/hermes_cli/test_xai_retirement.py tests/hermes_cli/test_migrate_xai.py50/50 passing.
  • E2E with retired refs in an isolated HERMES_HOME:
    • hermes migrate xai dry-run lists both violations with the right replacement.
    • hermes migrate xai --apply creates config.yaml.bak-pre-migrate-xai-<ts>, rewrites to grok-4.3, preserves YAML structure.
    • hermes doctor surfaces the new section and flags retired refs with the migration-guide URL.

Closes #23278, closes #23320.

julientalbot-ergonomia and others added 6 commits May 20, 2026 03:25
Add hermes_cli.xai_retirement module that walks a Hermes config and
flags references to models being retired by xAI on May 15, 2026 per
the official migration guide.

Pure logic + dataclass, no I/O — testable in isolation and reusable
from a future hermes migrate xai sub-command.

Mappings (per https://docs.x.ai/developers/migration/may-15-retirement):
  - grok-4 / grok-4-0709                  -> grok-4.3
  - grok-4-fast{,-reasoning,-non-reasoning}    -> grok-4.3 (+reasoning_effort=none for non-reasoning)
  - grok-4-1-fast{,-reasoning,-non-reasoning}  -> grok-4.3 (+reasoning_effort=none for non-reasoning)
  - grok-code-fast-1                      -> grok-4.3
  - grok-imagine-image-pro                -> grok-imagine-image-quality

Slots scanned: principal.model, auxiliary.<any>.model (introspective),
delegation.model, tts.xai.model, plugins.image_gen.xai.model. Provider
prefix x-ai/ is normalized.

33 unit tests covering edge cases (empty/non-dict config, valid models,
ambiguous variants, all retired slots, formatter).
Add a new section in run_doctor that lists retired xAI model
references found in the active config and points the user at the
official xAI migration guide.

Each retired reference shows its config path (principal.model,
auxiliary.<slot>.model, delegation.model, tts.xai.model, or
plugins.image_gen.xai.model), the recommended replacement, and
whether reasoning_effort needs to be set (for non-reasoning variants
that map to grok-4.3 + reasoning_effort=none).

Findings are appended to manual_issues so the final doctor summary
reminds the user to update their config.yaml manually (no automatic
YAML rewriting in this PR — preserves comments, key order, types).

Wrapped in try/except so doctor still completes if load_config or
the retirement module raise unexpectedly.
Print a non-blocking stderr warning at the top of cmd_chat when the
active config still references xAI models scheduled for retirement
on May 15, 2026. Each line includes the config path, the recommended
replacement, and the reasoning_effort to set for non-reasoning
variants. Points to hermes doctor for full diagnostic.

Wrapped in try/except — never blocks startup. After May 15 the
upstream xAI API will return a clear error anyway; this is purely a
heads-up to give users time to migrate before that happens.
…round-trip

Extends hermes_cli.xai_retirement with apply_migration(config_path,
issues, backup=True), used by the upcoming `hermes migrate xai`
sub-command.

Uses ruamel.yaml round-trip mode so that comments, key order,
indentation, quoting style, and scalar types are preserved on
rewrite — config.yaml is treated as a user-edited file, not a
data dump.

Behavior:
  - Each issue rewrites parent[leaf] to issue.replacement
  - When issue.reasoning_effort is set (non-reasoning variants
    that map to grok-4.3), a sibling reasoning_effort key is
    added/updated alongside the model
  - Empty issues list or missing slots are no-ops (no backup,
    no rewrite)
  - When changes occur, a timestamped backup
    (.bak-pre-migrate-xai-YYYYMMDD-HHMMSS) is written first
    unless backup=False

17 unit tests cover dry-run/no-op, surgical replacement (each
slot), comment + key-order preservation, backup creation, and
idempotence (apply twice → no-op the second time).
Adds a new `migrate` top-level sub-command that delegates to
`migrate xai` for now. xAI handler:

  - Default: dry-run. Lists every retired xAI model reference
    found in config.yaml, with the recommended replacement and
    reasoning_effort hint, and points to the official xAI
    migration guide.
  - --apply: rewrites config.yaml in-place (via the ruamel
    round-trip apply_migration helper from hermes_cli.xai_retirement).
    A timestamped backup is created automatically.
  - --no-backup: skips the backup when applying (opt-in only —
    the safe default keeps a copy).

Together with the doctor + chat-startup warnings already in
this stack, this gives users three escalating signals before
the May 15, 2026 retirement date: green check / warning at
chat startup / actionable migration command.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-4a9379ae vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8983 on HEAD, 8974 on base (🆕 +9)

🆕 New issues (9):

Rule Count
invalid-argument-type 5
unresolved-import 4
First entries
hermes_cli/xai_retirement.py:190: [unresolved-import] unresolved-import: Cannot resolve imported module `ruamel.yaml`
tests/hermes_cli/test_xai_retirement.py:63: [invalid-argument-type] invalid-argument-type: Argument to function `_looks_like_xai` is incorrect: Expected `str | None`, found `Literal[42]`
tests/hermes_cli/test_xai_retirement.py:76: [invalid-argument-type] invalid-argument-type: Argument to function `find_retired_xai_refs` is incorrect: Expected `dict[str, Any]`, found `None`
hermes_cli/xai_retirement.py:84: [invalid-argument-type] invalid-argument-type: Argument is incorrect: Expected `str`, found `str | None`
tests/hermes_cli/test_xai_retirement.py:4: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/hermes_cli/test_migrate_xai.py:61: [unresolved-import] unresolved-import: Cannot resolve imported module `ruamel.yaml`
tests/hermes_cli/test_xai_retirement.py:64: [invalid-argument-type] invalid-argument-type: Argument to function `_looks_like_xai` is incorrect: Expected `str | None`, found `dict[str, str]`
tests/hermes_cli/test_migrate_xai.py:6: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/hermes_cli/test_xai_retirement.py:77: [invalid-argument-type] invalid-argument-type: Argument to function `find_retired_xai_refs` is incorrect: Expected `dict[str, Any]`, found `Literal["nope"]`

✅ Fixed issues: none

Unchanged: 4731 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/feature New feature or request comp/cli CLI entry point, hermes_cli/, setup wizard provider/xai xAI (Grok) P2 Medium — degraded but workaround exists labels May 20, 2026
@teknium1 teknium1 merged commit 5af4b73 into main May 20, 2026
20 of 21 checks passed
@teknium1 teknium1 deleted the hermes/hermes-4a9379ae branch May 20, 2026 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists provider/xai xAI (Grok) type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants