diff --git a/.github/workflows/ci-beta.yml b/.github/workflows/ci-beta.yml new file mode 100644 index 0000000..b7ade02 --- /dev/null +++ b/.github/workflows/ci-beta.yml @@ -0,0 +1,138 @@ +# Beta-tier proxy, BHoM variant. Bundles the tier's checks plus +# copyright-compliance (BHoM enforces OSS copyright; the BHE variant omits it). +# Copy to .github/workflows/ci-beta.yml in each BHoM beta repo. +# Runs on pull_request, non-blocking until a ruleset requires its checks. +# Workflow name CI keeps check contexts bare: required contexts are the job names. + +name: CI + +on: + pull_request: + branches: + - develop + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true + +jobs: + ci-build: + runs-on: windows-2025-vs2026 + timeout-minutes: 30 + steps: + - name: Run build + uses: BHoM/CI_Toolkit/.github/actions/ci-build@develop + with: + app_id: ${{ secrets.BHOM_APP_ID }} + private_key: ${{ secrets.BHOM_APP_PRIVATE_KEY }} + + ci-code-compliance: + runs-on: windows-2025-vs2026 + timeout-minutes: 20 + permissions: + contents: read + pull-requests: read + actions: write + steps: + - name: Run code compliance + uses: BHoM/CI_Toolkit/.github/actions/ci-compliance@develop + with: + check_type: code + patterns: '*.cs' + app_id: ${{ secrets.BHOM_APP_ID }} + private_key: ${{ secrets.BHOM_APP_PRIVATE_KEY }} + + ci-copyright-compliance: + runs-on: windows-2025-vs2026 + timeout-minutes: 20 + permissions: + contents: read + pull-requests: read + actions: write + steps: + - name: Run copyright compliance + uses: BHoM/CI_Toolkit/.github/actions/ci-compliance@develop + with: + check_type: copyright + patterns: '*.cs' + app_id: ${{ secrets.BHOM_APP_ID }} + private_key: ${{ secrets.BHOM_APP_PRIVATE_KEY }} + + ci-dataset-compliance: + runs-on: windows-2025-vs2026 + timeout-minutes: 20 + permissions: + contents: read + pull-requests: read + actions: write + steps: + - name: Run dataset compliance + uses: BHoM/CI_Toolkit/.github/actions/ci-compliance@develop + with: + check_type: dataset + patterns: ':(icase)*datasets*.json' + app_id: ${{ secrets.BHOM_APP_ID }} + private_key: ${{ secrets.BHOM_APP_PRIVATE_KEY }} + + ci-documentation-compliance: + runs-on: windows-2025-vs2026 + timeout-minutes: 20 + permissions: + contents: read + pull-requests: read + actions: write + steps: + - name: Run documentation compliance + uses: BHoM/CI_Toolkit/.github/actions/ci-compliance@develop + with: + check_type: documentation + patterns: '*.cs' + app_id: ${{ secrets.BHOM_APP_ID }} + private_key: ${{ secrets.BHOM_APP_PRIVATE_KEY }} + + ci-project-compliance: + runs-on: windows-2025-vs2026 + timeout-minutes: 20 + permissions: + contents: read + pull-requests: read + actions: write + steps: + - name: Run project compliance + uses: BHoM/CI_Toolkit/.github/actions/ci-compliance@develop + with: + check_type: project + patterns: '*AssemblyInfo.cs *.csproj' + app_id: ${{ secrets.BHOM_APP_ID }} + private_key: ${{ secrets.BHOM_APP_PRIVATE_KEY }} + + ci-dataset-tests: + runs-on: windows-2025-vs2026 + timeout-minutes: 30 + steps: + - name: Run dataset tests + uses: BHoM/CI_Toolkit/.github/actions/ci-dataset-tests@develop + with: + app_id: ${{ secrets.BHOM_APP_ID }} + private_key: ${{ secrets.BHOM_APP_PRIVATE_KEY }} + + ci-serialisation: + runs-on: windows-2025-vs2026 + timeout-minutes: 90 + steps: + - name: Run serialisation + uses: BHoM/CI_Toolkit/.github/actions/ci-serialisation@develop + with: + app_id: ${{ secrets.BHOM_APP_ID }} + private_key: ${{ secrets.BHOM_APP_PRIVATE_KEY }} + base_ref: ${{ github.base_ref }} + + ci-versioning: + runs-on: windows-2025-vs2026 + timeout-minutes: 90 + steps: + - name: Run versioning + uses: BHoM/CI_Toolkit/.github/actions/ci-versioning@develop + with: + app_id: ${{ secrets.BHOM_APP_ID }} + private_key: ${{ secrets.BHOM_APP_PRIVATE_KEY }} 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_Adapter/OpenAI_Adapter.csproj b/OpenAI_Adapter/OpenAI_Adapter.csproj index 5261ccf..3e8e692 100644 --- a/OpenAI_Adapter/OpenAI_Adapter.csproj +++ b/OpenAI_Adapter/OpenAI_Adapter.csproj @@ -1,65 +1,65 @@ - - - - netstandard2.0 - 9.0.0.0 - https://github.com/BHoM/OpenAI_Toolkit - 8.0.0 - BHoM - Copyright © https://github.com/BHoM - BH.Adapter.OpenAI - 9.2.0.0 - true - - - - Off - ..\Build\ - - - - - - - - - - - - - - - - - - $(ProgramData)\BHoM\Assemblies\BHoM.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\Data_oM.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\Adapter_oM.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\Adapter_Engine.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\BHoM_Adapter.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\BHoM_Engine.dll - false - false - - - + + + + netstandard2.0 + 9.0.0.0 + https://github.com/BHoM/OpenAI_Toolkit + 8.0.0 + BHoM + Copyright © https://github.com/BHoM + BH.Adapter.OpenAI + 9.3.0.0 + true + + + + Off + ..\Build\ + + + + + + + + + + + + + + + + + + $(ProgramData)\BHoM\Assemblies\BHoM.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\Data_oM.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\Adapter_oM.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\Adapter_Engine.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\BHoM_Adapter.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\BHoM_Engine.dll + false + false + + + diff --git a/OpenAI_Engine/OpenAI_Engine.csproj b/OpenAI_Engine/OpenAI_Engine.csproj index 6a4a03c..a3c2a1b 100644 --- a/OpenAI_Engine/OpenAI_Engine.csproj +++ b/OpenAI_Engine/OpenAI_Engine.csproj @@ -1,74 +1,74 @@ - - - - netstandard2.0 - 9.0.0.0 - https://github.com/BHoM/OpenAI_Toolkit - 8.0.0 - BHoM - Copyright © https://github.com/BHoM - BH.Engine.Adapters.OpenAI - 9.2.0.0 - true - - - - Off - ..\Build\ - - - - - - - - - - - - - - - - - $(ProgramData)\BHoM\Assemblies\BHoM.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\Data_oM.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\Adapter_oM.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\Adapter_Engine.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\BHoM_Adapter.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\BHoM_Engine.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\File_Engine.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\Serialiser_Engine.dll - false - false - - - + + + + netstandard2.0 + 9.0.0.0 + https://github.com/BHoM/OpenAI_Toolkit + 8.0.0 + BHoM + Copyright © https://github.com/BHoM + BH.Engine.Adapters.OpenAI + 9.3.0.0 + true + + + + Off + ..\Build\ + + + + + + + + + + + + + + + + + $(ProgramData)\BHoM\Assemblies\BHoM.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\Data_oM.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\Adapter_oM.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\Adapter_Engine.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\BHoM_Adapter.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\BHoM_Engine.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\File_Engine.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\Serialiser_Engine.dll + false + false + + + 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/OpenAI_oM.csproj b/OpenAI_oM/OpenAI_oM.csproj index 8e12ee1..e895ccb 100644 --- a/OpenAI_oM/OpenAI_oM.csproj +++ b/OpenAI_oM/OpenAI_oM.csproj @@ -1,41 +1,41 @@ - - - - netstandard2.0 - 9.0.0.0 - https://github.com/BHoM/OpenAI_Toolkit - 8.0.0 - BHoM - Copyright © https://github.com/BHoM - BH.oM.Adapters.OpenAI - 9.2.0.0 - true - - - - Off - ..\Build\ - - - - - - - - - $(ProgramData)\BHoM\Assemblies\Adapter_oM.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\BHoM.dll - false - false - - - $(ProgramData)\BHoM\Assemblies\Data_oM.dll - false - false - - - + + + + netstandard2.0 + 9.0.0.0 + https://github.com/BHoM/OpenAI_Toolkit + 8.0.0 + BHoM + Copyright © https://github.com/BHoM + BH.oM.Adapters.OpenAI + 9.3.0.0 + true + + + + Off + ..\Build\ + + + + + + + + + $(ProgramData)\BHoM\Assemblies\Adapter_oM.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\BHoM.dll + false + false + + + $(ProgramData)\BHoM\Assemblies\Data_oM.dll + false + false + + + 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 + { + + } +}