Skip to content

Commit d32391f

Browse files
committed
Add readme and screenshot
1 parent 5ba18a7 commit d32391f

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

assets/run.png

25.9 KB
Loading

readme.md

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,85 @@
1-
An opinionated meta-package for doing AI agents using Microsoft.Extensions.AI and MCP
1+
An opinionated meta-package for doing AI agents using Microsoft.Extensions.AI and MCP and dotnet run file.
2+
3+
Examle Claude-based agent:
4+
5+
![](https://raw.githubusercontent.com/devlooped/smith/main/assets/run.png)
6+
7+
```csharp
8+
#:package Smith@0.*
9+
10+
var configuration = new ConfigurationBuilder()
11+
.AddEnvironmentVariables()
12+
.AddUserSecrets()
13+
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
14+
.AddIniFile("appsettings.ini", optional: true, reloadOnChange: true)
15+
.Build();
16+
17+
var services = new ServiceCollection();
18+
19+
services.AddHttpClient("ai").AddStandardResilienceHandler();
20+
21+
services.AddChatClient(services => new Anthropic.AnthropicClient(
22+
configuration["Claude:Key"] ?? throw new InvalidOperationException("Missing Claude:Key configuration."),
23+
services.GetRequiredService<IHttpClientFactory>().CreateClient("ai")))
24+
//.UseConsoleLogging();
25+
26+
var provider = services.BuildServiceProvider();
27+
var history = new List<ChatMessage> { new ChatMessage(ChatRole.System, Prompts.System) };
28+
var chat = provider.GetRequiredService<IChatClient>();
29+
var options = new ChatOptions
30+
{
31+
ModelId = "claude-sonnet-4-20250514",
32+
MaxOutputTokens = 1000,
33+
Temperature = 0.7f,
34+
Tools = [AIFunctionFactory.Create(() => DateTime.Now, "get_datetime", "Gets the current date and time on the user's local machine.")]
35+
};
36+
37+
AnsiConsole.MarkupLine($":robot: Ready v{ThisAssembly.Info.Version}");
38+
AnsiConsole.Markup($":person_beard: ");
39+
while (true)
40+
{
41+
var input = Console.ReadLine()?.Trim();
42+
if (string.IsNullOrEmpty(input))
43+
continue;
44+
45+
history.Add(new ChatMessage(ChatRole.User, input));
46+
47+
try
48+
{
49+
var response = await AnsiConsole.Status().StartAsync(":robot: Thinking...",
50+
ctx => chat.GetResponseAsync(input, options));
51+
52+
history.AddRange(response.Messages);
53+
// Try rendering as formatted markup
54+
try
55+
{
56+
if (response.Text is { Length: > 0 })
57+
AnsiConsole.MarkupLine($":robot: {response.Text}");
58+
}
59+
catch (Exception)
60+
{
61+
// Fallback to escaped markup text if rendering fails
62+
AnsiConsole.MarkupInterpolated($":robot: {response.Text}");
63+
}
64+
65+
AnsiConsole.WriteLine();
66+
AnsiConsole.Markup($":person_beard: ");
67+
}
68+
catch (Exception e)
69+
{
70+
AnsiConsole.WriteException(e);
71+
}
72+
}
73+
74+
static class Prompts
75+
{
76+
public const string System =
77+
"""
78+
Your responses will be rendered using Spectre.Console.AnsiConsole.Write(new Markup(string text))).
79+
This means that you can use rich text formatting, colors, and styles in your responses, but you must
80+
ensure that the text is valid markup syntax.
81+
""";
82+
}
83+
```
84+
85+
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->

0 commit comments

Comments
 (0)