Open
Description
Confirm this is a feature request for the .NET library and not the underlying OpenAI API
- This is a feature request for the .NET library
Describe the feature or improvement you are requesting
Sorry if this is just missing because I'm using the 2.2.0-beta.4 SDK version. I assume it's the implementation isn't fully complete
I want to be able to provide a file to the responses API as described in the API documentation here
import fs from "fs";
import OpenAI from "openai";
const client = new OpenAI();
const data = fs.readFileSync("draconomicon.pdf");
const base64String = data.toString("base64");
const response = await client.responses.create({
model: "gpt-4o",
input: [
{
role: "user",
content: [
{
type: "input_file",
filename: "draconomicon.pdf",
file_data: `data:application/pdf;base64,${base64String}`,
},
{
type: "input_text",
text: "What is the first dragon in the book?",
},
],
},
],
});
console.log(response.output_text);
There doesn't seem to be an example of this feature for the .NET library, and I also can't find a matching interface.
This is the minimal version of what I'm trying to do:
private static async Task<ClientResult<OpenAIResponse?>> PassFileToResponseApi(
OpenAIClient openAiClient,
Uri url
)
{
var responsesClient = openAiClient.GetOpenAIResponseClient("gpt-4o");
using var httpClient = new HttpClient();
var fileResponse = await httpClient.GetAsync(url);
var fileData = await BinaryData.FromStreamAsync(
await fileResponse.Content.ReadAsStreamAsync()
);
ResponseItem[] responseInputs =
[
ResponseItem.CreateUserMessageItem(
[ResponseContentPart.CreateInputFilePart("fileId", "fileName.pdf", fileData)]
),
];
ResponseCreationOptions options = new()
{
Temperature = 2.8f,
Instructions = "Tell me something about the file",
};
var clientResult = await responsesClient.CreateResponseAsync(responseInputs, options);
return clientResult;
}
but the call to CreateResponseAsync
fails:
System.Text.Json.JsonReaderException: '%' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker)
at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first)
at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
at System.Text.Json.Utf8JsonReader.Read()
at System.Text.Json.Utf8JsonWriter.WriteRawValueCore(ReadOnlySpan`1 utf8Json, Boolean skipInputValidation)
at System.Text.Json.Utf8JsonWriter.WriteRawValue(ReadOnlySpan`1 utf8Json, Boolean skipInputValidation)
at OpenAI.Responses.InternalResponsesInputFileContentPart.JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
at OpenAI.Responses.InternalResponsesInputFileContentPart.System.ClientModel.Primitives.IJsonModel<OpenAI.Responses.InternalResponsesInputFileContentPart>.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
at OpenAI.ModelSerializationExtensions.WriteObjectValue[T](Utf8JsonWriter writer, T value, ModelReaderWriterOptions options)
at OpenAI.Responses.InternalResponsesSystemMessage.JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
at OpenAI.Responses.InternalResponsesSystemMessage.System.ClientModel.Primitives.IJsonModel<OpenAI.Responses.InternalResponsesSystemMessage>.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
at OpenAI.ModelSerializationExtensions.WriteObjectValue[T](Utf8JsonWriter writer, T value, ModelReaderWriterOptions options)
at OpenAI.Responses.ResponseCreationOptions.JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
at OpenAI.Responses.ResponseCreationOptions.System.ClientModel.Primitives.IJsonModel<OpenAI.Responses.ResponseCreationOptions>.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
at System.ClientModel.Internal.ModelWriter`1.ExtractReader()
at System.ClientModel.BinaryContent.ModelBinaryContent`1.get_SequenceReader()
at System.ClientModel.BinaryContent.ModelBinaryContent`1.TryComputeLength(Int64& length)
at System.ClientModel.Primitives.HttpClientPipelineTransport.HttpPipelineRequest.MessageBodyAdapter.TryComputeLength(Int64& length)
at System.Net.Http.HttpContent.GetComputedOrBufferLength()
at System.Net.Http.Headers.HttpContentHeaders.get_ContentLength()
at System.Net.Http.SocketsHttpHandler.ValidateAndNormalizeRequest(HttpRequestMessage request)
at System.Net.Http.SocketsHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at System.ClientModel.Primitives.HttpClientPipelineTransport.ProcessSyncOrAsync(PipelineMessage message, Boolean async)
at System.ClientModel.Primitives.HttpClientPipelineTransport.ProcessCoreAsync(PipelineMessage message)
at System.ClientModel.Primitives.PipelineTransport.ProcessSyncOrAsync(PipelineMessage message, Boolean async)
at System.ClientModel.Primitives.PipelineTransport.ProcessAsync(PipelineMessage message)
at System.ClientModel.Primitives.PipelineTransport.ProcessAsync(PipelineMessage message, IReadOnlyList`1 pipeline, Int32 currentIndex)
at System.ClientModel.Primitives.PipelinePolicy.ProcessNextAsync(PipelineMessage message, IReadOnlyList`1 pipeline, Int32 currentIndex)
at System.ClientModel.Primitives.ApiKeyAuthenticationPolicy.ProcessAsync(PipelineMessage message, IReadOnlyList`1 pipeline, Int32 currentIndex)
at System.ClientModel.Primitives.PipelinePolicy.ProcessNextAsync(PipelineMessage message, IReadOnlyList`1 pipeline, Int32 currentIndex)
at System.ClientModel.Primitives.ClientRetryPolicy.ProcessSyncOrAsync(PipelineMessage message, IReadOnlyList`1 pipeline, Int32 currentIndex, Boolean async)
at System.ClientModel.Primitives.ClientRetryPolicy.ProcessSyncOrAsync(PipelineMessage message, IReadOnlyList`1 pipeline, Int32 currentIndex, Boolean async)
at System.ClientModel.Primitives.ClientRetryPolicy.ProcessAsync(PipelineMessage message, IReadOnlyList`1 pipeline, Int32 currentIndex)
at OpenAI.GenericActionPipelinePolicy.ProcessAsync(PipelineMessage message, IReadOnlyList`1 pipeline, Int32 currentIndex)
at System.ClientModel.Primitives.ClientPipeline.SendAsync(PipelineMessage message)
at OpenAI.ClientPipelineExtensions.ProcessMessageAsync(ClientPipeline pipeline, PipelineMessage message, RequestOptions options)
at OpenAI.Responses.OpenAIResponseClient.CreateResponseAsync(BinaryContent content, RequestOptions options)
at OpenAI.Responses.OpenAIResponseClient.CreateResponseAsync(IEnumerable`1 inputItems, ResponseCreationOptions options, CancellationToken cancellationToken)
so it seems it's trying to parse the fileBytes as JSON when generating the API request (the file is a PDF with the first byte being '%'). I'm unsure what JSON it is expecting. I've also tried encoding the data url myself and passing that in but that obviously doesn't work. Is it just a bug?
Additional context
No response