Skip to content

Commit 962aabb

Browse files
authored
Merge pull request #9 from ProjectVG/feature/memory
Feature/memory
2 parents 22acc5f + 71b3cec commit 962aabb

File tree

78 files changed

+3280
-4006
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+3280
-4006
lines changed

ProjectVG.Api/Controllers/ChatController.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Microsoft.AspNetCore.Mvc;
2-
using Microsoft.AspNetCore.Authorization;
32
using ProjectVG.Application.Models.Chat;
43
using ProjectVG.Application.Models.API.Request;
54
using ProjectVG.Application.Services.Chat;
@@ -28,12 +27,12 @@ public async Task<IActionResult> ProcessChat([FromBody] ChatRequest request)
2827
throw new ValidationException(ErrorCode.AUTHENTICATION_FAILED);
2928
}
3029

31-
var command = new ProcessChatCommand
32-
{
33-
UserId = userGuid,
34-
Message = request.Message,
35-
CharacterId = request.CharacterId
36-
};
30+
var command = new ChatRequestCommand(
31+
userGuid,
32+
request.CharacterId,
33+
request.Message,
34+
request.RequestAt,
35+
request.UseTTS);
3736

3837
var result = await _chatService.EnqueueChatRequestAsync(command);
3938

ProjectVG.Api/Middleware/GlobalExceptionHandler.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ private ErrorResponse CreateErrorResponse(Exception exception, HttpContext conte
101101

102102
private ErrorResponse HandleValidationException(ValidationException exception, HttpContext context)
103103
{
104-
_logger.LogWarning(exception, "유효성 검사 예외 발생: {ErrorCode} - {Message}", exception.ErrorCode.ToString(), exception.Message);
104+
_logger.LogWarning(exception, "유효성 검사 예외 발생: {ErrorCode} - {UserPrompt}", exception.ErrorCode.ToString(), exception.Message);
105105

106106
var details = exception.ValidationErrors?.Select(e => e.ErrorMessage ?? string.Empty).ToList();
107107

@@ -117,7 +117,7 @@ private ErrorResponse HandleValidationException(ValidationException exception, H
117117

118118
private ErrorResponse HandleNotFoundException(NotFoundException exception, HttpContext context)
119119
{
120-
_logger.LogWarning(exception, "리소스를 찾을 수 없음: {ErrorCode} - {Message}", exception.ErrorCode.ToString(), exception.Message);
120+
_logger.LogWarning(exception, "리소스를 찾을 수 없음: {ErrorCode} - {UserPrompt}", exception.ErrorCode.ToString(), exception.Message);
121121

122122
return new ErrorResponse {
123123
ErrorCode = exception.ErrorCode.ToString(),
@@ -130,7 +130,7 @@ private ErrorResponse HandleNotFoundException(NotFoundException exception, HttpC
130130

131131
private ErrorResponse HandleAuthenticationException(AuthenticationException exception, HttpContext context)
132132
{
133-
_logger.LogWarning(exception, "인증 실패: {ErrorCode} - {Message}", exception.ErrorCode.ToString(), exception.Message);
133+
_logger.LogWarning(exception, "인증 실패: {ErrorCode} - {UserPrompt}", exception.ErrorCode.ToString(), exception.Message);
134134

135135
return new ErrorResponse {
136136
ErrorCode = exception.ErrorCode.ToString(),
@@ -143,7 +143,7 @@ private ErrorResponse HandleAuthenticationException(AuthenticationException exce
143143

144144
private ErrorResponse HandleProjectVGException(ProjectVGException exception, HttpContext context)
145145
{
146-
_logger.LogWarning(exception, "ProjectVG 예외 발생: {ErrorCode} - {Message}", exception.ErrorCode.ToString(), exception.Message);
146+
_logger.LogWarning(exception, "ProjectVG 예외 발생: {ErrorCode} - {UserPrompt}", exception.ErrorCode.ToString(), exception.Message);
147147

148148
return new ErrorResponse {
149149
ErrorCode = exception.ErrorCode.ToString(),
@@ -156,7 +156,7 @@ private ErrorResponse HandleProjectVGException(ProjectVGException exception, Htt
156156

157157
private ErrorResponse HandleExternalServiceException(ExternalServiceException exception, HttpContext context)
158158
{
159-
_logger.LogError(exception, "외부 서비스 오류 발생: {ServiceName} - {Endpoint} - {Message}",
159+
_logger.LogError(exception, "외부 서비스 오류 발생: {ServiceName} - {Endpoint} - {UserPrompt}",
160160
exception.ServiceName, exception.Endpoint, exception.Message);
161161

162162
return new ErrorResponse {
@@ -206,7 +206,7 @@ private ErrorResponse HandleDbUpdateException(DbUpdateException exception, HttpC
206206

207207
private ErrorResponse HandleKeyNotFoundException(KeyNotFoundException exception, HttpContext context)
208208
{
209-
_logger.LogWarning(exception, "리소스를 찾을 수 없음: {Message}", exception.Message);
209+
_logger.LogWarning(exception, "리소스를 찾을 수 없음: {UserPrompt}", exception.Message);
210210

211211
return new ErrorResponse {
212212
ErrorCode = "RESOURCE_NOT_FOUND",
@@ -219,7 +219,7 @@ private ErrorResponse HandleKeyNotFoundException(KeyNotFoundException exception,
219219

220220
private ErrorResponse HandleArgumentException(ArgumentException exception, HttpContext context)
221221
{
222-
_logger.LogWarning(exception, "잘못된 인수: {Message}", exception.Message);
222+
_logger.LogWarning(exception, "잘못된 인수: {UserPrompt}", exception.Message);
223223

224224
return new ErrorResponse {
225225
ErrorCode = "INVALID_ARGUMENT",
@@ -233,7 +233,7 @@ private ErrorResponse HandleArgumentException(ArgumentException exception, HttpC
233233

234234
private ErrorResponse HandleInvalidOperationException(InvalidOperationException exception, HttpContext context)
235235
{
236-
_logger.LogWarning(exception, "잘못된 작업: {Message}", exception.Message);
236+
_logger.LogWarning(exception, "잘못된 작업: {UserPrompt}", exception.Message);
237237

238238
return new ErrorResponse {
239239
ErrorCode = "INVALID_OPERATION",
@@ -247,7 +247,7 @@ private ErrorResponse HandleInvalidOperationException(InvalidOperationException
247247

248248
private ErrorResponse HandleUnauthorizedAccessException(UnauthorizedAccessException exception, HttpContext context)
249249
{
250-
_logger.LogWarning(exception, "권한 없음: {Message}", exception.Message);
250+
_logger.LogWarning(exception, "권한 없음: {UserPrompt}", exception.Message);
251251

252252
return new ErrorResponse {
253253
ErrorCode = "UNAUTHORIZED",
@@ -260,7 +260,7 @@ private ErrorResponse HandleUnauthorizedAccessException(UnauthorizedAccessExcept
260260

261261
private ErrorResponse HandleTimeoutException(TimeoutException exception, HttpContext context)
262262
{
263-
_logger.LogWarning(exception, "타임아웃 발생: {Message}", exception.Message);
263+
_logger.LogWarning(exception, "타임아웃 발생: {UserPrompt}", exception.Message);
264264

265265
return new ErrorResponse {
266266
ErrorCode = "TIMEOUT",
@@ -273,7 +273,7 @@ private ErrorResponse HandleTimeoutException(TimeoutException exception, HttpCon
273273

274274
private ErrorResponse HandleHttpRequestException(HttpRequestException exception, HttpContext context)
275275
{
276-
_logger.LogError(exception, "HTTP 요청 오류: {Message}", exception.Message);
276+
_logger.LogError(exception, "HTTP 요청 오류: {UserPrompt}", exception.Message);
277277

278278
return new ErrorResponse {
279279
ErrorCode = "HTTP_REQUEST_ERROR",
@@ -289,7 +289,7 @@ private ErrorResponse HandleGenericException(Exception exception, HttpContext co
289289
var exceptionType = exception.GetType().Name;
290290
var isDevelopment = _environment.IsDevelopment();
291291

292-
_logger.LogError(exception, "예상치 못한 예외 발생: {ExceptionType} - {Message}", exceptionType, exception.Message);
292+
_logger.LogError(exception, "예상치 못한 예외 발생: {ExceptionType} - {UserPrompt}", exceptionType, exception.Message);
293293

294294
return new ErrorResponse {
295295
ErrorCode = "INTERNAL_SERVER_ERROR",

ProjectVG.Api/Models/Chat/Request/ChatRequest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ namespace ProjectVG.Application.Models.API.Request
55
{
66
public class ChatRequest
77
{
8-
[JsonPropertyName("session_id")]
9-
public string SessionId { get; set; } = string.Empty;
10-
118
[JsonPropertyName("message")]
129
public string Message { get; set; } = string.Empty;
1310

@@ -19,5 +16,8 @@ public class ChatRequest
1916

2017
[JsonPropertyName("use_tts")]
2118
public bool UseTTS { get; set; } = true;
19+
20+
[JsonPropertyName("request_at")]
21+
public DateTime RequestAt { get; set; }
2222
}
2323
}

ProjectVG.Application/ApplicationServiceCollectionExtensions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static IServiceCollection AddApplicationServices(this IServiceCollection
2020
{
2121
// Auth Services
2222
services.AddScoped<IAuthService, AuthService>();
23-
services.AddSingleton<IOAuth2Service, OAuth2Service>();
23+
services.AddScoped<IOAuth2Service, OAuth2Service>();
2424
services.AddScoped<IOAuth2ProviderFactory, OAuth2ProviderFactory>();
2525

2626
// User Services
@@ -48,8 +48,9 @@ public static IServiceCollection AddApplicationServices(this IServiceCollection
4848
services.AddScoped<ChatLLMProcessor>();
4949
services.AddScoped<ChatTTSProcessor>();
5050
services.AddScoped<ChatResultProcessor>();
51-
51+
5252
// Chat Services - Handlers
53+
services.AddScoped<ChatSuccessHandler>();
5354
services.AddScoped<ChatFailureHandler>();
5455

5556
// Chat Services - Cost Tracking Decorators

ProjectVG.Application/Models/Character/CharacterDto.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ public class CharacterDto
1111
public bool IsActive { get; set; } = true;
1212
public string Personality { get; set; } = string.Empty;
1313
public string SpeechStyle { get; set; } = string.Empty;
14+
public string Summary { get; set; } = string.Empty;
15+
public string UserAlias { get; set; } = string.Empty;
1416
public string VoiceId { get; set; } = string.Empty;
1517

16-
public CharacterDto()
17-
{
18-
}
1918

2019
public CharacterDto(Domain.Entities.Characters.Character character)
2120
{
@@ -26,6 +25,8 @@ public CharacterDto(Domain.Entities.Characters.Character character)
2625
IsActive = character.IsActive;
2726
Personality = character.Personality;
2827
SpeechStyle = character.SpeechStyle;
28+
UserAlias = character.UserAlias;
29+
Summary = character.Summary;
2930
VoiceId = character.VoiceId;
3031
}
3132
}

ProjectVG.Application/Models/Chat/ChatMessageSegment.cs

Lines changed: 0 additions & 35 deletions
This file was deleted.

ProjectVG.Application/Models/Chat/ChatProcessContext.cs

Lines changed: 78 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class ChatProcessContext
1010
public Guid CharacterId { get; private set; }
1111
public string UserMessage { get; private set; } = string.Empty;
1212
public string MemoryStore { get; private set; } = string.Empty;
13+
public DateTime UserRequestAt { get; private set; } = DateTime.Now;
1314
public bool UseTTS { get; private set; } = true;
1415

1516
public CharacterDto? Character { get; private set; }
@@ -18,33 +19,27 @@ public class ChatProcessContext
1819

1920
public string Response { get; private set; } = string.Empty;
2021
public double Cost { get; private set; }
21-
public List<ChatMessageSegment> Segments { get; private set; } = new List<ChatMessageSegment>();
22-
23-
public string FullText => string.Join(" ", Segments.Where(s => s.HasText).Select(s => s.Text));
24-
public bool HasAudio => Segments.Any(s => s.HasAudio);
25-
public bool HasText => Segments.Any(s => s.HasText);
26-
22+
public List<ChatSegment> Segments { get; private set; } = new List<ChatSegment>();
2723

28-
public ChatProcessContext(ProcessChatCommand command)
24+
public ChatProcessContext(ChatRequestCommand command)
2925
{
30-
SessionId = command.SessionId;
3126
UserId = command.UserId;
3227
CharacterId = command.CharacterId;
33-
UserMessage = command.Message;
28+
UserMessage = command.UserPrompt;
3429
MemoryStore = command.UserId.ToString();
3530
UseTTS = command.UseTTS;
31+
UserRequestAt = command.UserRequestAt;
3632
}
3733

3834
public ChatProcessContext(
39-
ProcessChatCommand command,
35+
ChatRequestCommand command,
4036
CharacterDto character,
4137
IEnumerable<ConversationHistory> conversationHistory,
4238
IEnumerable<string> memoryContext)
4339
{
44-
SessionId = command.SessionId;
4540
UserId = command.UserId;
4641
CharacterId = command.CharacterId;
47-
UserMessage = command.Message;
42+
UserMessage = command.UserPrompt;
4843
MemoryStore = command.UserId.ToString();
4944
UseTTS = command.UseTTS;
5045

@@ -53,7 +48,7 @@ public ChatProcessContext(
5348
MemoryContext = memoryContext;
5449
}
5550

56-
public void SetResponse(string response, List<ChatMessageSegment> segments, double cost)
51+
public void SetResponse(string response, List<ChatSegment> segments, double cost)
5752
{
5853
Response = response;
5954
Segments = segments;
@@ -69,9 +64,76 @@ public IEnumerable<string> ParseConversationHistory(int count = 5)
6964
{
7065
if (ConversationHistory == null) return Enumerable.Empty<string>();
7166

72-
return ConversationHistory
73-
.Take(count)
74-
.Select(h => $"{h.Role}: {h.Content}");
67+
return ConversationHistory.Take(count).Select(h => $"{h.Role}: {h.Content}");
68+
}
69+
70+
public string ToDebugString()
71+
{
72+
var sb = new System.Text.StringBuilder();
73+
74+
// Request 기본 정보
75+
sb.AppendLine($"[ChatProcessContext Debug Info]");
76+
sb.AppendLine($"=== REQUEST INFO ===");
77+
sb.AppendLine($"SessionId: {SessionId}");
78+
sb.AppendLine($"UserId: {UserId}");
79+
sb.AppendLine($"CharacterId: {CharacterId}");
80+
sb.AppendLine($"UserMessage: \"{UserMessage}\"");
81+
sb.AppendLine($"UseTTS: {UseTTS}");
82+
sb.AppendLine($"UserRequestAt: {UserRequestAt:yyyy-MM-dd HH:mm:ss}");
83+
sb.AppendLine($"Character: {Character?.Name ?? "null"}");
84+
85+
// LLM 전처리 정보
86+
sb.AppendLine($"=== LLM PREPROCESSING INFO ===");
87+
88+
// ConversationHistory 전체 내용
89+
sb.AppendLine($"ConversationHistory ({ConversationHistory?.Count() ?? 0} items):");
90+
if (ConversationHistory != null && ConversationHistory.Any())
91+
{
92+
foreach (var history in ConversationHistory)
93+
{
94+
sb.AppendLine($" - {history.Role}: \"{history.Content}\"");
95+
}
96+
}
97+
else
98+
{
99+
sb.AppendLine(" (No conversation history)");
100+
}
101+
102+
// MemoryContext 전체 내용
103+
sb.AppendLine($"MemoryContext ({MemoryContext?.Count() ?? 0} items):");
104+
if (MemoryContext != null && MemoryContext.Any())
105+
{
106+
foreach (var memory in MemoryContext)
107+
{
108+
sb.AppendLine($" - \"{memory}\"");
109+
}
110+
}
111+
else
112+
{
113+
sb.AppendLine(" (No memory context)");
114+
}
115+
116+
// 결과 정보
117+
sb.AppendLine($"=== RESULT INFO ===");
118+
sb.AppendLine($"Response: \"{Response}\"");
119+
sb.AppendLine($"Cost: {Cost:F4}");
120+
121+
// Segments 전체 내용
122+
sb.AppendLine($"Segments ({Segments?.Count ?? 0} items):");
123+
if (Segments != null && Segments.Any())
124+
{
125+
for (int i = 0; i < Segments.Count; i++)
126+
{
127+
var segment = Segments[i];
128+
sb.AppendLine($" [{i}] Type: {segment.Type}, Content: \"{segment.Content}\"");
129+
}
130+
}
131+
else
132+
{
133+
sb.AppendLine(" (No segments)");
134+
}
135+
136+
return sb.ToString();
75137
}
76138
}
77139
}

0 commit comments

Comments
 (0)