Skip to content

[OMEGA-350] Add unit tests for LLM token-budget handling - #362

Merged
TossSky merged 3 commits into
mainfrom
OMEGA-350-retry-without-reasoning
Sep 25, 2026
Merged

TossSky merged 3 commits into
mainfrom
OMEGA-350-retry-without-reasoning

Conversation

@TossSky

@TossSky TossSky commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

Description

Follow-up to #337, based on its branch. Unit tests only, no behaviour change.

Autotests/unit/test_llm_budget.py (15 tests), registered in run_mandatory, covers what #337 added: the finish_reason and incomplete_reason checks before the notice, the notice itself on an empty reply that ran out of budget for OpenRouter, OpenAI and ASI:One, the ASI:One reasoning budget mapping, the OpenRouter reasoning body, [LLM_USAGE] at INFO on both APIs, and an API error returning an empty string. The provider modules are loaded by file path with openai and config stubbed, so the tests need no container, network or token.

Earlier versions of this PR also changed provider behaviour: a retry without reasoning, one notice per streak, and keeping a truncated reply out of the loop. All three are dropped after the discussion here and in #337.

How Has This Been Tested?

CI: tests/pytest.sh 65 passed, Phase 1 144 passed (129 + 15 new), Phase 2 6 passed, MeTTa tests green.

Checklist

  • PR contains autogenerated code
  • Self-review completed
  • Test scenarios above are passed with the version of the code from PR

Comment thread Autotests/unit/test_llm_budget.py Outdated
Comment on lines +103 to +106
def make_base(create, name="ASICloud"):
provider = llm.AIProvider(name, "ASI_API_KEY", "minimax/minimax-m3", "https://example.invalid/v1")
provider._client = NS(chat=NS(completions=NS(create=create)))
return provider

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.

make_base is defined but never used.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@paul-v-snet thanks for catching this, pushed the fix in 7f5bb68.

Comment on lines +134 to +156
def test_empty_reply_out_of_budget_is_explained():
create = FakeCreate(chat_response("", "length"))
assert sent_text(make_openrouter(create).chat(PROMPT)) == llm.LLM_EMPTY_RESPONSE_MESSAGE


def test_empty_reply_with_stop_is_not_blamed_on_the_budget():
create = FakeCreate(chat_response("", "stop", completion_tokens=0, reasoning_tokens=0))
assert make_openrouter(create).chat(PROMPT) == ""


def test_openai_empty_reply_out_of_budget_is_explained():
create = FakeCreate(responses_response("", "incomplete", "max_output_tokens"))
assert sent_text(make_openai(create).chat(PROMPT, max_tokens=120)) == llm.LLM_EMPTY_RESPONSE_MESSAGE


def test_openai_empty_reply_without_incomplete_reason_returns_empty():
create = FakeCreate(responses_response("", "completed", output_tokens=0, reasoning_tokens=0))
assert make_openai(create).chat(PROMPT) == ""


def test_asione_empty_reply_out_of_budget_is_explained():
create = FakeCreate(chat_response("", "length"))
assert sent_text(make_asione(create).chat(PROMPT)) == llm.LLM_EMPTY_RESPONSE_MESSAGE

@paul-v-snet paul-v-snet Sep 23, 2026 •

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.

All test_*_empty_reply_* tests also pass when chat() crashes, since each provider's chat() returns "" when it catches an exception. Is this the expected behavior?

@TossSky TossSky Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@paul-v-snet thanks for the catch, it holds for two of them.

These three expect the notice, so a crash inside chat() already made them fail.

These two expect "" and did pass on a crash, because chat() catches the exception and returns "" in lib_llm_ext.py, openai.py and asione.py.

They now also check through swallowed_errors that chat() logged no exception. With an exception raised inside chat() all five tests fail.

Pushed the fix in 7f5bb68.

@TossSky
TossSky requested a review from paul-v-snet September 25, 2026 03:41

@paul-v-snet paul-v-snet 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.

Looks good to me now, thank you @TossSky, approved.

@TossSky
TossSky merged commit ee0618a into main Sep 25, 2026
4 checks passed
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.

2 participants