Skip to content

Commit e0e0f0e

Browse files
Copilotstephentoub
andcommitted
Add DebuggerDisplay attributes to ContentBlock and ResourceContents types
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
1 parent c74d383 commit e0e0f0e

File tree

7 files changed

+102
-0
lines changed

7 files changed

+102
-0
lines changed

src/ModelContextProtocol.Core/Protocol/BlobResourceContents.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using System.Text.Json.Serialization;
23

34
namespace ModelContextProtocol.Protocol;
@@ -20,11 +21,23 @@ namespace ModelContextProtocol.Protocol;
2021
/// See the <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/">schema</see> for more details.
2122
/// </para>
2223
/// </remarks>
24+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
2325
public sealed class BlobResourceContents : ResourceContents
2426
{
2527
/// <summary>
2628
/// Gets or sets the base64-encoded string representing the binary data of the item.
2729
/// </summary>
2830
[JsonPropertyName("blob")]
2931
public required string Blob { get; set; }
32+
33+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
34+
private string DebuggerDisplay
35+
{
36+
get
37+
{
38+
const int MaxLength = 80;
39+
string blobPreview = Blob.Length <= MaxLength ? Blob : $"{Blob.Substring(0, MaxLength)}...";
40+
return $"Uri = {Uri}, Blob = {blobPreview}";
41+
}
42+
}
3043
}

src/ModelContextProtocol.Core/Protocol/ContentBlock.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ public override void Write(Utf8JsonWriter writer, ContentBlock value, JsonSerial
356356
}
357357

358358
/// <summary>Represents text provided to or from an LLM.</summary>
359+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
359360
public sealed class TextContentBlock : ContentBlock
360361
{
361362
/// <inheritdoc/>
@@ -366,9 +367,16 @@ public sealed class TextContentBlock : ContentBlock
366367
/// </summary>
367368
[JsonPropertyName("text")]
368369
public required string Text { get; set; }
370+
371+
/// <inheritdoc/>
372+
public override string ToString() => Text;
373+
374+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
375+
private string DebuggerDisplay => $"Text = \"{Text}\"";
369376
}
370377

371378
/// <summary>Represents an image provided to or from an LLM.</summary>
379+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
372380
public sealed class ImageContentBlock : ContentBlock
373381
{
374382
/// <inheritdoc/>
@@ -388,9 +396,21 @@ public sealed class ImageContentBlock : ContentBlock
388396
/// </remarks>
389397
[JsonPropertyName("mimeType")]
390398
public required string MimeType { get; set; }
399+
400+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
401+
private string DebuggerDisplay
402+
{
403+
get
404+
{
405+
const int MaxLength = 80;
406+
string dataPreview = Data.Length <= MaxLength ? Data : $"{Data.Substring(0, MaxLength)}...";
407+
return $"MimeType = {MimeType}, Data = {dataPreview}";
408+
}
409+
}
391410
}
392411

393412
/// <summary>Represents audio provided to or from an LLM.</summary>
413+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
394414
public sealed class AudioContentBlock : ContentBlock
395415
{
396416
/// <inheritdoc/>
@@ -410,12 +430,24 @@ public sealed class AudioContentBlock : ContentBlock
410430
/// </remarks>
411431
[JsonPropertyName("mimeType")]
412432
public required string MimeType { get; set; }
433+
434+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
435+
private string DebuggerDisplay
436+
{
437+
get
438+
{
439+
const int MaxLength = 80;
440+
string dataPreview = Data.Length <= MaxLength ? Data : $"{Data.Substring(0, MaxLength)}...";
441+
return $"MimeType = {MimeType}, Data = {dataPreview}";
442+
}
443+
}
413444
}
414445

415446
/// <summary>Represents the contents of a resource, embedded into a prompt or tool call result.</summary>
416447
/// <remarks>
417448
/// It is up to the client how best to render embedded resources for the benefit of the LLM and/or the user.
418449
/// </remarks>
450+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
419451
public sealed class EmbeddedResourceBlock : ContentBlock
420452
{
421453
/// <inheritdoc/>
@@ -433,12 +465,16 @@ public sealed class EmbeddedResourceBlock : ContentBlock
433465
/// </remarks>
434466
[JsonPropertyName("resource")]
435467
public required ResourceContents Resource { get; set; }
468+
469+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
470+
private string DebuggerDisplay => $"Uri = {Resource.Uri}";
436471
}
437472

438473
/// <summary>Represents a resource that the server is capable of reading, included in a prompt or tool call result.</summary>
439474
/// <remarks>
440475
/// Resource links returned by tools are not guaranteed to appear in the results of `resources/list` requests.
441476
/// </remarks>
477+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
442478
public sealed class ResourceLinkBlock : ContentBlock
443479
{
444480
/// <inheritdoc/>
@@ -500,9 +536,13 @@ public sealed class ResourceLinkBlock : ContentBlock
500536
/// </remarks>
501537
[JsonPropertyName("size")]
502538
public long? Size { get; set; }
539+
540+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
541+
private string DebuggerDisplay => $"Name = {Name}, Uri = {Uri}";
503542
}
504543

505544
/// <summary>Represents a request from the assistant to call a tool.</summary>
545+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
506546
public sealed class ToolUseContentBlock : ContentBlock
507547
{
508548
/// <inheritdoc/>
@@ -528,9 +568,13 @@ public sealed class ToolUseContentBlock : ContentBlock
528568
/// </summary>
529569
[JsonPropertyName("input")]
530570
public required JsonElement Input { get; set; }
571+
572+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
573+
private string DebuggerDisplay => $"Name = {Name}, Id = {Id}";
531574
}
532575

533576
/// <summary>Represents the result of a tool use, provided by the user back to the assistant.</summary>
577+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
534578
public sealed class ToolResultContentBlock : ContentBlock
535579
{
536580
/// <inheritdoc/>
@@ -575,4 +619,7 @@ public sealed class ToolResultContentBlock : ContentBlock
575619
/// </remarks>
576620
[JsonPropertyName("isError")]
577621
public bool? IsError { get; set; }
622+
623+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
624+
private string DebuggerDisplay => $"ToolUseId = {ToolUseId}, ContentCount = {Content.Count}, IsError = {IsError ?? false}";
578625
}

src/ModelContextProtocol.Core/Protocol/Prompt.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using System.Text.Json.Nodes;
23
using System.Text.Json.Serialization;
34
using ModelContextProtocol.Server;
@@ -10,6 +11,7 @@ namespace ModelContextProtocol.Protocol;
1011
/// <remarks>
1112
/// See the <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/">schema</see> for details.
1213
/// </remarks>
14+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
1315
public sealed class Prompt : IBaseMetadata
1416
{
1517
/// <inheritdoc />
@@ -75,4 +77,14 @@ public sealed class Prompt : IBaseMetadata
7577
/// </summary>
7678
[JsonIgnore]
7779
public McpServerPrompt? McpServerPrompt { get; set; }
80+
81+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
82+
private string DebuggerDisplay
83+
{
84+
get
85+
{
86+
string desc = Description is not null ? $", Description = \"{Description}\"" : "";
87+
return $"Name = {Name}{desc}";
88+
}
89+
}
7890
}

src/ModelContextProtocol.Core/Protocol/PromptMessage.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using Microsoft.Extensions.AI;
23
using System.Text.Json.Serialization;
34

@@ -26,6 +27,7 @@ namespace ModelContextProtocol.Protocol;
2627
/// See the <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/">schema</see> for details.
2728
/// </para>
2829
/// </remarks>
30+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
2931
public sealed class PromptMessage
3032
{
3133
/// <summary>
@@ -49,4 +51,7 @@ public sealed class PromptMessage
4951
/// </remarks>
5052
[JsonPropertyName("role")]
5153
public required Role Role { get; set; }
54+
55+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
56+
private string DebuggerDisplay => $"Role = {Role}, ContentType = {Content.Type}";
5257
}

src/ModelContextProtocol.Core/Protocol/Resource.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using System.Diagnostics.CodeAnalysis;
23
using System.Text.Json.Nodes;
34
using System.Text.Json.Serialization;
@@ -11,6 +12,7 @@ namespace ModelContextProtocol.Protocol;
1112
/// <remarks>
1213
/// See the <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/">schema</see> for details.
1314
/// </remarks>
15+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
1416
public sealed class Resource : IBaseMetadata
1517
{
1618
/// <inheritdoc />
@@ -105,4 +107,7 @@ public sealed class Resource : IBaseMetadata
105107
/// </summary>
106108
[JsonIgnore]
107109
public McpServerResource? McpServerResource { get; set; }
110+
111+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
112+
private string DebuggerDisplay => $"Name = {Name}, Uri = {Uri}";
108113
}

src/ModelContextProtocol.Core/Protocol/TextResourceContents.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using System.Text.Json.Serialization;
23

34
namespace ModelContextProtocol.Protocol;
@@ -19,11 +20,18 @@ namespace ModelContextProtocol.Protocol;
1920
/// See the <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/">schema</see> for more details.
2021
/// </para>
2122
/// </remarks>
23+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
2224
public sealed class TextResourceContents : ResourceContents
2325
{
2426
/// <summary>
2527
/// Gets or sets the text of the item.
2628
/// </summary>
2729
[JsonPropertyName("text")]
2830
public required string Text { get; set; }
31+
32+
/// <inheritdoc/>
33+
public override string ToString() => Text;
34+
35+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
36+
private string DebuggerDisplay => $"Uri = {Uri}, Text = \"{Text}\"";
2937
}

src/ModelContextProtocol.Core/Protocol/Tool.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using System.Text.Json;
23
using System.Text.Json.Nodes;
34
using System.Text.Json.Serialization;
@@ -8,6 +9,7 @@ namespace ModelContextProtocol.Protocol;
89
/// <summary>
910
/// Represents a tool that the server is capable of calling.
1011
/// </summary>
12+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
1113
public sealed class Tool : IBaseMetadata
1214
{
1315
/// <inheritdoc />
@@ -130,4 +132,14 @@ public JsonElement? OutputSchema
130132
/// </summary>
131133
[JsonIgnore]
132134
public McpServerTool? McpServerTool { get; set; }
135+
136+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
137+
private string DebuggerDisplay
138+
{
139+
get
140+
{
141+
string desc = Description is not null ? $", Description = \"{Description}\"" : "";
142+
return $"Name = {Name}{desc}";
143+
}
144+
}
133145
}

0 commit comments

Comments
 (0)