Skip to content

fix: resolve segmented controls not appearing due to esbuild enum inlining#1319

Open
SameDesu123 wants to merge 1 commit intokwaroran:mainfrom
SameDesu123:fix/enum-inlining-segmented-controls
Open

fix: resolve segmented controls not appearing due to esbuild enum inlining#1319
SameDesu123 wants to merge 1 commit intokwaroran:mainfrom
SameDesu123:fix/enum-inlining-segmented-controls

Conversation

@SameDesu123
Copy link
Contributor

@SameDesu123 SameDesu123 commented Mar 8, 2026

PR Checklist

  • Required Checks
    • Have you added type definitions?
    • Have you tested your changes?
    • Have you checked that it won't break any existing features?
  • If your PR uses models1, check the following:
    • Have you checked if it works normally in all models?
    • Have you checked if it works normally in all web, local, and node-hosted versions? If it doesn't, have you blocked it in those versions?
  • If your PR is highly AI generated2, check the following:
    • Have you understood what the code does?
    • Have you cleaned up any unnecessary or redundant code?
    • Is it not a huge change?
      • We currently do not accept highly AI generated PRs that are large changes.

Summary

Segmented controls (e.g., Thinking Mode, Adaptive Thinking Effort) were not appearing in Bot Settings when selecting Claude models in Vite dev mode, despite working correctly in production builds (pnpm run preview).

Related Issues

Regression introduced by #1303 (Component Registry Architecture refactor).

Changes

1. Convert TypeScript enums to const objects (src/ts/model/types.ts)

LLMFlags, LLMProvider, LLMFormat, LLMTokenizer were all TypeScript enums. esbuild (used by Vite in dev mode) inlines enum values at each import site during transpilation. When HMR causes modules to be transpiled at different times, inlined values can become stale/inconsistent — e.g., LLMFlags.claudeThinking evaluated to 12 in one module but 21 in another.

Converted all four to as const objects with companion type aliases. This preserves full type safety while ensuring values are always resolved at runtime via object property access, not compile-time inlining.

2. Simplify SettingSegmented wrapper (src/lib/Setting/Wrappers/SettingSegmented.svelte)

Replaced the fragile 3-$effect chain (DB→local sync, local→DB write-back, option reset) with direct bind:value to DBState.db. Also cleaned up processedOptions to only output { value, label } instead of spreading the full option object (which leaked condition functions).

Impact

  • No breaking changes: The const object pattern is fully backwards-compatible — LLMFlags.claudeThinking works identically as a value, and LLMFlags works as a type.
  • Fixes: Segmented controls now appear correctly in both dev and production for all models with flag-based conditions.
  • Prevents future issues: Any new enum members added to these objects will be immune to esbuild inlining inconsistencies.

Additional Notes

The numeric values are explicitly assigned and match the original enum ordinals, so no database migration or stored-value changes are needed.

Footnotes

  1. Modifies the behavior of prompting, requesting, or handling responses from AI models.

  2. Over 80% of the code is AI generated.

…ining

Convert TypeScript enums (LLMFlags, LLMProvider, LLMFormat, LLMTokenizer)
to const objects with type aliases to prevent esbuild from inlining enum
values during Vite dev mode, which caused inconsistent values across modules.

Also simplify SettingSegmented wrapper by removing fragile localValue/$effect
sync pattern in favor of direct DB binding.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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