Skip to content

fix(vertex): prepend mandatory google/ publisher prefix to bare model names - #56809

Open
tangtaizong666 wants to merge 2 commits into
NousResearch:mainfrom
tangtaizong666:fix/vertex-model-publisher-prefix
Open

fix(vertex): prepend mandatory google/ publisher prefix to bare model names#56809
tangtaizong666 wants to merge 2 commits into
NousResearch:mainfrom
tangtaizong666:fix/vertex-model-publisher-prefix

Conversation

@tangtaizong666

@tangtaizong666 tangtaizong666 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes the native Vertex AI provider (--provider vertex) failing every request with HTTP 400 INVALID_ARGUMENT ("Malformed publisher model") when the user supplies a standard bare model name such as gemini-3.1-flash-lite.

Vertex AI's OpenAI-compatible endpoint requires the model field in the mandatory <publisher>/<model> form (e.g. google/gemini-3.1-flash-lite). normalize_model_for_provider() in hermes_cli/model_normalize.py had no vertex branch, so bare names fell straight through the "pass through as-is" fallback and reached the API unprefixed. (The original Vertex feature PR #16010 — which contained normalization — was closed unmerged; the provider that landed as a plugin never picked up the prefix injection.)

The new vertex branch applies these rules:

  • Bare name (gemini-3.1-flash-lite) → prepend the google/ publisher prefix.
  • Explicit publisher prefix (google/…, anthropic/…, meta/…, mistralai/…) → pass through unchanged. This deliberately deviates from the snippet suggested in the issue, which rewrote any vendor/model to google/model — Vertex hosts non-Google publishers, so an explicit publisher is authoritative and must survive.
  • Matching provider prefix (vertex/gemini-3.5-flash, google-vertex/… — the aggregator-style form users copy into config.yaml) → repaired to the google/ publisher form, consistent with how other direct providers repair provider/ prefixes.

Dots in model IDs are preserved (Vertex model IDs use them, e.g. gemini-2.5-flash), and provider aliases (google-vertex, vertex-ai, gcp-vertex, vertexai) resolve to the same behavior. google/ is never mistaken for a provider prefix because the google alias canonicalizes to the gemini provider, not vertex.

Relationship to #56805 and #56806

Both opened while this change was going through its test run — flagging the overlap up front and deferring to maintainers on which to take. The behavioral differences are material, not cosmetic:

Input (provider vertex) #56805 #56806 this PR
gemini-3.1-flash-lite (the issue) google/gemini-3.1-flash-lite google/gemini-3.1-flash-lite google/gemini-3.1-flash-lite
anthropic/claude-sonnet-4.6 google/anthropic/claude-sonnet-4.6 — double prefix, malformed unchanged ✓ unchanged ✓
meta/llama-3.3-70b-instruct-maas (Vertex MaaS) google/meta/… — malformed unchanged ✓ unchanged ✓
vertex/gemini-3.5-flash (copied into config) google/gemini-3.5-flash unchanged — vertex isn't a Vertex publisher, still HTTP 400 google/gemini-3.5-flash
bare name w/o detectable vendor google/<name> unchanged — bare names are always rejected by the endpoint google/<name>

(On the last row: the endpoint's <publisher>/<model> form is mandatory, so passing a bare name through can never succeed; defaulting to google/ matches the provider's documented scope, "Gemini models via Google Cloud".)

Related Issue

Fixes #56778

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • hermes_cli/model_normalize.py — new vertex branch in normalize_model_for_provider() (strip a matching vertex/ provider prefix, keep any remaining explicit publisher/, otherwise prepend google/); module docstring and function doctest examples updated.
  • tests/hermes_cli/test_model_normalize.py — new TestIssue56778VertexPublisherPrefix regression class (12 cases: bare-name prefixing, google/ pass-through, non-Google publisher preservation, vertex/-prefix repair, alias handling, dot preservation, empty input).
  • scripts/release.py — added my commit email to AUTHOR_MAP, as required by the contributor-attribution CI check for first-time commit emails.

How to Test

  1. Automated: pytest tests/hermes_cli/test_model_normalize.py -q — the 12 new TestIssue56778VertexPublisherPrefix cases fail on main (bare names pass through unprefixed) and pass with this change; the pre-existing 86 cases stay green. scripts/run_tests.sh tests/hermes_cli/test_model_normalize.py tests/hermes_cli/test_vertex_provider.py tests/agent/test_vertex_adapter.py (CI-equivalent per-file isolation) — 125/125 pass. ruff check . clean; ty reports no new diagnostics.
  2. Repro from the issue: hermes chat -q "echo" --provider vertex --model gemini-3.1-flash-lite (with GCP ADC configured) — previously died on the first turn with HTTP 400 "Malformed publisher model ('model': 'gemini-3.1-flash-lite')"; the request now goes out as google/gemini-3.1-flash-lite, the form the issue reporter verified works.
  3. Workaround unchanged: --model google/gemini-3.1-flash-lite still passes through untouched.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: Ubuntu (WSL2, kernel 6.6.87.2-microsoft-standard)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A (no config keys changed)
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A (no architecture change)
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A (pure string normalization, no I/O)
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A (no tool behavior change)

Screenshots / Logs

Normalization through the real path (normalize_providernormalize_model_for_provider), before vs. after:

# main (bare name reaches the API unprefixed → HTTP 400)
'gemini-3.1-flash-lite'        + provider 'vertex' -> 'gemini-3.1-flash-lite'

# this PR
'gemini-3.1-flash-lite'        + provider 'vertex' -> 'google/gemini-3.1-flash-lite'
'gemini-3.5-flash'             + provider 'vertex' -> 'google/gemini-3.5-flash'
'google/gemini-3.1-flash-lite' + provider 'vertex' -> 'google/gemini-3.1-flash-lite'
'anthropic/claude-sonnet-4.6'  + provider 'vertex' -> 'anthropic/claude-sonnet-4.6'
'vertex/gemini-3.5-flash'      + provider 'vertex' -> 'google/gemini-3.5-flash'

@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard provider/gemini Google Gemini (AI Studio, Cloud Code) P3 Low — cosmetic, nice to have duplicate This issue or pull request already exists labels Jul 2, 2026
@alt-glitch

alt-glitch commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related Vertex normalization cluster: the former duplicate anchor #56806 is now closed unmerged, while current main still lacks a vertex normalization branch. This PR remains a valid focused repair for #56778: it prefixes bare Gemini/Gemma names, repairs matching Vertex aliases, and preserves explicit non-Google publisher prefixes. It is related to the broader open #56820 (which also covers native-route normalization), not a duplicate; maintainer review marked this PR keep_open with high salvageability. Related: #56778, #56805 (closed), #56806 (closed), #56820.

@tangtaizong666

Copy link
Copy Markdown
Contributor Author

Acknowledged — overlap with #56806 is disclosed in the PR body (opened while my change was mid-test-run), including a behavior comparison table. The two deltas vs #56806: (1) bare names without a detectable Google vendor still get the mandatory google/ prefix there is no bare form the endpoint accepts, so passing them through can only reproduce the 400; (2) a matching vertex/-alias provider prefix copied into config is repaired to the google/ publisher form instead of reaching the API as a nonexistent publisher. Happy either way: take this PR, or fold those two cases + the non-Google-publisher pass-through tests into #56806 — deferring to maintainers.

@tangtaizong666
tangtaizong666 force-pushed the fix/vertex-model-publisher-prefix branch from 56e1144 to aaed31a Compare July 2, 2026 14:50
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused Vertex fix. Current main still lacks a vertex branch in normalize_model_for_provider() and falls through unchanged at hermes_cli/model_normalize.py:466-467; agent/agent_init.py:498-505 applies that normalizer to Vertex models before requests. The proposed branch directly corrects that path and is consistent with the documented Vertex requirement for a google/ model prefix at website/docs/guides/google-vertex.md:87-96.

The preservation of explicit publisher-qualified IDs and repair of aliases rely on the existing _strip_matching_provider_prefix() behavior (hermes_cli/model_normalize.py:226-244) and provider aliases (hermes_cli/models.py:1231-1237). The added tests cover bare names, explicit prefixes, aliases, and the empty-input guard. GitHub reports the PR cleanly mergeable against current main.

This is an automated hermes-sweeper review.

… names

Vertex AI's OpenAI-compatible endpoint requires the model field in
<publisher>/<model> form and rejects bare names like gemini-3.1-flash-lite
with HTTP 400 INVALID_ARGUMENT ("Malformed publisher model").
normalize_model_for_provider() had no vertex branch, so bare names fell
through the as-is fallback and reached the API unprefixed.

Add a vertex branch: bare names gain the google/ publisher prefix;
explicit publisher prefixes (google/, anthropic/, meta/, ...) pass
through unchanged because Vertex hosts non-Google publishers too; a
matching vertex/ provider prefix copied from config is repaired to the
google/ publisher form.

Fixes NousResearch#56778
@tangtaizong666
tangtaizong666 force-pushed the fix/vertex-model-publisher-prefix branch from cd5621f to 099a032 Compare August 5, 2026 02:12
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 P3 Low — cosmetic, nice to have provider/gemini Google Gemini (AI Studio, Cloud Code) sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(providers): Vertex AI provider fails with HTTP 400 due to missing mandatory 'google/' publisher prefix

3 participants