-
Notifications
You must be signed in to change notification settings - Fork 0
Feature: chat result hanlder #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
0a811da
197e9ce
95b63cc
6d9fc88
b08e756
a050c89
0948bc7
d07f011
d055636
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
namespace ProjectVG.Application.Models.Chat | ||
{ | ||
public class ChatMetrics | ||
{ | ||
public string SessionId { get; set; } = string.Empty; | ||
public string UserId { get; set; } = string.Empty; | ||
public string CharacterId { get; set; } = string.Empty; | ||
public DateTime StartTime { get; set; } | ||
public DateTime EndTime { get; set; } | ||
public List<ProcessMetrics> ProcessMetrics { get; set; } = new(); | ||
public decimal TotalCost { get; set; } | ||
public TimeSpan TotalDuration { get; set; } | ||
Comment on lines
+11
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 코스트 타입을 double로 통일하여 파이프라인과 정합성 확보 파이프라인 전반의 비용 산출이 - public decimal TotalCost { get; set; }
+ public double TotalCost { get; set; }
...
- public decimal Cost { get; set; }
+ public double Cost { get; set; } 참고: IChatMetricsService.EndProcessMetrics의 파라미터도 Also applies to: 21-21 🤖 Prompt for AI Agents
|
||
} | ||
|
||
public class ProcessMetrics | ||
{ | ||
public string ProcessName { get; set; } = string.Empty; | ||
public DateTime StartTime { get; set; } | ||
public DateTime EndTime { get; set; } | ||
public TimeSpan Duration { get; set; } | ||
public decimal Cost { get; set; } | ||
public string? ErrorMessage { get; set; } | ||
public Dictionary<string, object>? AdditionalData { get; set; } | ||
} | ||
} |
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
using ProjectVG.Application.Models.Character; | ||
using ProjectVG.Domain.Entities.ConversationHistorys; | ||
|
||
namespace ProjectVG.Application.Models.Chat | ||
{ | ||
public class ChatProcessContext | ||
{ | ||
public string SessionId { get; private set; } = string.Empty; | ||
public Guid UserId { get; private set; } | ||
public Guid CharacterId { get; private set; } | ||
public string UserMessage { get; private set; } = string.Empty; | ||
public string MemoryStore { get; private set; } = string.Empty; | ||
public bool UseTTS { get; private set; } = true; | ||
|
||
public CharacterDto? Character { get; private set; } | ||
public IEnumerable<string>? MemoryContext { get; private set; } | ||
public IEnumerable<ConversationHistory>? ConversationHistory { get; private set; } | ||
|
||
public string Response { get; private set; } = string.Empty; | ||
public double Cost { get; private set; } | ||
public List<ChatMessageSegment> Segments { get; private set; } = new List<ChatMessageSegment>(); | ||
|
||
public string FullText => string.Join(" ", Segments.Where(s => s.HasText).Select(s => s.Text)); | ||
public bool HasAudio => Segments.Any(s => s.HasAudio); | ||
public bool HasText => Segments.Any(s => s.HasText); | ||
|
||
|
||
public ChatProcessContext(ProcessChatCommand command) | ||
{ | ||
SessionId = command.SessionId; | ||
UserId = command.UserId; | ||
CharacterId = command.CharacterId; | ||
UserMessage = command.Message; | ||
MemoryStore = command.UserId.ToString(); | ||
UseTTS = command.UseTTS; | ||
} | ||
|
||
public ChatProcessContext( | ||
ProcessChatCommand command, | ||
CharacterDto character, | ||
IEnumerable<ConversationHistory> conversationHistory, | ||
IEnumerable<string> memoryContext) | ||
{ | ||
SessionId = command.SessionId; | ||
UserId = command.UserId; | ||
CharacterId = command.CharacterId; | ||
UserMessage = command.Message; | ||
MemoryStore = command.UserId.ToString(); | ||
UseTTS = command.UseTTS; | ||
|
||
Character = character; | ||
ConversationHistory = conversationHistory; | ||
MemoryContext = memoryContext; | ||
} | ||
|
||
public void SetResponse(string response, List<ChatMessageSegment> segments, double cost) | ||
{ | ||
Response = response; | ||
Segments = segments; | ||
Cost = cost; | ||
} | ||
|
||
public void AddCost(double additionalCost) | ||
{ | ||
Cost += additionalCost; | ||
} | ||
|
||
public IEnumerable<string> ParseConversationHistory(int count = 5) | ||
{ | ||
if (ConversationHistory == null) return Enumerable.Empty<string>(); | ||
|
||
return ConversationHistory | ||
.Take(count) | ||
.Select(h => $"{h.Role}: {h.Content}"); | ||
} | ||
} | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
ChatMetricsService 수명(Scope)으로 인한 백그라운드 작업 파손 위험 — Singleton 권장
현재
IChatMetricsService
가 Scoped입니다. 하지만ChatService
에서Task.Run
으로 백그라운드 파이프라인을 구동하고, 해당 메서드 내에서 필드로 보관된IChatMetricsService
인스턴스를 사용합니다. HTTP 요청이 빠르게 반환되면 원 스코프가 먼저 Dispose되어, 백그라운드에서 Scoped 서비스를 참조하는 순간 예기치 않은 동작/예외가 발생할 수 있습니다. 메트릭 서비스는AsyncLocal
기반 컨텍스트를 사용하므로 Singleton로 두는 편이 안전하고 일반적입니다.또한 관련 구현(참조 스니펫의 ChatMetricsService)에는 필드명이 혼재되어 컴파일 실패 가능성도 있습니다:
_currentMetrics
vs_current_metrics
. 이 부분도 함께 정리해야 합니다.권장 수정:
IChatMetricsService
를 Singleton으로 전환ChatService
의 백그라운드 처리 전반을 새IServiceScope
안에서 해결하고, 백그라운드에서 사용할 서비스는 스코프 내부에서 획득하도록 리팩터링ChatMetricsService
내 오탈자 필드명 정리아래는 등록 수명 변경 diff입니다.
다음 스크립트로 파손 가능 지점을 빠르게 점검해 주세요.
🏁 Script executed:
Length of output: 7823
ChatService에서
IChatMetricsService
주입 및Task.Run
내 사용 위치를 확인하기 위해 아래 스크립트를 실행해 주세요.🏁 Script executed:
Length of output: 594
다음과 같이
rg
명령의 파일 경로 지정을 수정하여 다시 실행해 주세요.🏁 Script executed:
Length of output: 3185
ChatMetricsService를 Singleton으로 전환하여 백그라운드 작업 안전성 확보
Scoped 수명의
IChatMetricsService
를Task.Run
으로 실행되는 백그라운드 작업에서 클로저로 사용하면, DI 컨테이너의 스코프가 종료된 이후에도 해당 인스턴스가 참조되어 의도치 않은 경고나 예외가 발생할 수 있습니다.또한,
ChatMetricsService
내부 필드명_currentMetrics
의 혼용(_current_metrics
)은 코드 상에서 발견되지 않았으므로 별도 수정이 필요 없습니다.– 수정 대상
ProjectVG.Application/ApplicationServiceCollectionExtensions.cs
(라인 39): 수명 변경ProjectVG.Application/Services/Chat/ChatService.cs
(라인 71 인근): 백그라운드 작업 시IServiceScopeFactory.CreateScope()
로 새 스코프를 열고, 그 안에서 필요한 서비스들을 Resolve하도록 리팩터링– 등록 수명 변경 예시
📝 Committable suggestion