Skip to content

Commit 4b3b454

Browse files
Merge pull request #98 from wisedev-code/feat/97-include-tools-support-for-cloud-providers
Feat/97 include tools support for cloud providers
2 parents f6388b0 + 3dc6da4 commit 4b3b454

37 files changed

+1491
-115
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using Examples.Utils;
2+
using MaIN.Core.Hub;
3+
using MaIN.Core.Hub.Utils;
4+
5+
namespace Examples.Agents;
6+
7+
public class AgentExampleTools : IExample
8+
{
9+
public async Task Start()
10+
{
11+
AnthropicExample.Setup();
12+
Console.WriteLine("(Anthropic) Tool example is running!");
13+
14+
var context = await AIHub.Agent()
15+
.WithModel("claude-sonnet-4-5-20250929")
16+
.WithSteps(StepBuilder.Instance
17+
.Answer()
18+
.Build())
19+
.WithTools(new ToolsConfigurationBuilder()
20+
.AddTool<ListNotesArgs>(
21+
"list_notes",
22+
"List all available notes",
23+
new
24+
{
25+
type = "object",
26+
properties = new
27+
{
28+
folder = new { type = "string", description = "Notes folder", @default = "notes" }
29+
}
30+
},
31+
NoteTools.ListNotes)
32+
.AddTool<ReadNoteArgs>(
33+
"read_note",
34+
"Read the content of a specific note",
35+
new
36+
{
37+
type = "object",
38+
properties = new
39+
{
40+
noteName = new
41+
{ type = "string", description = "Name of the note (without .txt extension)" }
42+
},
43+
required = new[] { "noteName" }
44+
},
45+
NoteTools.ReadNote)
46+
.AddTool<SaveNoteArgs>(
47+
"save_note",
48+
"Save or update a note with new content",
49+
new
50+
{
51+
type = "object",
52+
properties = new
53+
{
54+
noteName = new
55+
{ type = "string", description = "Name of the note (without .txt extension)" },
56+
content = new { type = "string", description = "Content to save in the note" }
57+
},
58+
required = new[] { "noteName", "content" }
59+
},
60+
NoteTools.SaveNote)
61+
.WithToolChoice("auto")
62+
.Build())
63+
.CreateAsync(interactiveResponse: true);
64+
65+
await context.ProcessAsync("What notes do I currently have?");
66+
67+
Console.WriteLine("--//--");
68+
69+
await context.ProcessAsync("Create a new note for a shopping list that includes healthy foods.");
70+
}
71+
}

Examples/Examples/Chat/ChatExampleAnthropic.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Examples.Utils;
22
using MaIN.Core.Hub;
3+
using MaIN.Domain.Configuration;
34

45
namespace Examples.Chat;
56

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using Examples.Utils;
2+
using MaIN.Core.Hub;
3+
using MaIN.Core.Hub.Utils;
4+
using MaIN.Domain.Configuration;
5+
6+
namespace Examples.Chat;
7+
8+
public class ChatExampleToolsSimple : IExample
9+
{
10+
public async Task Start()
11+
{
12+
OpenAiExample.Setup(); //We need to provide OpenAi API key
13+
14+
Console.WriteLine("(OpenAi) ChatExample with tools is running!");
15+
16+
await AIHub.Chat()
17+
.WithModel("gpt-5-nano")
18+
.WithMessage("What time is it right now?")
19+
.WithTools(new ToolsConfigurationBuilder()
20+
.AddTool(
21+
name: "get_current_time",
22+
description: "Get the current date and time",
23+
execute: Tools.GetCurrentTime)
24+
.WithToolChoice("auto")
25+
.Build())
26+
.CompleteAsync(interactive: true);
27+
}
28+
}

Examples/Examples/Mcp/AgentWithKnowledgeMcpExample.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ public async Task Start()
3333
Arguments = ["-y",
3434
"@modelcontextprotocol/server-filesystem",
3535
"C:\\Users\\stach\\Desktop", //Align paths to fit your system
36-
"C:\\WiseDev"], //Align paths to fit your system
36+
"C:\\WiseDev" //Align paths to fit your system
37+
], //Align paths to fit your system
3738
Backend = BackendType.GroqCloud,
3839
Model = "openai/gpt-oss-20b"
3940
}, ["filesystem", "file operations", "read write", "disk search"])

Examples/Examples/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ static void RegisterExamples(IServiceCollection services)
5151
services.AddTransient<ChatWithImageGenExample>();
5252
services.AddTransient<ChatFromExistingExample>();
5353
services.AddTransient<ChatWithReasoningExample>();
54+
services.AddTransient<ChatExampleToolsSimple>();
55+
services.AddTransient<AgentExampleTools>();
5456
services.AddTransient<AgentExample>();
5557
services.AddTransient<AgentConversationExample>();
5658
services.AddTransient<AgentWithRedirectExample>();
@@ -142,6 +144,7 @@ public class ExampleRegistry(IServiceProvider serviceProvider)
142144
("\u25a0 Chat with custom grammar", serviceProvider.GetRequiredService<ChatCustomGrammarExample>()),
143145
("\u25a0 Chat with Files from stream", serviceProvider.GetRequiredService<ChatWithFilesFromStreamExample>()),
144146
("\u25a0 Chat with Vision", serviceProvider.GetRequiredService<ChatWithVisionExample>()),
147+
("\u25a0 Chat with Tools (simple)", serviceProvider.GetRequiredService<ChatExampleToolsSimple>()),
145148
("\u25a0 Chat with Image Generation", serviceProvider.GetRequiredService<ChatWithImageGenExample>()),
146149
("\u25a0 Chat from Existing", serviceProvider.GetRequiredService<ChatFromExistingExample>()),
147150
("\u25a0 Chat with reasoning", serviceProvider.GetRequiredService<ChatWithReasoningExample>()),
@@ -151,6 +154,7 @@ public class ExampleRegistry(IServiceProvider serviceProvider)
151154
("\u25a0 Agent with Redirect (Multi backends)", serviceProvider.GetRequiredService<MultiBackendAgentWithRedirectExample>()),
152155
("\u25a0 Agent with Redirect Image", serviceProvider.GetRequiredService<AgentWithRedirectImageExample>()),
153156
("\u25a0 Agent with Become", serviceProvider.GetRequiredService<AgentWithBecomeExample>()),
157+
("\u25a0 Agent with Tools (advanced)", serviceProvider.GetRequiredService<AgentExampleTools>()),
154158
("\u25a0 Agent with Knowledge", serviceProvider.GetRequiredService<AgentWithKnowledgeFileExample>()),
155159
("\u25a0 Agent with Web Knowledge", serviceProvider.GetRequiredService<AgentWithKnowledgeWebExample>()),
156160
("\u25a0 Agent with Mcp Knowledge", serviceProvider.GetRequiredService<AgentWithKnowledgeMcpExample>()),

Examples/Examples/Utils/Tools.cs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using System.Text.Json;
2+
3+
namespace Examples.Utils;
4+
5+
public static class Tools
6+
{
7+
public static object GetCurrentTime()
8+
{
9+
var now = DateTime.Now;
10+
var timeInfo = new
11+
{
12+
date = now.ToString("yyyy-MM-dd"),
13+
time = now.ToString("HH:mm:ss"),
14+
dayOfWeek = now.DayOfWeek.ToString()
15+
};
16+
17+
return $"Date: {timeInfo.date}, Time: {timeInfo.time}, Day of week: {timeInfo.dayOfWeek}";
18+
}
19+
}
20+
21+
public static class NoteTools
22+
{
23+
private const string NotesFolder = "notes";
24+
25+
public static async Task<object> ListNotes(ListNotesArgs args)
26+
{
27+
if (!Directory.Exists(args.Folder))
28+
Directory.CreateDirectory(args.Folder);
29+
30+
var files = Directory.GetFiles(args.Folder, "*.txt");
31+
32+
return new
33+
{
34+
count = files.Length,
35+
notes = files.Select(f => new
36+
{
37+
name = Path.GetFileNameWithoutExtension(f),
38+
lastModified = File.GetLastWriteTime(f).ToString("yyyy-MM-dd HH:mm:ss"),
39+
sizeBytes = new FileInfo(f).Length
40+
}).ToArray()
41+
};
42+
}
43+
44+
public static async Task<object> ReadNote(ReadNoteArgs args)
45+
{
46+
var filePath = Path.Combine(NotesFolder, $"{args.NoteName}.txt");
47+
48+
if (!File.Exists(filePath))
49+
return new { error = $"Note '{args.NoteName}' not found" };
50+
51+
var content = await File.ReadAllTextAsync(filePath);
52+
53+
return new
54+
{
55+
name = args.NoteName,
56+
content = content,
57+
lastModified = File.GetLastWriteTime(filePath).ToString("yyyy-MM-dd HH:mm:ss")
58+
};
59+
}
60+
61+
public static async Task<object> SaveNote(SaveNoteArgs args)
62+
{
63+
if (!Directory.Exists(NotesFolder))
64+
Directory.CreateDirectory(NotesFolder);
65+
66+
var filePath = Path.Combine(NotesFolder, $"{args.NoteName}.txt");
67+
var isNew = !File.Exists(filePath);
68+
69+
await File.WriteAllTextAsync(filePath, args.Content);
70+
71+
return new
72+
{
73+
success = true,
74+
name = args.NoteName,
75+
action = isNew ? "created" : "updated",
76+
path = filePath
77+
};
78+
}
79+
}
80+
81+
public class ListNotesArgs
82+
{
83+
public string Folder { get; set; } = "notes";
84+
}
85+
86+
public class ReadNoteArgs
87+
{
88+
public string NoteName { get; set; } = null!;
89+
}
90+
91+
public class SaveNoteArgs
92+
{
93+
public string NoteName { get; set; } = null!;
94+
public string Content { get; set; } = null!;
95+
}

Releases/0.7.0.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# 0.7.0 release
2+
3+
- Add full tool support for all available cloud providers
4+
5+
On chat/agent context
6+
7+
```
8+
.WithTools(new ToolsConfigurationBuilder()
9+
.AddTool(
10+
name: "get_current_time",
11+
description: "Get the current date and time",
12+
execute: Tools.GetCurrentTime)
13+
.WithToolChoice("auto")
14+
.Build())
15+
```

src/MaIN.Core/.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package>
33
<metadata>
44
<id>MaIN.NET</id>
5-
<version>0.6.4</version>
5+
<version>0.7.0</version>
66
<authors>Wisedev</authors>
77
<owners>Wisedev</owners>
88
<icon>favicon.png</icon>

src/MaIN.Core/Hub/Contexts/AgentContext.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using MaIN.Services.Services.Models;
88
using MaIN.Core.Hub.Utils;
99
using MaIN.Domain.Entities.Agents.Knowledge;
10+
using MaIN.Domain.Entities.Tools;
1011

1112
namespace MaIN.Core.Hub.Contexts;
1213

@@ -51,7 +52,7 @@ public AgentContext WithId(string id)
5152
_agent.Id = id;
5253
return this;
5354
}
54-
55+
5556
public string GetAgentId() => _agent.Id;
5657

5758
public Agent GetAgent() => _agent;
@@ -187,6 +188,12 @@ public AgentContext Create(bool flow = false, bool interactiveResponse = false)
187188
return this;
188189
}
189190

191+
public AgentContext WithTools(ToolsConfiguration toolsConfiguration)
192+
{
193+
_agent.ToolsConfiguration = toolsConfiguration;
194+
return this;
195+
}
196+
190197
internal void LoadExistingKnowledgeIfExists()
191198
{
192199
_knowledge ??= new Knowledge(_agent);

src/MaIN.Core/Hub/Contexts/ChatContext.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using MaIN.Domain.Configuration;
22
using MaIN.Domain.Entities;
3+
using MaIN.Domain.Entities.Tools;
34
using MaIN.Domain.Models;
45
using MaIN.Services;
56
using MaIN.Services.Constants;
@@ -47,6 +48,12 @@ public ChatContext WithInferenceParams(InferenceParams inferenceParams)
4748
return this;
4849
}
4950

51+
public ChatContext WithTools(ToolsConfiguration toolsConfiguration)
52+
{
53+
_chat.ToolsConfiguration = toolsConfiguration;
54+
return this;
55+
}
56+
5057
public ChatContext WithMemoryParams(MemoryParams memoryParams)
5158
{
5259
_chat.MemoryParams = memoryParams;

0 commit comments

Comments
 (0)