Skip to main content

Route an image question to a capable model

Section ID: Guide/j8qfgsv52q#filter-candidate-models

Let a customer ask what is in an uploaded image and require image-capable candidates for that request. Use a per-send filter for this occasional attachment; keep a thread default for workloads that always have the same requirement.

The recipe finishes with a correlated answer from the accepted run or a clear selection failure. Catalog metadata filters candidate models; it does not validate the image or guarantee correct interpretation.

Before you start​

Section ID: Guide/j8qfgsv52q#get-started

Use an existing authenticated conversation, permitted image content and named model candidates available to your account. Replace research-001 and <base64_image> with the actual thread and input.

Wait for any unresolved turn to settle. The current queue path does not retain overrideGenerationConfig, so an override-dependent image request must not be queued behind an active run.

If the thread already has a routing filter, copy every constraint this image request must keep into the per-send filter. That filter replaces the whole base filter; adding image support alone does not preserve a prior context or price constraint.

Choose the filter’s lifetime​

Section ID: Guide/j8qfgsv52q#where-to-set-the-filter

The per-send recipe below serves one image request. Use the persistent research-thread variant when every turn has the same requirement. A per-send filter replaces the entire base filter, so include every constraint the current request must keep.

Step 1: send the image with its required capability​

Section ID: Guide/j8qfgsv52q#2-per-message-override

Set via send-message in overrideGenerationConfig.modelRoutingFilter. Applies to a single message only.

Request example: Send a message to a conversation. Example identifiers and values are illustrative; substitute authorized values.

Example request headers: X-API-Key: $API_KEY; Authorization: Bearer $JWT; Content-Type: application/json. Replace the credential and user placeholders with your own authorized values.

Note: The override merges — it does not replace

overrideGenerationConfig is merged field-by-field onto the config the thread would otherwise use. Send only what you want to change; everything you leave out is inherited.

The granularity is the top-level config field. A field you do set replaces the base value wholesale rather than merging into it, so a partial modelRoutingFilter in an override replaces the thread's filter entirely — it does not combine with it.

Two details worth knowing:

  • Explicit zeros count. Scalars are presence-aware, so "temperature": 0 overrides the base rather than reading as "unset".

  • Empty lists do not. Repeated and map fields have no presence, so an empty list is indistinguishable from an absent one and inherits instead. clearTools: true clears inherited static tools only when the override's own tools list is empty; a non-empty list replaces the inherited list. It never clears clientTools. When MCP discovery returns a result, it replaces tools after the merge, including when discovery returns no tools. Discovery normally runs even with no configured servers; it is skipped for a profile that disables default tools and has no nonblank server references. The flag therefore does not disable MCP discovery or guarantee a turn without tool calls.

Retain the returned run ID. If all candidates are rejected, show the routing error; do not quietly drop the image requirement to obtain an answer.

Step 2: inspect the accepted run and its answer​

Section ID: Guide/j8qfgsv52q#how-filters-combine

Follow generation to a correlated outcome, then inspect the image answer and actual returned model. Use these rules to diagnose why a candidate or constraint was selected.

Finished result: the request either has a completed image answer for its accepted run or a visible failure. If the user asks a later text-only question, omit this per-send override to use the thread's default configuration again.

Variant: keep a capability requirement for a long research thread​

Section ID: Guide/j8qfgsv52q#1-thread-level-default

Set via create-thread in defaultGenerationConfig.modelRoutingFilter. Applies to every message in the thread.

Request example: Create a new conversation thread. Example identifiers and values are illustrative; substitute authorized values.

Example request headers: X-API-Key: $API_KEY; Authorization: Bearer $JWT; Content-Type: application/json. Replace the credential and user placeholders with your own authorized values.

Keep the returned thread ID and send the research material to that thread. Inspect the first run and later context size; requiring a 128k catalog window does not make an arbitrarily long history fit. Use compaction when the material grows.

Choose the additional constraints the task needs​

Section ID: Guide/j8qfgsv52q#modelroutingfilter-fields

Add a constraint only when it serves the customer task, then repeat the request and inspect its outcome. For a longer answer, require the needed output capacity. For a tool-using structured answer, require the supported parameters. Multiple constraints are ANDed; every specified requirement must pass.

For price constraints, use the variant below and track actual usage separately.

Variant: narrow catalog prices while tracking actual cost​

Section ID: Guide/j8qfgsv52q#price-filters-are-not-spending-budgets

Use catalog-price filters to narrow candidates, then track the task’s actual usage. Set separately enforced spending limits before increasing paid traffic.

Document ID: Guide/j8qfgsv52q