Skip to content

Commit 96658f9

Browse files
authored
Merge branch 'microsoft:main' into fix-model-produced-invalid-content
2 parents abc708f + ca1a89c commit 96658f9

File tree

9 files changed

+145
-54
lines changed

9 files changed

+145
-54
lines changed

autogen/coding/local_commandline_code_executor.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,12 @@ def _setup_functions(self) -> None:
221221
cmd = [py_executable, "-m", "pip", "install"] + required_packages
222222
try:
223223
result = subprocess.run(
224-
cmd, cwd=self._work_dir, capture_output=True, text=True, timeout=float(self._timeout)
224+
cmd,
225+
cwd=self._work_dir,
226+
capture_output=True,
227+
text=True,
228+
timeout=float(self._timeout),
229+
encoding="utf-8",
225230
)
226231
except subprocess.TimeoutExpired as e:
227232
raise ValueError("Pip install timed out") from e
@@ -303,7 +308,13 @@ def _execute_code_dont_check_setup(self, code_blocks: List[CodeBlock]) -> Comman
303308

304309
try:
305310
result = subprocess.run(
306-
cmd, cwd=self._work_dir, capture_output=True, text=True, timeout=float(self._timeout), env=env
311+
cmd,
312+
cwd=self._work_dir,
313+
capture_output=True,
314+
text=True,
315+
timeout=float(self._timeout),
316+
env=env,
317+
encoding="utf-8",
307318
)
308319
except subprocess.TimeoutExpired:
309320
logs_all += "\n" + TIMEOUT_MSG

dotnet/sample/AutoGen.OpenAI.Sample/Structural_Output.cs

+40-37
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@
99
using Json.Schema;
1010
using Json.Schema.Generation;
1111
using OpenAI;
12-
using OpenAI.Chat;
1312

1413
namespace AutoGen.OpenAI.Sample;
1514

16-
internal class Structural_Output
15+
public class Structural_Output
1716
{
1817
public static async Task RunAsync()
1918
{
@@ -23,24 +22,25 @@ public static async Task RunAsync()
2322

2423
var schemaBuilder = new JsonSchemaBuilder().FromType<Person>();
2524
var schema = schemaBuilder.Build();
26-
27-
var personSchemaFormat = ChatResponseFormat.CreateJsonSchemaFormat(
28-
name: "Person",
29-
jsonSchema: BinaryData.FromObjectAsJson(schema),
30-
description: "Person schema");
31-
3225
var openAIClient = new OpenAIClient(apiKey);
3326
var openAIClientAgent = new OpenAIChatAgent(
3427
chatClient: openAIClient.GetChatClient(model),
3528
name: "assistant",
36-
systemMessage: "You are a helpful assistant",
37-
responseFormat: personSchemaFormat) // structural output by passing schema to response format
29+
systemMessage: "You are a helpful assistant")
3830
.RegisterMessageConnector()
3931
.RegisterPrintMessage();
4032
#endregion create_agent
4133

4234
#region chat_with_agent
43-
var reply = await openAIClientAgent.SendAsync("My name is John, I am 25 years old, and I live in Seattle. I like to play soccer and read books.");
35+
var prompt = new TextMessage(Role.User, """
36+
My name is John, I am 25 years old, and I live in Seattle. I like to play soccer and read books.
37+
""");
38+
var reply = await openAIClientAgent.GenerateReplyAsync(
39+
messages: [prompt],
40+
options: new GenerateReplyOptions
41+
{
42+
OutputSchema = schema,
43+
});
4444

4545
var person = JsonSerializer.Deserialize<Person>(reply.GetContent());
4646
Console.WriteLine($"Name: {person.Name}");
@@ -60,31 +60,34 @@ public static async Task RunAsync()
6060
person.City.Should().Be("Seattle");
6161
person.Hobbies.Count.Should().Be(2);
6262
}
63-
}
6463

65-
#region person_class
66-
public class Person
67-
{
68-
[JsonPropertyName("name")]
69-
[Description("Name of the person")]
70-
[Required]
71-
public string Name { get; set; }
72-
73-
[JsonPropertyName("age")]
74-
[Description("Age of the person")]
75-
[Required]
76-
public int Age { get; set; }
77-
78-
[JsonPropertyName("city")]
79-
[Description("City of the person")]
80-
public string? City { get; set; }
81-
82-
[JsonPropertyName("address")]
83-
[Description("Address of the person")]
84-
public string? Address { get; set; }
85-
86-
[JsonPropertyName("hobbies")]
87-
[Description("Hobbies of the person")]
88-
public List<string>? Hobbies { get; set; }
64+
65+
#region person_class
66+
[Title("Person")]
67+
public class Person
68+
{
69+
[JsonPropertyName("name")]
70+
[Description("Name of the person")]
71+
[Required]
72+
public string Name { get; set; }
73+
74+
[JsonPropertyName("age")]
75+
[Description("Age of the person")]
76+
[Required]
77+
public int Age { get; set; }
78+
79+
[JsonPropertyName("city")]
80+
[Description("City of the person")]
81+
public string? City { get; set; }
82+
83+
[JsonPropertyName("address")]
84+
[Description("Address of the person")]
85+
public string? Address { get; set; }
86+
87+
[JsonPropertyName("hobbies")]
88+
[Description("Hobbies of the person")]
89+
public List<string>? Hobbies { get; set; }
90+
}
91+
#endregion person_class
92+
8993
}
90-
#endregion person_class

dotnet/sample/AutoGen.OpenAI.Sample/Use_Json_Mode.cs

+14-13
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
using System.Text.Json;
55
using System.Text.Json.Serialization;
66
using AutoGen.Core;
7-
using AutoGen.OpenAI;
87
using AutoGen.OpenAI.Extension;
98
using FluentAssertions;
109
using OpenAI;
1110
using OpenAI.Chat;
1211

13-
namespace AutoGen.BasicSample;
12+
namespace AutoGen.OpenAI.Sample;
1413

1514
public class Use_Json_Mode
1615
{
@@ -50,18 +49,20 @@ public static async Task RunAsync()
5049
person.Age.Should().Be(25);
5150
person.Address.Should().BeNullOrEmpty();
5251
}
53-
}
5452

55-
#region person_class
56-
public class Person
57-
{
58-
[JsonPropertyName("name")]
59-
public string Name { get; set; }
6053

61-
[JsonPropertyName("age")]
62-
public int Age { get; set; }
54+
#region person_class
55+
public class Person
56+
{
57+
[JsonPropertyName("name")]
58+
public string Name { get; set; }
59+
60+
[JsonPropertyName("age")]
61+
public int Age { get; set; }
6362

64-
[JsonPropertyName("address")]
65-
public string Address { get; set; }
63+
[JsonPropertyName("address")]
64+
public string Address { get; set; }
65+
}
66+
#endregion person_class
6667
}
67-
#endregion person_class
68+

dotnet/src/AutoGen.Core/Agent/IAgent.cs

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Threading;
77
using System.Threading.Tasks;
8+
using Json.Schema;
89

910
namespace AutoGen.Core;
1011

@@ -42,6 +43,7 @@ public GenerateReplyOptions(GenerateReplyOptions other)
4243
this.MaxToken = other.MaxToken;
4344
this.StopSequence = other.StopSequence?.Select(s => s)?.ToArray();
4445
this.Functions = other.Functions?.Select(f => f)?.ToArray();
46+
this.OutputSchema = other.OutputSchema;
4547
}
4648

4749
public float? Temperature { get; set; }
@@ -51,4 +53,9 @@ public GenerateReplyOptions(GenerateReplyOptions other)
5153
public string[]? StopSequence { get; set; }
5254

5355
public FunctionContract[]? Functions { get; set; }
56+
57+
/// <summary>
58+
/// Structural schema for the output. This property only applies to certain LLMs.
59+
/// </summary>
60+
public JsonSchema? OutputSchema { get; set; }
5461
}

dotnet/src/AutoGen.OpenAI/Agent/OpenAIChatAgent.cs

+9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using AutoGen.OpenAI.Extension;
1111
using global::OpenAI;
1212
using global::OpenAI.Chat;
13+
using Json.Schema;
1314

1415
namespace AutoGen.OpenAI;
1516

@@ -179,6 +180,14 @@ private ChatCompletionOptions CreateChatCompletionsOptions(GenerateReplyOptions?
179180
}
180181
}
181182

183+
if (options?.OutputSchema is not null)
184+
{
185+
option.ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
186+
name: options.OutputSchema.GetTitle() ?? throw new ArgumentException("Output schema must have a title"),
187+
jsonSchema: BinaryData.FromObjectAsJson(options.OutputSchema),
188+
description: options.OutputSchema.GetDescription());
189+
}
190+
182191
return option;
183192
}
184193

dotnet/test/AutoGen.OpenAI.Tests/AutoGen.OpenAI.Tests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
</ItemGroup>
1313

1414
<ItemGroup>
15+
<ProjectReference Include="..\..\sample\AutoGen.OpenAI.Sample\AutoGen.OpenAI.Sample.csproj" />
1516
<ProjectReference Include="..\..\src\AutoGen.OpenAI\AutoGen.OpenAI.csproj" />
1617
<ProjectReference Include="..\..\src\AutoGen.SourceGenerator\AutoGen.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
1718
<ProjectReference Include="..\AutoGen.Test.Share\AutoGen.Tests.Share.csproj" />

dotnet/test/AutoGen.OpenAI.Tests/OpenAIChatAgentTest.cs

-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ public async Task ItCreateOpenAIChatAgentWithChatCompletionOptionAsync()
246246
respond.GetContent()?.Should().NotBeNullOrEmpty();
247247
}
248248

249-
250249
private OpenAIClient CreateOpenAIClientFromAzureOpenAI()
251250
{
252251
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new Exception("Please set AZURE_OPENAI_ENDPOINT environment variable.");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// OpenAISampleTest.cs
3+
4+
using System;
5+
using System.IO;
6+
using System.Threading.Tasks;
7+
using AutoGen.OpenAI.Sample;
8+
using AutoGen.Tests;
9+
using Xunit.Abstractions;
10+
11+
namespace AutoGen.OpenAI.Tests;
12+
13+
public class OpenAISampleTest
14+
{
15+
private readonly ITestOutputHelper _output;
16+
17+
public OpenAISampleTest(ITestOutputHelper output)
18+
{
19+
_output = output;
20+
Console.SetOut(new ConsoleWriter(_output));
21+
}
22+
23+
[ApiKeyFact("OPENAI_API_KEY")]
24+
public async Task Structural_OutputAsync()
25+
{
26+
await Structural_Output.RunAsync();
27+
}
28+
29+
[ApiKeyFact("OPENAI_API_KEY")]
30+
public async Task Use_Json_ModeAsync()
31+
{
32+
await Use_Json_Mode.RunAsync();
33+
}
34+
35+
public class ConsoleWriter : StringWriter
36+
{
37+
private ITestOutputHelper output;
38+
public ConsoleWriter(ITestOutputHelper output)
39+
{
40+
this.output = output;
41+
}
42+
43+
public override void WriteLine(string? m)
44+
{
45+
output.WriteLine(m);
46+
}
47+
}
48+
}

samples/apps/autogen-studio/autogenstudio/datamodel.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,19 @@
1616
Enum as SqlEnum,
1717
)
1818

19-
SQLModel.model_config["protected_namespaces"] = ()
19+
# added for python3.11 and sqlmodel 0.0.22 incompatibility
20+
if hasattr(SQLModel, "model_config"):
21+
SQLModel.model_config["protected_namespaces"] = ()
22+
elif hasattr(SQLModel, "Config"):
23+
24+
class CustomSQLModel(SQLModel):
25+
class Config:
26+
protected_namespaces = ()
27+
28+
SQLModel = CustomSQLModel
29+
else:
30+
print("Warning: Unable to set protected_namespaces.")
31+
2032
# pylint: disable=protected-access
2133

2234

0 commit comments

Comments
 (0)