하단 안내 카드 가림 문제와 라이브 타이핑 표시를 보정한다
- Cowork·Chat 하단 프리셋 안내 카드가 실제 결과를 가리지 않도록 대화 메시지 존재 시 자동으로 숨기도록 조정 - FooterPresentation에 남아 있던 깨진 한글 워터마크와 상태 문구를 정상 한국어로 복구 - 라이브 타이핑 속도와 최종 프리뷰 deadline을 재조정해 SSE 및 Cowork·Code 최종 응답이 한 번에 붙지 않고 더 눈에 보이게 표시되도록 보정
This commit is contained in:
@@ -1469,3 +1469,7 @@ MIT License
|
|||||||
- 업데이트: 2026-04-07 09:32 (KST)
|
- 업데이트: 2026-04-07 09:32 (KST)
|
||||||
- Cowork/Code 장시간 실행 뒤 마지막 응답을 라이브 프리뷰로 붙이는 단계에서 `_streamCts` 필드를 다시 읽다가 `Object reference not set to an instance of an object.`로 실패할 수 있던 경로를 수정했습니다. 이제 실행 시작 시 캡처한 지역 토큰을 끝까지 재사용하고, 최종 타이핑 프리뷰 컨테이너가 준비되지 않으면 조용히 건너뛰도록 방어 로직을 추가했습니다.
|
- Cowork/Code 장시간 실행 뒤 마지막 응답을 라이브 프리뷰로 붙이는 단계에서 `_streamCts` 필드를 다시 읽다가 `Object reference not set to an instance of an object.`로 실패할 수 있던 경로를 수정했습니다. 이제 실행 시작 시 캡처한 지역 토큰을 끝까지 재사용하고, 최종 타이핑 프리뷰 컨테이너가 준비되지 않으면 조용히 건너뛰도록 방어 로직을 추가했습니다.
|
||||||
- 같은 실패가 다시 생기면 원인을 더 빨리 찾을 수 있도록 AX Agent 실행 예외 전체를 앱 로그에 남기도록 보강했습니다.
|
- 같은 실패가 다시 생기면 원인을 더 빨리 찾을 수 있도록 AX Agent 실행 예외 전체를 앱 로그에 남기도록 보강했습니다.
|
||||||
|
- 업데이트: 2026-04-07 09:44 (KST)
|
||||||
|
- Cowork/Chat 하단의 프리셋 안내 카드가 실제 결과를 가리던 문제를 수정했습니다. 이제 대화에 사용자/assistant 메시지가 생기거나 실행 중일 때는 해당 카드가 자동으로 숨겨집니다.
|
||||||
|
- [ChatWindow.FooterPresentation.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.FooterPresentation.cs)에 남아 있던 깨진 한글 워터마크/안내 문구를 정상 한국어로 정리했습니다.
|
||||||
|
- 라이브 타이핑 속도를 조정해 SSE 및 Cowork/Code 최종 프리뷰가 한 번에 붙는 느낌을 줄이고, 더 눈에 보이게 점진적으로 출력되도록 보정했습니다.
|
||||||
|
|||||||
@@ -5328,6 +5328,12 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
|||||||
- Cowork/Code 장시간 실행 뒤 최종 응답을 `ShowTypedAssistantPreviewAsync(...)`로 붙이는 단계에서 `_streamCts` 필드를 다시 읽다가 null 참조로 실패할 수 있던 경로를 수정했다. 실행 시작 시 만든 `CancellationTokenSource`의 토큰을 지역 변수로 고정해 마지막 프리뷰 단계까지 재사용하도록 변경했다.
|
- Cowork/Code 장시간 실행 뒤 최종 응답을 `ShowTypedAssistantPreviewAsync(...)`로 붙이는 단계에서 `_streamCts` 필드를 다시 읽다가 null 참조로 실패할 수 있던 경로를 수정했다. 실행 시작 시 만든 `CancellationTokenSource`의 토큰을 지역 변수로 고정해 마지막 프리뷰 단계까지 재사용하도록 변경했다.
|
||||||
- 최종 타이핑 프리뷰 컨테이너가 정상적으로 준비되지 않은 경우 조용히 건너뛰도록 방어 로직을 추가했고, 타이핑 대기 중 취소가 들어오면 `OperationCanceledException`을 내부에서 흡수해 최종 실패로 뒤집히지 않도록 정리했다.
|
- 최종 타이핑 프리뷰 컨테이너가 정상적으로 준비되지 않은 경우 조용히 건너뛰도록 방어 로직을 추가했고, 타이핑 대기 중 취소가 들어오면 `OperationCanceledException`을 내부에서 흡수해 최종 실패로 뒤집히지 않도록 정리했다.
|
||||||
- 에이전트 실행 중 예외 전체를 `Services.LogService.Debug(...)`에 남겨, 이후 장시간 실행 실패 원인을 앱 로그에서 바로 추적할 수 있게 했다.
|
- 에이전트 실행 중 예외 전체를 `Services.LogService.Debug(...)`에 남겨, 이후 장시간 실행 실패 원인을 앱 로그에서 바로 추적할 수 있게 했다.
|
||||||
|
- [ChatWindow.FooterPresentation.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.FooterPresentation.cs)
|
||||||
|
- Cowork/Chat 하단 프리셋 안내 카드의 문자열을 정상 한국어로 복구했다.
|
||||||
|
- 실제 사용자/assistant 메시지가 이미 있거나 스트리밍 중일 때는 프리셋 안내 카드를 자동으로 숨겨, 결과 본문을 가리지 않도록 조정했다.
|
||||||
|
- Cowork/Code 입력 워터마크와 폴더/메모리 상태 문구도 정상 한국어로 다시 정리했다.
|
||||||
|
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)
|
||||||
|
- `TypingTimer_Tick(...)`의 글자 증가량과 최종 프리뷰 deadline을 재조정해, 스트리밍/최종 프리뷰가 한 번에 붙는 느낌 없이 더 눈에 보이는 타이핑 흐름으로 출력되도록 보정했다.
|
||||||
- Document update: 2026-04-07 09:19 (KST) - Restored the AX Agent footer/status total token aggregate so it no longer disappears after runs return to idle. The status strip now rehydrates totals from the current conversation message token sums when live loop counters are empty.
|
- Document update: 2026-04-07 09:19 (KST) - Restored the AX Agent footer/status total token aggregate so it no longer disappears after runs return to idle. The status strip now rehydrates totals from the current conversation message token sums when live loop counters are empty.
|
||||||
- Document update: 2026-04-07 09:19 (KST) - Corrected context-compaction popup accuracy by switching its detail copy to the last real compaction metrics (`before -> after`, automatic/manual kind, cumulative compaction count, cumulative saved tokens) instead of only the generic trigger-threshold text.
|
- Document update: 2026-04-07 09:19 (KST) - Corrected context-compaction popup accuracy by switching its detail copy to the last real compaction metrics (`before -> after`, automatic/manual kind, cumulative compaction count, cumulative saved tokens) instead of only the generic trigger-threshold text.
|
||||||
- Document update: 2026-04-07 09:19 (KST) - Prevented `total_stats` loop events from being swallowed into the generic process-feed path. AX Agent now routes those events back through the dedicated total-stats presentation so transcript summaries and footer token totals stay aligned.
|
- Document update: 2026-04-07 09:19 (KST) - Prevented `total_stats` loop events from being swallowed into the generic process-feed path. AX Agent now routes those events back through the dedicated total-stats presentation so transcript summaries and footer token totals stay aligned.
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ public partial class ChatWindow
|
|||||||
? "문서 작성, 데이터 분석, 파일 작업을 요청하세요. 필요하면 작업 폴더 파일도 함께 참고합니다."
|
? "문서 작성, 데이터 분석, 파일 작업을 요청하세요. 필요하면 작업 폴더 파일도 함께 참고합니다."
|
||||||
: "문서 작성, 데이터 분석, 파일 작업을 요청하세요. 작업 폴더를 선택하면 관련 파일도 함께 참고합니다.",
|
: "문서 작성, 데이터 분석, 파일 작업을 요청하세요. 작업 폴더를 선택하면 관련 파일도 함께 참고합니다.",
|
||||||
"Code" => hasFolder
|
"Code" => hasFolder
|
||||||
? "코드 수정, 원인 분석, 빌드·테스트를 요청하세요. 작업 폴더 코드를 참고하고 저장소 상태도 함께 보여줍니다."
|
? "코드 수정, 원인 분석, 빌드와 테스트를 요청하세요. 작업 폴더 코드와 저장소 상태를 함께 참고합니다."
|
||||||
: "작업 폴더를 선택한 뒤 코드 수정, 원인 분석, 빌드·테스트를 요청하세요.",
|
: "작업 폴더를 선택한 뒤 코드 수정, 원인 분석, 빌드와 테스트를 요청하세요.",
|
||||||
_ => "질문, 요약, 초안 작성, 아이디어 정리를 요청하세요.",
|
_ => "질문, 요약, 초안 작성, 아이디어 정리를 요청하세요.",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ public partial class ChatWindow
|
|||||||
if (string.Equals(_activeTab, "Cowork", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(_activeTab, "Cowork", StringComparison.OrdinalIgnoreCase))
|
||||||
return "선택한 작업 유형에 맞춰 문서·데이터·파일 작업 흐름으로 이어집니다.";
|
return "선택한 작업 유형에 맞춰 문서·데이터·파일 작업 흐름으로 이어집니다.";
|
||||||
|
|
||||||
return "선택한 대화 주제에 맞춰 응답 방향과 초안 흐름이 정리됩니다.";
|
return "선택한 대화 주제에 맞춰 응답 방향과 초안 흐름을 정리합니다.";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateFolderBar()
|
private void UpdateFolderBar()
|
||||||
@@ -199,7 +199,7 @@ public partial class ChatWindow
|
|||||||
{
|
{
|
||||||
panel.Children.Add(new TextBlock
|
panel.Children.Add(new TextBlock
|
||||||
{
|
{
|
||||||
Text = "감사 로그가 꺼져 있어 include 이력을 기록하지 않습니다.",
|
Text = "감사 로그가 꺼져 있어 include 이력은 기록되지 않습니다.",
|
||||||
FontSize = 11,
|
FontSize = 11,
|
||||||
Foreground = secondaryText,
|
Foreground = secondaryText,
|
||||||
TextWrapping = TextWrapping.Wrap,
|
TextWrapping = TextWrapping.Wrap,
|
||||||
@@ -354,7 +354,13 @@ public partial class ChatWindow
|
|||||||
if (SelectedPresetGuide == null || SelectedPresetGuideTitle == null || SelectedPresetGuideDesc == null)
|
if (SelectedPresetGuide == null || SelectedPresetGuideTitle == null || SelectedPresetGuideDesc == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (string.Equals(_activeTab, "Code", StringComparison.OrdinalIgnoreCase))
|
conversation ??= _currentConversation;
|
||||||
|
var hasVisibleMessages = conversation?.Messages?.Any(m =>
|
||||||
|
!string.IsNullOrWhiteSpace(m.Content) &&
|
||||||
|
(string.Equals(m.Role, "user", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(m.Role, "assistant", StringComparison.OrdinalIgnoreCase))) == true;
|
||||||
|
|
||||||
|
if (string.Equals(_activeTab, "Code", StringComparison.OrdinalIgnoreCase) || hasVisibleMessages || _isStreaming)
|
||||||
{
|
{
|
||||||
SelectedPresetGuide.Visibility = Visibility.Collapsed;
|
SelectedPresetGuide.Visibility = Visibility.Collapsed;
|
||||||
SelectedPresetGuideTitle.Text = "";
|
SelectedPresetGuideTitle.Text = "";
|
||||||
@@ -362,7 +368,6 @@ public partial class ChatWindow
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
conversation ??= _currentConversation;
|
|
||||||
var category = conversation?.Category?.Trim();
|
var category = conversation?.Category?.Trim();
|
||||||
if (string.IsNullOrWhiteSpace(category))
|
if (string.IsNullOrWhiteSpace(category))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2372,9 +2372,10 @@ public partial class ChatWindow : Window
|
|||||||
// 버퍼에 쌓인 미표시 글자 수에 따라 속도 적응
|
// 버퍼에 쌓인 미표시 글자 수에 따라 속도 적응
|
||||||
var pending = targetLen - _displayedLength;
|
var pending = targetLen - _displayedLength;
|
||||||
int step;
|
int step;
|
||||||
if (pending > 200) step = Math.Min(pending / 5, 40); // 대량 버퍼: 빠르게 따라잡기
|
if (pending > 300) step = Math.Min(Math.Max(8, pending / 12), 18); // 대량 버퍼도 한 번에 다 붙지 않게 제한
|
||||||
else if (pending > 50) step = Math.Min(pending / 4, 15); // 중간 버퍼: 적당히 가속
|
else if (pending > 120) step = Math.Min(Math.Max(5, pending / 14), 10); // 중간 버퍼는 자연스럽게 가속
|
||||||
else step = Math.Min(3, pending); // 소량: 자연스러운 1~3자
|
else if (pending > 24) step = Math.Min(4, pending); // 소량은 1~4자
|
||||||
|
else step = Math.Min(2, pending); // 마무리는 더 천천히
|
||||||
|
|
||||||
_displayedLength += step;
|
_displayedLength += step;
|
||||||
|
|
||||||
@@ -5750,7 +5751,7 @@ public partial class ChatWindow : Window
|
|||||||
_typingTimer.Start();
|
_typingTimer.Start();
|
||||||
streamText.Text = _cursorVisible ? "\u258c" : " ";
|
streamText.Text = _cursorVisible ? "\u258c" : " ";
|
||||||
|
|
||||||
var deadline = DateTime.UtcNow.AddMilliseconds(Math.Clamp(finalContent.Length * 6, 500, 1800));
|
var deadline = DateTime.UtcNow.AddMilliseconds(Math.Clamp(finalContent.Length * 18, 1400, 6500));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (_displayedLength < _cachedStreamContent.Length && DateTime.UtcNow < deadline && !ct.IsCancellationRequested)
|
while (_displayedLength < _cachedStreamContent.Length && DateTime.UtcNow < deadline && !ct.IsCancellationRequested)
|
||||||
|
|||||||
Reference in New Issue
Block a user