fix(providers): gate thinking on model capability; add an installed-font picker - #162
Merged
Merged
Conversation
`ProviderSpec.thinking_style` describes the endpoint's dialect — how this API
spells a thinking toggle. It says nothing about whether the model behind it
has one, and the two were never intersected, so any model routed through a
DeepSeek- or Zhipu-compatible endpoint received:
thinking: {"type": "enabled"}
including gpt-4o and llama3, which have no thinking mode at all. The empty
`reasoning_content` echo rode along with it.
Pre-existing, but #161 widened it by giving Zhipu a style, which is why this
is not waiting for a larger cleanup. Both halves of the answer now live in one
place: the catalog knows whether the model thinks, the spec knows how the
endpoint writes it. `model_supports_thinking()` asks the first, and the style
only applies when both agree.
Deliberately not narrowed to a vendor. A capable model reached through an
endpoint that speaks a given dialect should get that dialect — gpt-5.4 behind
a DeepSeek-compatible gateway still gets the DeepSeek body, because that is
the endpoint's contract, not a claim about who made the model.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#155 asked for a font dropdown. #161 shipped free text instead, on the grounds that a fixed menu is a hardcoded guess about the user's machine. The premise was right and the conclusion was not: the browser can be asked. `document.fonts.check()` answers whether a family resolves here, so the candidate list is filtered to what is actually installed and grouped by Interface / Monospace / CJK. Picking one appends it to the field rather than replacing it, which keeps the CJK case #155 raises working — put the CJK face alongside the Latin one and mixed text renders through a single fallback chain. The list stays advisory. Free text remains the source of truth, so a family outside the candidates is still reachable, and the candidates themselves cost nothing when absent because they are filtered out. Where the Font Loading API is missing the picker hides rather than claiming every family exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Two follow-ups to #161: one fixes a bug that PR widened, the other delivers the part of #155 it declined.
A thinking body reaching models that have no thinking mode
ProviderSpec.thinking_styledescribes the endpoint's dialect — how this API spells a thinking toggle. It says nothing about whether the model behind it has one, and the two were never intersected. Any model routed through a DeepSeek- or Zhipu-compatible endpoint received:{"thinking": {"type": "enabled"}}including
gpt-4oandllama3. The emptyreasoning_contentecho rode along with it.Pre-existing, but #161 widened it by giving Zhipu a style, so it is not waiting for a larger cleanup. Both halves of the answer now live in one place — the catalog knows whether the model thinks, the spec knows how the endpoint writes it — and the style applies only when both agree.
Deliberately not narrowed to a vendor. A capable model reached through an endpoint that speaks a given dialect should get that dialect:
gpt-5.4behind a DeepSeek-compatible gateway still gets the DeepSeek body, because that is the endpoint's contract, not a claim about who built the model.The font picker #155 actually asked for
#161 shipped a free-text field and argued a fixed dropdown would be a hardcoded guess about the user's machine. The premise was right; the conclusion was not — the browser can be asked.
document.fonts.check()reports whether a family resolves locally, so the candidate list is filtered to what is installed and grouped Interface / Monospace / CJK. Selecting one appends to the field rather than replacing it, which keeps the mixed-script case from #155 working: list the CJK face next to the Latin one and both render through a single fallback chain.Free text stays the source of truth, so families outside the candidate list remain reachable, and where the Font Loading API is absent the picker hides rather than offering settings that would do nothing.
Testing
tsc --noEmit,eslint,npm run buildcleanStill open from the same investigation
AgentDefaults.context_window_tokensis dead config on the modern path. Nothing outsidecore/compat/reads it; the runner takes its window fromExecutionProfile, which comes from the catalog. Setting it indeepcode_config.jsonhas no effect today, which matters for the context-length half of [Feature Request]: Adjustable thinking strength & context length for DeepSeek and other reasoning models #153.tests/application/test_automation_goal_runs.py::test_legacy_unreserved_turn_is_never_adopted_as_automation_initial_turnfails ~2/20 on cleanmain, unrelated to this work.