Skip to content

Commit

Permalink
Merge branch 'microsoft:main' into fix-model-produced-invalid-content
Browse files Browse the repository at this point in the history
  • Loading branch information
davorrunje authored Sep 2, 2024
2 parents abc708f + ca1a89c commit 96658f9
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 54 deletions.
15 changes: 13 additions & 2 deletions autogen/coding/local_commandline_code_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,12 @@ def _setup_functions(self) -> None:
cmd = [py_executable, "-m", "pip", "install"] + required_packages
try:
result = subprocess.run(
cmd, cwd=self._work_dir, capture_output=True, text=True, timeout=float(self._timeout)
cmd,
cwd=self._work_dir,
capture_output=True,
text=True,
timeout=float(self._timeout),
encoding="utf-8",
)
except subprocess.TimeoutExpired as e:
raise ValueError("Pip install timed out") from e
Expand Down Expand Up @@ -303,7 +308,13 @@ def _execute_code_dont_check_setup(self, code_blocks: List[CodeBlock]) -> Comman

try:
result = subprocess.run(
cmd, cwd=self._work_dir, capture_output=True, text=True, timeout=float(self._timeout), env=env
cmd,
cwd=self._work_dir,
capture_output=True,
text=True,
timeout=float(self._timeout),
env=env,
encoding="utf-8",
)
except subprocess.TimeoutExpired:
logs_all += "\n" + TIMEOUT_MSG
Expand Down
77 changes: 40 additions & 37 deletions dotnet/sample/AutoGen.OpenAI.Sample/Structural_Output.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
using Json.Schema;
using Json.Schema.Generation;
using OpenAI;
using OpenAI.Chat;

namespace AutoGen.OpenAI.Sample;

internal class Structural_Output
public class Structural_Output
{
public static async Task RunAsync()
{
Expand All @@ -23,24 +22,25 @@ public static async Task RunAsync()

var schemaBuilder = new JsonSchemaBuilder().FromType<Person>();
var schema = schemaBuilder.Build();

var personSchemaFormat = ChatResponseFormat.CreateJsonSchemaFormat(
name: "Person",
jsonSchema: BinaryData.FromObjectAsJson(schema),
description: "Person schema");

var openAIClient = new OpenAIClient(apiKey);
var openAIClientAgent = new OpenAIChatAgent(
chatClient: openAIClient.GetChatClient(model),
name: "assistant",
systemMessage: "You are a helpful assistant",
responseFormat: personSchemaFormat) // structural output by passing schema to response format
systemMessage: "You are a helpful assistant")
.RegisterMessageConnector()
.RegisterPrintMessage();
#endregion create_agent

#region chat_with_agent
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.");
var prompt = new TextMessage(Role.User, """
My name is John, I am 25 years old, and I live in Seattle. I like to play soccer and read books.
""");
var reply = await openAIClientAgent.GenerateReplyAsync(
messages: [prompt],
options: new GenerateReplyOptions
{
OutputSchema = schema,
});

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

#region person_class
public class Person
{
[JsonPropertyName("name")]
[Description("Name of the person")]
[Required]
public string Name { get; set; }

[JsonPropertyName("age")]
[Description("Age of the person")]
[Required]
public int Age { get; set; }

[JsonPropertyName("city")]
[Description("City of the person")]
public string? City { get; set; }

[JsonPropertyName("address")]
[Description("Address of the person")]
public string? Address { get; set; }

[JsonPropertyName("hobbies")]
[Description("Hobbies of the person")]
public List<string>? Hobbies { get; set; }

#region person_class
[Title("Person")]
public class Person
{
[JsonPropertyName("name")]
[Description("Name of the person")]
[Required]
public string Name { get; set; }

[JsonPropertyName("age")]
[Description("Age of the person")]
[Required]
public int Age { get; set; }

[JsonPropertyName("city")]
[Description("City of the person")]
public string? City { get; set; }

[JsonPropertyName("address")]
[Description("Address of the person")]
public string? Address { get; set; }

[JsonPropertyName("hobbies")]
[Description("Hobbies of the person")]
public List<string>? Hobbies { get; set; }
}
#endregion person_class

}
#endregion person_class
27 changes: 14 additions & 13 deletions dotnet/sample/AutoGen.OpenAI.Sample/Use_Json_Mode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using AutoGen.Core;
using AutoGen.OpenAI;
using AutoGen.OpenAI.Extension;
using FluentAssertions;
using OpenAI;
using OpenAI.Chat;

namespace AutoGen.BasicSample;
namespace AutoGen.OpenAI.Sample;

public class Use_Json_Mode
{
Expand Down Expand Up @@ -50,18 +49,20 @@ public static async Task RunAsync()
person.Age.Should().Be(25);
person.Address.Should().BeNullOrEmpty();
}
}

#region person_class
public class Person
{
[JsonPropertyName("name")]
public string Name { get; set; }

[JsonPropertyName("age")]
public int Age { get; set; }
#region person_class
public class Person
{
[JsonPropertyName("name")]
public string Name { get; set; }

[JsonPropertyName("age")]
public int Age { get; set; }

[JsonPropertyName("address")]
public string Address { get; set; }
[JsonPropertyName("address")]
public string Address { get; set; }
}
#endregion person_class
}
#endregion person_class

7 changes: 7 additions & 0 deletions dotnet/src/AutoGen.Core/Agent/IAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Json.Schema;

namespace AutoGen.Core;

Expand Down Expand Up @@ -42,6 +43,7 @@ public GenerateReplyOptions(GenerateReplyOptions other)
this.MaxToken = other.MaxToken;
this.StopSequence = other.StopSequence?.Select(s => s)?.ToArray();
this.Functions = other.Functions?.Select(f => f)?.ToArray();
this.OutputSchema = other.OutputSchema;
}

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

public FunctionContract[]? Functions { get; set; }

/// <summary>
/// Structural schema for the output. This property only applies to certain LLMs.
/// </summary>
public JsonSchema? OutputSchema { get; set; }
}
9 changes: 9 additions & 0 deletions dotnet/src/AutoGen.OpenAI/Agent/OpenAIChatAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using AutoGen.OpenAI.Extension;
using global::OpenAI;
using global::OpenAI.Chat;
using Json.Schema;

namespace AutoGen.OpenAI;

Expand Down Expand Up @@ -179,6 +180,14 @@ private ChatCompletionOptions CreateChatCompletionsOptions(GenerateReplyOptions?
}
}

if (options?.OutputSchema is not null)
{
option.ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
name: options.OutputSchema.GetTitle() ?? throw new ArgumentException("Output schema must have a title"),
jsonSchema: BinaryData.FromObjectAsJson(options.OutputSchema),
description: options.OutputSchema.GetDescription());
}

return option;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\sample\AutoGen.OpenAI.Sample\AutoGen.OpenAI.Sample.csproj" />
<ProjectReference Include="..\..\src\AutoGen.OpenAI\AutoGen.OpenAI.csproj" />
<ProjectReference Include="..\..\src\AutoGen.SourceGenerator\AutoGen.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\AutoGen.Test.Share\AutoGen.Tests.Share.csproj" />
Expand Down
1 change: 0 additions & 1 deletion dotnet/test/AutoGen.OpenAI.Tests/OpenAIChatAgentTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ public async Task ItCreateOpenAIChatAgentWithChatCompletionOptionAsync()
respond.GetContent()?.Should().NotBeNullOrEmpty();
}


private OpenAIClient CreateOpenAIClientFromAzureOpenAI()
{
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new Exception("Please set AZURE_OPENAI_ENDPOINT environment variable.");
Expand Down
48 changes: 48 additions & 0 deletions dotnet/test/AutoGen.OpenAI.Tests/OpenAISampleTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// OpenAISampleTest.cs

using System;
using System.IO;
using System.Threading.Tasks;
using AutoGen.OpenAI.Sample;
using AutoGen.Tests;
using Xunit.Abstractions;

namespace AutoGen.OpenAI.Tests;

public class OpenAISampleTest
{
private readonly ITestOutputHelper _output;

public OpenAISampleTest(ITestOutputHelper output)
{
_output = output;
Console.SetOut(new ConsoleWriter(_output));
}

[ApiKeyFact("OPENAI_API_KEY")]
public async Task Structural_OutputAsync()
{
await Structural_Output.RunAsync();
}

[ApiKeyFact("OPENAI_API_KEY")]
public async Task Use_Json_ModeAsync()
{
await Use_Json_Mode.RunAsync();
}

public class ConsoleWriter : StringWriter
{
private ITestOutputHelper output;
public ConsoleWriter(ITestOutputHelper output)
{
this.output = output;
}

public override void WriteLine(string? m)
{
output.WriteLine(m);
}
}
}
14 changes: 13 additions & 1 deletion samples/apps/autogen-studio/autogenstudio/datamodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,19 @@
Enum as SqlEnum,
)

SQLModel.model_config["protected_namespaces"] = ()
# added for python3.11 and sqlmodel 0.0.22 incompatibility
if hasattr(SQLModel, "model_config"):
SQLModel.model_config["protected_namespaces"] = ()
elif hasattr(SQLModel, "Config"):

class CustomSQLModel(SQLModel):
class Config:
protected_namespaces = ()

SQLModel = CustomSQLModel
else:
print("Warning: Unable to set protected_namespaces.")

# pylint: disable=protected-access


Expand Down

0 comments on commit 96658f9

Please sign in to comment.