Skip to content

Commit cbf21a1

Browse files
authored
Improve WinUI model metadata and GPU discovery filtering (#261)
WinUI discovery omitted build update dates and kept repositories for other GPU platforms when For this PC was enabled. Downloaded cores could also appear under preparation names such as checkpoint. Revision metadata, published platform branches, and retained acquisition records supply the display information without downloading weights or loading a core. Carry the resolved branch's lastModified through the catalog and native bridge, showing its date on cards and UTC time in Details. Compare all recognized platform branches with the detected GPU for filtering, prefer matching suffixed branches for display metadata, and retain unknown results. Downloaded cores continue to use inspected requirements. Use a single recorded repository for local card names, with the stored name as the fallback for missing or ambiguous origins. Branch matches remain display hints; loading validates core compatibility and available memory. Users can see build freshness, hide repositories published only for other GPU platforms, and identify downloaded models on Home and in the library. Catalog regressions passed for GB10/GB202/GB300 pairings, branch suffixes, branch-specific and missing dates, and unknown hardware or build metadata. Local naming, acquisition association, recommendation, and native bridge tests passed. Live ARM64/GB10 UI checks verified the date and UTC timestamp, GB202 entries hiding and returning with the checkbox, a matching GB10 entry remaining visible, and the cached Nemotron repository name on Home. The ARM64 native rebuild and standalone packaging passed. The naming smoke check used MSBuild /t:Rebuild because incremental native linking retained an older executable; the relink defect is tracked in docs/TODO.txt. Native x64 and live GB202/GB300 machines were not exercised. Design-Signed-Off-By: Codex (GPT-6); design-review=cfcf
1 parent 7f534bb commit cbf21a1

11 files changed

Lines changed: 265 additions & 36 deletions

File tree

‎docs/TODO.txt‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
[ ] Ensure Rust bridge updates relink the WinUI executable during incremental
2+
builds. MSBuild can retain flare-winui.exe after the bridge library changes;
3+
verify loose and single-file outputs without requiring /t:Rebuild.
4+
15
[ ] Expose the selected deployment's rebuild metadata in flare inspect --json.
26
Payload cores report rebuild: null even when DeploymentBody.rebuild is present.
37

‎flare-winui/Dashboard.inl‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
auto name=label(model.name,15);name.MaxLines(2);name.FontWeight(Windows::UI::Text::FontWeights::SemiBold());info.Children().Append(name);
2727
auto metadata=model.available()?(model.size_known?bytes(model.size)+L" · ":L"")+(model.flags&FLARE_MODEL_LOCAL?L"Downloaded":L"On this PC"):L"";
2828
if(!model.available()&&(model.metadata_known&FLARE_MODEL_REVISION_SIZE))metadata=bytes(model.revision_bytes)+L" repository files";
29+
if(!model.revision_updated_at.empty())metadata+=(metadata.empty()?L"":L" · ")+std::wstring(L"Hub updated ")+updated_text(model.revision_updated_at,true);
2930
if(!model.error.empty())metadata=L"Needs attention";
3031
if(!metadata.empty()){auto caption=label(metadata,12,true);caption.MaxLines(2);info.Children().Append(caption);}row.Children().Append(info);
3132
StackPanel actions;actions.Orientation(Orientation::Horizontal);actions.Spacing(8);actions.VerticalAlignment(VerticalAlignment::Center);Grid::SetColumn(actions,2);
@@ -42,7 +43,7 @@
4243
auto fingerprint=std::to_wstring(can_change_model_)+L"/"+std::to_wstring(current_operation_)+L"/"+std::to_wstring(session_state_)+L"/"+std::to_wstring(home_inventory_pending_)+L"/"+std::to_wstring(card_padding_);
4344
for(auto const& model:models_)if((model.available()&&!model.catalog())||(model.catalog()&&model.recommended())){
4445
if(model.catalog())recommended.push_back(&model);else local.push_back(&model);
45-
for(auto const& field:{std::wstring(to_hstring(model.id)),model.name,model.source,model.error})fingerprint+=std::to_wstring(field.size())+L":"+field;
46+
for(auto const& field:{std::wstring(to_hstring(model.id)),model.name,model.source,model.error,model.revision_updated_at})fingerprint+=std::to_wstring(field.size())+L":"+field;
4647
fingerprint+=L"/"+std::to_wstring(model.flags)+L"/"+std::to_wstring(model.size)+L"/"+std::to_wstring(model.size_known);
4748
fingerprint+=L"/"+std::to_wstring(model.metadata_known)+L"/"+std::to_wstring(model.revision_bytes);
4849
}

‎flare-winui/Details.inl‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
if(model.metadata_known&FLARE_MODEL_PARAMETERS)property(detail_rows_,L"Parameters",count_text(model.parameter_count));
2323
if(!model.hardware.empty())property(detail_rows_,L"Published builds",model.hardware);
2424
if(!model.license.empty())property(detail_rows_,L"License",model.license);
25-
if(model.metadata_known&FLARE_MODEL_REVISION_SIZE){property(detail_rows_,L"Revision files",bytes(model.revision_bytes));property(detail_rows_,L"Revision",model.revision);detail_rows_.Children().Append(label(L"Includes every file in this Hub revision. The selected core download and GPU memory use can differ.",12,true));}
25+
if(model.metadata_known&FLARE_MODEL_REVISION_SIZE){property(detail_rows_,L"Revision files",bytes(model.revision_bytes));detail_rows_.Children().Append(label(L"Includes every file in this Hub revision. The selected core download and GPU memory use can differ.",12,true));}
26+
if(!model.revision.empty())property(detail_rows_,L"Revision",model.revision);
27+
if(!model.revision_updated_at.empty())property(detail_rows_,L"Last updated",updated_text(model.revision_updated_at));
2628
if(!model.revision_commit.empty())property(detail_rows_,L"Commit",model.revision_commit);
2729
detail_rows_.Children().Append(label(L"These details are reported by the Hugging Face repository. Core verification and compatibility checks run before use.",12,true));
2830
} else detail_rows_.Children().Append(label(L"Inspecting core metadata…",14,true));
@@ -44,6 +46,7 @@
4446
if(fingerprint==detail_fingerprint_)return;detail_fingerprint_=fingerprint;
4547
detail_rows_.Children().Clear();detail_rows_.Children().Append(label(detail_model_.description.empty()?L"Prepared Flare core":detail_model_.description,14,true));
4648
property(detail_rows_,L"Source",detail_model_.catalog()?detail_model_.source:L"On this PC");
49+
if(!detail_model_.revision_updated_at.empty())property(detail_rows_,L"Hub last updated",updated_text(detail_model_.revision_updated_at)+L" · "+detail_model_.revision);
4750
property(detail_rows_,L"Publisher",wide(value.publisher));
4851
property(detail_rows_,L"Core checks",wide(value.metadata_status));
4952
property(detail_rows_,L"Core size",detail_model_.size_known?bytes(detail_model_.size):L"Not reported");

‎flare-winui/README.md‎

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ Discovery cards show the repository author, published precision, task, license,
109109
context, and hardware builds when that metadata is available. Missing fields
110110
are omitted. Hub file sizes cover every file in one resolved revision, including
111111
documentation and other deployments; they are not an exact download size or a
112-
GPU memory requirement. Details identifies the revision and commit. Cached
112+
GPU memory requirement. Cards show the last update date of the resolved hardware
113+
branch when Hugging Face provides it. Details identifies the branch, commit, and
114+
last commit time in UTC. For downloaded discovery entries, this date describes
115+
the Hub branch; the installed core may be from an earlier commit. Cached
113116
cores show logical payload size as Core data, with context and hardware from
114117
installed deployments. Logical payload size can differ from storage usage.
115118
Discovery reads Hub metadata and small configuration files, without fetching
@@ -120,10 +123,13 @@ promotional subtitles; the empty Downloads view shows No downloads and Browse
120123
models alongside access to core storage.
121124

122125
Home centers on running a local core and observing its runtime. Installed
123-
cores have a Run model action. Add model opens a single chooser for Hugging Face
124-
discovery, a repository link, or a local core file or folder. Model details are
125-
available in Models. Loading shows runtime progress. A running model exposes
126-
switch and stop controls alongside the serving address and its copy action.
126+
cores have a Run model action. Cached models with one recorded Hugging Face
127+
repository use its repository name on Home and in the library. Local exports
128+
use the model name recorded in their core metadata. Add model opens a single
129+
chooser for Hugging Face discovery, a repository link, or a local core file or
130+
folder. Model details are available in Models. Loading shows runtime progress.
131+
A running model exposes switch and stop controls alongside the serving address
132+
and its copy action.
127133
Chat remains available in the sidebar for testing the active session.
128134
The dashboard uses the CLI overview's two-second rate window and 120-second
129135
history for prefill, generation, verification, and draft acceptance/depth.
@@ -147,8 +153,13 @@ Clear failed removes failed entries from download history. Completed, active,
147153
paused, and cancelled entries remain, and downloaded data is kept for retries.
148154

149155
Model details inspect signed metadata without granting publisher consent or
150-
loading the GPU. The PC filter hides cores whose inspected requirements are
151-
known to be incompatible; unknown candidates remain visible. Chat streams
156+
loading the GPU. For this PC hides undownloaded repositories whose published
157+
platform branches exclude the first visible GPU's platform, and local cores
158+
whose inspected requirements are known to be incompatible. Missing build metadata
159+
or an unknown GPU platform leaves a repository visible. Downloaded cores use
160+
their inspected requirements even if the repository no longer publishes a
161+
matching platform branch. A matching branch does not establish core compatibility
162+
or available memory; loading performs those checks. Chat streams
152163
multi-turn test conversations from the active Helios session.
153164
Enter sends a message; Shift+Enter adds a line.
154165
Stop preserves partial output, and New chat clears the conversation. Successful

‎flare-winui/Shell.xaml.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ LR"xaml(
6161
LR"xaml(
6262
<Grid x:Name="ModelsPage" Visibility="Collapsed" RowSpacing="16"><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/><RowDefinition/><RowDefinition Height="Auto"/></Grid.RowDefinitions>
6363
<Border BorderBrush="{ThemeResource StrokeBrush}" BorderThickness="0,0,0,1"><StackPanel Orientation="Horizontal" Spacing="22"><StackPanel><Button x:Name="DiscoverTab" Content="Discover" Style="{StaticResource TextAction}" FontWeight="SemiBold"/><Border x:Name="DiscoverUnderline" Height="3" Background="{ThemeResource AppAccentBrush}"/></StackPanel><StackPanel><Button x:Name="LibraryTab" Content="On this PC" Style="{StaticResource TextAction}"/><Border x:Name="LibraryUnderline" Height="3" Background="{ThemeResource AppAccentBrush}" Visibility="Collapsed"/></StackPanel></StackPanel></Border>
64-
<Grid Grid.Row="1" ColumnSpacing="10"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width="Auto"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><TextBox x:Name="ModelSearch" PlaceholderText="Search Hugging Face models" AutomationProperties.Name="Search models"/><Button x:Name="SearchButton" Grid.Column="1" Content="Search"/><CheckBox x:Name="CompatibleFilter" Grid.Column="2" Content="For this PC" VerticalAlignment="Center" ToolTipService.ToolTip="Hides cores known to be incompatible. Unknown requirements stay visible and need inspection."/></Grid>
64+
<Grid Grid.Row="1" ColumnSpacing="10"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width="Auto"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><TextBox x:Name="ModelSearch" PlaceholderText="Search Hugging Face models" AutomationProperties.Name="Search models"/><Button x:Name="SearchButton" Grid.Column="1" Content="Search"/><CheckBox x:Name="CompatibleFilter" Grid.Column="2" Content="For this PC" VerticalAlignment="Center" ToolTipService.ToolTip="Hides repositories with published platform builds but none for the selected GPU, and local cores known to be incompatible. Unknown requirements remain visible. Memory is checked when loading."/></Grid>
6565
<Grid Grid.Row="2"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><TextBlock x:Name="LibrarySummary" Text="Hugging Face · Discover prepared Flare cores" Style="{StaticResource Caption}"/><TextBlock x:Name="CatalogState" Grid.Column="1" Text="Search to discover cores" Style="{StaticResource Caption}"/></Grid>
6666
<Grid Grid.Row="3"><GridView x:Name="ModelList" ScrollViewer.HorizontalScrollMode="Disabled" SelectionMode="None" IsItemClickEnabled="False" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto"><GridView.ItemContainerStyle><Style TargetType="GridViewItem"><Setter Property="Margin" Value="0"/><Setter Property="HorizontalContentAlignment" Value="Stretch"/></Style></GridView.ItemContainerStyle><GridView.Header><StackPanel x:Name="RecommendedSection" HorizontalAlignment="Left" Spacing="10" Margin="0,0,0,16" Visibility="Collapsed"><TextBlock Text="Recommended" FontSize="17" FontWeight="SemiBold"/><StackPanel x:Name="RecommendedModelList" Spacing="12"/><TextBlock x:Name="RecommendedMoreLabel" Text="More models" FontSize="17" FontWeight="SemiBold" Margin="0,8,0,0"/></StackPanel></GridView.Header><GridView.ItemsPanel><ItemsPanelTemplate><ItemsWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="2"/></ItemsPanelTemplate></GridView.ItemsPanel></GridView><StackPanel x:Name="ModelsEmpty" Spacing="7" HorizontalAlignment="Center" VerticalAlignment="Center" MaxWidth="390"><TextBlock x:Name="ModelsEmptyTitle" Text="Find your next local model" FontSize="17" FontWeight="SemiBold" HorizontalAlignment="Center"/><TextBlock x:Name="ModelsEmptyDetail" Text="Search Hugging Face for prepared Flare cores, or add a repository or a core from this PC." Style="{StaticResource Secondary}" TextAlignment="Center"/><Button x:Name="EmptyAddButton" Content="Add model" HorizontalAlignment="Center" Margin="0,6,0,0"/></StackPanel></Grid>
6767
<Grid Grid.Row="4"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><TextBlock Text="Have a repository link or a core on disk?" Style="{StaticResource Caption}" VerticalAlignment="Center"/><Button x:Name="AddDirectButton" Grid.Column="1" Content="Add it directly ↗" Style="{StaticResource TextAction}"/></Grid>

‎flare-winui/bridge/include/flare.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ typedef struct flare_model {
142142
uint64_t context_tokens, parameter_count, revision_bytes;
143143
uint32_t rank_count;
144144
uint32_t metadata_known;
145+
flare_string revision_updated_at;
146+
uint32_t published_build_mismatch;
145147
} flare_model;
146148
enum {
147149
FLARE_MODEL_CONTEXT = 1, FLARE_MODEL_PARAMETERS = 2,

‎flare-winui/bridge/src/lib.rs‎

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,36 @@ fn text(value: &str) -> FlareString {
3131
mod tests {
3232
use super::*;
3333
#[test]
34+
fn published_build_mismatch_preserves_unknown_and_matching_targets() {
35+
let mut view = Snapshot::default();
36+
for target in [None, Some(true), Some(false)] {
37+
view.models.push(flare::controller::ModelView {
38+
flags: 16,
39+
metadata: flare::controller::ModelMetadata {
40+
build_target_match: target,
41+
..Default::default()
42+
},
43+
..Default::default()
44+
});
45+
}
46+
let held = Box::into_raw(Box::new(FlareSnapshot { view }));
47+
unsafe {
48+
for (index, expected) in [0, 0, 1].into_iter().enumerate() {
49+
let mut out = std::mem::MaybeUninit::<FlareModel>::uninit();
50+
assert_eq!(flare_snapshot_model(held, index, out.as_mut_ptr()), 1);
51+
assert_eq!(out.assume_init().published_build_mismatch, expected);
52+
}
53+
flare_snapshot_destroy(held);
54+
}
55+
}
56+
#[test]
3457
fn model_metadata_preserves_optional_fields_and_utf8() {
3558
let mut view = Snapshot::default();
3659
view.models.push(flare::controller::ModelView {
3760
metadata: flare::controller::ModelMetadata {
3861
author: "模型作者".into(),
3962
hardware: "GB10".into(),
63+
revision_updated_at: "2026-11-05T18:06:29.000Z".into(),
4064
context_tokens: Some(262144),
4165
revision_bytes: Some(25_528_087_320),
4266
rank_count: Some(1),
@@ -54,13 +78,22 @@ mod tests {
5478
assert_eq!(found.context_tokens, 262144);
5579
assert_eq!(found.revision_bytes, 25_528_087_320);
5680
assert_eq!(found.rank_count, 1);
81+
assert_eq!(
82+
slice::from_raw_parts(
83+
found.revision_updated_at.data.cast::<u8>(),
84+
found.revision_updated_at.length,
85+
),
86+
b"2026-11-05T18:06:29.000Z"
87+
);
5788
assert_eq!(
5889
slice::from_raw_parts(found.author.data.cast::<u8>(), found.author.length),
5990
"模型作者".as_bytes()
6091
);
6192
let mut out = std::mem::MaybeUninit::<FlareModel>::uninit();
6293
assert_eq!(flare_snapshot_model(held, 1, out.as_mut_ptr()), 1);
63-
assert_eq!(out.assume_init().metadata_known, 0);
94+
let missing = out.assume_init();
95+
assert_eq!(missing.metadata_known, 0);
96+
assert_eq!(missing.revision_updated_at.length, 0);
6497
assert_eq!(flare_snapshot_model(held, 2, ptr::null_mut()), 0);
6598
flare_snapshot_destroy(held);
6699
}
@@ -504,6 +537,8 @@ pub struct FlareModel {
504537
revision_bytes: u64,
505538
rank_count: u32,
506539
metadata_known: u32,
540+
revision_updated_at: FlareString,
541+
published_build_mismatch: u32,
507542
}
508543
#[repr(C)]
509544
pub struct FlareDownload {
@@ -588,6 +623,8 @@ pub unsafe extern "C" fn flare_snapshot_model(
588623
| (u32::from(s.metadata.parameter_count.is_some()) << 1)
589624
| (u32::from(s.metadata.revision_bytes.is_some()) << 2)
590625
| (u32::from(s.metadata.rank_count.is_some()) << 3),
626+
revision_updated_at: text(&s.metadata.revision_updated_at),
627+
published_build_mismatch: u32::from(s.metadata.build_target_match == Some(false)),
591628
},
592629
)
593630
}

0 commit comments

Comments
 (0)