10
10
11
11
namespace DevProxy . Abstractions . LanguageModel ;
12
12
13
- public abstract class BaseLanguageModelClient ( ILogger logger ) : ILanguageModelClient
13
+ public abstract class BaseLanguageModelClient ( LanguageModelConfiguration configuration , ILogger logger ) : ILanguageModelClient
14
14
{
15
- private readonly ILogger _logger = logger ;
15
+ protected LanguageModelConfiguration Configuration { get ; } = configuration ;
16
+ protected ILogger Logger { get ; } = logger ;
17
+
18
+ private bool ? _lmAvailable ;
19
+
16
20
private readonly ConcurrentDictionary < string , ( IEnumerable < ILanguageModelChatCompletionMessage > ? , CompletionOptions ? ) > _promptCache = new ( ) ;
17
21
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 )
19
23
{
20
24
ArgumentNullException . ThrowIfNull ( promptFileName , nameof ( promptFileName ) ) ;
21
25
22
26
if ( ! promptFileName . EndsWith ( ".prompty" , StringComparison . OrdinalIgnoreCase ) )
23
27
{
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 ) ;
25
29
promptFileName += ".prompty" ;
26
30
}
27
31
@@ -34,35 +38,78 @@ public abstract class BaseLanguageModelClient(ILogger logger) : ILanguageModelCl
34
38
return null ;
35
39
}
36
40
37
- return await GenerateChatCompletionAsync ( messages , options ) ;
41
+ return await GenerateChatCompletionAsync ( messages , options , cancellationToken ) ;
42
+ }
43
+
44
+ public async Task < ILanguageModelCompletionResponse ? > GenerateChatCompletionAsync ( IEnumerable < ILanguageModelChatCompletionMessage > messages , CompletionOptions ? options , CancellationToken cancellationToken )
45
+ {
46
+ if ( Configuration is null )
47
+ {
48
+ return null ;
49
+ }
50
+
51
+ if ( ! await IsEnabledAsync ( cancellationToken ) )
52
+ {
53
+ Logger . LogDebug ( "Language model is not available." ) ;
54
+ return null ;
55
+ }
56
+
57
+ return await GenerateChatCompletionCoreAsync ( messages , options , cancellationToken ) ;
58
+ }
59
+
60
+ public async Task < ILanguageModelCompletionResponse ? > GenerateCompletionAsync ( string prompt , CompletionOptions ? options , CancellationToken cancellationToken )
61
+ {
62
+ if ( Configuration is null )
63
+ {
64
+ return null ;
65
+ }
66
+
67
+ if ( ! await IsEnabledAsync ( cancellationToken ) )
68
+ {
69
+ Logger . LogDebug ( "Language model is not available." ) ;
70
+ return null ;
71
+ }
72
+
73
+ return await GenerateCompletionCoreAsync ( prompt , options , cancellationToken ) ;
74
+ }
75
+
76
+ public async Task < bool > IsEnabledAsync ( CancellationToken cancellationToken )
77
+ {
78
+ if ( _lmAvailable . HasValue )
79
+ {
80
+ return _lmAvailable . Value ;
81
+ }
82
+
83
+ _lmAvailable = await IsEnabledCoreAsync ( cancellationToken ) ;
84
+ return _lmAvailable . Value ;
38
85
}
39
86
40
- public virtual Task < ILanguageModelCompletionResponse ? > GenerateChatCompletionAsync ( IEnumerable < ILanguageModelChatCompletionMessage > messages , CompletionOptions ? options = null ) => throw new NotImplementedException ( ) ;
87
+ protected abstract IEnumerable < ILanguageModelChatCompletionMessage > ConvertMessages ( ChatMessage [ ] messages ) ;
41
88
42
- public virtual Task < ILanguageModelCompletionResponse ? > GenerateCompletionAsync ( string prompt , CompletionOptions ? options = null ) => throw new NotImplementedException ( ) ;
89
+ protected abstract Task < ILanguageModelCompletionResponse ? > GenerateChatCompletionCoreAsync ( IEnumerable < ILanguageModelChatCompletionMessage > messages , CompletionOptions ? options , CancellationToken cancellationToken ) ;
43
90
44
- public virtual Task < bool > IsEnabledAsync ( ) => throw new NotImplementedException ( ) ;
91
+ protected abstract Task < ILanguageModelCompletionResponse ? > GenerateCompletionCoreAsync ( string prompt , CompletionOptions ? options , CancellationToken cancellationToken ) ;
45
92
46
- protected virtual IEnumerable < ILanguageModelChatCompletionMessage > ConvertMessages ( ChatMessage [ ] messages ) => throw new NotImplementedException ( ) ;
93
+ protected abstract Task < bool > IsEnabledCoreAsync ( CancellationToken cancellationToken ) ;
47
94
48
95
private ( IEnumerable < ILanguageModelChatCompletionMessage > ? , CompletionOptions ? ) LoadPrompt ( string promptFileName , Dictionary < string , object > parameters )
49
96
{
50
- _logger . LogDebug ( "Prompt file {PromptFileName} not in the cache. Loading..." , promptFileName ) ;
97
+ Logger . LogDebug ( "Prompt file {PromptFileName} not in the cache. Loading..." , promptFileName ) ;
51
98
52
99
var filePath = Path . Combine ( ProxyUtils . AppFolder ! , "prompts" , promptFileName ) ;
53
100
if ( ! File . Exists ( filePath ) )
54
101
{
55
102
throw new FileNotFoundException ( $ "Prompt file '{ filePath } ' not found.") ;
56
103
}
57
104
58
- _logger . LogDebug ( "Loading prompt file: {FilePath}" , filePath ) ;
105
+ Logger . LogDebug ( "Loading prompt file: {FilePath}" , filePath ) ;
59
106
var promptContents = File . ReadAllText ( filePath ) ;
60
107
61
108
var prompty = PromptyCore . Prompty . Load ( promptContents , [ ] ) ;
62
109
if ( prompty . Prepare ( parameters ) is not ChatMessage [ ] promptyMessages ||
63
110
promptyMessages . Length == 0 )
64
111
{
65
- _logger . LogError ( "No messages found in the prompt file: {FilePath}" , filePath ) ;
112
+ Logger . LogError ( "No messages found in the prompt file: {FilePath}" , filePath ) ;
66
113
return ( null , null ) ;
67
114
}
68
115
0 commit comments