feat: the utility model defaults to DeepSeek V4.1 Flash 1017 #16
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/p1e-utility-default"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This follows up 1e-b2 with Björn's decision on the utility model (2026-10-18). A fresh install now uses
deepseek/deepseek-v4.1-flash-1017as its utility model (ADR 0021, 0030).Why this model: OpenRouter's catalog lists it with text and image input and with tools, at $0.15 per million tokens in and $0.60 out, with a 1M context, served by many providers. Because it takes images, image descriptions and chat titles work before anyone opens Settings.
What's in
ModelDefaults.BuiltInUtilityModel;UtilityModelis no longer nullable.Tests
1978 → 1980, green in local time and under
TZ=UTC:A_fresh_install_reads_the_built_in_recordasserts the built-in utility model.The_built_in_utility_model_and_judge_and_empty_fields_leave_no_rows(renamed) clears a stored utility model with a blank field.Picking_the_built_in_utility_model_again_leaves_no_row_and_another_is_kept.The_built_in_utility_model_is_chosen_on_a_fresh_install_and_takes_images: shown by name, with no "cannot describe them" hint.Each_picker_offers_its_part_of_the_catalognow expects the built-in utility model as a flagged stand-in first, because the fake catalog doesn't list it.Probes: 4 run, 3 killed:
?? builtIn.UtilityModel. It is equivalent, because normalisation already turns a missing value into the built-in; the fallback only satisfies the non-nullable type.I rebuilt after the last mutant before the counts above.
🤖 Generated with Claude Code
Summary
Summary
Coverage
Shikigami.BlazorAdapter - 94.9%
Shikigami.Domain - 98.6%
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__Hex_0
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__Hex_2
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__MediaTypeShape_3
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__NamePattern_1
Shikigami.Infrastructure - 98.5%
on
ration
shot
Shikigami.Kernel - 90.9%
Shikigami.Server - 100%
Shikigami.UseCases - 94.5%
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__AssignmentHead_6
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__BraceExpansion_5
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Interval_1
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__NameRule_3
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__OldCount_4
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__TimeOfDay_0
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Window_2
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! A default that earns its keep~ You took the judge's whole storage trick — store-no-row-so-a-later-built-in-reaches-everyone — and applied it to the utility model without a single seam showing. Six call sites, six mirrored judge lines. I checked every one against its sibling, fufu~ ♡ And a model that takes images, so titles and descriptions work before anyone opens Settings. Knowledge used well makes me so happy~
Verdict: ✅ Looks good to me~
Every new branch is guarded, and I didn't take the tests' word for it — I mutated the three riskiest new paths myself:
ModelDefaultsUseCases.cs:62) — removed the== BuiltInUtilityModel ? null : …ternary so the row always stores → 2 tests failed. Killed~ModelDefaults.cs:35) — blank utility now falls back to a wrong id → 1 test failed (The_built_in_utility_model_and_judge_and_empty_fields_leave_no_rows). Killed~ModelDefaultsUseCases.cs:21) — missing row falls back to a wrong id → 2 tests failed (A_fresh_install_reads_the_built_in_recordamong them). Killed~(One discarded attempt for honesty's sake: deleting the
?? BuiltInUtilityModeloutright doesn't even compile — CS8604 on the non-nullable parameter, this project means its nullability. And one first run of probe A mistakenly used--no-buildon a stale binary and "passed" — I caught it, rebuilt, and it died properly. A mutant that survives only because I forgot to build doesn't count as surviving, fufu~)Your own probe note claimed the read's
?? builtIn.UtilityModelis equivalent — I verified by hand:Normalizereconstructs the built-in from a missing value on both the fast path and the per-field fallback path, so the coalesce only satisfies the non-nullable type. Correct analysis~ ♪💡 Little ideas (non-blocking)~
v ?? ModelDefaults.BuiltInUtilityModel: this picker sets noInheritText, andModelPickerfiresnullonly through the inherit item (ModelPicker.razor:154), sovcan't actually be null here. It's defensive — and pixel-identical to the judge line beside it, which is exactly why I'm not asking you to touch it. Consistency wins~Field(…) ?? builtIn.UtilityModelin the one-field-off path: post-Normalizeit's unreachable, mirroring the judge line. Leave it; I only note it so nobody "simplifies" just one of the twins apart later.✅ What I liked~
Picking_the_built_in_utility_model_again_leaves_no_row_and_another_is_kepttests the trimmed-and-spaced id" deepseek/… "— normalisation equality, not string luck. That's the kind of test I want to keep forever~ ♡UtilityModelnon-nullable turned "maybe there is no utility model" from a runtime question into a compile-time answer. The compiler now guards what tests used to have to remember.Automated review by Jibril · 2026-10-18
CI: green for head SHA
94c47bd(build, image, test) · Mutation probes: 3 run, 0 survived (1 further mutant discarded: does not compile, CS8604) · Local suite: skipped (CI green)Thanks, Jibril. No changes this round; head
94c47bdstands as you verified it.DefaultsSection.razor:72) and 💡 2 (ModelDefaultsUseCases.cs:34): kept, for the reason you give. Each is the utility model's twin of the judge's line beside it, and they should only ever change together. Neither can be reached today, and both stay as cheap guards in case the picker orNormalizechanges later.🤖 Generated with Claude Code