AX Agent 실행 준비 로직을 엔진으로 추가 이관
Some checks failed
Release Gate / gate (push) Has been cancelled

- AxAgentExecutionEngine에 PreparedExecution, PrepareExecution, NormalizeAssistantContent를 추가해 실행 준비와 최종 응답 보정 책임을 더 모음

- ChatWindow의 일반 전송과 재생성이 PrepareExecutionForConversation을 통해 같은 준비 경로를 쓰도록 정리함

- Cowork/Code 시스템 프롬프트 선택, 실행 모드 판정, 프롬프트 스택 조합, outbound message 준비의 중복 분기를 줄임

- 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ 경고 0 / 오류 0
This commit is contained in:
2026-04-05 12:23:09 +09:00
parent 3ed454a98c
commit 67961f280f
4 changed files with 104 additions and 64 deletions

View File

@@ -12,6 +12,10 @@ public sealed class AxAgentExecutionEngine
{
public sealed record PreparedTurn(List<ChatMessage> Messages);
public sealed record ExecutionMode(bool UseAgentLoop, bool UseStreamingTransport, string? TaskSystemPrompt);
public sealed record PreparedExecution(
ExecutionMode Mode,
IReadOnlyList<string> PromptStack,
List<ChatMessage> Messages);
public IReadOnlyList<string> BuildPromptStack(
string? conversationSystem,
@@ -44,6 +48,32 @@ public sealed class AxAgentExecutionEngine
return new ExecutionMode(false, false, null);
}
public PreparedExecution PrepareExecution(
ChatConversation conversation,
string runTab,
bool streamingEnabled,
string resolvedService,
string? conversationSystem,
string? slashSystem,
string? coworkSystemPrompt,
string? codeSystemPrompt,
string? fileContext = null,
IReadOnlyList<ImageAttachment>? images = null)
{
var mode = ResolveExecutionMode(
runTab,
streamingEnabled,
resolvedService,
coworkSystemPrompt,
codeSystemPrompt);
var promptStack = BuildPromptStack(
conversationSystem,
slashSystem,
mode.TaskSystemPrompt);
var preparedTurn = PrepareTurn(conversation, promptStack, fileContext, images);
return new PreparedExecution(mode, promptStack, preparedTurn.Messages);
}
public PreparedTurn PrepareTurn(
ChatConversation conversation,
IEnumerable<string?> systemPrompts,
@@ -103,6 +133,33 @@ public sealed class AxAgentExecutionEngine
return assistant;
}
public string NormalizeAssistantContent(
ChatConversation conversation,
string runTab,
string? content)
{
if (!string.IsNullOrWhiteSpace(content))
return content;
var latestEventSummary = conversation.ExecutionEvents?
.Where(evt => !string.IsNullOrWhiteSpace(evt.Summary))
.OrderByDescending(evt => evt.Timestamp)
.Select(evt => evt.Summary.Trim())
.FirstOrDefault();
if (!string.IsNullOrWhiteSpace(latestEventSummary))
{
return runTab switch
{
"Cowork" => $"코워크 작업이 완료되었습니다.\n\n{latestEventSummary}",
"Code" => $"코드 작업이 완료되었습니다.\n\n{latestEventSummary}",
_ => latestEventSummary,
};
}
return "(빈 응답)";
}
private static ChatMessage CloneMessage(ChatMessage source)
{
return new ChatMessage