Skip to content

Commit d1b1363

Browse files
shanselmanCopilot
andauthored
Fix configured model filtering and test SDK bump
Fixes #684 and #705. - Bump Microsoft.NET.Test.Sdk to 18.6.0. - Preserve whether gateway model responses explicitly include configured. - Hide only models explicitly marked configured:false while keeping older gateway payloads visible. - Add regression coverage for configured true/false/omitted behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 25c11dd commit d1b1363

6 files changed

Lines changed: 84 additions & 3 deletions

File tree

src/OpenClaw.Shared/Models.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,7 @@ public class ModelInfo
18891889
public string? Provider { get; set; }
18901890
public int? ContextWindow { get; set; }
18911891
public bool IsConfigured { get; set; }
1892+
public bool HasConfiguredFlag { get; set; }
18921893

18931894
public string DisplayName => Name ?? Id;
18941895
}
@@ -1981,4 +1982,3 @@ public string HttpUrl
19811982
}
19821983
}
19831984
}
1984-

src/OpenClaw.Shared/OpenClawGatewayClient.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3560,13 +3560,16 @@ private void ParseModelsList(JsonElement payload)
35603560
{
35613561
foreach (var item in modelsArray.EnumerateArray())
35623562
{
3563+
var hasConfiguredFlag = item.TryGetProperty("configured", out var cfg)
3564+
&& (cfg.ValueKind == JsonValueKind.True || cfg.ValueKind == JsonValueKind.False);
35633565
var model = new ModelInfo
35643566
{
35653567
Id = item.TryGetProperty("id", out var id) ? id.GetString() ?? "" : "",
35663568
Name = item.TryGetProperty("name", out var name) ? name.GetString() : null,
35673569
Provider = item.TryGetProperty("provider", out var prov) ? prov.GetString() : null,
35683570
ContextWindow = item.TryGetProperty("contextWindow", out var cw) && cw.ValueKind == JsonValueKind.Number ? cw.GetInt32() : null,
3569-
IsConfigured = item.TryGetProperty("configured", out var cfg) && cfg.ValueKind == JsonValueKind.True
3571+
IsConfigured = hasConfiguredFlag && cfg.ValueKind == JsonValueKind.True,
3572+
HasConfiguredFlag = hasConfiguredFlag
35703573
};
35713574
if (!string.IsNullOrEmpty(model.Id))
35723575
info.Models.Add(model);

src/OpenClaw.Tray.WinUI/Chat/OpenClawChatDataProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,7 @@ private static string[] ExtractModelNames(ModelsListInfo info)
11501150
var list = new List<string>(info.Models.Count);
11511151
foreach (var m in info.Models)
11521152
{
1153+
if (m.HasConfiguredFlag && !m.IsConfigured) continue;
11531154
var id = m.Id;
11541155
if (string.IsNullOrEmpty(id)) continue;
11551156
if (seen.Add(id)) list.Add(id);

tests/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
dotnet-coverage uses a runtime profiler that does. CI installs the tool and
2727
wraps each `dotnet test` invocation with `dotnet-coverage collect`.
2828
-->
29-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.4.0" />
29+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.6.0" />
3030
<PackageReference Include="VCRuntime.CefSharp.140" Version="$(OpenClawVCRuntimeVersion)" PrivateAssets="all" ExcludeAssets="build" />
3131
<PackageReference Include="xunit" Version="2.9.3" />
3232
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />

tests/OpenClaw.Shared.Tests/OpenClawGatewayClientTests.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,24 @@ public void ParseSessionsPayload(string payloadJson)
246246
InvokePrivatePayloadParser("ParseSessions", payloadJson);
247247
}
248248

249+
public ModelsListInfo ParseModelsListPayload(string payloadJson)
250+
{
251+
ModelsListInfo? parsed = null;
252+
EventHandler<ModelsListInfo> handler = (_, models) => parsed = models;
253+
_client.ModelsListUpdated += handler;
254+
255+
try
256+
{
257+
InvokePrivatePayloadParser("ParseModelsList", payloadJson);
258+
}
259+
finally
260+
{
261+
_client.ModelsListUpdated -= handler;
262+
}
263+
264+
return parsed ?? new ModelsListInfo();
265+
}
266+
249267
private void InvokePrivatePayloadParser(string methodName, string payloadJson)
250268
{
251269
using var doc = JsonDocument.Parse(payloadJson);
@@ -708,6 +726,43 @@ public void ProcessRawMessage_AgentEventLogsRawLengthWithoutPayloadContent()
708726
Assert.DoesNotContain(logger.Logs, log => log.Contains("super-secret", StringComparison.OrdinalIgnoreCase));
709727
}
710728

729+
[Fact]
730+
public void ParseModelsList_PreservesConfiguredFlagPresence()
731+
{
732+
var helper = new GatewayClientTestHelper();
733+
734+
var models = helper.ParseModelsListPayload("""
735+
{
736+
"models": [
737+
{ "id": "gpt-5.4", "configured": true },
738+
{ "id": "gpt-5.5", "configured": false },
739+
{ "id": "legacy-gateway-model" }
740+
]
741+
}
742+
""");
743+
744+
Assert.Collection(
745+
models.Models,
746+
model =>
747+
{
748+
Assert.Equal("gpt-5.4", model.Id);
749+
Assert.True(model.HasConfiguredFlag);
750+
Assert.True(model.IsConfigured);
751+
},
752+
model =>
753+
{
754+
Assert.Equal("gpt-5.5", model.Id);
755+
Assert.True(model.HasConfiguredFlag);
756+
Assert.False(model.IsConfigured);
757+
},
758+
model =>
759+
{
760+
Assert.Equal("legacy-gateway-model", model.Id);
761+
Assert.False(model.HasConfiguredFlag);
762+
Assert.False(model.IsConfigured);
763+
});
764+
}
765+
711766
[Fact]
712767
public void ClassifyNotification_DetectsHealthAlerts()
713768
{

tests/OpenClaw.Tray.Tests/OpenClawChatDataProviderTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,28 @@ public async Task ModelsListUpdated_PopulatesAvailableModelsInSnapshot()
11741174
snapshots[^1].AvailableModels);
11751175
}
11761176

1177+
[Fact]
1178+
public async Task ModelsListUpdated_FiltersExplicitlyUnconfiguredModels()
1179+
{
1180+
var (bridge, provider, snapshots, _) = CreateProvider(new[] { MainSession() });
1181+
await provider.LoadAsync();
1182+
snapshots.Clear();
1183+
1184+
bridge.RaiseModels(new ModelsListInfo
1185+
{
1186+
Models = new List<ModelInfo>
1187+
{
1188+
new() { Id = "gpt-5.4", IsConfigured = true, HasConfiguredFlag = true },
1189+
new() { Id = "gpt-5.5", IsConfigured = false, HasConfiguredFlag = true },
1190+
new() { Id = "legacy-gateway-model" }
1191+
}
1192+
});
1193+
1194+
Assert.Equal(
1195+
new[] { "gpt-5.4", "legacy-gateway-model" },
1196+
snapshots[^1].AvailableModels);
1197+
}
1198+
11771199
[Fact]
11781200
public async Task ModelsListUpdated_DedupesDisplayNames()
11791201
{

0 commit comments

Comments
 (0)