diff --git a/OpenAI_Adapter/AdapterActions/Execute.cs b/OpenAI_Adapter/AdapterActions/Execute.cs index 636379a..2697e15 100644 --- a/OpenAI_Adapter/AdapterActions/Execute.cs +++ b/OpenAI_Adapter/AdapterActions/Execute.cs @@ -24,6 +24,7 @@ using BH.oM.Adapter; using BH.oM.Adapters.OpenAI; using BH.oM.Adapters.OpenAI.Commands; +using BH.oM.Adapters.OpenAI.Output; using BH.oM.Base; using System; using System.Collections.Generic; @@ -110,13 +111,29 @@ private async Task PromptAsync(string system, IEnumerable user, messages.AddRange(user.Select(x => new { role = "user", content = x })); messages.AddRange(assistant.Select(x => new { role = "assistant", content = x })); - var requestBody = new + object responseFormat = BuildResponseFormat(config.OutputType); + object requestBody; + if (responseFormat == null) { - messages = messages, - max_tokens = config.MaxTokens, - temperature = config.Temperature, - top_p = config.TopP - }; + requestBody = new + { + messages = messages, + max_tokens = config.MaxTokens, + temperature = config.Temperature, + top_p = config.TopP + }; + } + else + { + requestBody = new + { + messages = messages, + max_tokens = config.MaxTokens, + temperature = config.Temperature, + top_p = config.TopP, + response_format = responseFormat + }; + } string json = JsonSerializer.Serialize(requestBody); StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); @@ -138,6 +155,38 @@ private async Task PromptAsync(string system, IEnumerable user, } /***************************************************/ + + private static object BuildResponseFormat(IOutputType outputType) + { + if (outputType == null || outputType is Text) + return null; + + if (outputType is JsonObject) + return new { type = "json_object" }; + + if (outputType is JsonSchema jsonSchema) + { + if (string.IsNullOrWhiteSpace(jsonSchema.Schema)) + return null; + + string schemaName = string.IsNullOrWhiteSpace(jsonSchema.Name) ? "structured_output" : jsonSchema.Name; + + return new + { + type = "json_schema", + json_schema = new + { + strict = true, + name = schemaName, + schema = JsonSerializer.Deserialize(jsonSchema.Schema), + } + }; + } + + return null; + } + + /***************************************************/ } } diff --git a/OpenAI_oM/Config/PromptExecutionConfig.cs b/OpenAI_oM/Config/PromptExecutionConfig.cs index 274b2c7..b72f822 100644 --- a/OpenAI_oM/Config/PromptExecutionConfig.cs +++ b/OpenAI_oM/Config/PromptExecutionConfig.cs @@ -21,6 +21,7 @@ */ using BH.oM.Adapter; +using BH.oM.Adapters.OpenAI.Output; using System.ComponentModel; namespace BH.oM.Adapters.OpenAI @@ -44,6 +45,9 @@ public class PromptExecutionConfig : ActionConfig [Description("Timeout in seconds for the prompt execution. This setting determines how long the system will wait for a response before timing out. A typical value is 30 seconds, but it can be adjusted based on the expected response time of the API.")] public virtual int TimeoutSeconds { get; set; } = 30; + [Description("How the model response should be formatted. Defaults to plain text with no response_format constraint.")] + public virtual IOutputType OutputType { get; set; } = new Text(); + /***************************************************/ } } diff --git a/OpenAI_oM/Output/IOutputType.cs b/OpenAI_oM/Output/IOutputType.cs new file mode 100644 index 0000000..d7addbd --- /dev/null +++ b/OpenAI_oM/Output/IOutputType.cs @@ -0,0 +1,33 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Base; +using System.ComponentModel; + +namespace BH.oM.Adapters.OpenAI.Output +{ + [Description("Describes how the model response should be formatted when executing a prompt.")] + public interface IOutputType : IObject + { + + } +} diff --git a/OpenAI_oM/Output/JsonObject.cs b/OpenAI_oM/Output/JsonObject.cs new file mode 100644 index 0000000..029c539 --- /dev/null +++ b/OpenAI_oM/Output/JsonObject.cs @@ -0,0 +1,32 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System.ComponentModel; + +namespace BH.oM.Adapters.OpenAI.Output +{ + [Description("JSON object output. The API is asked to return valid JSON, but no schema is enforced.")] + public class JsonObject : IOutputType + { + + } +} diff --git a/OpenAI_oM/Output/JsonSchema.cs b/OpenAI_oM/Output/JsonSchema.cs new file mode 100644 index 0000000..534589e --- /dev/null +++ b/OpenAI_oM/Output/JsonSchema.cs @@ -0,0 +1,42 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System.ComponentModel; + +namespace BH.oM.Adapters.OpenAI.Output +{ + [Description("Structured JSON output with a strict JSON Schema. The API validates the response against Schema.")] + public class JsonSchema : IOutputType + { + /***************************************************/ + /**** Public properties ****/ + /***************************************************/ + + [Description("Identifier for the JSON Schema in the API request. Required by OpenAI when using json_schema mode. Use a descriptive name when several schemas exist in one integration; otherwise leave null and the adapter supplies a default.")] + public virtual string Name { get; set; } = null; + + [Description("JSON Schema describing the expected response shape, serialised as a JSON string.")] + public virtual string Schema { get; set; } = null; + + /***************************************************/ + } +} diff --git a/OpenAI_oM/Output/Text.cs b/OpenAI_oM/Output/Text.cs new file mode 100644 index 0000000..946d864 --- /dev/null +++ b/OpenAI_oM/Output/Text.cs @@ -0,0 +1,32 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System.ComponentModel; + +namespace BH.oM.Adapters.OpenAI.Output +{ + [Description("Plain-text model output. No response_format constraint is sent to the API.")] + public class Text : IOutputType + { + + } +}