???? ???? ?? ????????? ????? ?? ????? PPT ?? ???? ??

??:
- ?? ?? ???? ?? ?? ??, ?? ? ?? ?? ??, ?????? ???? ??? ? ?? ?????.
- ?? ?? ??? ??? ?? PPT? ?? ??? ?? ???? ?? ????? ????.

?? ????:
- AgentCommandQueue? steering, permission continuation, resume, user decision ? ??? ???? AgentLoopService?? ?? ???? ????? ??
- CodeLanguageCatalog? LspClientService? ??? Go, Rust, PHP, Ruby, Kotlin, Swift? ?? LSP ?? ???? ??
- SettingsWindow? SettingsViewModel?? ?? ? ?? ??? ?? ?? / LSP / ?? ???? ????? ??
- WorkspaceContextGenerator? Language Snapshot, Agent Context, Key Manifests ??? ???? .claude/skills, .ax/rules, AXMEMORY.md ??? ??
- DeckRepairGuideService? ???? PptxSkill ??? Deck repair guide? ?? ??
- ?? ?? ???? ?? ???? ?? ? ??

??:
- dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_master_batch\\ -p:IntermediateOutputPath=obj\\verify_master_batch\\
- dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter AgentCommandQueueTests,CodeLanguageCatalogTests,WorkspaceContextGeneratorTests,PptxSkillConsultingDeckTests,DeckRepairGuideServiceTests -p:OutputPath=bin\\verify_master_batch_tests\\ -p:IntermediateOutputPath=obj\\verify_master_batch_tests\\
This commit is contained in:
2026-04-15 00:21:15 +09:00
parent 59ec4a1371
commit f33ee7f7db
16 changed files with 422 additions and 14 deletions

View File

@@ -49,20 +49,60 @@ public partial class AgentLoopService
requestInterrupt: IsRunning);
}
/// <summary>실행 중 사용자 지시 보강 메시지를 우선순위 높게 주입합니다.</summary>
public void InjectSteeringMessage(string message, bool requestInterrupt = true)
{
if (!string.IsNullOrWhiteSpace(message))
_pendingCommands.EnqueueSteering(
message,
IsRunning ? "now" : "next",
requestInterrupt: IsRunning && requestInterrupt);
}
/// <summary>권한 승인 후 이어서 진행할 내용을 큐에 넣습니다.</summary>
public void EnqueuePermissionContinuation(string toolName, string? target, string decisionSummary)
{
if (string.IsNullOrWhiteSpace(decisionSummary))
return;
var targetLabel = string.IsNullOrWhiteSpace(target) ? "" : $" ({target})";
_pendingCommands.EnqueuePermissionContinuation(
$"[permission continuation] Continue {toolName}{targetLabel}: {decisionSummary}");
}
/// <summary>도구 실행 중 참고용 시스템 알림을 큐에 넣습니다.</summary>
public void EnqueueNotification(string message, string priority = "later")
{
if (!string.IsNullOrWhiteSpace(message))
_pendingCommands.EnqueueNotification(message, priority);
}
/// <summary>사용자 의사결정 결과를 다음 턴 입력으로 주입합니다.</summary>
public void EnqueueUserDecision(string message, bool requestInterrupt = false)
{
if (!string.IsNullOrWhiteSpace(message))
_pendingCommands.EnqueueUserDecision(
message,
IsRunning ? "next" : "now",
requestInterrupt && IsRunning);
}
private void DrainPendingCommands(List<ChatMessage> messages)
{
var drained = _pendingCommands.DrainAll();
if (drained.Count == 0)
return;
var interruptingPrompts = drained.Count(x => x.Kind == AgentCommandKind.Prompt && x.RequestInterrupt);
if (interruptingPrompts > 0)
var interruptingCommands = drained.Count(x =>
x.RequestInterrupt &&
x.Kind is AgentCommandKind.Prompt or AgentCommandKind.Steering or AgentCommandKind.UserDecision or AgentCommandKind.PermissionContinuation);
if (interruptingCommands > 0)
{
messages.Add(new ChatMessage
{
Role = "system",
MetaKind = "queued_input_interrupt",
Content = $"[queued input] {interruptingPrompts} new prompt(s) arrived during execution. Prioritize the newest user direction before continuing.",
Content = $"[queued input] {interruptingCommands} new instruction(s) arrived during execution. Prioritize the newest user direction before continuing.",
Timestamp = DateTime.Now,
});
}
@@ -82,6 +122,40 @@ public partial class AgentLoopService
EmitEvent(AgentEventType.Thinking, "", item.Content);
break;
case AgentCommandKind.PermissionContinuation:
messages.Add(new ChatMessage
{
Role = "system",
MetaKind = "queue_permission_continuation",
Content = item.Content,
Timestamp = item.CreatedAt,
});
EmitEvent(AgentEventType.Thinking, "", item.Content);
break;
case AgentCommandKind.Resume:
messages.Add(new ChatMessage
{
Role = "system",
MetaKind = "queue_resume",
Content = item.Content,
Timestamp = item.CreatedAt,
});
EmitEvent(AgentEventType.Thinking, "", item.Content);
break;
case AgentCommandKind.Steering:
case AgentCommandKind.UserDecision:
messages.Add(new ChatMessage
{
Role = "user",
MetaKind = item.Kind == AgentCommandKind.Steering ? "queued_steering" : "queued_user_decision",
Content = item.Content,
Timestamp = item.CreatedAt,
});
EmitEvent(AgentEventType.UserMessage, "", item.Content);
break;
default:
messages.Add(new ChatMessage
{
@@ -209,6 +283,8 @@ public partial class AgentLoopService
{
// 이미 릴리즈된 상태 — 무시
}
if (IsRunning)
_pendingCommands.EnqueueResume("Execution resumed after pause. Re-evaluate the latest queued context before proceeding.");
EmitEvent(AgentEventType.Resumed, "", "에이전트가 재개되었습니다");
}