Skip to content

local models: make max output tokens configurable (#246)#305

Open
praxstack wants to merge 2 commits into
JerryZLiu:mainfrom
praxstack:fix/246-configurable-local-max-tokens
Open

local models: make max output tokens configurable (#246)#305
praxstack wants to merge 2 commits into
JerryZLiu:mainfrom
praxstack:fix/246-configurable-local-max-tokens

Conversation

@praxstack

@praxstack praxstack commented Jul 6, 2026

Copy link
Copy Markdown

Reasoning models like qwen3.5-35b-a3b burn through the hardcoded 4000-token cap on thinking tokens before emitting any content, so titles come back empty with finish_reason length. This adds a llmLocalMaxOutputTokens UserDefaults key that overrides the cap for all local provider calls (chat requests, callTextAPI, generateText); unset, zero, or negative values keep the existing 4000 default so current local setups are unaffected.

Users can bump it with defaults write teleportlabs.com.Dayflow llmLocalMaxOutputTokens -int 32000. Kept it defaults-key-only for now; happy to add a settings row next to the local model options if you'd like it surfaced in the UI.

Fixes #246

Tested with the new OllamaProviderMaxTokensTests plus the existing suite:

Test case 'OllamaProviderMaxTokensTests.testChatRequestUsesConfiguredMaxOutputTokens()' passed
Test case 'OllamaProviderMaxTokensTests.testMaxOutputTokensDefaultsTo4000WhenUnset()' passed
Test case 'OllamaProviderMaxTokensTests.testMaxOutputTokensFallsBackToDefaultForInvalidValues()' passed
Test case 'OllamaProviderMaxTokensTests.testMaxOutputTokensReadsUserDefaultsOverride()' passed
Test case 'ProvidersSettingsViewModelTests.testProviderSetupCompletionRefreshesLocalModelSettingsFromDefaults()' passed
Test case 'TimeParsingTests.testInvalidTimes()' passed
Test case 'TimeParsingTests.testValidTimes()' passed
Test case 'WeeklyDashboardBuilderTests.testSankeyCoalescesRealOtherAppWithOverflowBucket()' passed
Test case 'WeeklyDashboardBuilderTests.testWeeklyDashboardSnapshotIsSendableForBackgroundLoading()' passed
Test case 'WeeklyDashboardBuilderTests.testWeeklyDistributionExcludesIdleFromDonutTotal()' passed
** TEST SUCCEEDED **

Follow-up hardening pass (2026-07-08)

Ran an internal hardening pass (independent code review + fresh-context verification) on this branch — no additional issues found. Independently rebuilt (xcodebuild ... build → BUILD SUCCEEDED, clean derived data) and re-ran the full DayflowTests suite from the xcresult bundle: 10/10 passed (6 pre-existing + the 4 OllamaProviderMaxTokensTests above). Also re-traced all 6 callTextAPI call sites and confirmed none passes an explicit maxTokens, so the configured default reaches every local-provider call path; no hardcoded 4000 caps remain in Core/AI/.


Follow-up hardening pass (2026-07-08)

Added 4 edge-case tests (no production code change): minimum positive override (exactly 1, pins the exclusive-zero guard), large reasoning-model override (131072 passes through unclamped into ChatRequest — the #246 case), and a default-constant-matches-fallback consistency check. Full suite: 8/8 pass.

@praxstack
praxstack force-pushed the fix/246-configurable-local-max-tokens branch from 82aec8b to 627395d Compare July 7, 2026 03:55
Follow-up hardening pass. Adds 4 tests covering gaps in the original suite:
- minimum positive override (exactly 1) pins the `configured > 0` exclusive-
  zero guard against a future `>= 0` regression
- large reasoning-model override (131072) passes through unclamped, both via
  configuredMaxOutputTokens and into the ChatRequest — the JerryZLiu#246 use case
- default constant matches the unset fallback (catches drift if one changes)

All 8 tests pass (4 original + 4 new); no production code changed.
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.

Bug: Empty title response with reasoning models (qwen3.5-35b-a3b) - hardcoded max_tokens: 4000 too small

1 participant