1010
1111namespace DevProxy . Abstractions . LanguageModel ;
1212
13- public abstract class BaseLanguageModelClient ( ILogger logger ) : ILanguageModelClient
13+ public abstract class BaseLanguageModelClient ( LanguageModelConfiguration configuration , ILogger logger ) : ILanguageModelClient
1414{
15- private readonly ILogger _logger = logger ;
15+ protected LanguageModelConfiguration Configuration { get ; } = configuration ;
16+ protected ILogger Logger { get ; } = logger ;
17+
18+ private bool ? _lmAvailable ;
19+
1620 private readonly ConcurrentDictionary < string , ( IEnumerable < ILanguageModelChatCompletionMessage > ? , CompletionOptions ? ) > _promptCache = new ( ) ;
1721
18- public virtual async Task < ILanguageModelCompletionResponse ? > GenerateChatCompletionAsync ( string promptFileName , Dictionary < string , object > parameters )
22+ public virtual async Task < ILanguageModelCompletionResponse ? > GenerateChatCompletionAsync ( string promptFileName , Dictionary < string , object > parameters , CancellationToken cancellationToken )
1923 {
2024 ArgumentNullException . ThrowIfNull ( promptFileName , nameof ( promptFileName ) ) ;
2125
2226 if ( ! promptFileName . EndsWith ( ".prompty" , StringComparison . OrdinalIgnoreCase ) )
2327 {
24- _logger . LogDebug ( "Prompt file name '{PromptFileName}' does not end with '.prompty'. Appending the extension." , promptFileName ) ;
28+ Logger . LogDebug ( "Prompt file name '{PromptFileName}' does not end with '.prompty'. Appending the extension." , promptFileName ) ;
2529 promptFileName += ".prompty" ;
2630 }
2731 var ( messages , options ) = _promptCache . GetOrAdd ( promptFileName , _ =>
@@ -32,35 +36,78 @@ public abstract class BaseLanguageModelClient(ILogger logger) : ILanguageModelCl
3236 return null ;
3337 }
3438
35- return await GenerateChatCompletionAsync ( messages , options ) ;
39+ return await GenerateChatCompletionAsync ( messages , options , cancellationToken ) ;
40+ }
41+
42+ public async Task < ILanguageModelCompletionResponse ? > GenerateChatCompletionAsync ( IEnumerable < ILanguageModelChatCompletionMessage > messages , CompletionOptions ? options , CancellationToken cancellationToken )
43+ {
44+ if ( Configuration is null )
45+ {
46+ return null ;
47+ }
48+
49+ if ( ! await IsEnabledAsync ( cancellationToken ) )
50+ {
51+ Logger . LogDebug ( "Language model is not available." ) ;
52+ return null ;
53+ }
54+
55+ return await GenerateChatCompletionCoreAsync ( messages , options , cancellationToken ) ;
56+ }
57+
58+ public async Task < ILanguageModelCompletionResponse ? > GenerateCompletionAsync ( string prompt , CompletionOptions ? options , CancellationToken cancellationToken )
59+ {
60+ if ( Configuration is null )
61+ {
62+ return null ;
63+ }
64+
65+ if ( ! await IsEnabledAsync ( cancellationToken ) )
66+ {
67+ Logger . LogDebug ( "Language model is not available." ) ;
68+ return null ;
69+ }
70+
71+ return await GenerateCompletionCoreAsync ( prompt , options , cancellationToken ) ;
72+ }
73+
74+ public async Task < bool > IsEnabledAsync ( CancellationToken cancellationToken )
75+ {
76+ if ( _lmAvailable . HasValue )
77+ {
78+ return _lmAvailable . Value ;
79+ }
80+
81+ _lmAvailable = await IsEnabledCoreAsync ( cancellationToken ) ;
82+ return _lmAvailable . Value ;
3683 }
3784
38- public virtual Task < ILanguageModelCompletionResponse ? > GenerateChatCompletionAsync ( IEnumerable < ILanguageModelChatCompletionMessage > messages , CompletionOptions ? options = null ) => throw new NotImplementedException ( ) ;
85+ protected abstract IEnumerable < ILanguageModelChatCompletionMessage > ConvertMessages ( ChatMessage [ ] messages ) ;
3986
40- public virtual Task < ILanguageModelCompletionResponse ? > GenerateCompletionAsync ( string prompt , CompletionOptions ? options = null ) => throw new NotImplementedException ( ) ;
87+ protected abstract Task < ILanguageModelCompletionResponse ? > GenerateChatCompletionCoreAsync ( IEnumerable < ILanguageModelChatCompletionMessage > messages , CompletionOptions ? options , CancellationToken cancellationToken ) ;
4188
42- public virtual Task < bool > IsEnabledAsync ( ) => throw new NotImplementedException ( ) ;
89+ protected abstract Task < ILanguageModelCompletionResponse ? > GenerateCompletionCoreAsync ( string prompt , CompletionOptions ? options , CancellationToken cancellationToken ) ;
4390
44- protected virtual IEnumerable < ILanguageModelChatCompletionMessage > ConvertMessages ( ChatMessage [ ] messages ) => throw new NotImplementedException ( ) ;
91+ protected abstract Task < bool > IsEnabledCoreAsync ( CancellationToken cancellationToken ) ;
4592
4693 private ( IEnumerable < ILanguageModelChatCompletionMessage > ? , CompletionOptions ? ) LoadPrompt ( string promptFileName , Dictionary < string , object > parameters )
4794 {
48- _logger . LogDebug ( "Prompt file {PromptFileName} not in the cache. Loading..." , promptFileName ) ;
95+ Logger . LogDebug ( "Prompt file {PromptFileName} not in the cache. Loading..." , promptFileName ) ;
4996
5097 var filePath = Path . Combine ( ProxyUtils . AppFolder ! , "prompts" , promptFileName ) ;
5198 if ( ! File . Exists ( filePath ) )
5299 {
53100 throw new FileNotFoundException ( $ "Prompt file '{ filePath } ' not found.") ;
54101 }
55102
56- _logger . LogDebug ( "Loading prompt file: {FilePath}" , filePath ) ;
103+ Logger . LogDebug ( "Loading prompt file: {FilePath}" , filePath ) ;
57104 var promptContents = File . ReadAllText ( filePath ) ;
58105
59106 var prompty = PromptyCore . Prompty . Load ( promptContents , [ ] ) ;
60107 if ( prompty . Prepare ( parameters ) is not ChatMessage [ ] promptyMessages ||
61108 promptyMessages . Length == 0 )
62109 {
63- _logger . LogError ( "No messages found in the prompt file: {FilePath}" , filePath ) ;
110+ Logger . LogError ( "No messages found in the prompt file: {FilePath}" , filePath ) ;
64111 return ( null , null ) ;
65112 }
66113
0 commit comments