-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConversationManager.cs
More file actions
113 lines (99 loc) · 3.64 KB
/
ConversationManager.cs
File metadata and controls
113 lines (99 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using System.Linq;
namespace YAOLlm;
public class ConversationManager
{
private readonly List<ChatMessage> _conversationHistory = new();
private readonly object _historyLock = new();
private const int MaxHistoryEntries = 32;
private string _currentWindowTitle = "";
private readonly Logger _logger;
public ConversationManager(Logger logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public void Initialize(string systemPrompt)
{
lock (_historyLock)
{
_conversationHistory.Clear();
_conversationHistory.Add(new ChatMessage(ChatRole.System, systemPrompt));
}
}
public List<ChatMessage> GetSnapshot()
{
lock (_historyLock)
{
return new List<ChatMessage>(_conversationHistory);
}
}
public void AddExchange(ChatMessage userMessage, string modelResponse)
{
lock (_historyLock)
{
_conversationHistory.Add(userMessage);
_conversationHistory.Add(new ChatMessage(ChatRole.Model, modelResponse));
TrimHistoryIfNeeded();
}
}
public string CurrentWindowTitle
{
get => _currentWindowTitle;
set
{
_currentWindowTitle = value;
if (!string.IsNullOrEmpty(value))
{
lock (_historyLock)
{
if (_conversationHistory.Count > 0)
{
_conversationHistory[0].Content = BuildSystemPrompt();
}
}
}
}
}
private void TrimHistoryIfNeeded()
{
bool shouldTrim;
int count;
lock (_historyLock)
{
count = _conversationHistory.Count;
shouldTrim = count > MaxHistoryEntries;
if (shouldTrim)
_conversationHistory.RemoveRange(1, count - MaxHistoryEntries);
}
if (shouldTrim)
_logger.Log($"Trimming history from {count} to {MaxHistoryEntries}");
}
public string BuildSystemPrompt()
{
var windowContext = string.IsNullOrEmpty(CurrentWindowTitle) ? "" :
$"- The user's currently active application title: \"{CurrentWindowTitle}\"\n Use this context to tailor responses to what the user is doing. The title is provided by the system — do not search for it.\n";
return $@"
You are an AI assistant with the following guidelines:
## Context
- Today's date: {DateTime.Now:yyyy-MM-dd}
{windowContext}
## Core Principles
- Provide accurate, helpful, and contextually relevant responses.
- Use available tools (such as Web Search) when appropriate to enhance response quality.
- Confirm online any information that might have changed since your training cutoff date.
- Maintain user engagement and immersion, especially in creative or gaming contexts.
## Response Guidelines
- For games and puzzles: Avoid direct spoilers. Instead, provide subtle hints and background information to guide users toward solutions while preserving enjoyment.
- Only provide exact solutions, codes, or walkthroughs when explicitly requested after initial guidance attempts.
- Support multimodal interactions: Process images and handle mixed text/image inputs.
## Capabilities
- Access to real-time information via Web Search as often as needed, do not hesitate getting more data sources.
- Context-aware responses based on current date and active application.";
}
public int GetTotalCharacterCount()
{
lock (_historyLock)
{
return _conversationHistory.Sum(turn => turn.Content?.Length ?? 0);
}
}
}