Skip to content

Add OpenRouter quantization support and propagate model names through assistant messages#149

Merged
presstab merged 4 commits into
masterfrom
persist_modelinfo_in_chat_thread
Jun 19, 2026
Merged

Add OpenRouter quantization support and propagate model names through assistant messages#149
presstab merged 4 commits into
masterfrom
persist_modelinfo_in_chat_thread

Conversation

@presstab

Copy link
Copy Markdown
Owner

Overview

This pull request introduces two complementary improvements to the codebase. First, it adds support for configuring quantization filters specifically for OpenRouter models, allowing users to control which quantized versions of a model the provider may serve. Second, it ensures that the model name used to generate each assistant response is recorded in the message thread and displayed in the UI, giving users immediate visibility into which model produced a given response. Along the way, several related changes improve error handling, maintainability, and test coverage.

What This Means for Users

  • New /model subcommand for OpenRouter quantization – Users can now restrict an OpenRouter model to specific quantizations (e.g., int4, int8) by running /model <model_name> quantizations [int4, int8]. This helps control inference speed, cost, and quality when using OpenRouter.
  • Model name visible in assistant message bubbles – In the Textual TUI, each assistant message now shows the model name in the bubble’s border title. This provides immediate context about which model generated the response.
  • Improved error robustness – The agent pipeline now catches additional error types (e.g., json.JSONDecodeError, TypeError) when parsing JSON responses, reducing the chance of crashes from malformed output.

A Closer Look at the Changes

Error Handling Improvements

  • fetch_context_phase.py – Moved json.loads(json_content) inside the try block and extended the exception tuple to include json.JSONDecodeError and TypeError in addition to AttributeError. This prevents crashes when the LLM returns non‑JSON content or unexpected data structures.

Model Tracking in Threads

  • messages/thread.py – The add_response, add_response_partial, and finalize_response methods now accept an optional model parameter. When provided, the model name is stored alongside the message in the thread’s message list.
  • messages/message_builder.py – Type annotations were updated to reflect that message dictionaries can now contain a "model" key alongside the standard "role" and "content".
  • message_service.py – The streaming response path now consistently passes the active model name (response_model) to all thread update methods, ensuring the model is recorded during streaming and finalization.
  • commands/compact.py – When compacting a thread, the new assistant message now includes a "model" field (taken from the original compacted data) to preserve model information across compaction.

OpenRouter Quantization Support

  • commands/model.py – Added a new _parse_quantizations helper and a _handle_quantizations function that processes the /model <name> quantizations [...] subcommand. The command validates that the target model uses the OpenRouter provider and that the quantization list is well‑formed.
  • models/model_list.py – Introduced update_model_quantizations to modify the "quantizations" field of an existing model entry in the in‑memory list and persist it to disk.
  • core/application.py – Added set_model_quantizations as a public method that delegates to ModelList and triggers a UI refresh.
  • services/streaming/openai_stream.py – When the model provider is "open_router" and the model entry contains a non‑empty "quantizations" list, the stream request now includes an extra_body with {"provider": {"quantizations": [...]}}. This tells the OpenRouter API to only use the specified quantization levels.
  • services/llm_requests.py – Added _provider_messages to strip out any non‑essential keys (such as "model") from messages before they are sent to the LLM provider. This ensures that internal metadata does not leak into provider‑side message formatting.

UI Model Display

  • ui/ui_wrapper.py, ui/cli_events.py, ui/tui/textual_events.py – The stream_chunk method now accepts an optional model parameter, which is forwarded to the TUI event system.
  • ui/tui/chat/chat_view_widget.py – The StreamChunk event handler uses the provided model (or falls back to the latest assistant message’s model) when creating or updating MessageBubble widgets.
  • ui/tui/chat/message_bubble.py – The MessageBubble class now stores a model attribute and sets the bubble’s border title to the model name for assistant messages. A set_model method allows updating the model name after creation.

Help Text & Documentation

  • commands/help.py – Updated the inline help text for /model to include the quantizations subcommand, showing the full usage syntax.

Test Coverage

  • tests/test_commands_model.py – Added test cases for setting quantizations on an OpenRouter model, rejecting invalid providers, and rejecting empty quantization lists. A new OpenRouter model entry was added to the test fixtures.
  • tests/test_openai_stream.py – New test file that verifies the OpenRouter quantization parameter is correctly included in the API request extra_body when the model has a quantization list configured.

Generated by JrDev AI using deepseek-v4-flash

presstab added 4 commits June 19, 2026 14:53
- Add `/model <name> quantizations [int4, int8]` command
- Pass quantizations as provider routing in OpenAI stream for OpenRouter models
- Introduce `_parse_quantizations`, `set_model_quantizations`, `update_model_quantizations`
- Update help text and tests accordingly
- Fix error handling in fetch_context_phase by broadening exception catch
@presstab presstab merged commit 80d883e into master Jun 19, 2026
8 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.

1 participant