Skip to content

fix(memory): scale honcho_reasoning tier with prompt complexity (#59470) - #59665

Closed
SquabbyZ wants to merge 1 commit into
NousResearch:mainfrom
SquabbyZ:fix/medium-07-issue-59470
Closed

SquabbyZ wants to merge 1 commit into
NousResearch:mainfrom
SquabbyZ:fix/medium-07-issue-59470

Conversation

@SquabbyZ

@SquabbyZ SquabbyZ commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Fixes #59470

Problem

The honcho_reasoning tool used to forward whatever reasoning_level
the calling model chose, including minimal. Honcho's minimal dialectic
tier hard-caps output at 250 tokens (MAX_OUTPUT_TOKENS=250,
MAX_TOOL_ITERATIONS=1). On reasoning-capable backend models (OpenAI
gpt-5.x / o-series and similar) that 250-token budget is shared between
hidden reasoning tokens and visible output — so a multi-fact prompt that
needed real synthesis would exhaust the budget mid chain-of-thought and
return no synthesized answer.

The minimal framing in the tool description read as "fast/cheap" —
a normal quality dial — rather than "hard output cap that can
truncate before answering". So the model reliably picked minimal for
queries that weren't suited to it.

Fix

Add a deterministic complexity heuristic in
plugins/memory/honcho/__init__.py and route every honcho_reasoning
tool call through it:

  • Classifier (_classify_query_complexity) — counts sentences,
    clause separators (;/commas), numbered-list markers, and distinct
    content tokens (after stopword removal) to bucket the prompt into
    simple / moderate / complex.
  • Selector (_select_reasoning_level) — maps the bucket to a tier
    (minimal / medium / high), honors an explicit caller override
    unless it would fall below the complexity floor (so minimal on a
    complex query is bumped to high), and clamps everything to the
    configured reasoningLevelCap.
  • Wired into handle_tool_call("honcho_reasoning", ...) so every
    explicit tool call now benefits. The existing
    _apply_reasoning_heuristic for the auto-injected dialectic is left
    untouched — it still scales by query length for the implicit cadence
    path.

This is a heuristic, not an LLM classifier, matching the issue's
expected behavior.

Tests

tests/plugins/test_honcho_tier_selection.py — 30 tests covering:

All 30 tests pass: pytest tests/plugins/test_honcho_tier_selection.py.

Relationship to existing PR #52395

That PR rewrites the tool-level description of honcho_reasoning
and the other tools. It does not touch the reasoning_level
parameter description or add runtime tier selection, so it's orthogonal.
This fix is at the handler level — the model can still see whatever
description we give it, but even if it picks minimal for a complex
query, the runtime promotes the tier so Honcho's hard cap can't
silently truncate the answer.

Environment

Verified locally on Windows / Python 3.11 against a self-hosted Honcho
backend (the same reproduction as #59470).

AI-assisted fix by https://github.com/SquabbyZ/peaks-loop

…Research#59470)

The honcho_reasoning tool used to forward whatever reasoning_level the
calling model chose, including 'minimal'. Honcho's minimal dialectic
tier hard-caps output at 250 tokens (MAX_OUTPUT_TOKENS=250,
MAX_TOOL_ITERATIONS=1), and on reasoning-capable backend models that
budget is shared between hidden reasoning tokens and visible output.
For multi-fact prompts the model routinely picks minimal and the
answer truncates mid chain-of-thought before any synthesized result.

Add a deterministic complexity heuristic (sentence count, clause
separators, numbered-list markers, distinct content tokens) and a
selector that:
  - bumps 'no override' picks to medium for multi-sentence prompts and
    to high for multi-topic / multi-clause prompts,
  - floors explicit 'minimal' / 'low' picks up to the complexity tier
    (caller can still raise the tier above the floor, but can't drop
    below it),
  - clamps everything to the configured reasoning_level_cap.

The existing _apply_reasoning_heuristic still drives the auto-injected
dialectic; this fix is scoped to the explicit honcho_reasoning tool
call path where the model picks the tier per call.

Tests cover the classifier, the selector with and without explicit
overrides, cap clamping, invalid-input handling, and an end-to-end
regression pinning issue NousResearch#59470's minimal-on-complex-query scenario.

AI-assisted fix by https://github.com/SquabbyZ/peaks-loop
@alt-glitch alt-glitch added type/bug Something isn't working comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers P3 Low — cosmetic, nice to have labels Jul 6, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

Competing with #59472 for the same issue #59470. Different mechanism: this PR adds a deterministic complexity heuristic that auto-bumps a minimal tier up to a complexity floor (logic change), while #59472 (canonical, earlier) steers the model away from minimal via the schema description string only. Related, not a duplicate — flagging the cluster for a maintainer to pick.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for targeting a real current-main path: plugins/memory/honcho/__init__.py:1352-1362 still forwards a model-selected reasoning_level unchanged.

Problems

  • plugins/memory/honcho/__init__.py:1050 accepts default, but the no-explicit return at :1087-1089 never uses it. With dialecticDynamic=true, an omitted level on a simple query becomes minimal, replacing the configured dialecticReasoningLevel; current schema text says omission uses that configured default (plugins/memory/honcho/__init__.py:110-112).
  • The explicit branch at plugins/memory/honcho/__init__.py:1081-1084 also clamps max to reasoningLevelCap. Current docs define that cap for automatic reasoningHeuristic scaling, while dialecticDynamic allows per-call model overrides (plugins/memory/honcho/README.md:266-269). The new test at tests/plugins/test_honcho_tier_selection.py:302-314 codifies the regression.

Suggested changes

  • Preserve None for omission, or use the configured default as the selector base without lowering it; add coverage with dialecticReasoningLevel=high.
  • Floor explicit low/minimal choices for complex prompts without capping higher explicit choices under the auto-heuristic cap.

Automated hermes-sweeper review.

chosen_idx = min(chosen_idx, cap_idx)
return cls._LEVEL_ORDER[chosen_idx]

# No explicit override — complexity heuristic picks the floor.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

default is validated above but never participates in selection. This makes an omitted level on a simple query become minimal; with dialecticDynamic=true, the session manager will honor that value instead of the configured dialecticReasoningLevel. Preserve None for omission or use default as the non-explicit base.

if explicit and explicit in cls._LEVEL_ORDER:
explicit_idx = cls._LEVEL_ORDER.index(explicit)
chosen_idx = max(explicit_idx, target_idx)
chosen_idx = min(chosen_idx, cap_idx)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This newly caps explicit higher choices such as max. Current Honcho documentation defines reasoningLevelCap as the ceiling for automatic reasoningHeuristic scaling, while dialecticDynamic permits per-call overrides. Do not apply this cap to explicit choices unless that public contract is deliberately changed and documented.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 15, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Closing after review against current main (post #62290 + #66052).

The issue you targeted (#59470minimal tier truncating multi-fact answers at Honcho's 250-token cap) was real, and your diagnosis was right. It's now fixed on main via #66052, which merged the guidance-side approach from #59472: the reasoning_level parameter guide explicitly warns about the 250-token cap and steers multi-fact queries to low+.

We went with guidance over enforcement deliberately: overriding an explicit reasoning_level the model chose with a keyword-counting heuristic falls into a pattern we consistently decline — second-guessing explicit choices with heuristics. When the model picks wrong, we fix the information it picks with, not silently rewrite its choice.

Appreciate the thorough test coverage in this one — the diagnosis helped confirm the issue was worth fixing. Thanks @SquabbyZ!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/memory Memory subsystem: store, providers, sync, background reviews comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades tool/memory Memory tool and memory providers type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: honcho_reasoning picks Honcho's minimal reasoning tier for multi-fact queries → answers cut off at the 250-token combined budget

3 participants