Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/build-options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"os": [
"ubuntu-latest",
"windows-latest",
"macos-latest"
],
"unity-version": [
"2022.x",
"6000.0.x",
"6000.1.x",
"6000.2.x"
],
"include": [
{
"os": "ubuntu-latest",
"build-target": "StandaloneLinux64"
},
{
"os": "ubuntu-latest",
"build-target": "WebGL"
},
{
"os": "ubuntu-latest",
"build-target": "Android"
},
{
"os": "ubuntu-latest",
"build-target": "iOS"
},
{
"os": "windows-latest",
"build-target": "StandaloneWindows64"
},
{
"os": "windows-latest",
"build-target": "WSAPlayer"
},
{
"os": "macos-latest",
"build-target": "StandaloneOSX"
}
]
}
108 changes: 29 additions & 79 deletions .github/workflows/unity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,94 +3,44 @@ on:
schedule:
- cron: '0 0 * * 0' # Every Sunday at midnight
push:
branches:
- 'main'
branches: [main]
pull_request:
types: [opened, reopened, synchronize, ready_for_review]
branches:
- '**'
workflow_dispatch:
branches: ['**']
workflow_dispatch: # manual workflow trigger
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{(github.event_name == 'pull_request' || github.event.action == 'synchronize')}}
jobs:
build:
name: ${{ matrix.os }} ${{ matrix.unity-version }} ${{ matrix.build-target }}
runs-on: ${{ matrix.os }}
setup:
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include: # for each os specify the build targets
- os: ubuntu-latest
unity-version: 2022.x
build-target: Android
- os: ubuntu-latest
unity-version: 6000.x
build-target: Android
- os: ubuntu-latest
unity-version: 2022.x
build-target: StandaloneLinux64
- os: ubuntu-latest
unity-version: 6000.x
build-target: StandaloneLinux64
- os: ubuntu-latest
unity-version: 2022.x
build-target: WebGL
- os: ubuntu-latest
unity-version: 6000.x
build-target: WebGL
- os: windows-latest
unity-version: 2022.x
build-target: StandaloneWindows64
- os: windows-latest
unity-version: 6000.x
build-target: StandaloneWindows64
- os: windows-latest
unity-version: 2022.x
build-target: WSAPlayer
- os: windows-latest
unity-version: 6000.x
build-target: WSAPlayer
- os: macos-latest
unity-version: 2022.x
build-target: iOS
- os: macos-latest
unity-version: 6000.x
build-target: iOS
- os: macos-latest
unity-version: 2022.x
build-target: StandaloneOSX
- os: macos-latest
unity-version: 6000.x
build-target: StandaloneOSX
steps:
- uses: actions/checkout@v4
- uses: RageAgainstThePixel/unity-setup@v1
with:
unity-version: ${{ matrix.unity-version }}
build-targets: ${{ matrix.build-target }}
- uses: RageAgainstThePixel/activate-unity-license@v1
with:
license: 'Personal'
username: ${{ secrets.UNITY_USERNAME }}
password: ${{ secrets.UNITY_PASSWORD }}
- uses: RageAgainstThePixel/unity-action@v1
name: '${{ matrix.build-target }}-Validate'
with:
build-target: ${{ matrix.build-target }}
log-name: '${{ matrix.build-target }}-Validate'
args: '-quit -nographics -batchmode -executeMethod Utilities.Editor.BuildPipeline.UnityPlayerBuildTools.ValidateProject -importTMProEssentialsAsset'
- uses: RageAgainstThePixel/unity-action@v1
name: '${{ matrix.build-target }}-Build'
- uses: actions/checkout@v5
with:
build-target: ${{ matrix.build-target }}
log-name: '${{ matrix.build-target }}-Build'
args: '-quit -nographics -batchmode -executeMethod Utilities.Editor.BuildPipeline.UnityPlayerBuildTools.StartCommandLineBuild'
- uses: actions/upload-artifact@v4
if: success() || failure()
sparse-checkout: .github/
- uses: RageAgainstThePixel/job-builder@v1
id: setup-jobs
with:
name: '${{ github.run_number }}.${{ github.run_attempt }}-${{ matrix.os }}-${{ matrix.unity-version }}-${{ matrix.build-target }}-Artifacts'
path: '${{ github.workspace }}/**/*.log'
build-options: ./.github/workflows/build-options.json
group-by: 'unity-version'
job-name-prefix: 'Build'
outputs:
jobs: ${{ steps.setup-jobs.outputs.jobs }}
validate:
if: ${{ needs.setup.outputs.jobs }}
needs: setup
name: ${{ matrix.jobs.name }}
permissions:
contents: read
actions: write
strategy:
matrix: ${{ fromJSON(needs.setup.outputs.jobs) }}
fail-fast: false
max-parallel: 1
secrets: inherit
uses: RageAgainstThePixel/workflows/.github/workflows/build-unity-package.yml@main
with:
matrix: ${{ toJSON(matrix.jobs.matrix) }}
2 changes: 2 additions & 0 deletions .github/workflows/upm-subtree-split.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ on:
jobs:
upm-subtree-split:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
Expand Down
142 changes: 134 additions & 8 deletions OpenAI/Packages/com.openai.unity/Documentation~/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ openupm add com.openai.unity
- [List Input Items](#list-input-items)
- [Cancel Response](#cancel-response)
- [Delete Response](#delete-response)
- [Conversations](#conversations) :new:
- [Create Conversation](#create-conversation) :new:
- [Retrieve Conversation](#retrieve-conversation) :new:
- [Update Conversation](#update-conversation) :new:
- [Delete Conversation](#delete-conversation) :new:
- [List Conversation Items](#list-conversation-items) :new:
- [Create Conversation Item](#create-conversation-item) :new:
- [Retrieve Conversation Item](#retrieve-conversation-item) :new:
- [Delete Conversation Item](#delete-conversation-item) :new:
- [Realtime](#realtime)
- [Create Realtime Session](#create-realtime-session)
- [Client Events](#client-events)
Expand Down Expand Up @@ -452,7 +461,7 @@ Creates a model response. Provide text or image inputs to generate text or JSON
var api = new OpenAIClient();
var response = await api.ResponsesEndpoint.CreateModelResponseAsync("Tell me a three sentence bedtime story about a unicorn.");
var responseItem = response.Output.LastOrDefault();
Debug.Log($"{messageItem.Role}:{textContent.Text}");
Debug.Log($"{responseItem.Role}:{responseItem}");
response.PrintUsage();
```

Expand All @@ -469,7 +478,7 @@ var tools = new List<Tool>
{
Tool.GetOrCreateTool(typeof(DateTimeUtility), nameof(DateTimeUtility.GetDateTime))
};
var request = new CreateResponseRequest(conversation, Model.GPT4_1_Nano, tools: tools);
var request = new CreateResponseRequest(conversation, Model.GPT5_Nano, tools: tools);

async Task StreamCallback(string @event, IServerSentEvent sseEvent)
{
Expand All @@ -482,7 +491,7 @@ async Task StreamCallback(string @event, IServerSentEvent sseEvent)
conversation.Add(functionToolCall);
var output = await functionToolCall.InvokeFunctionAsync();
conversation.Add(output);
await api.ResponsesEndpoint.CreateModelResponseAsync(new(conversation, Model.GPT4_1_Nano, tools: tools, toolChoice: "none"), StreamCallback);
await api.ResponsesEndpoint.CreateModelResponseAsync(new(conversation, Model.GPT5_Nano, tools: tools, toolChoice: "none"), StreamCallback);
break;
}
}
Expand Down Expand Up @@ -541,6 +550,120 @@ Assert.IsTrue(isDeleted);

---

### [Conversations](https://platform.openai.com/docs/api-reference/conversations)

Create and manage conversations to store and retrieve conversation state across Response API calls.

The Conversations API is accessed via `OpenAIClient.ConversationsEndpoint`

#### [Create Conversation](https://platform.openai.com/docs/api-reference/conversations/create)

Create a conversation.

```csharp
var api = new OpenAIClient();
conversation = await api.ConversationsEndpoint.CreateConversationAsync(
new CreateConversationRequest(new Message(Role.Developer, systemPrompt)));
Debug.Log(conversation.ToString());
// use the conversation object when creating responses.
var request = await api.ResponsesEndpoint.CreateResponseAsync(
new CreateResponseRequest(textInput: "Hello!", conversationId: conversation, model: Model.GPT5_Nano));
var response = await openAI.ResponsesEndpoint.CreateModelResponseAsync(request);
var responseItem = response.Output.LastOrDefault();
Debug.Log($"{responseItem.Role}:{responseItem}");
response.PrintUsage();
```

#### [Retrieve Conversation](https://platform.openai.com/docs/api-reference/conversations/retrieve)

Get a conversation by id.

```csharp
var api = new OpenAIClient();
var conversation = await api.ConversationsEndpoint.GetConversationAsync("conversation-id");
Debug.Log(conversation.ToString());
```

#### [Update Conversation](https://platform.openai.com/docs/api-reference/conversations/update)

Update a conversation with custom metadata.

```csharp
var api = new OpenAIClient();
var metadata = new Dictionary<string, object>
{
{ "favorite_color", "blue" },
{ "favorite_food", "pizza" }
};
var updatedConversation = await api.ConversationsEndpoint.UpdateConversationAsync("conversation-id", metadata);
```

#### [Delete Conversation](https://platform.openai.com/docs/api-reference/conversations/delete)

Delete a conversation by id.

```csharp
var api = new OpenAIClient();
var isDeleted = await api.ConversationsEndpoint.DeleteConversationAsync("conversation-id");
Assert.IsTrue(isDeleted);
```

#### [List Conversation Items](https://platform.openai.com/docs/api-reference/conversations/list-items)

List all items for a conversation with the given ID.

```csharp
var api = new OpenAIClient();
var query = new ListQuery(limit: 10);
var items = await api.ConversationsEndpoint.ListConversationItemsAsync("conversation-id", query);

foreach (var item in items)
{
Debug.Log(item.ToJsonString());
}
```

#### [Create Conversation Item](https://platform.openai.com/docs/api-reference/conversations/create-item)

Create a new conversation item for a conversation with the given ID.

```csharp
var api = new OpenAIClient();
var items = new List<IResponseItem>
{
new Message(Role.User, "Hello!"),
new Message(Role.Assistant, "Hi! How can I help you?")
}
var addedItems = await api.ConversationsEndpoint.CreateConversationItemsAsync("conversation-id", items);

foreach (var item in addedItems)
{
Debug.Log(item.ToJsonString());
}
```

#### [Retrieve Conversation Item](https://platform.openai.com/docs/api-reference/conversations/retrieve-item)

Get a conversation item by id.

```csharp
var api = new OpenAIClient();
var item = await api.ConversationsEndpoint.GetConversationItemAsync("conversation-id", "item-id");
Debug.Log(item.ToJsonString());
```

#### [Delete Conversation Item](https://platform.openai.com/docs/api-reference/conversations/delete-item)

Delete a conversation item by id.

```csharp
var api = new OpenAIClient();
var isDeleted = await api.ConversationsEndpoint.DeleteConversationItemAsync("conversation-id", "item-id");
Assert.IsTrue(isDeleted);
```

---

### [Realtime](https://platform.openai.com/docs/api-reference/realtime)

> [!WARNING]
Expand Down Expand Up @@ -903,7 +1026,8 @@ Debug.Log($"Retrieve thread {thread.Id} -> {thread.CreatedAt}");

Modifies a thread.

> Note: Only the metadata can be modified.
> [!NOTE]
> Only the metadata can be modified.

```csharp
var api = new OpenAIClient();
Expand Down Expand Up @@ -981,7 +1105,8 @@ Debug.Log($"{message.Id}: {message.Role}: {message.PrintContent()}");

Modify a message.

> Note: Only the message metadata can be modified.
> [!NOTE]
> Only the message metadata can be modified.

```csharp
var api = new OpenAIClient();
Expand Down Expand Up @@ -1076,7 +1201,8 @@ Debug.Log($"[{run.Id}] {run.Status} | {run.CreatedAt}");

Modifies a run.

> Note: Only the metadata can be modified.
> [!NOTE]
> Only the metadata can be modified.

```csharp
var api = new OpenAIClient();
Expand Down Expand Up @@ -1795,7 +1921,7 @@ Generates audio from the input text.
```csharp
var api = new OpenAIClient();
var request = new SpeechRequest("Hello world!");
var speechClip = await api.AudioEndpoint.CreateSpeechAsync(request);
var speechClip = await api.AudioEndpoint.GetSpeechAsync(request);
audioSource.PlayOneShot(speechClip);
Debug.Log(speechClip);
```
Expand All @@ -1807,7 +1933,7 @@ Generate streamed audio from the input text.
```csharp
var api = new OpenAIClient();
var request = new SpeechRequest("Hello world!", responseFormat: SpeechResponseFormat.PCM);
var speechClip = await api.AudioEndpoint.CreateSpeechStreamAsync(request, partialClip =>
var speechClip = await api.AudioEndpoint.GetSpeechAsync(request, partialClip =>
{
audioSource.PlayOneShot(partialClip);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal AssistantResponse(
[JsonProperty("description")] string description,
[JsonProperty("model")] string model,
[JsonProperty("instructions")] string instructions,
[JsonProperty("tools")] IReadOnlyList<Tool> tools,
[JsonProperty("tools")] List<Tool> tools,
[JsonProperty("tool_resources")] ToolResources toolResources,
[JsonProperty("metadata")] Dictionary<string, string> metadata,
[JsonProperty("temperature")] float? temperature,
Expand Down
Loading
Loading