Skip to content

Commit 5215c12

Browse files
committed
Add ResponsePrompt and ResponseCreationOptions with serialization support
- Implement ResponsePrompt class with properties for Id, Version, and Variables. - Add serialization and deserialization methods for ResponsePrompt. - Introduce ResponseCreationOptions class to support stored prompts. - Create example tests for serialization and deserialization of ResponsePrompt. - Add basic functionality tests for ResponsePrompt integration.
1 parent 5f13e29 commit 5215c12

File tree

8 files changed

+401
-0
lines changed

8 files changed

+401
-0
lines changed

TestResponsePrompt.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text.Json;
4+
using OpenAI.Responses;
5+
6+
class TestResponsePrompt
7+
{
8+
static void Main(string[] args)
9+
{
10+
Console.WriteLine("Testing ResponsePrompt implementation...");
11+
12+
// Test 1: Basic serialization
13+
var prompt = new ResponsePrompt("test-prompt-id", "v1.0");
14+
var json = JsonSerializer.Serialize(prompt);
15+
Console.WriteLine($"Serialized ResponsePrompt: {json}");
16+
17+
// Test 2: With variables
18+
var variables = new Dictionary<string, object>
19+
{
20+
["name"] = "John",
21+
["age"] = 30,
22+
["isActive"] = true
23+
};
24+
25+
var promptWithVars = new ResponsePrompt("test-prompt-id", "v1.0", variables);
26+
var jsonWithVars = JsonSerializer.Serialize(promptWithVars);
27+
Console.WriteLine($"Serialized ResponsePrompt with variables: {jsonWithVars}");
28+
29+
// Test 3: Deserialization
30+
var deserializedPrompt = JsonSerializer.Deserialize<ResponsePrompt>(jsonWithVars);
31+
Console.WriteLine($"Deserialized - ID: {deserializedPrompt.Id}, Version: {deserializedPrompt.Version}");
32+
Console.WriteLine($"Variables count: {deserializedPrompt.Variables?.Count ?? 0}");
33+
34+
if (deserializedPrompt.Variables != null)
35+
{
36+
foreach (var kvp in deserializedPrompt.Variables)
37+
{
38+
Console.WriteLine($" {kvp.Key}: {kvp.Value} (Type: {kvp.Value?.GetType().Name ?? "null"})");
39+
}
40+
}
41+
42+
// Test 4: ResponseCreationOptions with prompt
43+
var options = new ResponseCreationOptions
44+
{
45+
Model = "gpt-4",
46+
Prompt = promptWithVars
47+
};
48+
49+
var optionsJson = JsonSerializer.Serialize(options);
50+
Console.WriteLine($"Serialized ResponseCreationOptions: {optionsJson}");
51+
52+
var deserializedOptions = JsonSerializer.Deserialize<ResponseCreationOptions>(optionsJson);
53+
Console.WriteLine($"Deserialized options - Model: {deserializedOptions.Model}");
54+
Console.WriteLine($"Prompt ID: {deserializedOptions.Prompt?.Id}");
55+
56+
Console.WriteLine("All tests completed successfully!");
57+
}
58+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using NUnit.Framework;
2+
using OpenAI.Responses;
3+
using System;
4+
using System.Collections.Generic;
5+
6+
namespace OpenAI.Examples;
7+
8+
public partial class ResponseExamples
9+
{
10+
[Test]
11+
public void Example03_StoredPrompts()
12+
{
13+
OpenAIResponseClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
14+
15+
// Create options using a stored prompt
16+
ResponseCreationOptions options = new()
17+
{
18+
Prompt = new ResponsePrompt
19+
{
20+
Id = "your-stored-prompt-id",
21+
Version = "v1.0"
22+
}
23+
};
24+
25+
// Add variables to substitute in the prompt template
26+
options.Prompt.Variables["location"] = "San Francisco";
27+
options.Prompt.Variables["unit"] = "celsius";
28+
29+
// Use stored prompt with variables
30+
IEnumerable<ResponseItem> inputItems = Array.Empty<ResponseItem>();
31+
OpenAIResponse response = client.CreateResponse(inputItems, options);
32+
33+
Console.WriteLine($"[ASSISTANT]: {response.GetOutputText()}");
34+
}
35+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using NUnit.Framework;
2+
using OpenAI.Responses;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Threading.Tasks;
6+
7+
namespace OpenAI.Examples;
8+
9+
public partial class ResponseExamples
10+
{
11+
[Test]
12+
public async Task Example03_StoredPromptsAsync()
13+
{
14+
OpenAIResponseClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
15+
16+
// Create options using a stored prompt
17+
ResponseCreationOptions options = new()
18+
{
19+
Prompt = new ResponsePrompt
20+
{
21+
Id = "your-stored-prompt-id",
22+
Version = "v1.0"
23+
}
24+
};
25+
26+
// Add variables to substitute in the prompt template
27+
options.Prompt.Variables["location"] = "San Francisco";
28+
options.Prompt.Variables["unit"] = "celsius";
29+
30+
// Use stored prompt with variables
31+
IEnumerable<ResponseItem> inputItems = Array.Empty<ResponseItem>();
32+
OpenAIResponse response = await client.CreateResponseAsync(inputItems, options);
33+
34+
Console.WriteLine($"[ASSISTANT]: {response.GetOutputText()}");
35+
}
36+
}

src/Custom/Responses/ResponseCreationOptions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ public partial class ResponseCreationOptions
3434
// CUSTOM: Made internal. This value comes from a parameter on the client method.
3535
internal bool? Stream { get; set; }
3636

37+
// CUSTOM: Added prompt parameter support for stored prompts.
38+
[CodeGenMember("Prompt")]
39+
public ResponsePrompt Prompt { get; set; }
40+
41+
// CUSTOM: Added public default constructor now that there are no required properties.
42+
public ResponseCreationOptions()
43+
{
44+
Input = new ChangeTrackingList<ResponseItem>();
45+
Metadata = new ChangeTrackingDictionary<string, string>();
46+
Tools = new ChangeTrackingList<ResponseTool>();
47+
Include = new ChangeTrackingList<InternalCreateResponsesRequestIncludable>();
48+
}
49+
3750
// CUSTOM: Renamed.
3851
[CodeGenMember("User")]
3952
public string EndUserId { get; set; }
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
using System;
2+
using System.ClientModel.Primitives;
3+
using System.Collections.Generic;
4+
using System.Text.Json;
5+
6+
namespace OpenAI.Responses;
7+
8+
public partial class ResponsePrompt : IJsonModel<ResponsePrompt>
9+
{
10+
void IJsonModel<ResponsePrompt>.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
11+
=> CustomSerializationHelpers.SerializeInstance(this, SerializeResponsePrompt, writer, options);
12+
13+
ResponsePrompt IJsonModel<ResponsePrompt>.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
14+
=> CustomSerializationHelpers.DeserializeNewInstance(this, DeserializeResponsePrompt, ref reader, options);
15+
16+
BinaryData IPersistableModel<ResponsePrompt>.Write(ModelReaderWriterOptions options)
17+
=> CustomSerializationHelpers.SerializeInstance(this, options);
18+
19+
ResponsePrompt IPersistableModel<ResponsePrompt>.Create(BinaryData data, ModelReaderWriterOptions options)
20+
=> CustomSerializationHelpers.DeserializeNewInstance(this, DeserializeResponsePrompt, data, options);
21+
22+
string IPersistableModel<ResponsePrompt>.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
23+
24+
internal static void SerializeResponsePrompt(ResponsePrompt instance, Utf8JsonWriter writer, ModelReaderWriterOptions options)
25+
{
26+
writer.WriteStartObject();
27+
28+
if (instance.Id != null)
29+
{
30+
writer.WritePropertyName("id");
31+
writer.WriteStringValue(instance.Id);
32+
}
33+
34+
if (instance.Version != null)
35+
{
36+
writer.WritePropertyName("version");
37+
writer.WriteStringValue(instance.Version);
38+
}
39+
40+
if (instance.Variables != null && instance.Variables.Count > 0)
41+
{
42+
writer.WritePropertyName("variables");
43+
writer.WriteStartObject();
44+
foreach (var variable in instance.Variables)
45+
{
46+
writer.WritePropertyName(variable.Key);
47+
if (variable.Value is JsonElement element)
48+
{
49+
#if NET6_0_OR_GREATER
50+
writer.WriteRawValue(element.GetRawText());
51+
#else
52+
using JsonDocument document = JsonDocument.Parse(element.GetRawText());
53+
JsonSerializer.Serialize(writer, document.RootElement);
54+
#endif
55+
}
56+
else if (variable.Value != null)
57+
{
58+
// Handle primitive types directly
59+
switch (variable.Value)
60+
{
61+
case string str:
62+
writer.WriteStringValue(str);
63+
break;
64+
case int intVal:
65+
writer.WriteNumberValue(intVal);
66+
break;
67+
case long longVal:
68+
writer.WriteNumberValue(longVal);
69+
break;
70+
case float floatVal:
71+
writer.WriteNumberValue(floatVal);
72+
break;
73+
case double doubleVal:
74+
writer.WriteNumberValue(doubleVal);
75+
break;
76+
case decimal decimalVal:
77+
writer.WriteNumberValue(decimalVal);
78+
break;
79+
case bool boolVal:
80+
writer.WriteBooleanValue(boolVal);
81+
break;
82+
default:
83+
// For other types, write as string value
84+
writer.WriteStringValue(variable.Value.ToString());
85+
break;
86+
}
87+
}
88+
else
89+
{
90+
writer.WriteNullValue();
91+
}
92+
}
93+
writer.WriteEndObject();
94+
}
95+
96+
writer.WriteEndObject();
97+
}
98+
99+
internal static ResponsePrompt DeserializeResponsePrompt(JsonElement element, ModelReaderWriterOptions options = null)
100+
{
101+
if (element.ValueKind == JsonValueKind.Null)
102+
{
103+
return null;
104+
}
105+
106+
string id = null;
107+
string version = null;
108+
Dictionary<string, object> variables = new Dictionary<string, object>();
109+
110+
foreach (var property in element.EnumerateObject())
111+
{
112+
if (property.NameEquals("id"))
113+
{
114+
id = property.Value.GetString();
115+
}
116+
else if (property.NameEquals("version"))
117+
{
118+
version = property.Value.GetString();
119+
}
120+
else if (property.NameEquals("variables"))
121+
{
122+
foreach (var variable in property.Value.EnumerateObject())
123+
{
124+
// Handle different JSON value types appropriately
125+
object value = variable.Value.ValueKind switch
126+
{
127+
JsonValueKind.String => variable.Value.GetString(),
128+
JsonValueKind.Number => variable.Value.TryGetInt32(out int intVal) ? intVal : variable.Value.GetDouble(),
129+
JsonValueKind.True => true,
130+
JsonValueKind.False => false,
131+
JsonValueKind.Null => null,
132+
_ => variable.Value.GetRawText() // For objects/arrays, store as raw JSON string
133+
};
134+
variables[variable.Name] = value;
135+
}
136+
}
137+
}
138+
139+
var result = new ResponsePrompt();
140+
result.Id = id;
141+
result.Version = version;
142+
143+
// Add variables to the existing dictionary (Variables property is get-only)
144+
if (variables.Count > 0)
145+
{
146+
foreach (var variable in variables)
147+
{
148+
result.Variables[variable.Key] = variable.Value;
149+
}
150+
}
151+
152+
return result;
153+
}
154+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Collections.Generic;
2+
3+
namespace OpenAI.Responses;
4+
5+
[CodeGenType("ResponsesPrompt")]
6+
public partial class ResponsePrompt
7+
{
8+
[CodeGenMember("Id")]
9+
public string Id { get; set; }
10+
11+
[CodeGenMember("Version")]
12+
public string Version { get; set; }
13+
14+
[CodeGenMember("Variables")]
15+
public IDictionary<string, object> Variables { get; }
16+
17+
public ResponsePrompt()
18+
{
19+
Variables = new Dictionary<string, object>();
20+
}
21+
}

temp-test/Program.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text.Json;
4+
using OpenAI.Responses;
5+
6+
Console.WriteLine("Testing ResponsePrompt implementation...");
7+
8+
// Test 1: Basic prompt without variables
9+
var basicPrompt = new ResponsePrompt()
10+
{
11+
Id = "test-prompt-id",
12+
Version = "v1.0"
13+
};
14+
15+
var basicJson = JsonSerializer.Serialize(basicPrompt);
16+
Console.WriteLine($"Basic prompt JSON: {basicJson}");
17+
18+
var basicDeserialized = JsonSerializer.Deserialize<ResponsePrompt>(basicJson);
19+
Console.WriteLine($"Basic deserialized - ID: {basicDeserialized?.Id}, Version: {basicDeserialized?.Version}");
20+
21+
// Test 2: ResponseCreationOptions integration
22+
var options = new ResponseCreationOptions
23+
{
24+
Prompt = basicPrompt
25+
};
26+
27+
var optionsJson = JsonSerializer.Serialize(options);
28+
Console.WriteLine($"Options JSON contains prompt: {optionsJson.Contains("test-prompt-id")}");
29+
30+
var deserializedOptions = JsonSerializer.Deserialize<ResponseCreationOptions>(optionsJson);
31+
Console.WriteLine($"Options deserialized prompt ID: {deserializedOptions?.Prompt?.Id}");
32+
33+
Console.WriteLine("Basic functionality test completed!");

0 commit comments

Comments
 (0)