Skip to content

Commit 3128af8

Browse files
committed
a2a: 0.3.3
1 parent 380718b commit 3128af8

12 files changed

+205
-240
lines changed

src/LlmTornado.A2A/A2AConnectorClient.cs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
using A2A;
2-
using System;
3-
using System.Collections.Generic;
4-
using System.Linq;
1+
using A2A;
52
using System.Net.ServerSentEvents;
6-
using System.Text;
73
using System.Text.Json;
8-
using System.Threading.Tasks;
94

105
namespace LlmTornado.A2A;
116

@@ -18,11 +13,11 @@ public async Task<AgentCard> GetAgentCardAsync(string endPoint)
1813

1914
public async Task<A2AResponse> SendMessageAsync(string endPoint, List<Part> parts)
2015
{
21-
A2ACardResolver cardResolver = new(new Uri(endPoint));
16+
A2ACardResolver cardResolver = new A2ACardResolver(new Uri(endPoint));
2217
AgentCard agentCard = await cardResolver.GetAgentCardAsync();
2318
A2AClient client = new A2AClient(new Uri(agentCard.Url));
2419

25-
AgentMessage message = new()
20+
AgentMessage message = new AgentMessage
2621
{
2722
Role = MessageRole.User,
2823
Parts = parts
@@ -38,19 +33,19 @@ public async Task<A2AResponse> SendMessageAsync(string endPoint, List<Part> part
3833

3934
public async Task SendMessageStreamingAsync(string endPoint, List<Part> parts, Func<SseItem<A2AEvent>, Task>? onStreamingEventReceived)
4035
{
41-
A2ACardResolver cardResolver = new(new Uri(endPoint));
36+
A2ACardResolver cardResolver = new A2ACardResolver(new Uri(endPoint));
4237
AgentCard agentCard = await cardResolver.GetAgentCardAsync();
4338
A2AClient client = new A2AClient(new Uri(agentCard.Url));
4439

45-
AgentMessage userMessage = new()
40+
AgentMessage userMessage = new AgentMessage
4641
{
4742
Role = MessageRole.User,
4843
Parts = parts
4944
};
5045

5146
await foreach (SseItem<A2AEvent> sseItem in client.SendMessageStreamingAsync(new MessageSendParams { Message = userMessage }))
5247
{
53-
await onStreamingEventReceived?.Invoke(sseItem);
48+
if (onStreamingEventReceived is not null) await onStreamingEventReceived.Invoke(sseItem);
5449
}
5550

5651
Console.WriteLine(" Streaming completed.");
@@ -64,7 +59,7 @@ public async Task ListenForTaskEventAsync(string endPoint, string taskId, Func<S
6459
return;
6560
}
6661

67-
A2ACardResolver cardResolver = new(new Uri(endPoint));
62+
A2ACardResolver cardResolver = new A2ACardResolver(new Uri(endPoint));
6863
AgentCard agentCard = await cardResolver.GetAgentCardAsync();
6964
A2AClient client = new A2AClient(new Uri(agentCard.Url));
7065

@@ -78,26 +73,26 @@ public async Task ListenForTaskEventAsync(string endPoint, string taskId, Func<S
7873

7974
public async Task SetPushNotifications(string endPoint, PushNotificationConfig config)
8075
{
81-
A2ACardResolver cardResolver = new(new Uri(endPoint));
76+
A2ACardResolver cardResolver = new A2ACardResolver(new Uri(endPoint));
8277
AgentCard agentCard = await cardResolver.GetAgentCardAsync();
8378
A2AClient client = new A2AClient(new Uri(agentCard.Url));
84-
await client.SetPushNotificationAsync(new TaskPushNotificationConfig()
79+
await client.SetPushNotificationAsync(new TaskPushNotificationConfig
8580
{
8681
PushNotificationConfig = config
8782
});
8883
}
8984

9085
public async Task<AgentTask> CancelTaskAsync(string endPoint, string taskId)
9186
{
92-
A2ACardResolver cardResolver = new(new Uri(endPoint));
87+
A2ACardResolver cardResolver = new A2ACardResolver(new Uri(endPoint));
9388
AgentCard agentCard = await cardResolver.GetAgentCardAsync();
9489
A2AClient client = new A2AClient(new Uri(agentCard.Url));
9590
return await client.CancelTaskAsync(taskId);
9691
}
9792

9893
public async Task<AgentTask> GetTaskAsync(string endPoint, string taskId)
9994
{
100-
A2ACardResolver cardResolver = new(new Uri(endPoint));
95+
A2ACardResolver cardResolver = new A2ACardResolver(new Uri(endPoint));
10196
AgentCard agentCard = await cardResolver.GetAgentCardAsync();
10297
A2AClient client = new A2AClient(new Uri(agentCard.Url));
10398
return await client.GetTaskAsync(taskId);

src/LlmTornado.A2A/A2ATornadoConnector.cs

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
using A2A;
2-
using System;
3-
using System.Collections.Generic;
42
using System.ComponentModel;
5-
using System.Linq;
63
using System.Text;
7-
using System.Threading.Tasks;
84

95
namespace LlmTornado.A2A;
106

117
public class A2ATornadoConnector
128
{
13-
private List<string> a2AServersEndpoints { get; set; } = new List<string> ();
9+
private List<string> a2AServersEndpoints { get; set; } = [];
1410
public Dictionary<string, AgentCard> A2ACards { get; set; } = new Dictionary<string, AgentCard>();
1511

1612
private A2AConnectorClient connectorClient { get; set; } = new A2AConnectorClient();
@@ -27,11 +23,11 @@ public A2ATornadoConnector(List<string> agentEndpoints)
2723

2824
private async Task SetupClientInfo()
2925
{
30-
foreach (var endpoint in a2AServersEndpoints)
26+
foreach (string endpoint in a2AServersEndpoints)
3127
{
3228
try
3329
{
34-
var agentCard = await connectorClient.GetAgentCardAsync(endpoint);
30+
AgentCard agentCard = await connectorClient.GetAgentCardAsync(endpoint);
3531
A2ACards[agentCard.Name] = agentCard;
3632
}
3733
catch (Exception ex)
@@ -53,7 +49,7 @@ public string GetAvailableAgentsTool()
5349
{
5450
StringBuilder sb = new StringBuilder();
5551
sb.AppendLine("Available Agents:");
56-
foreach (var agent in A2ACards.Values)
52+
foreach (AgentCard agent in A2ACards.Values)
5753
{
5854
sb.AppendLine($"- {agent.Name}: {agent.Description} (Endpoint: {agent.Url})");
5955
}
@@ -75,27 +71,25 @@ public async Task<string> SendMessageTool(
7571
[Description("The name of the agent to send the message to.")] string agentName,
7672
[Description("The message to send to the agent.")] string message)
7773
{
78-
if (!A2ACards.ContainsKey(agentName))
74+
if (!A2ACards.TryGetValue(agentName, out AgentCard? agentCard))
7975
{
8076
return $"Agent '{agentName}' not found.";
8177
}
8278

83-
var agentCard = A2ACards[agentName];
84-
var parts = new List<Part> { new TextPart { Text = message } };
79+
List<Part> parts = [new TextPart { Text = message }];
8580
A2AResponse response = await connectorClient.SendMessageAsync(agentCard.Url, parts);
8681

87-
if (response is AgentMessage amessage)
82+
switch (response)
8883
{
89-
var responseText = string.Join("\n", amessage.Parts.OfType<TextPart>().Select(p => p.Text));
90-
return responseText;
91-
}
92-
else if (response is AgentTask atask)
93-
{
94-
return $"Task created with ID: {atask.Id}, Status: {atask.Status}";
95-
}
96-
else
97-
{
98-
return "Unexpected response type.";
84+
case AgentMessage amessage:
85+
{
86+
string responseText = string.Join("\n", amessage.Parts.OfType<TextPart>().Select(p => p.Text));
87+
return responseText;
88+
}
89+
case AgentTask atask:
90+
return $"Task created with ID: {atask.Id}, Status: {atask.Status}";
91+
default:
92+
return "Unexpected response type.";
9993
}
10094
}
10195

src/LlmTornado.A2A/A2ATornadoExtension.ChatMessage.cs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
using A2A;
1+
using A2A;
22
using LlmTornado.Chat;
33
using LlmTornado.Code;
4-
using System;
5-
using System.Collections.Generic;
6-
using System.Linq;
7-
using System.Text;
84
using System.Text.Json;
9-
using System.Threading.Tasks;
105

116
namespace LlmTornado.A2A;
127
/// <summary>
@@ -15,61 +10,72 @@ namespace LlmTornado.A2A;
1510
/// </summary>
1611
public static partial class A2ATornadoExtension
1712
{
18-
public static TextPart ToA2ATextPart(this string text) => new TextPart() { Text = text };
13+
public static TextPart ToA2ATextPart(this string text) => new TextPart { Text = text };
1914

20-
public static FilePart ToA2AFileWithUriPart(this Uri uri) => new FilePart() { File = new FileWithUri() { Uri = uri.AbsoluteUri } };
15+
public static FilePart ToA2AFileWithUriPart(this Uri uri) => new FilePart
16+
{
17+
File = new FileContent(uri)
18+
};
2119

2220
public static FilePart ToA2AFilePart(this ChatDocument doc)
2321
{
24-
if (doc.Uri != null)
25-
return new FilePart() { File = new FileWithUri() { Uri = doc.Uri.AbsoluteUri } };
26-
else
27-
{
28-
return new FilePart() { File = new FileWithBytes() { Bytes = doc.Base64 } };
29-
}
22+
return doc.Uri != null ? new FilePart { File = new FileContent(doc.Uri) } : new FilePart { File = new FileContent(doc.Base64) };
3023
}
3124

32-
public static FilePart ToA2AFilePart(this ChatImage img) => new FilePart() { File = new FileWithUri() { Uri = img.Url, MimeType = img.MimeType } };
25+
public static FilePart ToA2AFilePart(this ChatImage img) => new FilePart
26+
{
27+
File = new FileContent(new Uri(img.Url))
28+
{
29+
MimeType = img.MimeType
30+
}
31+
};
3332

3433
public static FilePart ToA2AFilePart(this ChatAudio audio)
3534
{
3635
if (audio.Url != null)
37-
return new FilePart() { File = new FileWithUri() { Uri = audio.Url.AbsoluteUri } };
38-
else
39-
return new FilePart() { File = new FileWithBytes() { Bytes = audio.Data, MimeType = audio.MimeType } };
36+
return new FilePart { File = new FileContent(audio.Url) };
37+
38+
return new FilePart { File = new FileContent(audio.Data) { MimeType = audio.MimeType } };
4039
}
4140

4241
public static FilePart ToA2AFilePart(this ChatMessageAudio audio)
4342
{
44-
return new FilePart() { File = new FileWithBytes() { Bytes = audio.Data, Name = audio.Id, MimeType = audio.MimeType } };
43+
return new FilePart { File = new FileContent(audio.Data) { Name = audio.Id, MimeType = audio.MimeType } };
4544
}
4645

47-
public static FilePart ToA2AFilePart(this ChatVideo video) => new FilePart() { File = new FileWithUri() { Uri = video.Url.AbsoluteUri } };
46+
public static FilePart ToA2AFilePart(this ChatVideo video) => new FilePart { File = new FileContent(video.Url) };
4847

4948
public static TextPart ToA2ATextPart(this ChatMessageReasoningData reasoning)
5049
{
5150
if (reasoning.IsRedacted ?? false)
5251
{
5352
JsonElement stringElement = JsonDocument.Parse($"{{\"message\": \"{reasoning.Content}\"}}").RootElement.GetProperty("message");
54-
return new TextPart() { Text = "Reasoning", Metadata = new Dictionary<string, JsonElement>() { { "Content", stringElement } } };
53+
return new TextPart { Text = "Reasoning", Metadata = new Dictionary<string, JsonElement> { { "Content", stringElement } } };
5554
}
5655
else
5756
{
58-
return new TextPart() { Text = reasoning.Content ?? "Reasoning" };
57+
return new TextPart { Text = reasoning.Content ?? "Reasoning" };
5958
}
6059
}
6160

6261
public static FilePart ToA2AFilePart(this ChatMessagePartFileLinkData linkdata)
6362
{
64-
return new FilePart() { File = new FileWithUri() { Uri = linkdata.FileUri, Name = linkdata.File?.Name ?? "", MimeType = linkdata.MimeType } };
63+
return new FilePart
64+
{
65+
File = new FileContent(new Uri(linkdata.FileUri))
66+
{
67+
Name = linkdata.File?.Name ?? "",
68+
MimeType = linkdata.MimeType
69+
}
70+
};
6571
}
6672

6773
public static TextPart ToA2ATextPart(this ChatMessagePartExecutableCode code)
6874
{
69-
return new TextPart()
75+
return new TextPart
7076
{
7177
Text = code.Code ?? "Code",
72-
Metadata = new Dictionary<string, JsonElement>() {
78+
Metadata = new Dictionary<string, JsonElement> {
7379
{ "Language", JsonDocument.Parse($"\"{(code.CustomLanguage != null ? code.CustomLanguage : code.Language)}\"").RootElement }
7480
}
7581
};

src/LlmTornado.A2A/A2ATornadoExtension.Events.AgentRunner.cs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
using A2A;
1+
using A2A;
22
using LlmTornado.Agents.DataModels;
3-
using LlmTornado.Chat;
4-
using LlmTornado.Code;
5-
using System;
6-
using System.Collections.Generic;
7-
using System.Linq;
8-
using System.Text;
9-
using System.Text.Json;
10-
using System.Threading.Tasks;
113

124
namespace LlmTornado.A2A;
135
/// <summary>
@@ -28,12 +20,12 @@ public static Artifact ToArtifact(this ChatRuntimeAgentRunnerEvents evt)
2820

2921
public static Artifact ToArtifact(this AgentRunnerToolInvokedEvent evt)
3022
{
31-
Artifact artifact = new Artifact()
23+
Artifact artifact = new Artifact
3224
{
3325
Name = evt.EventType.ToString(),
26+
Description = "Tool Invoked"
3427
};
35-
artifact.Description = "Tool Invoked";
36-
artifact.Parts.Add(new TextPart()
28+
artifact.Parts.Add(new TextPart
3729
{
3830
Text = $@"
3931
{evt.ToolCalled.Name} was invoked.
@@ -45,28 +37,30 @@ public static Artifact ToArtifact(this AgentRunnerToolInvokedEvent evt)
4537

4638
public static Artifact ToArtifact(this AgentRunnerToolCompletedEvent evt)
4739
{
48-
Artifact artifact = new Artifact()
40+
Artifact artifact = new Artifact
4941
{
5042
Name = evt.EventType.ToString(),
43+
Description = "Tool Completed"
5144
};
52-
artifact.Description = "Tool Completed";
53-
artifact.Parts.Add(new TextPart()
45+
artifact.Parts.Add(new TextPart
5446
{
55-
Text = $@"{evt.ToolCall.Name} has completed.
56-
With Results: {evt.ToolCall.Result.RemoteContent?.ToString() ?? evt.ToolCall.Result.Content}"
47+
Text = $"""
48+
{evt.ToolCall.Name} has completed.
49+
With Results: {evt.ToolCall.Result?.RemoteContent?.ToString() ?? evt.ToolCall.Result?.Content}
50+
"""
5751
});
5852
return artifact;
5953
}
6054

6155
public static Artifact ToArtifact(this AgentRunnerGuardrailTriggeredEvent evt)
6256
{
63-
Artifact artifact = new Artifact()
57+
Artifact artifact = new Artifact
6458
{
6559
Name = evt.EventType.ToString(),
60+
Description = "Guardrail Triggered"
6661
};
6762

68-
artifact.Description = "Guardrail Triggered";
69-
artifact.Parts.Add(new TextPart()
63+
artifact.Parts.Add(new TextPart
7064
{
7165
Text = $@"Guardrail was triggered. Reason: {evt.Reason}"
7266
});

src/LlmTornado.A2A/A2ATornadoExtension.Events.ModelStreaming.cs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
using A2A;
22
using LlmTornado.Agents.DataModels;
3-
using LlmTornado.Chat;
4-
using LlmTornado.Code;
5-
using System;
6-
using System.Collections.Generic;
7-
using System.Linq;
8-
using System.Text;
9-
using System.Text.Json;
10-
using System.Threading.Tasks;
113

124
namespace LlmTornado.A2A;
135
/// <summary>
@@ -27,14 +19,14 @@ public static Artifact ToArtifact(this AgentRunnerStreamingEvent evt)
2719

2820
public static Artifact ToArtifact(this ModelStreamingOutputTextDeltaEvent e)
2921
{
30-
Artifact artifact = new Artifact()
22+
Artifact artifact = new Artifact
3123
{
3224
Description = e.EventType.ToString(),
33-
Parts = new List<Part>(),
25+
Parts = [],
3426
Name = e.EventType.ToString(),
3527
};
3628
artifact.Description = e.GetType().Name;
37-
artifact.Parts.Add(new TextPart()
29+
artifact.Parts.Add(new TextPart
3830
{
3931
Text = e.DeltaText ?? ""
4032
});

0 commit comments

Comments
 (0)