@@ -17,6 +17,14 @@ public class GameInputHandler
17
17
private readonly Dictionary < SystemPromptType , string > _systemPromptsWithVerdict = new ( ) ;
18
18
private readonly AutoResetEvent _autoResetEvent = new ( true ) ;
19
19
20
+ private readonly Dictionary < string , string > _redirectionStrategies = new ( )
21
+ {
22
+ { "Hard Deny" , "No" } ,
23
+ { "More Information" , "Acktually" } ,
24
+ { "NPC Influence" , "Sarmi says" } ,
25
+ { "Consequences" , "Kill" }
26
+ } ;
27
+
20
28
public GameInputHandler (
21
29
ILogger < GameInputHandler > logger ,
22
30
IReActLlmClient llmClient ,
@@ -43,6 +51,22 @@ public GameInputHandler(
43
51
_systemPrompts . Add ( SystemPromptType . GameOver , sysPromptSec . GetValue ( "GameOver" , "" ) ) ;
44
52
_systemPromptsWithVerdict . Add ( SystemPromptType . DoAction , sysPromptSec . GetValue ( "DoActionWithVerdict" , "" ) ) ;
45
53
_systemPromptsWithVerdict . Add ( SystemPromptType . SayAction , sysPromptSec . GetValue ( "SayActionWithVerdict" , "" ) ) ;
54
+ _systemPromptsWithVerdict . Add ( SystemPromptType . DoActionHardDeny ,
55
+ sysPromptSec . GetValue ( "DoActionHardDenyRedirect" , "" ) ) ;
56
+ _systemPromptsWithVerdict . Add ( SystemPromptType . DoActionMoreInfo ,
57
+ sysPromptSec . GetValue ( "DoActionMoreInformationRedirect" , "" ) ) ;
58
+ _systemPromptsWithVerdict . Add ( SystemPromptType . DoActionNpcInfluence ,
59
+ sysPromptSec . GetValue ( "DoActionNPCInfluenceRedirect" , "" ) ) ;
60
+ _systemPromptsWithVerdict . Add ( SystemPromptType . DoActionConsequences ,
61
+ sysPromptSec . GetValue ( "DoActionConsequencesRedirect" , "" ) ) ;
62
+ _systemPromptsWithVerdict . Add ( SystemPromptType . SayActionHardDeny ,
63
+ sysPromptSec . GetValue ( "SayActionHardDenyRedirect" , "" ) ) ;
64
+ _systemPromptsWithVerdict . Add ( SystemPromptType . SayActionMoreInfo ,
65
+ sysPromptSec . GetValue ( "SayActionMoreInformationRedirect" , "" ) ) ;
66
+ _systemPromptsWithVerdict . Add ( SystemPromptType . SayActionNpcInfluence ,
67
+ sysPromptSec . GetValue ( "SayActionNPCInfluenceRedirect" , "" ) ) ;
68
+ _systemPromptsWithVerdict . Add ( SystemPromptType . SayActionConsequences ,
69
+ sysPromptSec . GetValue ( "SayActionConsequencesRedirect" , "" ) ) ;
46
70
}
47
71
48
72
public event EventHandler < ChatCompletionReceivedEventArgs > ? ChatCompletionReceived ;
@@ -88,18 +112,55 @@ public async Task HandleUserPrompt(Campaign campaign, UserPromptType promptType,
88
112
}
89
113
}
90
114
91
- switch ( promptType )
115
+ if ( campaign . IsSnapshot && userInputAdherenceVerdict != null &&
116
+ userInputAdherenceVerdict . Contains ( "DISALLOWED" , StringComparison . Ordinal ) )
92
117
{
93
- case UserPromptType . Do :
94
- await GetResponseAndUpdateState ( campaign , relevantSystemPrompts [ SystemPromptType . DoAction ] ,
95
- userInput , userInputAdherenceVerdict , graphUpdateSummary ) ;
96
- break ;
97
- case UserPromptType . Say :
98
- await GetResponseAndUpdateState ( campaign , relevantSystemPrompts [ SystemPromptType . SayAction ] ,
99
- userInput , userInputAdherenceVerdict , graphUpdateSummary ) ;
100
- break ;
101
- default :
102
- throw new ArgumentOutOfRangeException ( ) ;
118
+ switch ( promptType )
119
+ {
120
+ case UserPromptType . Do :
121
+ await GetResponseAndUpdateState ( campaign , relevantSystemPrompts [ SystemPromptType . DoActionHardDeny ] ,
122
+ userInput , userInputAdherenceVerdict , graphUpdateSummary , "A.\n \n " ) ;
123
+ await GetResponseAndUpdateState ( campaign , relevantSystemPrompts [ SystemPromptType . DoActionMoreInfo ] ,
124
+ userInput , userInputAdherenceVerdict , graphUpdateSummary , "B.\n \n " ) ;
125
+ await GetResponseAndUpdateState ( campaign ,
126
+ relevantSystemPrompts [ SystemPromptType . DoActionNpcInfluence ] ,
127
+ userInput , userInputAdherenceVerdict , graphUpdateSummary , "C.\n \n " ) ;
128
+ await GetResponseAndUpdateState ( campaign ,
129
+ relevantSystemPrompts [ SystemPromptType . DoActionConsequences ] ,
130
+ userInput , userInputAdherenceVerdict , graphUpdateSummary , "D.\n \n " ) ;
131
+ ;
132
+ break ;
133
+ case UserPromptType . Say :
134
+ await GetResponseAndUpdateState ( campaign , relevantSystemPrompts [ SystemPromptType . SayActionHardDeny ] ,
135
+ userInput , userInputAdherenceVerdict , graphUpdateSummary , "A.\n \n " ) ;
136
+ await GetResponseAndUpdateState ( campaign , relevantSystemPrompts [ SystemPromptType . SayActionMoreInfo ] ,
137
+ userInput , userInputAdherenceVerdict , graphUpdateSummary , "B.\n \n " ) ;
138
+ await GetResponseAndUpdateState ( campaign ,
139
+ relevantSystemPrompts [ SystemPromptType . SayActionNpcInfluence ] ,
140
+ userInput , userInputAdherenceVerdict , graphUpdateSummary , "C.\n \n " ) ;
141
+ await GetResponseAndUpdateState ( campaign ,
142
+ relevantSystemPrompts [ SystemPromptType . SayActionConsequences ] ,
143
+ userInput , userInputAdherenceVerdict , graphUpdateSummary , "D.\n \n " ) ;
144
+ break ;
145
+ default :
146
+ throw new ArgumentOutOfRangeException ( ) ;
147
+ }
148
+ }
149
+ else
150
+ {
151
+ switch ( promptType )
152
+ {
153
+ case UserPromptType . Do :
154
+ await GetResponseAndUpdateState ( campaign , relevantSystemPrompts [ SystemPromptType . DoAction ] ,
155
+ userInput , userInputAdherenceVerdict , graphUpdateSummary ) ;
156
+ break ;
157
+ case UserPromptType . Say :
158
+ await GetResponseAndUpdateState ( campaign , relevantSystemPrompts [ SystemPromptType . SayAction ] ,
159
+ userInput , userInputAdherenceVerdict , graphUpdateSummary ) ;
160
+ break ;
161
+ default :
162
+ throw new ArgumentOutOfRangeException ( ) ;
163
+ }
103
164
}
104
165
105
166
_logger . LogInformation ( "Finished processing prompt" ) ;
@@ -122,7 +183,7 @@ await GetResponseAndUpdateState(campaign, _systemPrompts[SystemPromptType.Initia
122
183
}
123
184
124
185
private async Task GetResponseAndUpdateState ( Campaign campaign , string actionPrompt , string playerInput ,
125
- string ? verdict = null , string ? graphUpdateSummary = null )
186
+ string ? verdict = null , string ? graphUpdateSummary = null , string ? redirectionPrefix = null )
126
187
{
127
188
var input = playerInput ;
128
189
if ( ! campaign . IsOpenWorld )
@@ -145,7 +206,7 @@ private async Task GetResponseAndUpdateState(Campaign campaign, string actionPro
145
206
146
207
if ( _streamChatCompletions )
147
208
{
148
- OpenAiGptMessage message = new ( MessageRole . Assistant , "" ) ;
209
+ OpenAiGptMessage message = new ( MessageRole . Assistant , redirectionPrefix ?? "" ) ;
149
210
OnChatCompletionReceived ( message ) ;
150
211
151
212
await foreach ( var chunk in
@@ -164,14 +225,20 @@ private async Task GetResponseAndUpdateState(Campaign campaign, string actionPro
164
225
165
226
_ = Task . Run ( async ( ) =>
166
227
{
167
- await SaveInteraction ( campaign , playerInput , message . Content , verdict , gameOverMessage ) ;
228
+ if ( ! campaign . IsSnapshot || campaign . IsSnapshot &&
229
+ ( verdict != null && ! verdict . Contains ( "DISALLOWED" , StringComparison . Ordinal ) ) )
230
+ {
231
+ await SaveInteraction ( campaign , playerInput , message . Content , verdict , gameOverMessage ) ;
232
+ }
233
+
168
234
_autoResetEvent . Set ( ) ;
235
+ OnCampaignUpdated ( ) ;
169
236
} ) ;
170
237
}
171
238
else
172
239
{
173
240
var response = await _llmClient . GetChatCompletionAsync ( campaign , actionPrompt , input ) ;
174
- OpenAiGptMessage message = new ( MessageRole . Assistant , response ) ;
241
+ OpenAiGptMessage message = new ( MessageRole . Assistant , redirectionPrefix ?? "" + response ) ;
175
242
OnChatCompletionReceived ( message ) ;
176
243
177
244
string ? gameOverMessage = null ;
@@ -182,8 +249,14 @@ private async Task GetResponseAndUpdateState(Campaign campaign, string actionPro
182
249
183
250
_ = Task . Run ( async ( ) =>
184
251
{
185
- await SaveInteraction ( campaign , playerInput , message . Content , verdict , gameOverMessage ) ;
252
+ if ( ! campaign . IsSnapshot || campaign . IsSnapshot &&
253
+ ( verdict != null && ! verdict . Contains ( "DISALLOWED" , StringComparison . Ordinal ) ) )
254
+ {
255
+ await SaveInteraction ( campaign , playerInput , message . Content , verdict , gameOverMessage ) ;
256
+ }
257
+
186
258
_autoResetEvent . Set ( ) ;
259
+ OnCampaignUpdated ( ) ;
187
260
} ) ;
188
261
}
189
262
}
0 commit comments