Skip to content

Commit 9146699

Browse files
authored
0.9.0 preview (#3)
* Implemented agents service. * Improved and expanded request config overrides. * Reworked plugin implementation for more flexibility and clarity. * Minor fixes and improvements.
1 parent 000d772 commit 9146699

File tree

179 files changed

+7444
-2868
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

179 files changed

+7444
-2868
lines changed

.github/workflows/build-and-deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
- master
99
env:
1010
APP_NAME: Vivet.AI
11-
VERSION: 0.8.0-preview
11+
VERSION: 0.9.0-preview
1212
NUGET_HOST: https://api.nuget.org/v3/index.json
1313
NUGET_APIKEY: ${{ secrets.NUGET_APIKEY }}
1414
jobs:

.tests/IntegrationTests.Vivet.AI/BaseTests.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ public class BaseTests
1515

1616
protected IServiceProvider ServiceProvider => this.services.BuildServiceProvider();
1717

18-
protected readonly string tenantId = "5232f275-40e2-4d18-9dce-d619b6180b40";
19-
protected readonly string subTenantId = "bed6e482-6bcb-447b-b509-65d7c833e698a";
20-
protected readonly string userId = "a823dd01-4734-44bb-9402-29c7813652a4";
18+
protected readonly Guid tenantId = Guid.Parse("5232f275-40e2-4d18-9dce-d619b6180b40");
19+
protected readonly Guid subTenantId = Guid.Parse("bed6e482-6bcb-447b-b509-65d7c833e698");
20+
protected readonly Guid userId = Guid.Parse("a823dd01-4734-44bb-9402-29c7813652a4");
2121
protected readonly string language = "en";
2222
protected readonly string createdBy = "createdBy";
2323
protected readonly string source = "source";
@@ -34,7 +34,11 @@ public virtual void TestSetup()
3434

3535
this.services
3636
.AddSingleton<IConfiguration>(configuration)
37-
.AddLogging(x => x.AddConsole());
37+
.AddLogging(x =>
38+
{
39+
x.SetMinimumLevel(LogLevel.Trace);
40+
x.AddConsole();
41+
});
3842

3943
this.services
4044
.AddVivetAzureOpenAi();
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.SemanticKernel;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using System.Threading.Tasks;
5+
using Vivet.AI.Services.Interfaces;
6+
using Vivet.AI.Services.Requests.Agents;
7+
using Vivet.AI.Services.Requests.Agents.Models;
8+
9+
namespace IntegrationTests.Vivet.AI.Services;
10+
11+
[TestClass]
12+
public class AgentsServiceTests : BaseTests
13+
{
14+
private IAgentsService AgentsService => this.ServiceProvider.GetRequiredService<IAgentsService>();
15+
16+
private sealed class OrderStatusPlugin
17+
{
18+
[KernelFunction]
19+
// ReSharper disable UnusedMember.Local
20+
public string CheckOrderStatus(string orderId) => $"Order {orderId} is shipped and will arrive in 2-3 days.";
21+
// ReSharper restore UnusedMember.Local
22+
}
23+
24+
private sealed class OrderReturnPlugin
25+
{
26+
[KernelFunction]
27+
// ReSharper disable UnusedMember.Local
28+
public string ProcessReturn(string orderId, string reason) => $"Return for order {orderId} has been processed successfully. {reason}";
29+
// ReSharper restore UnusedMember.Local
30+
}
31+
32+
private sealed class OrderRefundPlugin
33+
{
34+
[KernelFunction]
35+
// ReSharper disable UnusedMember.Local
36+
public string ProcessReturn(string orderId, string reason) => $"Refund for order {orderId} has been processed successfully. {reason}";
37+
// ReSharper restore UnusedMember.Local
38+
}
39+
40+
[TestMethod]
41+
public async Task InvokeWhenOrchestrationSequentialTest()
42+
{
43+
var agents = new AgentDescriptor[]
44+
{
45+
new()
46+
{
47+
Name = "Analyst",
48+
Description = "A agent that extracts key concepts from a product description.",
49+
Instructions = @"You are a marketing analyst. Given a product description, identify:
50+
- Key features
51+
- Target audience
52+
- Unique selling points"
53+
},
54+
new()
55+
{
56+
Name = "copywriter",
57+
Description = "An agent that writes a marketing copy based on the extracted concepts.",
58+
Instructions = @"You are a marketing copywriter. Given a block of text describing features, audience, and USPs,
59+
compose a compelling marketing copy (like a newsletter section) that highlights these points.
60+
Output should be short (around 150 words), output just the copy as a single text block."
61+
},
62+
new()
63+
{
64+
Name = "editor",
65+
Description = "An agent that formats and proofreads the marketing copy.",
66+
Instructions = @"You are an editor. Given the draft copy, correct grammar, improve clarity, ensure consistent tone,
67+
give format and make it polished. Output the final improved copy as a single text block."
68+
}
69+
};
70+
71+
var response = await this.AgentsService
72+
.InvokeAsync(new SequentialAgentsRequest
73+
{
74+
Name = "Sequential",
75+
Input = "An eco-friendly stainless steel water bottle that keeps drinks cold for 24 hours",
76+
Agents = agents,
77+
ConfigOverrides =
78+
{
79+
Plugins =
80+
{
81+
Memory =
82+
{
83+
EnableMemoryPlugin = false
84+
}
85+
}
86+
}
87+
});
88+
89+
Assert.IsNotNull(response);
90+
Assert.IsNull(response.Exception);
91+
}
92+
93+
[TestMethod]
94+
public async Task InvokeWhenOrchestrationConcurrentTest()
95+
{
96+
var agents = new AgentDescriptor[]
97+
{
98+
new()
99+
{
100+
Name = "Physicist",
101+
Description = "An expert in physics",
102+
Instructions = "You are an expert in physics, and anwer all questions from a physics perspective."
103+
},
104+
new()
105+
{
106+
Name = "Chemist",
107+
Description = "An expert in chemistry",
108+
Instructions = "You are an expert in chemist, and anwer all questions from a chemistry perspective."
109+
}
110+
};
111+
112+
var response = await this.AgentsService
113+
.InvokeAsync(new ConcurrentAgentsRequest
114+
{
115+
Name = "Concurrent",
116+
Input = "What is temperature?",
117+
Agents = agents,
118+
ConfigOverrides =
119+
{
120+
Plugins =
121+
{
122+
Memory =
123+
{
124+
EnableMemoryPlugin = false
125+
}
126+
}
127+
}
128+
});
129+
130+
Assert.IsNotNull(response);
131+
Assert.IsNull(response.Exception);
132+
}
133+
134+
[TestMethod]
135+
public async Task InvokeWhenOrchestrationGroupChatTest()
136+
{
137+
await Task.CompletedTask;
138+
Assert.Inconclusive();
139+
140+
// var agents = new AgentDescriptor[]
141+
// {
142+
// new()
143+
// {
144+
// Name = "copywriter",
145+
// Description = "An agent that writes a marketing copy based on the extracted concepts.",
146+
// Instructions = @" You are a copywriter with ten years of experience and are known for brevity and a dry humor.
147+
//The goal is to refine and decide on the single best copy as an expert in the field.
148+
//Only provide a single proposal per response.
149+
//You're laser focused on the goal at hand.
150+
//Don't waste time with chit chat.
151+
//Consider suggestions when refining an idea"
152+
// },
153+
// new()
154+
// {
155+
// Name = "reviewer",
156+
// Description = "An editor.",
157+
// Instructions = @"You are an art director who has opinions about copywriting born of a love for David Ogilvy.
158+
//The goal is to determine if the given copy is acceptable to print.
159+
//If so, state: ""I Approve"".
160+
//If not, provide insight on how to refine suggested copy without example."
161+
// }
162+
// };
163+
164+
// var response = await this.AgentsService
165+
// .InvokeAsync(new SequentialAgentsRequest
166+
// {
167+
// Name = "Sequential",
168+
// Input = "Create a slogan for a new electric SUV that is affordable and fun to drive.",
169+
// Agents = agents,
170+
// ConfigOverrides =
171+
// {
172+
// Plugins =
173+
// {
174+
// Memory =
175+
// {
176+
// EnableMemoryPlugin = false
177+
// }
178+
// }
179+
// }
180+
// });
181+
}
182+
183+
[TestMethod]
184+
public async Task InvokeWhenOrchestrationHandOffTest()
185+
{
186+
await Task.CompletedTask;
187+
Assert.Inconclusive();
188+
189+
//var agents = new AgentDescriptor[]
190+
//{
191+
// new()
192+
// {
193+
// Name = "TriageAgent",
194+
// Description = "Handle customer requests.",
195+
// Instructions = "A customer support agent that triages issues."
196+
// },
197+
// new()
198+
// {
199+
// Name = "OrderStatusAgent",
200+
// Description = "A customer support agent that checks order status.",
201+
// Instructions = "Handle order status requests.",
202+
// Plugins =
203+
// {
204+
// CustomPlugins =
205+
// [
206+
// new CustomPlugin
207+
// {
208+
// Name = "OrderStatusPlugin",
209+
// Type = typeof(OrderStatusPlugin)
210+
// }
211+
// ]
212+
// }
213+
// },
214+
// new()
215+
// {
216+
// Name = "OrderReturnAgent",
217+
// Description = "A customer support agent that handles order returns.",
218+
// Instructions = "Handle order return requests.",
219+
// Plugins =
220+
// {
221+
// CustomPlugins =
222+
// [
223+
// new CustomPlugin
224+
// {
225+
// Name = "OrderReturnPlugin",
226+
// Type = typeof(OrderReturnPlugin)
227+
// }
228+
// ]
229+
// }
230+
// },
231+
// new()
232+
// {
233+
// Name = "OrderRefundAgent",
234+
// Description = "A customer support agent that handles order refund.",
235+
// Instructions = "Handle order refund requests.",
236+
// Plugins =
237+
// {
238+
// CustomPlugins =
239+
// [
240+
// new CustomPlugin
241+
// {
242+
// Name = "OrderRefundPlugin",
243+
// Type = typeof(OrderRefundPlugin)
244+
// }
245+
// ]
246+
// }
247+
// }
248+
//};
249+
250+
//var response = await this.AgentsService
251+
// .InvokeAsync(new HandOffAgentsRequest
252+
// {
253+
// Name = "Sequential",
254+
// Input = "I am a customer that needs help with my orders",
255+
// Agents = agents,
256+
// ConfigOverrides =
257+
// {
258+
// Plugins =
259+
// {
260+
// Memory =
261+
// {
262+
// EnableMemoryPlugin = false
263+
// }
264+
// }
265+
// }
266+
// });
267+
268+
//Assert.IsNotNull(response);
269+
//Assert.IsNull(response.Exception);
270+
}
271+
272+
[TestMethod]
273+
public async Task InvokeWhenOrchestrationMagneticTest()
274+
{
275+
await Task.CompletedTask;
276+
Assert.Inconclusive();
277+
}
278+
279+
[TestMethod]
280+
public async Task InvokeWhenBlobsTest()
281+
{
282+
await Task.CompletedTask;
283+
Assert.Inconclusive();
284+
}
285+
286+
[TestMethod]
287+
public async Task InvokeWhenBuiltInPluginsTest()
288+
{
289+
await Task.CompletedTask;
290+
Assert.Inconclusive();
291+
}
292+
293+
[TestMethod]
294+
public async Task InvokeWhenCustomPluginsTest()
295+
{
296+
await Task.CompletedTask;
297+
Assert.Inconclusive();
298+
}
299+
300+
[TestMethod]
301+
public async Task InvokeWhenErrorMessageTest()
302+
{
303+
await Task.CompletedTask;
304+
Assert.Inconclusive();
305+
}
306+
}

0 commit comments

Comments
 (0)