Skip to content

Auxiliary client uses independent resolution path, diverges from main conversation loop #19437

@hunterlarcuad

Description

@hunterlarcuad

Summary

The main conversation loop at run_agent.py:4683-4684 constructs its request client from self._client_kwargs (the updated runtime kwargs). However, the auxiliary client (agent/auxiliary_client.py) resolves providers via a completely independent code path (_resolve_task_provider_model()resolve_provider_client()).

This means any runtime changes to _client_kwargs (e.g., model switch, provider override, base_url update) are not reflected in auxiliary tasks.

Affected Code Paths

All auxiliary consumers go through get_text_auxiliary_client(task) or get_async_text_auxiliary_client(task):

Purpose / Task Entry Point
Context compression get_text_auxiliary_client("compression")
Summarization get_text_auxiliary_client("summarization")
Memory flush get_text_auxiliary_client("memory_flush")
Vision analysis resolve_vision_provider_client()

Impact

  • Severity: Medium
  • Scope: All auxiliary tasks across every platform (CLI, Telegram gateway, cron jobs)

Symptoms

  1. User switches model/provider mid-session via /model → main loop picks it up, but compression/summarization/vision still use the original provider from config/env.
  2. Runtime _client_kwargs mutations (base_url, api_key changes) are invisible to auxiliary calls.
  3. Inconsistent behavior: main LLM call succeeds with new provider, but auxiliary task fails or returns stale results because it resolved a different (or unavailable) backend.

Root Cause

Two separate resolution paths:

Main loop (correct — runtime-aware):

# run_agent.py ~L4683-4684
request_client = self._create_request_openai_client(reason="chat_completion_request")
result["response"] = request_client.chat.completions.create(**api_kwargs)
# Uses self._client_kwargs which is updated at runtime

Auxiliary (stale — config-only):

# auxiliary_client.py get_text_auxiliary_client()
provider, model, base_url, api_key, api_mode = _resolve_task_provider_model(task or None)
return resolve_provider_client(provider, model=model, ...)
# Reads from config/env, never sees self._client_kwargs

Suggested Fix Direction

Pass runtime client kwargs (or the resolved client itself) into auxiliary call sites so they reuse the same resolution as the main loop. At minimum:

  1. Add an optional runtime_client_kwargs parameter to get_text_auxiliary_client() / get_async_text_auxiliary_client().
  2. When provided, skip _resolve_task_provider_model() and build the client directly from the passed kwargs.
  3. Callers in run_agent.py pass self._client_kwargs; fallback for external callers (gateway, cron) remains current behavior.

Environment

  • Relevant file: agent/auxiliary_client.py, run_agent.py
  • AIAgent class owns self._client_kwargs which is the source of truth for the main loop

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/agentCore agent loop, run_agent.py, prompt buildertype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions