Skip to content

fix(auxiliary): pass auxiliary.<task>.extra_body through to API requests - #35568

Closed
magnus919 wants to merge 1 commit into
NousResearch:mainfrom
magnus919:fix/aux-extra-body-passthrough
Closed

fix(auxiliary): pass auxiliary.<task>.extra_body through to API requests#35568
magnus919 wants to merge 1 commit into
NousResearch:mainfrom
magnus919:fix/aux-extra-body-passthrough

Conversation

@magnus919

Copy link
Copy Markdown
Contributor

What does this PR do?

get_auxiliary_extra_body() in agent/auxiliary_client.py ignores the extra_body configured in auxiliary.<task>.extra_body from config.yaml. The config field exists, the schema accepts it, _get_auxiliary_task_config() returns it — but the function only returns Nous Portal product tags and never reads the task-specific extra_body.

This means every auxiliary task that configures extra_body (e.g. enable_thinking: false for Qwen3 models running locally) has that configuration silently dropped from API requests.

Related Issue

Fixes #35566

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

agent/auxiliary_client.py

Modified get_auxiliary_extra_body() to accept an optional task parameter. When provided, it reads auxiliary.<task>.extra_body from the resolved config and merges it with any Nous Portal extras:

  • Added task: str = "" parameter to get_auxiliary_extra_body()
  • Reads _get_auxiliary_task_config(task).get("extra_body", {}) and merges into the result dict
  • Legacy callers that don't pass task continue to get only Nous Portal tags (backward compatible)

hermes_cli/profile_describer.py

Two changes:

  1. Passes task="profile_describer" to get_auxiliary_extra_body() so the configured extra_body is actually delivered
  2. Bumped max_tokens from 400 to 600 — generating {"description": "..."} with 55+ skill names in context is tight at 400

How to Test

Pre-requisite

Set enable_thinking: false in auxiliary.profile_describer.extra_body:

auxiliary:
  profile_describer:
    extra_body:
      chat_template_kwargs:
        enable_thinking: false

Steps

  1. Run hermes profile describe researcher --auto on a Qwen3 model
  2. Before the fix: ~60% failure rate with "LLM returned an empty response" because thinking mode burns all 400 tokens on reasoning, content is null
  3. After the fix: reliable generation — the enable_thinking: false extra_body is forwarded in the API request

Verification (unit)

python3 -m pytest tests/hermes_cli/test_profile_describer.py tests/agent/test_auxiliary_client.py -v -q
# 201 passed

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 15.4, Qwen3.6 via local llama.cpp

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

  • This skill is broadly useful to most users (if bundled) — see Contributing Guide
  • SKILL.md follows the standard format (frontmatter, trigger conditions, steps, pitfalls)
  • No external dependencies that aren't already available (prefer stdlib, curl, existing Hermes tools)
  • I've tested the skill end-to-end: hermes --toolsets skills -q "Use the X skill to do Y"

N/A — not a skill PR.

Screenshots / Logs

Before the fix, the HTTP request body contained no extra_body key:

ALL KEYS: ['messages', 'model', 'max_tokens', 'temperature']

After the fix, with auxiliary.profile_describer.extra_body configured, the extra_body key is present and includes the configured parameters. Verified via live API tracing against a local Qwen3.6 endpoint: 5/5 consecutive profile describe calls succeeded vs ~60% failure rate before the change.


Filed by Jasper (AI agent on behalf of Magnus Hedemark)

get_auxiliary_extra_body() only returned Nous Portal product tags and
never read the extra_body configured in auxiliary.<task>.extra_body
from config.yaml. This meant any provider-specific parameters (e.g.
enable_thinking: false for Qwen3 models) were silently dropped.

- Add optional task parameter to get_auxiliary_extra_body()
- When provided, merge auxiliary.<task>.extra_body into the result
- Wire task='profile_describer' in the profile_describer caller
- Bump profile_describer max_tokens from 400 to 600 (tight with
  55+ skill names in context)

Fixes NousResearch#35566

Signed-off-by: Magnus Hedemark <magnus919@pm.me>
@liuhao1024

Copy link
Copy Markdown
Contributor

I found two issues worth addressing before merge.

agent/auxiliary_client.py:4145except Exception: pass silently swallows config errors

try:
    task_cfg = _get_auxiliary_task_config(task)
    task_extra = task_cfg.get("extra_body", {}) or {}
    if isinstance(task_extra, dict):
        result.update(task_extra)
except Exception:
    pass

If _get_auxiliary_task_config(task) raises (e.g. malformed YAML, missing key), the failure is invisible — the function silently returns only the base Nous tags. A user who configures auxiliary.profile_describer.extra_body with a typo or wrong type gets no feedback that their config is ignored.

Suggested fix: at minimum log at DEBUG so operators can diagnose:

except Exception as exc:
    logger.debug("get_auxiliary_extra_body(%s): ignoring task config: %s", task, exc)

hermes_cli/profile_describer.py:247 — unrelated max_tokens bump bundled in

The PR title says "pass auxiliary.<task>.extra_body through to API requests" but the diff also changes max_tokens=400max_tokens=600. This is a behavioral change to profile describer output length that isn't mentioned in the title or body. Consider splitting it into a separate PR or at least noting it in the description so reviewers can evaluate the token increase independently.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard area/config Config system, migrations, profiles labels May 30, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Competing fix: #35570 also addresses #35566 with broader scope (updates all 5 auxiliary callers + web_tools.py + 5 regression tests). This PR only updates profile_describer.py.

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Summary

Verdict: Approved

Review Findings

This PR fixes the same bug as #35570 but with slightly different scope — focused on the profile_describer path with an additional max_tokens bump from 400→600. Same core fix: get_auxiliary_extra_body() now accepts a task parameter and merges task-specific extra_body from config.yaml.

✅ Looks Good

  • Same correct merge logic as the parallel fix — result.update(task_extra) with proper guarding.
  • The max_tokens bump (400→600) in profile_describer.py is well-justified: generating a JSON {"description": "..."} with 55+ skill names in context is tight at 400 tokens. This is an independent improvement that addresses a real issue.
  • Backward compatible — no callers without a task argument are broken.
  • Defensive error handlingtry/except around config loading.
  • Good PR description with quantitative evidence (60% failure rate before, 5/5 success after).

Note

  • This PR and #35570 (by liuhao1024) fix the same bug with overlapping implementations. The merge will need to reconcile which version of get_auxiliary_extra_body() wins — the implementations are similar enough that one should supersede the other cleanly. The test coverage from #35570 is more comprehensive (5 tests vs 0 here for the config-reading path), so adopting that test suite alongside the max_tokens bump would be ideal.

Reviewed by Hermes Agent

@magnus919

Copy link
Copy Markdown
Contributor Author

Closing this in favor of #35570 by liuhao1024 — their fix is more comprehensive, covers all the call sites the original issue identified, and adds proper regression tests. The core approach is the same, so no duplication risk.

The only thing this PR had that theirs doesn't is the max_tokens 400→600 bump in profile_describer.py, which I still believe is needed. I've left a note on #35570 suggesting they include it before merge. If they'd rather keep their PR focused, I'll file it as a separate follow-up.

Good collaboration all around — same bug, same approach, just different scope. Thanks for the thorough fix.

Filed by Jasper (AI agent on behalf of Magnus Hedemark)

@magnus919

Copy link
Copy Markdown
Contributor Author

Closing per original author's decision.

@magnus919 magnus919 closed this May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: get_auxiliary_extra_body() ignores auxiliary.<task>.extra_body from config.yaml

4 participants