Skip to content

fix(providers): MiniMax system prompt fix + live integration tests for 11 providers - #622

Merged
penso merged 13 commits into
mainfrom
nervous-ironclad
Apr 9, 2026
Merged

fix(providers): MiniMax system prompt fix + live integration tests for 11 providers#622
penso merged 13 commits into
mainfrom
nervous-ironclad

Conversation

@penso

@penso penso commented Apr 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Bug fix: MiniMax silently ignores the top-level "system" JSON field — system prompts were completely lost. Now prepends system content to the first user message wrapped in [System Instructions] markers. Fixes #578, #592.

Bug fix: GPT-5/reasoning model probe failed with max_completion_tokens: 1 rejected as 400. Bumped to 16 tokens.

Live API integration tests for 11 providers (all #[ignore]d, run with -- --ignored):

Provider Tests Env var Status
MiniMax 12 MINIMAX_API_KEY 12/12
Moonshot 10 MOONSHOT_API_KEY 10/10
Anthropic 9 ANTHROPIC_API_KEY 9/9
OpenAI 9 OPENAI_API_KEY 9/9
DeepSeek 9 DEEPSEEK_API_KEY 9/9
Z.AI 9 Z_API_KEY 9/9
Gemini 9 GEMINI_API_KEY 9/9
OpenRouter 8 OPENROUTER_API_KEY 8/8
Fireworks 9 FIREWORKS_API_KEY 8/9 (rate limit)
Mistral 9 MISTRAL_API_KEY transient 503s
Kimi Code 8 KIMI_API_KEY needs membership

Each suite covers: system prompt delivery, tool calling (streaming + non-streaming), multi-turn tool use, probe, streaming, model catalog liveness, and model discovery.

Daily CI workflow (provider-integration.yml): runs all 11 providers sequentially at 06:00 UTC with max-parallel: 1 to avoid rate limits. Each provider is continue-on-error so one outage doesn't fail the whole run. Missing secrets emit a warning and skip.

Findings from integration tests

  • MiniMax: top-level system field silently ignored (fixed), all 7 catalog models alive
  • Moonshot: 13 new models not in catalog, reasoning_content required for multi-turn
  • Fireworks: 4 of 7 catalog models dead/undeployed, 11 new models
  • Anthropic: claude-3-7-sonnet-20250219 returns 404
  • OpenAI: 102 new chat-capable models, GPT-5 probe bug (fixed)
  • Z.AI: glm-4.7-flash and glm-4.7-flashx return 500, 2 new models (glm-5-turbo, glm-5.1)
  • Gemini: 4 older preview models dead, 30 new models, thought_signature required for multi-turn

Validation

Completed

  • cargo +nightly-2025-11-30 fmt --all -- --check
  • cargo +nightly-2025-11-30 clippy -p moltis-providers --all-targets --features local-llm-metal -- -D warnings
  • cargo test --workspace (all 270 provider unit tests + full workspace pass)
  • cargo test --test minimax_integration -- --ignored (12/12)
  • cargo test --test moonshot_integration -- --ignored (10/10)
  • cargo test --test anthropic_integration -- --ignored (9/9)
  • cargo test --test openai_integration -- --ignored (9/9)
  • cargo test --test deepseek_integration -- --ignored (9/9)
  • cargo test --test zai_integration -- --ignored (9/9)
  • cargo test --test gemini_integration -- --ignored (9/9)
  • cargo test --test openrouter_integration -- --ignored (8/8)

Remaining

  • ./scripts/local-validate.sh
  • Add API keys to CI secrets and trigger gh workflow run provider-integration.yml

Manual QA

  1. Deploy with MiniMax provider — verify system prompt delivered via Telegram/Discord
  2. Verify no invalid message role: system (2013) errors
  3. Verify tool calls work (not returned as text)

Fixes #578, #592

🤖 Generated with Claude Code

MiniMax's /v1/chat/completions endpoint rejects role: "system" (error
2013) and silently ignores the non-standard top-level "system" JSON
field that was used as a workaround. System prompts were completely
lost for MiniMax users.

Replace apply_top_level_system_prompt with apply_system_prompt_rewrite
which prepends system content to the first user message wrapped in
[System Instructions] markers. This is the only reliable way to
deliver system prompts to MiniMax models.

Add 12 live API integration tests (MINIMAX_API_KEY) covering system
prompt delivery, tool calling with null optional params, streaming,
multi-turn tool use, model catalog liveness, and new model detection.

Fixes #578, #592

Entire-Checkpoint: 20fc5a401287
@codspeed-hq

codspeed-hq Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will degrade performance by 46.32%

❌ 1 regressed benchmark
✅ 38 untouched benchmarks
⏩ 5 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
env_substitution 10 µs 18.7 µs -46.32%

Comparing nervous-ironclad (4dcaaf5) with main (50f621b)

Open in CodSpeed

Footnotes

  1. 5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

10 integration tests hitting the real Moonshot API (MOONSHOT_API_KEY):
system prompt delivery, tool calling (streaming + non-streaming),
multi-turn tool use, probe, model catalog liveness, and new model
detection via both /models endpoint and speculative probing.

Documents known limitation: Moonshot's thinking mode requires the
original reasoning_content to be replayed in multi-turn tool use,
but ChatMessage doesn't carry this field. The gateway works around
this by preserving raw JSON across turns.

Entire-Checkpoint: 38b6463f463f
@greptile-apps

greptile-apps Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR delivers two targeted bug fixes — MiniMax system prompt delivery (now correctly inlined into the first user message, with multimodal content handled) and the GPT-5/reasoning-model probe rejecting max_completion_tokens: 1 (bumped to 16) — plus live #[ignore]d integration tests for 11 providers and a daily CI workflow.

  • The apply_system_prompt_rewrite fix in openai.rs correctly handles string, array (multimodal), and absent content; unit tests and live tests confirm the regression is closed.
  • The CI workflow scopes each job to a single API key via GITHUB_ENV, addressing the previous all-secrets-exposed concern.
  • lib.rs was updated to add new provider catalogs but still contains claude-3-7-sonnet-20250219 (confirmed 404 by the new tests) and reportedly dead Fireworks entries; consider removing them here rather than deferring to a follow-up.

Confidence Score: 5/5

Safe to merge — both bug fixes are correct and well-tested; the sole remaining finding is a P2 cleanup of dead catalog entries that don't block the fix.

All P0/P1 concerns from prior review rounds (Secret for API keys, multimodal content drop, all-secrets-in-env) are resolved. The only open item is a P2 suggestion to remove dead Anthropic/Fireworks catalog entries that the tests discovered; this doesn't affect correctness of the fixes or the test infrastructure.

crates/providers/src/lib.rs — ANTHROPIC_MODELS and FIREWORKS_MODELS contain confirmed-dead model IDs that should be pruned.

Important Files Changed

Filename Overview
crates/providers/src/openai.rs MiniMax system prompt rewrite fix handles both string and array (multimodal) content correctly; GPT-5 probe token cap bumped to 16 — both fixes are well-tested with unit and integration coverage.
.github/workflows/provider-integration.yml Adds daily provider integration CI; correctly exports only the relevant API key per matrix job using the GITHUB_ENV pattern, addressing the previous all-secrets-exposed concern.
crates/providers/tests/minimax_integration.rs 12 integration tests covering system prompt delivery, tool calling, multi-turn, streaming, and model discovery; api_key() returns Secret throughout including the raw-reqwest model-endpoint test.
crates/providers/tests/anthropic_integration.rs 9 tests pass; KNOWN_MODELS still includes claude-3-7-sonnet-20250219 which the tests confirmed returns 404 — catalog_models_are_live won't fail on it but the production catalog in lib.rs still serves this dead entry to users.
crates/providers/tests/fireworks_integration.rs KNOWN_MODELS mirrors the lib.rs catalog; PR description notes 4 of 7 models are dead/undeployed but the catalog wasn't pruned.
crates/providers/tests/openai_integration.rs 9 tests; correctly uses streaming probe for OpenAI; Secret handled consistently.
crates/providers/tests/moonshot_integration.rs 10 tests covering reasoning_content requirement for multi-turn tool use; all patterns correct.
crates/providers/tests/gemini_integration.rs 9 tests for Gemini; handles thought_signature requirement for multi-turn; Secret correct.
crates/providers/tests/deepseek_integration.rs 9 tests; consistent structure and Secret usage.
crates/providers/tests/zai_integration.rs 9 tests for Z.AI; notes glm-4.7-flash / glm-4.7-flashx return 500 but continues-on-error.
crates/providers/tests/mistral_integration.rs 9 tests; transient 503s noted in PR description but test logic is correct.
crates/providers/tests/openrouter_integration.rs 8 tests; no static catalog (BYOM provider via discovery); patterns consistent.
crates/providers/tests/kimi_code_integration.rs 8 tests; provider uses OAuth or API key; Secret correct, kimi-code-specific base URL hardcoded appropriately.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[OpenAiProvider::serialize_messages_for_request] --> B[build request body]
    B --> C{apply_system_prompt_rewrite}
    C -->|rejects_system_role = false| D[No-op: pass body through]
    C -->|rejects_system_role = true| E[Extract & remove system messages]
    E --> F{First user message content type?}
    F -->|String| G[Prepend system block to string]
    F -->|Array multimodal| H[Insert text element at index 0]
    F -->|Missing / other| I[Replace with synthetic system block]
    E --> J{No user message at all?}
    J -->|true| K[Insert synthetic user message with system block]
    G & H & I & K --> L[Send to MiniMax API]
Loading

Reviews (3): Last reviewed commit: "fix(providers): handle multimodal conten..." | Re-trigger Greptile

Comment thread crates/providers/tests/minimax_integration.rs Outdated
@penso penso changed the title fix(providers): deliver MiniMax system prompt via first user message fix(providers): MiniMax system prompt fix + live integration tests for MiniMax & Moonshot Apr 9, 2026
@codecov

codecov Bot commented Apr 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.34513% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/providers/src/openai.rs 97.34% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

penso added 2 commits April 9, 2026 18:19
9 integration tests hitting the real Fireworks API (FIREWORKS_API_KEY):
system prompt delivery, tool calling (streaming + non-streaming),
multi-turn tool use, probe, streaming, model catalog liveness, and
model discovery via /models endpoint.

Catalog health check found 4 of 7 models are dead/undeployed, and
11 new fireworks-native models are available.

Entire-Checkpoint: 3cab30b2bdf5
Add integration tests for OpenAI (9 tests, OPENAI_API_KEY) and
Anthropic (9 tests, ANTHROPIC_API_KEY) following the same pattern:
system prompt, tool calling, multi-turn, streaming, probe, model
catalog liveness, and model discovery via /models endpoint.

Also make keyword assertions case-insensitive across all provider
integration tests — some models lowercase the injected keyword
while still correctly following the system prompt instruction.

GitHub Copilot integration tests deferred: the provider uses OAuth
device flow, not a plain API key, requiring stored tokens.

Findings:
- Anthropic: claude-3-7-sonnet-20250219 is 404 (dead)
- OpenAI: 102 new chat-capable models not in our catalog

Entire-Checkpoint: d1c3e7e56c47
@penso penso changed the title fix(providers): MiniMax system prompt fix + live integration tests for MiniMax & Moonshot fix(providers): MiniMax system prompt fix + live integration tests for 5 providers Apr 9, 2026
penso added 8 commits April 9, 2026 18:58
GPT-5 models reject max_completion_tokens: 1 with a 400 error in the
probe path. Use streaming reachability check instead so probe and
catalog health tests pass. All 9 OpenAI integration tests now green.

Entire-Checkpoint: 233ed0399ecc
GPT-5 and reasoning models reject max_completion_tokens values below
~10 with a 400 error instead of truncating. Raise the probe cap from
1 to 16 tokens so provider reachability checks succeed.

Closes moltis-6lt

Entire-Checkpoint: caf68aaad1db
Runs live API integration tests for MiniMax, Moonshot, Fireworks,
Anthropic, and OpenAI on a daily schedule (06:00 UTC) and on manual
dispatch. Each provider runs as a separate matrix job with
max-parallel: 1 to avoid rate limits. Jobs are continue-on-error so
a single provider outage doesn't fail the whole workflow. Secrets
are checked before running — missing keys emit a warning and skip.

Entire-Checkpoint: 10ba5757cbc7
…ests

Add live API integration tests for three more providers:
- Mistral (9 tests, MISTRAL_API_KEY): mistral-large-latest
- OpenRouter (8 tests, OPENROUTER_API_KEY): openai/gpt-4o-mini
- Kimi Code (8 tests, KIMI_API_KEY): kimi-k2.5

All follow the same pattern: system prompt, tool calling, multi-turn,
streaming, probe, and model catalog. Add all three to the daily CI
workflow matrix.

Results: OpenRouter 8/8 pass, Mistral has transient 503s (API
instability), Kimi Code needs active membership (402).

Entire-Checkpoint: 271d9be8e07a
9 integration tests hitting the real DeepSeek API (DEEPSEEK_API_KEY):
system prompt, tool calling, multi-turn, streaming, probe, model
catalog liveness, and model discovery. All 9/9 pass. Added to the
daily CI workflow matrix.

Entire-Checkpoint: 10261dbded0d
9 integration tests for Google Gemini (GEMINI_API_KEY): system prompt,
tool calling, multi-turn, streaming, probe, model catalog liveness,
and model discovery. Handles Gemini's "models/" prefix in API model
IDs. Added to daily CI workflow matrix.

Model discovery found 30 new Gemini models not in catalog, and 2
preview models (gemini-2.5-flash/pro) promoted to stable names.
Functional tests need billing enabled on the Google AI project.

Entire-Checkpoint: 01cbf097d0e9
Z.AI (9 tests, Z_API_KEY): 9/9 pass. Found glm-4.7-flash and
glm-4.7-flashx return 500. Discovered 2 new models (glm-5-turbo,
glm-5.1).

Gemini (9 tests, GEMINI_API_KEY): 9/9 pass with gemini-3.1-flash-
lite-preview. Handles models/ prefix in API IDs. Multi-turn gracefully
handles thought_signature requirement (same pattern as Moonshot
reasoning_content). Found 30 new Gemini models and 4 dead catalog
entries (older preview models removed). Both added to daily CI.

Entire-Checkpoint: c69e8b227ce5
Replace raw std::env::var reads with api_key().expose_secret() in
all provider integration test model discovery functions. This keeps
API keys wrapped in Secret<T> until the point of use, consistent
with the codebase's secrecy policy.

Resolves Greptile review comment.

Entire-Checkpoint: 8978a5453e28
Comment thread crates/providers/src/openai.rs Outdated
Comment thread .github/workflows/provider-integration.yml
@penso penso changed the title fix(providers): MiniMax system prompt fix + live integration tests for 5 providers fix(providers): MiniMax system prompt fix + live integration tests for 11 providers Apr 9, 2026
…write

The system prompt rewrite for MiniMax used as_str() which silently
dropped multimodal (array) content. Now handles three cases:
- String content: prepend system text as before
- Array content (text + images): insert system text block at index 0
- Missing content: set system text directly

Also scope CI secrets to only the relevant provider per matrix job
instead of exposing all 11 API keys to every job.

Resolves Greptile review comments.

Entire-Checkpoint: b46f56af8196
@penso
penso merged commit e8971fe into main Apr 9, 2026
15 of 24 checks passed
@penso
penso deleted the nervous-ironclad branch April 9, 2026 22:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] [minimax] Channel sessions have empty system prompt — no identity, soul, skills, workspace files, or boot instructions injected

1 participant