Skip to content

feat(provider/messages)Enable cross provider switch within conversation#3530

Merged
garyzhang99 merged 1 commit intoagentscope-ai:mainfrom
garyzhang99:dev/refactor_provider_messages
Apr 17, 2026
Merged

feat(provider/messages)Enable cross provider switch within conversation#3530
garyzhang99 merged 1 commit intoagentscope-ai:mainfrom
garyzhang99:dev/refactor_provider_messages

Conversation

@garyzhang99
Copy link
Copy Markdown
Collaborator

Description

Clean up provider-specific field leakage when switching models mid-conversation.

When a user switches between providers (e.g. Gemini → OpenAI) during a chat session, provider-specific artifacts stored on Msg content blocks could leak into API requests for the new provider, potentially causing request rejections or wasted payload:

  • extra_content (Gemini's thought_signature): Sent to OpenAI/Anthropic APIs which don't recognize it on tool call objects.
  • raw_input (AgentScope stream-parsing artifact): Leaked to all providers; some reject unknown fields.
  • reasoning_content injection: Applied unconditionally to all providers, including Anthropic which already passes thinking blocks natively via _format_anthropic_messages.

Changes

  1. New _clean_provider_specific_fields() in message_request_normalizer.py: Strips extra_content (unless target is Gemini) and raw_input (unconditionally) from cloned messages at normalization time.
  2. target_family parameter threaded from _normalize_messages_for_formatternormalize_messages_for_model_request so the normalizer knows which provider family to clean for.
  3. Conditional extra_content injection: Only injected into formatted payload when target is Gemini formatter.
  4. Conditional reasoning_content injection: Skipped for Anthropic (which handles thinking blocks natively), applied for OpenAI/Gemini.
  5. Fixed ordering bug: _sanitize_tool_messages (which uses raw_input to repair empty input fields) now runs before _clean_provider_specific_fields (which strips raw_input).

All operations run on deep-cloned messages; the stored conversation history is never mutated.

Related Issue: Relates to #2314

Security Considerations: N/A

Type of Change

  • Bug fix
  • Refactoring

Component(s) Affected

  • Core / Backend (app, agents, config, providers, utils, local_models)
  • Tests

Checklist

  • I ran pre-commit run --all-files locally and it passes
  • If pre-commit auto-fixed files, I committed those changes and reran checks
  • I ran tests locally (pytest or as relevant) and they pass
  • Documentation updated (if needed)
  • Ready for review

Copilot AI review requested due to automatic review settings April 17, 2026 07:00
@github-project-automation github-project-automation Bot moved this to Todo in QwenPaw Apr 17, 2026
@garyzhang99 garyzhang99 requested a deployment to maintainer-approved April 17, 2026 07:00 — with GitHub Actions Waiting
@github-actions
Copy link
Copy Markdown

Welcome to QwenPaw! 🐾

Hi @garyzhang99, this is your 17th Pull Request.

💡 Quick Tip

Great job using the PR template! Don't forget to fill in the Testing section with how to test your changes.

🙌 Join Developer Community

Thanks so much for your contribution! We'd love to invite you to join the official QwenPaw developer group! You can find the Discord and DingTalk group links under the "Developer Community" section on our docs page:
https://qwenpaw.agentscope.io/docs/community

We truly appreciate your enthusiasm—and look forward to your future contributions! 😊

We'll review your PR soon.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens request-time message normalization so users can switch model provider families (Gemini/OpenAI/Anthropic) mid-conversation without leaking provider-specific fields from previously-stored message blocks into the next provider’s API payload.

Changes:

  • Added provider-family-aware normalization that strips raw_input universally and strips Gemini-only extra_content unless targeting Gemini.
  • Threaded target_family through the formatter normalization path and fixed the ordering so tool-input repair runs before stripping raw_input.
  • Adjusted formatter-time injections so extra_content is only injected for Gemini and reasoning_content is not injected for Anthropic; added unit/integration tests covering cross-provider switches.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/qwenpaw/agents/utils/message_request_normalizer.py Adds _clean_provider_specific_fields() and target_family support; reorders sanitization before provider-field cleanup.
src/qwenpaw/agents/model_factory.py Derives target_family from formatter family; gates extra_content and reasoning_content injection by formatter family.
tests/unit/agents/test_message_request_normalizer.py Adds direct unit tests for _clean_provider_specific_fields() and target_family behavior + raw_input repair ordering.
tests/unit/agents/test_model_factory_message_normalization.py Adds tests asserting formatter-level normalization strips/preserves extra_content appropriately without mutating originals.
tests/unit/agents/test_cross_provider_normalization.py New integration-style tests simulating provider switches (Gemini→OpenAI/Anthropic/Gemini) and raw_input repair.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@garyzhang99 garyzhang99 changed the title (feat)Enable cross provider switch within conversation feat(provider/messages)Enable cross provider switch within conversation Apr 17, 2026
Copy link
Copy Markdown
Member

@qbc2016 qbc2016 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@garyzhang99 garyzhang99 merged commit ba9639f into agentscope-ai:main Apr 17, 2026
9 of 10 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in QwenPaw Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants