Skip to content

Retry and omit temperature when rejected by endpoint (fixes #23) - #25

Open
nandal wants to merge 1 commit into
openhackai:mainfrom
nandal:fix/issue-23-temperature-unsupported
Open

nandal wants to merge 1 commit into
openhackai:mainfrom
nandal:fix/issue-23-temperature-unsupported

Conversation

@nandal

@nandal nandal commented Oct 12, 2026

Copy link
Copy Markdown

Summary

Fixes #23.

Modern OpenAI models (gpt-5.6-sol, gpt-5.6-luna, gpt-6.*) and OpenAI-compatible gateways reject requests specifying temperature or temperature: 0.0, resulting in a 400 Bad Request error. Because gpt-5.6-sol is the default model for the openai provider in OpenHack, out-of-the-box requests to OpenAI currently fail.

Changes

  • In LLMClient.chat(), catch 400 errors where temperature is rejected as unsupported, mark the model in LLMClient._temperature_unsupported_models, log a warning, notify the UI status hook, and retry without temperature.
  • In LLMClient._chat(), omit temperature from request parameters when marked unsupported for the model.
  • Handled successive retries gracefully if both prompt_cache_key and temperature are rejected.
  • Added unit tests in tests/test_llm_retry.py covering unsupported temperature values, unsupported temperature parameters, unhandled 400 errors, and combined prompt-cache + temperature rejection.

@greptile-apps

greptile-apps Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[Medium impact] Adds retry logic for temperature parameter rejection.

The PR appears safe to merge, with non-blocking fixes recommended for the shared cache, retry notice, and test isolation.

Fix All in CodexFindings

  1. P2 Temperature settings cross endpoints ▶
  2. P2 Retry warning stays visible ▶
  3. P2 Tests leave shared flags changed ▶
Fix with agent prompt
### Issue 1
openhack/agents/llm.py:790
The shared cache uses only `self.model`. If one endpoint rejects temperature, another endpoint using the same model name will also stop receiving the client's configured temperature. The TUI lets users switch providers and models without restarting, so this state can carry across those switches. Key the cache by endpoint and model, or keep it on the client.

### Issue 2
openhack/agents/llm.py:794-795
The temperature retry notice stays set when the retry succeeds on its first attempt. Each call to `_chat` starts its attempt count over, but `_status("")` runs only when `attempt > 0`. The TUI keeps showing “retrying without it” during later work until the scan ends. Clear the notice when this retry recovers.

### Issue 3
tests/test_llm_retry.py:153-154
The new tests change shared state without restoring it. The combined test leaves `_cache_key_unsupported` true and the model in `_temperature_unsupported_models`. Later tests inherit those settings and may skip sending the parameters they are meant to check. Use a fixture with `monkeypatch.setattr` to give each test fresh flags and restore them afterward.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds retries that omit temperature after an endpoint rejects it. The client remembers rejected models and can recover when both prompt_cache_key and temperature are rejected.

  • LLM requests retry without temperature when a model rejects it.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[chat] --> B[_chat]
  B --> C{Request result}
  C -->|Success| D[Return response]
  C -->|Cache key rejected and not disabled| E[Disable prompt_cache_key]
  E --> B
  C -->|Temperature rejected and not disabled| F[Remember model and omit temperature]
  F --> B
  C -->|Other error| G[Raise error]
Loading

Reviews (1) · Last reviewed commit: "Retry and omit temperature when rejected..." · Reviewed by Greptile

Comment thread openhack/agents/llm.py
)
):
self._temperature_unsupported = True
LLMClient._temperature_unsupported_models.add(self.model)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Temperature settings cross endpoints

The shared cache uses only self.model. If one endpoint rejects temperature, another endpoint using the same model name will also stop receiving the client's configured temperature. The TUI lets users switch providers and models without restarting, so this state can carry across those switches. Key the cache by endpoint and model, or keep it on the client.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openhack/agents/llm.py
Line: 790

Comment:
**Temperature settings cross endpoints**

The shared cache uses only `self.model`. If one endpoint rejects temperature, another endpoint using the same model name will also stop receiving the client's configured temperature. The TUI lets users switch providers and models without restarting, so this state can carry across those switches. Key the cache by endpoint and model, or keep it on the client.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex Fix in Claude Code Fix in Cursor Fix in Conductor

Comment thread openhack/agents/llm.py
Comment on lines +794 to +795
self._status(f"model '{self.model}' rejected temperature — retrying without it")
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Retry warning stays visible

The temperature retry notice stays set when the retry succeeds on its first attempt. Each call to _chat starts its attempt count over, but _status("") runs only when attempt > 0. The TUI keeps showing “retrying without it” during later work until the scan ends. Clear the notice when this retry recovers.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openhack/agents/llm.py
Line: 794-795

Comment:
**Retry warning stays visible**

The temperature retry notice stays set when the retry succeeds on its first attempt. Each call to `_chat` starts its attempt count over, but `_status("")` runs only when `attempt > 0`. The TUI keeps showing “retrying without it” during later work until the scan ends. Clear the notice when this retry recovers.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex Fix in Claude Code Fix in Cursor Fix in Conductor

Comment thread tests/test_llm_retry.py
Comment on lines +153 to +154
LLMClient._temperature_unsupported_models.clear()
LLMClient._cache_key_unsupported = False

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Tests leave shared flags changed

The new tests change shared state without restoring it. The combined test leaves _cache_key_unsupported true and the model in _temperature_unsupported_models. Later tests inherit those settings and may skip sending the parameters they are meant to check. Use a fixture with monkeypatch.setattr to give each test fresh flags and restore them afterward.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/test_llm_retry.py
Line: 153-154

Comment:
**Tests leave shared flags changed**

The new tests change shared state without restoring it. The combined test leaves `_cache_key_unsupported` true and the model in `_temperature_unsupported_models`. Later tests inherit those settings and may skip sending the parameters they are meant to check. Use a fixture with `monkeypatch.setattr` to give each test fresh flags and restore them afterward.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex Fix in Claude Code Fix in Cursor Fix in Conductor

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.

temperature=0 is always sent; current OpenAI models reject it (including the openai provider's default gpt-5.6-sol)

1 participant