Repository navigation
[1.94] 대화 화면 통합 — 첫 전송 Note 무선생성·이력·진행 Activity·draft·정지 버튼 - #313
Merged
Merged
Conversation
…aft·정지 버튼 (1.94) - 홈 첫 질문: noteId 없이 POST /api/conversations 한 번, run.created noteId로 이동하며 세션을 registry로 넘겨 같은 stream을 이어 받음 (Note 선생성·제목 생성·직접 차감 없음) - Note 화면: 대화 조회(before/limit) 이력 + live run을 runId로 합쳐 표시, activeRun 복원, 409 시 진행 중 run에 붙고 draft 반환 - ChatInput: 직접 차감 제거, Active Run 동안 draft·정지 버튼, CANCELING 중단 중, 거부 시 draft 복원·안내(요청 한도·잔액 부족·미지원·recoverable 실패) - DEV MSW에 browser-run-v1 fixture handler를 구형 mock 앞에 둠 - fixture MSW 통합 테스트 10건 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
CI (Frontend CI run 39360934231, head
|
9 tasks done
…리, draft 덮어쓰기 방지, run 접수·종료 뒤 잔액·노트 invalidate, 이력 재조회와 세션 수명 분리 - #1 홈: run.created 전 reconnect_exhausted·stream_rejected면 세션을 남기고 '다시 연결'(같은 requestId)만 허용, 새 전송 차단 - #2 접수 대기 판정을 연결 중으로 좁히고 그 밖의 정지(unexpected·unauthorized)는 draft를 입력창에 돌려줌 - #3 요청 한도 차단 시각을 닫을 수 있는 안내와 분리(홈·Note) - #4 draft 복원·질문 다시 쓰기가 입력창 내용을 덮어쓰지 않고 앞에 붙임 - #5 run.created·terminal 뒤 credit·profile·note detail·note list invalidate - #6 #파일 멘션·@도구도 첨부처럼 안내 후 전송 막음 - #7 countdown 초는 aria-hidden, 시작·끝 문구만 live region - #8 여러 수식 latex를 '; '로 나눠 text에 없는 것만 덧붙임 - #9 접수 전·후 turn key를 requestId로 통일(remount·스크롤 끌림 방지) - #10 이력 다시 불러오기가 세션 dispose와 묶이지 않게 effect 분리 - #11 run.created 전 홈 이탈 시 연결 유지 후 접수되면 registry에 맡기고 노트 목록 invalidate Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
리뷰 1회차 반영 |
…, 되돌린 질문 줄바꿈 <br>, 복원 run turn key 유지, 무테스트 변경 보강 - 차단 1: 홈 unmount 시 접수 대기 구독을 먼저 끊어 이탈 뒤 접수는 background finish만 처리(이동 없음·handOff 1회·노트 목록 invalidate) - 권고 A: detached handoff는 terminal·stopped에 dispose·삭제, 같은 noteId에 다른 세션을 맡기면 이전 세션 dispose - 권고 B: 화면이 보낸 run만 requestId key, 복원·409 run은 runId key 유지 - 권고 C: 앞에 붙이는 질문은 <br>로 줄 구분 - 테스트: 홈 이탈 시나리오, Note 접수 전 stall, unexpected draft 반환, #파일 멘션 차단, countdown live region Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 관련 이슈
🏷️ PR 타입
📝 작업 내용
홈 첫 질문부터 Note 화면의 이력·진행 Activity·완료 응답·draft·정지 버튼까지 대화 화면을 1.93 run 세션·1.91 renderer·1.92 Activity 박스에 연결했다. 구형 v2 코드는 지우지 않았다(1.95). 화면 경로는 새 run 세션만 쓴다.
첫 질문 (
useHomeSend)POST /api/conversations한 번으로 보낸다.run.created의 noteId로/app/chat/{noteId}로 이동한다.RunSessionRegistryProvider(AppLayout, 라우트 위)에 맡긴다. Note 화면이 같은 세션을 이어 받아 stream이 끊기지 않는다.POST /api/notes·제목 생성·/api/credits/use를 호출하지 않는다.Note 화면 (
useNoteConversation+ConversationPanel)limit=30,before로 "이전 대화 더 보기")로 이력을 그리고, 그 페이지로session.restore(page)를 부른다.buildConversationTurns).run.created전) 전송은pending자리로 보인다.AssistantResponseView)만 그린다. 검증 전 본문은 없다.toCompletedAssistantResponse로 변환한다(인계 e).dispose()만 부른다. 연결만 끊고 run은 취소하지 않는다.입력창 (
ChatInput·InputToolbar)useUseCredit)과 크레딧 모달 호출을 제거했다. 차감은 Server 접수가 맡는다.답변 중단)을 보이고, 안내 줄을 붙인다.clearDraft()전에 입력창으로 되돌린다.run.created)·terminal 뒤 잔액(creditKeys.all)·프로필·노트 상세·노트 목록을 invalidate한다.안내 구분 (
conversation_notice.ts)Retry-After남은 초 카운트다운. 그동안 전송 버튼이 비활성이다(안내를 닫아도 유지, 초는aria-hidden·시작/끝 문구만 live region).unsupported_only: 1.91의 응답 안내not_found(RUN4041): Note 삭제 안내reconnect_exhausted·stream_rejected: "다시 연결" 버튼(session.reconnect())run.created전(홈·Note 모두)에 멈추면 접수됐을 수 있으므로 세션을 남기고 새 전송을 막는다. "다시 연결"이 같은 requestId로 다시 보내 중복 Note·run·차감을 막는다.unauthorized: 세션이/error/401로 보내므로 안내하지 않는다.conversation_notice.ts에 모았다.그 밖
src/mocks/handlers.ts): 1.93createBrowserRunFixtureServer()handler를 구형 editor mock보다 앞에 뒀다. 새 화면이 dev에서 v1 fixture를 쓴다.VITE_API_MODE명시 전환은 1.95.tsconfig.test.json에src/**/*.d.ts를 포함했다.notes_api.ts(axiosmeta모듈 확장src/shared/api/axios.d.ts)를 import한다.typecheck:test가 실패한다.src/features/run/**)과 1.88 공용 타입은 바꾸지 않았다.화면 문서 메모 — Activity header 요약 (인계 b)
startedSeq, 끝난 Activity는updatedSeq기준이다.📸 스크린샷 (UI 변경 시 필수)
fixture 모드(DEV MSW + browser-run-v1 fixture handler,
vite --port 5194)에서 실제 흐름으로 캡처했다.pr-assets/task-1.94에 올렸다(merge 대상 아님, 필요 없으면 지워도 된다).Before(구형 v2 경로: 노트 선생성 → 토큰 스트림·순환 진행 문구)는 이 PR에서 화면 경로가 바뀌어 같은 흐름으로 캡처할 수 없다.
데스크탑 1440×900
태블릿 가로 1024×768
태블릿 세로 768×1024
✅ 체크리스트
공통
pnpm tsc --noEmit타입 체크를 통과했습니다 (tsc -p tsconfig.app.json,pnpm typecheck:test,pnpm run build의tsc -b)worktree-task-1.94사용UI/레이아웃 변경 시
PageContainer/ContentGrid공통 컴포넌트를 활용했습니다 — 기존 ChatPage 레이아웃을 그대로 썼다인증 관련 변경 시
/error/401흐름🧪 검증
src/features/chat/run/conversation_screen.test.tsx(10건) 구성:HomePage·ChatPage·ChatInput을createMemoryRouter로 렌더한다.createBrowserRunMockServer(msw/node)가 받는다.9001로 이동, 진행 중 본문 없음, 완료 뒤 응답. 구형 기록에POST /api/notes·generate-title·/api/credits/use·구형/api/conversations없음. 두 번째 질문 run도 noteId9001GET /events(Last-Event-ID {runId}:{seq})로 이어 받음, POST 1회, 질문 bubble 1개/app/home유지, 안내·요금제 링크, 입력 유지, Note 생성 없음Retry-After: 30)failed-verification)unsupported_only응답mutation probe
restoreDraft)을 지우면 409·요청 한도·미지원 3건이 실패했다(확인 뒤 되돌림).busy로 한 번 더 막기 때문이고, 입력창 가드는 이중 방어다.로컬 실행 결과
pnpm test(flock): 19 files, 828 passed / 2 skippedpnpm typecheck:test,tsc -p tsconfig.app.json통과eslint·prettier --check통과pnpm run build(flock) 통과(기존 chunk 크기 경고만)CI 결과는 코멘트로 남긴다.
리뷰 1회차 반영 (
27ce60f)mutation probe: #10(이력 effect에 dispose 복귀)·#3(차단을 안내에서 읽기)을 되돌리면 각 테스트가 실패했다(확인 뒤 복원).
로컬:
pnpm test20 files 834 passed / 2 skipped,typecheck:test, 변경 파일 eslint·prettier,pnpm run build통과.리뷰 2회차 반영 (
6fe3446)handOff(detached)1회·노트 목록 invalidate만 한다(이동 없음). 통합 테스트와 probe<br>로 구분CI run 39383532779: test 21 files 840 passed / 2 skipped, typecheck:test·build·lint 통과.
📎 기타 참고사항
1.95 인계 — 화면 경로는 새 run 세션만 쓴다
홈·Note 화면이 import하는 대화 경로는 다음뿐이다.
features/chat/run/*features/run/{api,model,session,components}features/chat/components/rightpanel/Conversation*.tsx아래 구형 코드는 화면에서 참조하지 않지만 남겨 두었다.
src/features/chat/hooks/useChatMessages.ts(+hooks/index.tsexport)createConversation·parseSSEStream·generateNoteTitle·업로드src/features/chat/components/rightpanel/{RightPanel,ChatMessages,ThinkingBar}.tsx(+components/index.ts·rightpanel/index.tsexport)FINAL_LOADING_MESSAGES·ThinkingBarsrc/features/editor/api/editor_api.tscreateConversation·createConversationJson·getConversationDetailsearchConversations는 검색(useConversationSearch)이 쓰므로 남긴다.uploadCanvasImage는useEditorQueries가 쓴다src/features/editor/utils/parse_sse_stream.ts,src/features/editor/types/sse_types.tssrc/features/settings/hooks/useCredit.tsuseUseCreditsrc/features/notes/hooks/useNotes.tsuseCreateNote,notes_api.tscreateNote·generateNoteTitlesrc/pages/hooks/useHomeSend.tsFirstMessageState타입useChatMessages만 쓴다src/mocks/handlers/editor.ts구형POST /api/conversationsSSE mock,notes.tsPOST /api/notesmain.tsxDEV 자동 MSWVITE_API_MODE명시 전환알려진 한계
@도구 선택은 browser-run-v1requestedTasks와의 매핑이 정의되지 않아 위처럼 전송을 막는다. 매핑·#파일 멘션 연동은 S09·S11.$…$로 들어가고 latex 필드에도 실린다.$…$텍스트로 돌아온다.🤖 Generated with Claude Code