Refused JSON contracts built by reflection and checked all of them in the trimmed build (#1152)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-03 18:29:50 +01:00
1 parent f864359290
commit 0b42c0288e
23 files changed
+535 -99

No files matched your search

@@ -1,6 +1,7 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using AIStudio.Tools.ToolCallingSystem;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components;
@@ -37,7 +38,7 @@ public partial class JsonTreeView : ComponentBase
private static List<TreeItemData<JsonTreeNode>> CreateChildren(JsonNode? value) => value switch
{
JsonObject jsonObject => jsonObject
.Select(property => CreateTreeItem(JsonSerializer.Serialize(property.Key), property.Value))
.Select(property => CreateTreeItem(FormatKey(property.Key), property.Value))
.ToList(),
JsonArray jsonArray => jsonArray
.Select((item, index) => CreateTreeItem($"[{index}]", item))
@@ -45,14 +46,24 @@ public partial class JsonTreeView : ComponentBase
_ => [],
};
private static string FormatValue(JsonNode? value) => value switch
internal static string FormatKey(string key) => JsonValue.Create(key).ToJsonString(ToolExecutionResult.MODEL_CONTENT_OPTIONS);
/// <summary>
/// Writes a value as JSON, objects and arrays only as a placeholder.
/// </summary>
/// <remarks>
/// The tree shows the result of a tool, so it writes like the model reads it, see
/// ToolExecutionResult.MODEL_CONTENT_OPTIONS. The default options would escape every umlaut and
/// every quotation mark for a web page, although Blazor encodes the text for the page anyway.
/// </remarks>
internal static string FormatValue(JsonNode? value) => value switch
{
JsonObject jsonObject when jsonObject.Count == 0 => "{}",
JsonObject => "{...}",
JsonArray jsonArray when jsonArray.Count == 0 => "[]",
JsonArray => "[...]",
null => "null",
_ => value.ToJsonString(),
_ => value.ToJsonString(ToolExecutionResult.MODEL_CONTENT_OPTIONS),
};
private static string GetIcon(JsonNode? value) => value switch
@@ -21,7 +21,11 @@ public sealed class ToolExecutionResult
/// with every umlaut as six characters. The relaxed encoder escapes only what JSON requires.
/// </remarks>
// Internal, so a tool which keeps its result within a budget measures exactly what the model gets:
internal static readonly JsonSerializerOptions MODEL_CONTENT_OPTIONS = new() { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
internal static readonly JsonSerializerOptions MODEL_CONTENT_OPTIONS = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
TypeInfoResolver = ToolExecutionResultJsonContext.Default,
}.AsReadOnly();
public string? TextContent { get; init; }
@@ -0,0 +1,15 @@
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace AIStudio.Tools.ToolCallingSystem;
/// <summary>
/// The contracts of the options with which a tool result is written for the model, built at compile time.
/// </summary>
/// <remarks>
/// A JSON result is a tree of JSON nodes, which writes itself and needs no contract from the options. The
/// context is there all the same, so that these options can never fall back to reflection either.
/// </remarks>
[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Metadata)]
[JsonSerializable(typeof(JsonNode))]
internal sealed partial class ToolExecutionResultJsonContext : JsonSerializerContext;
@@ -17,6 +17,7 @@
- Fixed AI Studio loading none of your organization's configurations when one place, such as the Windows registry, named a configuration with an invalid ID. AI Studio now skips that entry and uses the configurations from the other places.
- Fixed chats being stored although you chose "Store chats manually" or "Disable workspaces". AI Studio now stores a chat only when you click "Save chat", or not at all while workspaces are disabled. In both modes, leaving a chat whose answer is still being written asks you first and stops that answer. Chats outside of workspaces that earlier versions stored this way appear among your disappearing chats once you use workspaces again.
- Fixed saving a code block as a file, where the last line could end differently from all other lines, for example, on Windows. All lines of the file now end the same way.
- Fixed the result of a tool in the chat showing umlauts, quotation marks, and other special characters as codes instead of the characters themselves.
- Upgraded several libraries to improve security.
- Upgraded Tauri to v2.12.5.
- Upgraded MudBlazor to v9.12.0.