11using System . ClientModel ;
22using System . ClientModel . Primitives ;
33using System . Collections . Concurrent ;
4- using System . Text . Json ;
54using Microsoft . Extensions . AI ;
65using OpenAI ;
7- using OpenAI . Responses ;
86
97namespace Devlooped . Extensions . AI . OpenAI ;
108
119/// <summary>
12- /// An <see cref="IChatClient"/> implementation for OpenAI.
10+ /// An <see cref="IChatClient"/> implementation for OpenAI that supports per-request model selection .
1311/// </summary>
1412public class OpenAIChatClient : IChatClient
1513{
@@ -39,38 +37,15 @@ public OpenAIChatClient(string apiKey, string modelId, OpenAIClientOptions? opti
3937
4038 /// <inheritdoc/>
4139 public Task < ChatResponse > GetResponseAsync ( IEnumerable < ChatMessage > messages , ChatOptions ? options = null , CancellationToken cancellation = default )
42- => GetChatClient ( options ? . ModelId ?? modelId ) . GetResponseAsync ( messages , SetOptions ( options ) , cancellation ) ;
40+ => GetChatClient ( options ? . ModelId ?? modelId ) . GetResponseAsync ( messages , options . SetResponseOptions ( ) , cancellation ) ;
4341
4442 /// <inheritdoc/>
4543 public IAsyncEnumerable < ChatResponseUpdate > GetStreamingResponseAsync ( IEnumerable < ChatMessage > messages , ChatOptions ? options = null , CancellationToken cancellation = default )
46- => GetChatClient ( options ? . ModelId ?? modelId ) . GetStreamingResponseAsync ( messages , SetOptions ( options ) , cancellation ) ;
44+ => GetChatClient ( options ? . ModelId ?? modelId ) . GetStreamingResponseAsync ( messages , options . SetResponseOptions ( ) , cancellation ) ;
4745
4846 IChatClient GetChatClient ( string modelId ) => clients . GetOrAdd ( modelId , model
4947 => new PipelineClient ( pipeline , options ) . GetOpenAIResponseClient ( modelId ) . AsIChatClient ( ) ) ;
5048
51- static ChatOptions ? SetOptions ( ChatOptions ? options )
52- {
53- if ( options is null )
54- return null ;
55-
56- if ( options . ReasoningEffort . HasValue || options . Verbosity . HasValue )
57- {
58- options . RawRepresentationFactory = _ =>
59- {
60- var creation = new ResponseCreationOptions ( ) ;
61- if ( options . ReasoningEffort . HasValue )
62- creation . ReasoningOptions = new ReasoningEffortOptions ( options . ReasoningEffort ! . Value ) ;
63-
64- if ( options . Verbosity . HasValue )
65- creation . TextOptions = new VerbosityOptions ( options . Verbosity ! . Value ) ;
66-
67- return creation ;
68- } ;
69- }
70-
71- return options ;
72- }
73-
7449 void IDisposable . Dispose ( ) => GC . SuppressFinalize ( this ) ;
7550
7651 /// <inheritdoc />
@@ -82,24 +57,4 @@ IChatClient GetChatClient(string modelId) => clients.GetOrAdd(modelId, model
8257
8358 // Allows creating the base OpenAIClient with a pre-created pipeline.
8459 class PipelineClient ( ClientPipeline pipeline , OpenAIClientOptions ? options ) : OpenAIClient ( pipeline , options ) { }
85-
86- class ReasoningEffortOptions ( ReasoningEffort effort ) : ResponseReasoningOptions
87- {
88- protected override void JsonModelWriteCore ( Utf8JsonWriter writer , ModelReaderWriterOptions options )
89- {
90- writer . WritePropertyName ( "effort"u8 ) ;
91- writer . WriteStringValue ( effort . ToString ( ) . ToLowerInvariant ( ) ) ;
92- base . JsonModelWriteCore ( writer , options ) ;
93- }
94- }
95-
96- class VerbosityOptions ( Verbosity verbosity ) : ResponseTextOptions
97- {
98- protected override void JsonModelWriteCore ( Utf8JsonWriter writer , ModelReaderWriterOptions options )
99- {
100- writer . WritePropertyName ( "verbosity"u8 ) ;
101- writer . WriteStringValue ( verbosity . ToString ( ) . ToLowerInvariant ( ) ) ;
102- base . JsonModelWriteCore ( writer , options ) ;
103- }
104- }
10560}
0 commit comments