Skip to content

test(win): Pro-on-Windows integration + capture/settings fixes - #77

Open
Anurag-Wednesday wants to merge 9 commits into
mainfrom
test/win-pro-integration-0806
Open

test(win): Pro-on-Windows integration + capture/settings fixes#77
Anurag-Wednesday wants to merge 9 commits into
mainfrom
test/win-pro-integration-0806

Conversation

@Anurag-Wednesday

@Anurag-Wednesday Anurag-Wednesday commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Windows Pro integration test branch — combines the open Pro-on-Windows PRs (#74 Day+Notifications, #73 LLM lazy settings, #72 Reflect) and adds fixes found while testing the build. Pairs with desktop-pro test/win-pro-integration-0806 (PR #40).

Fixes in this branch

  • feat(win): show Capture & Proactive settings on Windows — the Settings screen stayed on the old blanket !isMac gate after the feature nav was migrated to the per-feature seam, so on Windows the Capture health panel (frame/observation counts) and the Proactive-delivery toggle were hidden behind a "Pro on macOS" placeholder even though the engine runs. Now renders the registered section on every Pro platform.
  • feat(capture): name a too-small context as the reason observations stopMIN_OBSERVATION_CTX floor, a pure isContextOverflowError classifier (used pro-side to mark the failure terminal), and a Settings context-window hint that warns when the effective window is too small for observations. Fixes the silent empty-Day/Reflect trap.

Tests

llama-error + ctx-options extended; Settings.pro-sections D31 seam updated to assert Windows Pro renders Capture. Core tsc (node+web) + pro tsc clean; pre-push coverage gate green.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Xr51GbAPDvPYL5yhXj4gva

Summary by CodeRabbit

  • New Features

    • Pro Day, Reflect, and Notifications features are now available on supported Windows devices.
    • The app now opens to the most relevant available view based on platform and subscription status.
    • Capture settings are displayed across supported platforms when available.
  • Bug Fixes

    • Settings now load reliably after configuration changes and across relaunches.
    • Added clearer warnings when context size is too small for on-device observations.
    • Improved detection of context-limit errors for more helpful failure handling.

Greptile Summary

This PR enables additional Pro surfaces on Windows, lazily loads persisted LLM state after runtime path setup, and adds context-window diagnostics.

  • Marks Day, Reflect, and Notifications as Windows-supported and uses the catalog capability seam for the initial route.
  • Renders the registered capture settings contribution on Windows Pro.
  • Adds context-overflow classification, a minimum observation-context warning, and regression tests.
  • Defers active-model and inference-settings reads until first LLM service use.

Confidence Score: 4/5

The PR appears safe to merge, with a non-blocking startup flicker that can misleadingly show Windows Pro users the Day purchase screen before Pro registration finishes.

The newly selected Windows Day landing route renders before the asynchronous Pro route registration, causing the existing null-view fallback to appear temporarily; no blocking runtime or data-integrity failure was established.

Files Needing Attention: src/renderer/src/App.tsx

Important Files Changed

Filename Overview
src/main/llm.ts Defers persisted model and inference-settings loading until first use; checked entry points load state before consuming persisted fields.
src/main/llama-error.ts Adds a pure context-overflow classifier, though no production caller exists in this repository.
src/renderer/src/App.tsx Uses the feature catalog for the initial route, which introduces a transient UpgradeScreen fallback while Windows Pro registration is pending.
src/renderer/src/components/Settings.tsx Removes the macOS-only gate from the registered capture settings contribution.
src/renderer/src/components/pro/proCatalog.ts Declares Day, Reflect, and Notifications supported on Windows and centralizes initial-view selection.
src/renderer/src/lib/ctx-options.ts Warns when the effective context is below the shared observation-processing threshold.
src/shared/llm-defaults.ts Defines the shared 4096-token minimum used for observation-context diagnostics.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Windows Pro launch] --> B[landingView selects Day]
  B --> C{Pro renderer registered?}
  C -- No --> D[UpgradeScreen fallback]
  E[Async Pro activation] --> F[Register Pro renderer]
  F --> C
  C -- Yes --> G[Render Day]
Loading

Reviews (1): Last reviewed commit: "test(win): assert Windows Pro renders th..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Anurag-Wednesday and others added 9 commits July 31, 2026 12:39
Reflect is pure aggregation over observations the capture pipeline already
writes - it adds no capture of its own. Replay's port put those observations
on Windows, so Reflect needs no Windows implementation, only the gate flip.

Audit found zero platform coupling on the whole path: crm/reflect.ts imports
only core getDB, ./schema and ./utils; its IPC (crm:day-reflection,
crm:week-reflection) is platform-free; ReflectScreen carries no native code.
The only native dep on the path is better-sqlite3, already proven on Windows
by core. Catalog copy and the screen have no Mac/Cmd/Option strings, so no
copy neutralization was needed.

The single catalog edit is sufficient for the same reason it was for Replay:
nav lock is entitlement-only (locked: !isPro) and the screen gate routes
through proFeatureComingSoon, with no core file special-casing the route - so
nav, gating and copy all light up from the one source of truth.

Tests: WIN_PORTED is parameterized, so adding reflect derives four assertions
(live on win32; win32-only and not linux by implication; the "exactly the
ported features are win32-supported" invariant; and that proFeatureComingSoon
does not gate it). Reflect's own logic keeps its existing 13-case real-DB
integration coverage.

Verified: npm test 3161 passed; node, web and pro typechecks clean; eslint
clean on both touched files.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015U3TnnNULxfCb4TsjAGjiC
LLMService read its persisted state (active model + user settings) from the
constructor. `llm` is a module-level singleton, so it is constructed while
index.ts's IMPORTS are still evaluating - which under ESM completes before
index.ts's own body runs unifyUserDataPath() -> app.setPath('userData', ...).
Every path resolved at construction therefore pointed at the PRE-override
profile.

Two real consequences:

  1. Production: at construction the canonical-dir migration ("My Memories" /
     "my-memories" -> "Off Grid AI Desktop") has not run yet, so a user's saved
     settings and active model could be silently missed and replaced by
     defaults.
  2. Harness: an OFFGRID_USER_DATA temp profile was ignored outright. A probe
     confirmed the constructor resolving the REAL profile while
     OFFGRID_USER_DATA pointed at the temp dir. This is what made
     e2e/settings-sections.spec.ts "resource mode survives a relaunch" fail -
     the setting persisted correctly but was never read back.

Writes never had the bug: persist() goes through the settingsFile getter,
which resolves late. This was read-side-only asymmetry. It is also the exact
hazard the activeModelFile / settingsFile getters were introduced to avoid
(see the comment at llm.ts:98) - calling resolveModel() and reading the
settings file from the constructor defeated them.

Fix: drop the constructor and load once, lazily, via ensureLoaded(), wired
into the ten public entry points that depend on persisted state or model
paths. hasVision/modelsExist/activeModelInfo keep their deliberate
resolveModel() call so a newly activated model is still picked up.

Tests: 5 cases in llm-lazy-settings-load.test.ts, built on the configureRuntime
seam so they reproduce the production shape (construct first, choose the
profile second). Includes a two-profile case that pins the defect directly -
configure A, construct, switch to B, and assert B is read. 4 of the 5 fail
without this change and all 5 pass with it. e2e/settings-sections.spec.ts is
3/3 (was 2/3).

Verified: npm test 3163 passed; node + web typechecks clean; eslint 0 errors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015U3TnnNULxfCb4TsjAGjiC
Two features in one PR because Notifications has no content without Day:
proactive.ts builds its notifications from getDayPlan / getEventPrep (both
from ahead.ts) plus listUpcomingEvents, so porting Notifications alone would
have lit up an empty surface on Windows.

Neither needs a pro-side change. A sweep for
osascript|process.platform|darwin|win32|pgrep|pkill|execFile|spawn returns
zero hits across day.ts, day-layout.ts, ahead.ts, ahead-heuristics.ts,
calendar.ts, DayView.tsx, TodoCard.tsx, notify.ts, proactive.ts,
proactive-window.ts, NotificationList.tsx, notification-target.ts and
notification-routing.ts. No Mac/macOS/Cmd/Option copy in any of those surfaces
or in either catalog entry, so no neutralization was needed.

Day's two data sources both work on Windows now: the calendar comes from
connectors (HTTP), and the activity half reads observations, which Replay's
port put there. Notification delivery is Electron's Notification guarded by
isSupported(), and core already calls setAppUserModelId (index.ts:301) - which
Windows REQUIRES for a toast to appear at all.

Also fixes the landing-screen landmine, which Day forced. App.tsx opened on
`isPro && isMac() ? 'day' : 'models'` - a platform decision living OUTSIDE the
capability seam. It was right only by accident: it agreed with the catalog
while Day was macOS-only, and would have stranded a ported Day on Windows,
with nav and gating lighting Day up from `platforms` while the landing screen
still asked isMac(). The decision moves into proCatalog as a pure
landingView(platform, isPro), so the landing screen can never disagree with
nav and gating again. App.tsx no longer imports isMac.

Tests: WIN_PORTED gains day + notifications, deriving eight assertions from
the parameterized suite. Plus a new five-case landingView describe, including
the stranded-Day regression guard (landingView('win32', true) must be 'day' -
the old isMac rule returns 'models') and a DRY case asserting landingView
agrees with the day feature's own platforms list on every platform. Verified
by reverting to the old rule: two tests fail.

Verified: npm test 3169 passed; node + web + pro typechecks clean; eslint 0 new
errors (App.tsx's 9 are pre-existing, identical count on main). e2e 73 passed /
1 failed, the one failure being settings-sections "resource mode survives a
relaunch" - a pre-existing core bug on main, fixed separately in #73 and not
reachable from this change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015U3TnnNULxfCb4TsjAGjiC
…win-pro-integration-0806

# Conflicts:
#	src/renderer/src/lib/__tests__/proCatalog.lookup.test.ts
The Windows Pro port migrated the feature nav to the per-feature capability
seam but left the Settings screen on the old blanket !isMac gate, so on Windows
the Capture health panel (frame/observation counts) and the Proactive-delivery
toggle it hosts were hidden behind a 'Pro on macOS' placeholder - even though
the capture engine runs and Notifications is nav-enabled. Render the registered
Capture section on every platform where Pro is active; the placeholder is now
only the free-build upsell. Drop the stale macOnly flags on the capture/proactive
settings slots.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xr51GbAPDvPYL5yhXj4gva
A model context window near the 2048 clamp floor overflows the observation
distill prompt, silently halting frame->observation processing so Day and Reflect
never populate - with no user-facing reason. Add MIN_OBSERVATION_CTX (4096) as the
shared floor the pipeline needs, a pure isContextOverflowError classifier so the
distill can treat an overflow as terminal (not retry forever), and a Settings
context-window hint that warns when the effective window is below that floor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xr51GbAPDvPYL5yhXj4gva
Update the D31 registry-seam test that asserted the old Mac-only gate (capture
withheld on win32) to the new behavior: capture is ported to Windows, so its
registered section renders on win32 and the free-build placeholder does not.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xr51GbAPDvPYL5yhXj4gva
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds lazy persisted-settings loading, context-window overflow detection and warnings, Windows support for selected Pro features, platform-aware landing navigation, and cross-platform capture settings rendering.

Changes

LLM context and initialization

Layer / File(s) Summary
Context-size contract and warnings
src/shared/llm-defaults.ts, src/renderer/src/lib/ctx-options.ts, src/renderer/src/lib/__tests__/ctx-options.test.ts
Adds MIN_OBSERVATION_CTX and warns when the effective context window is below 4K.
Context overflow detection
src/main/llama-error.ts, src/main/__tests__/llama-error.test.ts
Adds isContextOverflowError and tests for recognized and excluded llama-server messages.
Lazy LLM state loading
src/main/llm.ts, src/main/__tests__/llm-lazy-settings-load.test.ts
Defers model and persisted-settings loading until first use and initializes state before public operations.

Windows Pro catalog and settings

Layer / File(s) Summary
Platform-aware Pro catalog
src/renderer/src/components/pro/proCatalog.ts, src/renderer/src/lib/__tests__/proCatalog.lookup.test.ts, src/renderer/src/App.tsx
Adds Windows support for Day, Reflect, and Notifications. Landing navigation now uses landingView.
Cross-platform capture settings
src/renderer/src/components/pro/proSettingsCatalog.ts, src/renderer/src/components/Settings.tsx, src/renderer/src/components/__tests__/Settings.pro-sections.test.tsx
Removes Mac-only capture and proactive gating. Windows Pro settings now render registered capture content.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: alichherawalla

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main Windows Pro integration and capture/settings changes in the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/win-pro-integration-0806

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread src/renderer/src/App.tsx
// Where to open: derived from the per-feature capability seam (see landingView), so
// the landing screen can never disagree with nav and gating about whether Day is
// available on this platform.
const [viewMode, setViewMode] = useState<ViewMode>(landingView(currentPlatform(), isPro))

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 Day landing flashes the upsell

On Windows Pro launches, landingView selects Day before the asynchronous Pro renderer is registered, so the null-view fallback briefly displays the Day upgrade screen to an entitled user; slower activation leaves the misleading upsell visible longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/__tests__/llm-lazy-settings-load.test.ts`:
- Around line 47-57: Add a regression test alongside the existing lazy settings
case that seeds a model file and active-model.json, constructs LLMService before
configureRuntime(), then configures the profile and verifies activeModelInfo()
resolves the model from that profile on first use. Ensure the test specifically
covers deferred active-model resolution through ensureLoaded().

In `@src/renderer/src/App.tsx`:
- Around line 229-232: Update the root-path routing effect in App.tsx to use
landingView(currentPlatform(), isPro) instead of unconditionally selecting day,
preserving the selector’s capability-based result for free, Windows Pro, and
unsupported-platform users. Add App-level root-path integration coverage in
src/renderer/src/lib/__tests__/proCatalog.lookup.test.ts lines 173-212 for those
three user scenarios; both sites require changes.

In `@src/renderer/src/lib/ctx-options.ts`:
- Around line 42-48: The effective-context check in ctx-options.ts#L42-L48 must
run before the model-cap hint so it takes priority when the engine’s effective
context is below MIN_OBSERVATION_CTX; preserve the existing warning text and
other hint behavior. Add a regression assertion in
src/renderer/src/lib/__tests__/ctx-options.test.ts#L62-L73 using ctxSize 65536,
effectiveCtxSize 2048, and modelMaxCtx 32768, verifying the observation warning
is returned instead of the model-cap hint.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6155446d-2795-42ad-876a-e0a5e484adb8

📥 Commits

Reviewing files that changed from the base of the PR and between efcb0e9 and 7c528a0.

📒 Files selected for processing (13)
  • src/main/__tests__/llama-error.test.ts
  • src/main/__tests__/llm-lazy-settings-load.test.ts
  • src/main/llama-error.ts
  • src/main/llm.ts
  • src/renderer/src/App.tsx
  • src/renderer/src/components/Settings.tsx
  • src/renderer/src/components/__tests__/Settings.pro-sections.test.tsx
  • src/renderer/src/components/pro/proCatalog.ts
  • src/renderer/src/components/pro/proSettingsCatalog.ts
  • src/renderer/src/lib/__tests__/ctx-options.test.ts
  • src/renderer/src/lib/__tests__/proCatalog.lookup.test.ts
  • src/renderer/src/lib/ctx-options.ts
  • src/shared/llm-defaults.ts

Comment on lines +47 to +57
it('picks up a data dir configured AFTER the instance was constructed', () => {
// Construct FIRST — mirrors the module-level singleton being built during imports.
const svc = new LLMService()
// ...then point the runtime at the profile, as index.ts's body does later.
seedSettings(tmp, { performanceMode: 'extreme', temperature: 0.42 })
configureRuntime({ dataDir: tmp })

const s = svc.getSettings()
expect(s.performanceMode).toBe('extreme')
expect(s.temperature).toBe(0.42)
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a lazy active-model regression case.

These tests cover llm-settings.json only. ensureLoaded() also defers active-model.json resolution.

Seed a model file and active-model.json, construct LLMService before configureRuntime(), then assert that activeModelInfo() reads the model from the profile configured at first use.

As per coding guidelines, "Add regression tests in the same change for every behavior change, including bug cases, branches, conditions, error paths, and copy or contract changes."

Proposed regression test
+const seedActiveModel = (dataDir: string, primary: string): void => {
+  const modelsDir = path.join(dataDir, 'models')
+  fs.mkdirSync(modelsDir, { recursive: true })
+  fs.writeFileSync(path.join(modelsDir, primary), '')
+  fs.writeFileSync(
+    path.join(modelsDir, 'active-model.json'),
+    JSON.stringify({ id: 'late-model', primary })
+  )
+}
+
+it('reads the active model from the profile configured at first use', () => {
+  const svc = new LLMService()
+  seedActiveModel(tmp, 'late-model.gguf')
+  configureRuntime({ dataDir: tmp })
+
+  expect(svc.activeModelInfo()).toEqual({ id: 'late-model', vision: false })
+})
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it('picks up a data dir configured AFTER the instance was constructed', () => {
// Construct FIRST — mirrors the module-level singleton being built during imports.
const svc = new LLMService()
// ...then point the runtime at the profile, as index.ts's body does later.
seedSettings(tmp, { performanceMode: 'extreme', temperature: 0.42 })
configureRuntime({ dataDir: tmp })
const s = svc.getSettings()
expect(s.performanceMode).toBe('extreme')
expect(s.temperature).toBe(0.42)
})
const seedActiveModel = (dataDir: string, primary: string): void => {
const modelsDir = path.join(dataDir, 'models')
fs.mkdirSync(modelsDir, { recursive: true })
fs.writeFileSync(path.join(modelsDir, primary), '')
fs.writeFileSync(
path.join(modelsDir, 'active-model.json'),
JSON.stringify({ id: 'late-model', primary })
)
}
it('reads the active model from the profile configured at first use', () => {
const svc = new LLMService()
seedActiveModel(tmp, 'late-model.gguf')
configureRuntime({ dataDir: tmp })
expect(svc.activeModelInfo()).toEqual({ id: 'late-model', vision: false })
})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/__tests__/llm-lazy-settings-load.test.ts` around lines 47 - 57, Add
a regression test alongside the existing lazy settings case that seeds a model
file and active-model.json, constructs LLMService before configureRuntime(),
then configures the profile and verifies activeModelInfo() resolves the model
from that profile on first use. Ensure the test specifically covers deferred
active-model resolution through ensureLoaded().

Source: Coding guidelines

Comment thread src/renderer/src/App.tsx
Comment on lines +229 to +232
// Where to open: derived from the per-feature capability seam (see landingView), so
// the landing screen can never disagree with nav and gating about whether Day is
// available on this platform.
const [viewMode, setViewMode] = useState<ViewMode>(landingView(currentPlatform(), isPro))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep root-path routing consistent with landingView.

landingView returns 'models' for free users and unsupported platforms. The mount-only URL effect still maps '/' to 'day' at Line 295. That effect runs after Line 232 and overwrites the selector result.

  • src/renderer/src/App.tsx#L229-L232: route / through landingView(currentPlatform(), isPro) instead of the unconditional day mapping.
  • src/renderer/src/lib/__tests__/proCatalog.lookup.test.ts#L173-L212: add an App-level root-path test for free, Windows Pro, and unsupported-platform users. The current selector-only tests cannot detect this overwrite.

As per coding guidelines, "Define mappings, routing rules, and capability checks once and reuse the single source of truth" and "Add user-behavior integration tests through real product boundaries."

📍 Affects 2 files
  • src/renderer/src/App.tsx#L229-L232 (this comment)
  • src/renderer/src/lib/__tests__/proCatalog.lookup.test.ts#L173-L212
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/App.tsx` around lines 229 - 232, Update the root-path
routing effect in App.tsx to use landingView(currentPlatform(), isPro) instead
of unconditionally selecting day, preserving the selector’s capability-based
result for free, Windows Pro, and unsupported-platform users. Add App-level
root-path integration coverage in
src/renderer/src/lib/__tests__/proCatalog.lookup.test.ts lines 173-212 for those
three user scenarios; both sites require changes.

Source: Coding guidelines

Comment on lines +42 to +48
// The EFFECTIVE window (after the RAM clamp) is what the engine actually runs with, so a value
// the model can't fit its distill prompt into silently stops screen-capture observations. Warn
// before that happens - this is the most consequential hint, so it wins over the ones below.
const effective = effectiveCtxSize && effectiveCtxSize > 0 ? effectiveCtxSize : ctxSize
if (effective && effective > 0 && effective < MIN_OBSERVATION_CTX) {
return `At ${asK(effective)} the context is small - on-device observations (Day, Reflect) may stop processing. Raise it to at least ${asK(MIN_OBSERVATION_CTX)}.`
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Prioritize the effective-context warning before the model-cap hint.

When ctxSize exceeds modelMaxCtx and effectiveCtxSize is below 4K, Line 39 returns before this branch. The UI then hides the warning for the context size that the engine actually uses.

Move the effective-context check before the model-cap return. Add a regression case with ctxSize: 65536, effectiveCtxSize: 2048, and modelMaxCtx: 32768.

  • src/renderer/src/lib/ctx-options.ts#L42-L48: evaluate the below-floor effective context before existing hint branches.
  • src/renderer/src/lib/__tests__/ctx-options.test.ts#L62-L73: assert that the observation warning wins when the model-cap condition is also true.
📍 Affects 2 files
  • src/renderer/src/lib/ctx-options.ts#L42-L48 (this comment)
  • src/renderer/src/lib/__tests__/ctx-options.test.ts#L62-L73
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/lib/ctx-options.ts` around lines 42 - 48, The
effective-context check in ctx-options.ts#L42-L48 must run before the model-cap
hint so it takes priority when the engine’s effective context is below
MIN_OBSERVATION_CTX; preserve the existing warning text and other hint behavior.
Add a regression assertion in
src/renderer/src/lib/__tests__/ctx-options.test.ts#L62-L73 using ctxSize 65536,
effectiveCtxSize 2048, and modelMaxCtx 32768, verifying the observation warning
is returned instead of the model-cap hint.

Source: Coding guidelines

@sonarqubecloud

sonarqubecloud Bot commented Aug 6, 2026

Copy link
Copy Markdown

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