#4707·higress

Proposal: prevent model-router auto routing from reusing stale text across user turns

Author: zmuxunyCreated Sep 16, 2026Updated Sep 16, 2026

Prevent model-router auto routing from reusing stale text across user turns

Summary

Fix model-router auto routing so that routing text is derived only from the last role: user message. If that last user message contains no text part (e.g. image-only multimodal content), an earlier user message must not remain as the routing input.

Background

On current main (faccaad586a3cdc9e85dc7fa39358ff31a6453b2), extractLastUserMessage keeps lastUserContent outside the message loop. For a user message with array content, it updates that variable only when it sees a type: text item.

Therefore a later user message containing only non-text parts leaves the previous user text intact. handleJsonBody can then match an auto-routing rule against text from an earlier turn rather than the actual last user turn.

This is a source-level diagnosis from the current implementation. Runtime red/green evidence has not yet been produced and will be required by the repository bug-fix policy before review.

Minimal diagnostic input

json
{
  "model": "higress/auto",
  "messages": [
    {"role":"user","content":"Please write code"},
    {"role":"assistant","content":"What should I inspect next?"},
    {"role":"user","content":[{"type":"image_url","image_url":{"url":"https://example.invalid/test.png"}}]}
  ]
}

With a routing rule matching code, the current helper can return Please write code even though the last user message has no text. The expected routing input is empty, so the existing defaultModel fallback should apply.

Goals

  • Make the helper's result depend only on the final user message.
  • Preserve current behavior for a string-valued last user message.
  • Preserve current behavior for a multimodal last user message containing text.
  • Preserve the current convention of returning the last text part when a single user message contains multiple text parts.
  • Return an empty routing string when the last user message has no text part.
  • Keep auto-routing rule ordering and default-model fallback unchanged.

Proposed behavior boundary

The fix should first identify or isolate the final role: user message, then extract text only from that message. An equivalent implementation may reset per-user-message state before inspecting each user turn, provided tests prove that earlier text cannot survive a later textless user message.

Scope

Expected production changes are limited to plugins/wasm-go/extensions/model-router/main.go and directly related tests. A Design must define the exact runtime-verification harness before implementation verification begins.

Non-goals

  • Interpreting images, audio, files, or other non-text content for routing.
  • Concatenating text across multiple user turns.
  • Redesigning multimodal message schemas.
  • Changing regex rules, target-model selection, or defaultModel semantics.
  • Broad refactoring of the model-router request parser.

Success criteria

  • A later image-only user message produces an empty routing string even if an earlier user turn contains a matching keyword.
  • The existing simple-string and multimodal-with-text cases continue to pass.
  • Multiple text parts in the same final user message retain the existing last-text-part behavior.
  • A request-level regression proves that stale text cannot select a routing rule and that the existing default-model fallback is used instead.
  • Required baseline/fixed real proxy-Wasm evidence uses identical pinned input, records exact source/Wasm SHAs, request/response identity, logs, rerun steps, hashes, and cleanup proof.

Related work and duplicate audit

Open Issue and PR searches on 2026-09-16 found no report or implementation for this stale cross-turn routing-text behavior in model-router.

Existing assumptions impact

The helper is already named and documented as extracting the content of the last user message. This change aligns the implementation with that existing contract rather than introducing a new routing policy.

Agent participation and approval request

A coding agent materially assisted with source analysis, duplicate checking, and preparation of this Proposal. No implementation, tests, or runtime verification for this bug fix have begun. Please review this Proposal before a Design and TASKs are authored; implementation will not begin until the Proposal and later Design receive explicit Higress maintainer approval and the implementation/verification TASKs are authorized.