- claude-code 선택적 탐색 흐름을 참고해 Cowork/Code 시스템 프롬프트에서 folder_map 상시 선행 지시를 완화하고 glob/grep 기반 좁은 탐색을 우선하도록 조정함 - FolderMapTool 기본 depth를 2로, include_files 기본값을 false로 낮추고 MultiReadTool 최대 파일 수를 8개로 줄여 초기 과탐색 폭을 보수적으로 조정함 - AgentLoopExplorationPolicy partial을 추가해 탐색 범위 분류, broad-scan corrective hint, exploration_breadth 성능 로그를 연결함 - AgentLoopService에 탐색 범위 가이드 주입과 실행 중 탐색 폭 추적을 추가하고, 좁은 질문에서 반복적인 folder_map/대량 multi_read를 교정하도록 정리함 - DocxToHtmlConverter nullable 경고를 수정해 Release 빌드 경고 0 / 오류 0 기준을 다시 충족함 - README와 docs/DEVELOPMENT.md에 2026-04-09 10:36 (KST) 기준 개발 이력을 반영함
This commit is contained in:
@@ -1,7 +1,81 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AxCopilot.Views;
|
||||
|
||||
public partial class ChatWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// B-3: 스트리밍 전용 append-only 렌더 경로.
|
||||
/// prefix 비교를 완전히 우회하고, stable 키의 부분집합 관계만 확인하여
|
||||
/// 새 항목만 추가하는 빠른 경로. B-1/B-2로 인크리멘탈이 대부분 성공하지만,
|
||||
/// 스트리밍 중 키 순서가 변경되는 극단적 경우에도 전체 재빌드를 방지합니다.
|
||||
/// </summary>
|
||||
private bool TryApplyStreamingAppendRender(TranscriptRenderPlan renderPlan)
|
||||
{
|
||||
if (!_isStreaming || _lastRenderedTimelineKeys.Count == 0 || renderPlan.NewKeys.Count == 0)
|
||||
return false;
|
||||
|
||||
// hiddenCount가 다르면 visible 범위 자체가 달라진 것 — append 불가
|
||||
if (renderPlan.HiddenCount != _lastRenderedHiddenCount)
|
||||
return false;
|
||||
|
||||
// 기존 stable 키가 새 키 집합의 부분집합인지 확인 (순서 무관)
|
||||
var previousStable = new HashSet<string>(StringComparer.Ordinal);
|
||||
foreach (var key in _lastRenderedTimelineKeys)
|
||||
{
|
||||
if (!key.StartsWith("_live_", StringComparison.Ordinal))
|
||||
previousStable.Add(key);
|
||||
}
|
||||
|
||||
var newStableSet = new HashSet<string>(StringComparer.Ordinal);
|
||||
foreach (var key in renderPlan.NewKeys)
|
||||
{
|
||||
if (!key.StartsWith("_live_", StringComparison.Ordinal))
|
||||
newStableSet.Add(key);
|
||||
}
|
||||
|
||||
if (!previousStable.IsSubsetOf(newStableSet))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
// 라이브 컨테이너 임시 분리
|
||||
var hadLiveContainer = _agentLiveContainer != null && ContainsTranscriptElement(_agentLiveContainer);
|
||||
if (hadLiveContainer)
|
||||
RemoveTranscriptElement(_agentLiveContainer!);
|
||||
|
||||
// 기존 live 항목 제거 (끝에서부터)
|
||||
for (var i = _lastRenderedTimelineKeys.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!_lastRenderedTimelineKeys[i].StartsWith("_live_", StringComparison.Ordinal))
|
||||
break;
|
||||
if (GetTranscriptElementCount() > 0)
|
||||
RemoveTranscriptElementAt(GetTranscriptElementCount() - 1);
|
||||
}
|
||||
|
||||
// 새로 추가된 항목만 렌더 (기존에 없던 키)
|
||||
foreach (var item in renderPlan.VisibleTimeline)
|
||||
{
|
||||
if (!previousStable.Contains(item.Key))
|
||||
item.Render();
|
||||
}
|
||||
|
||||
// 라이브 컨테이너 재삽입
|
||||
if (hadLiveContainer && _agentLiveContainer != null)
|
||||
AddTranscriptElement(_agentLiveContainer);
|
||||
|
||||
_lastRenderedTimelineKeys = renderPlan.NewKeys;
|
||||
_lastRenderedHiddenCount = renderPlan.HiddenCount;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Services.LogService.Warn($"스트리밍 append 렌더 실패, 전체 렌더로 전환: {ex.Message}");
|
||||
_lastRenderedTimelineKeys.Clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryApplyIncrementalTranscriptRender(TranscriptRenderPlan renderPlan)
|
||||
{
|
||||
if (!renderPlan.CanIncremental)
|
||||
@@ -22,12 +96,21 @@ public partial class ChatWindow
|
||||
|
||||
try
|
||||
{
|
||||
// B-2: 라이브 컨테이너가 transcript 끝에 있으면 임시 분리
|
||||
var hadLiveContainer = _agentLiveContainer != null && ContainsTranscriptElement(_agentLiveContainer);
|
||||
if (hadLiveContainer)
|
||||
RemoveTranscriptElement(_agentLiveContainer!);
|
||||
|
||||
for (var removeIndex = 0; removeIndex < renderPlan.PreviousLiveCount && GetTranscriptElementCount() > 0; removeIndex++)
|
||||
RemoveTranscriptElementAt(GetTranscriptElementCount() - 1);
|
||||
|
||||
for (var i = renderPlan.PreviousStableCount; i < renderPlan.VisibleTimeline.Count; i++)
|
||||
renderPlan.VisibleTimeline[i].Render();
|
||||
|
||||
// B-2: 라이브 컨테이너 재삽입
|
||||
if (hadLiveContainer && _agentLiveContainer != null)
|
||||
AddTranscriptElement(_agentLiveContainer);
|
||||
|
||||
_lastRenderedTimelineKeys = renderPlan.NewKeys;
|
||||
_lastRenderedHiddenCount = renderPlan.HiddenCount;
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user