Skip to content

fix: MiniMax max_tokens forwarding + test_learn_episodic_mirror hygiene - #65

Open
diazMelgarejo wants to merge 2 commits into
codejunkie99:masterfrom
diazMelgarejo:fix/minimax-tokens-and-mirror-test-hygiene
Open

fix: MiniMax max_tokens forwarding + test_learn_episodic_mirror hygiene#65
diazMelgarejo wants to merge 2 commits into
codejunkie99:masterfrom
diazMelgarejo:fix/minimax-tokens-and-mirror-test-hygiene

Conversation

@diazMelgarejo

@diazMelgarejo diazMelgarejo commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Two independent, unrelated fixes found while working on #64 in this same repo

1. harness/llm.py — MiniMax OpenAI wire drops max_tokens

call_model()'s MiniMax path forwards max_tokens correctly on the Anthropic wire but silently drops it entirely on the OpenAI-compatible wire — chat.completions.create() passes model/temperature/messages and nothing for output length. Every MiniMax call through that wire has been unbounded regardless of what the caller asked for.

MiniMax's OpenAI-compatible Chat Completions API deprecated bare max_tokens in favor of max_completion_tokens; this adds it. Extended test_call_model_openai_wire_global with an assertion on the new kwarg — verified it fails with KeyError against the pre-fix code and passes with the fix.

2. tools/test_learn_episodic_mirror.py — module-stub leak + missing encoding

_load_learn() stubs sys.modules["text"]/["cluster"] to isolate learn.py from its two sibling modules for the test, but never removed the stubs afterward — they stayed process-wide for the rest of the test run. This isn't theoretical: ran it directly and confirmed both names remain in sys.modules after one call, meaning any later test or import in the same process would silently get the throwaway lambda stand-ins instead of the real modules. Now saved and restored (or removed, if there was nothing there before) in a finally block around exec_module().

Also added encoding="utf-8" to the one read_text() call in this file using the platform default, matching the convention this file already follows everywhere else (_episodic(), learn.py itself).

Deliberately not touched: test_append_mirror_fails_open_on_write_error. _append_episodic_mirror()'s fail-open behavior on a write error is this file's own explicit, documented design choice — its docstring says so directly, matching _lesson_already_appended's read-only fail-open posture elsewhere in the same file. That's a design decision, not a bug, and this PR leaves it exactly as-is.

Tests

pytest tests/test_llm_provider.py — 8 passed. python3 -m unittest test_learn_episodic_mirror (from .agent/tools/) — 3 passed. Both fixes verified in both directions (fails pre-fix, passes post-fix) before opening this PR.

Scope

2 commits, one per fix, each independently revertable. No schema changes, no new dependencies.

Note

Fix max_tokens forwarding for MiniMax and fix module stub leaks in episodic mirror tests

  • Adds max_completion_tokens to the OpenAI-compatible wire call in _call_minimax, so the caller's max_tokens value is now respected by the MiniMax provider.
  • Fixes stub leakage in _load_learn: text and cluster modules injected into sys.modules are now restored (or removed) in a finally block after exec_module completes.
  • Adds a test assertion in test_call_model_openai_wire_global verifying max_completion_tokens=4096 is passed through.

Macroscope summarized 20441c2.

call_model()'s MiniMax path silently dropped the caller's max_tokens
entirely on the OpenAI-compatible wire -- the chat.completions.create()
call passed model/temperature/messages but nothing for output length.
Every MiniMax call through this wire has been unbounded regardless of
what max_tokens the caller specified.

The MiniMax OpenAI-compatible Chat Completions API deprecated bare
max_tokens in favor of max_completion_tokens; add
max_completion_tokens=max_tokens to close the gap. The Anthropic wire
is untouched -- it already forwards max_tokens correctly and Anthropic's
API keeps that parameter name.

Extends the existing test_call_model_openai_wire_global coverage with
an assertion on the new kwarg. Verified in both directions: fails with
KeyError against the pre-fix code, passes with the fix.
_load_learn() stubs sys.modules["text"]/["cluster"] to isolate
learn.py from its two sibling modules, but never removed the stubs
after loading -- they stayed process-wide for the rest of the test
run. Verified this is a real leak, not a theoretical one: after
calling _load_learn() once, both "text" and "cluster" remain in
sys.modules; any later test or import in the same process would
silently get the throwaway lambda stand-ins instead of the real
modules. Save whatever was previously in sys.modules for those two
names (or note there was nothing) before stubbing, and restore that
exact prior state in a finally block around exec_module() so the
stubs never outlive the one learn.py load they exist for.

Also adds encoding="utf-8" to the one read_text() call in this file
that was using the platform default encoding, per this repo's own
"force UTF-8 when reading/writing tracked text" convention (already
followed everywhere else _episodic() and learn.py itself read files).

The third test in this file, test_append_mirror_fails_open_on_write_error,
is untouched: _append_episodic_mirror()'s fail-open behavior on a
write error is this file's own explicit, documented design (its
docstring says so directly, matching _lesson_already_appended's
read-only fail-open posture) -- not a bug.
@diazMelgarejo

Copy link
Copy Markdown
Contributor Author

Related: #64 (the loop-event-export allowlist fix this PR's fixes were found alongside).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant