1.0.1 ko public

스펙

RAWP-CRS

Compliance rendering specification for RAWP consumers.

4. 에이전트 메시지 (Agent Message)

에이전트 메시지의 설계 목표는 다양한 형식의 콘텐츠를 복잡함 없이 제시하는 것이다. 에이전트는 텍스트, 마크다운, 사고 과정, 도구 호출 결과, 코드 diff, 태스크 목록 등 이질적인 형식의 출력을 생성하며, 이들이 하나의 대화 흐름에서 자연스럽게 읽히도록 해야 한다.

4.1. 레이아웃 원칙: 버블리스 디자인 (Bubble-less Design)

에이전트 메시지는 채팅 버블로 감싸지 않는다 (MUST NOT). 에이전트 출력에 채팅 버블을 적용하면 다음의 문제가 발생한다:

  • 코드 블록, diff 뷰어, 태스크 목록 등이 버블 내부에 중첩되어 이중 컨테이너(container-in-container) 구조가 되며, 시각적 노이즈가 증가한다.
  • 버블의 고정 패딩과 최대 너비 제한이 코드, 테이블, diff 등 가로 공간이 필요한 콘텐츠의 가독성을 저해한다.
  • 다양한 콘텐츠 유형(텍스트, 코드, diff, 파일 트리 등)이 동일한 버블 외형으로 감싸져 유형별 시각적 구분이 무너진다.

에이전트 출력은 대화 영역의 좌측에 정렬하되, 버블 없이 콘텐츠 자체의 시각적 형태(텍스트 블록, 코드 블록, diff 뷰어, 카드 등)로 유형을 구분한다. 각 콘텐츠 블록 사이에는 충분한 수직 간격(예: 12~16px)을 확보하여 블록 간 경계를 명확히 한다 (SHOULD).

4.2. 마크다운 렌더링 (Markdown Rendering)

에이전트의 텍스트 응답은 마크다운 형식을 포함할 수 있으며, 클라이언트는 아래에 명시된 마크다운 컴포넌트를 렌더링할 수 있어야 한다. 각 컴포넌트는 지원 수준에 따라 필수(MUST), 권장(SHOULD), 선택(MAY) 으로 분류된다. 필수 컴포넌트를 렌더링하지 못하는 클라이언트는 본 프로토콜의 UI 적합성을 만족하지 못하는 것으로 간주한다.

A. 인라인 텍스트 서식 (Inline Text Formatting)

인라인 서식은 문장 내에서 특정 텍스트 범위에 스타일을 적용하는 요소다. 모든 인라인 서식은 상호 중첩(nesting)이 가능해야 한다 (MUST). 예: ***bold and italic***, **bold with `code`**.

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
볼드 (Bold) **text** 또는 __text__ font-weight: bold 적용. 본문 텍스트보다 시각적으로 두꺼워야 한다. MUST
이텔릭 (Italic) *text* 또는 _text_ font-style: italic 적용. 기울어진 글꼴로 렌더링한다. MUST
볼드+이텔릭 ***text*** 볼드와 이텔릭을 동시에 적용. MUST
취소선 (Strikethrough) ~~text~~ text-decoration: line-through 적용. 텍스트 중앙을 가로지르는 선을 표시한다. MUST
인라인 코드 (Inline Code) `code` 모노스페이스 폰트 적용. 본문 텍스트와 구분되는 배경색(예: 연한 회색)과 미세한 패딩을 부여하여 시각적으로 분리한다. 내부 텍스트는 마크다운 파싱 대상에서 제외(escape)해야 한다. MUST
하이라이트 (Highlight) ==text== <mark> 또는 동등한 형광펜 배경색을 적용하여 강조한다. SHOULD
밑줄 (Underline) <u>text</u> (HTML 태그) text-decoration: underline 적용. 링크와의 시각적 혼동을 방지하기 위해 밑줄 색상은 링크 색상과 구분되어야 한다 (SHOULD). SHOULD
위첨자 (Superscript) ^text^ 또는 <sup>text</sup> 본문 기준선보다 위에, 작은 폰트 크기로 렌더링한다. SHOULD
아래첨자 (Subscript) ~text~ 또는 <sub>text</sub> 본문 기준선보다 아래에, 작은 폰트 크기로 렌더링한다. 취소선(~~)과의 구문 충돌에 주의: 물결표 1개는 아래첨자, 2개는 취소선으로 파싱한다. SHOULD
키보드 키 (Keyboard) <kbd>Ctrl</kbd> 키캡 스타일의 인라인 요소로 렌더링. 둥근 보더, 미세한 그림자, 모노스페이스 폰트를 적용하여 물리 키보드 키를 시각적으로 모방한다. MAY

B. 블록 요소: 헤더 (Headings)

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
헤더 1~6 # H1 ~ ###### H6 수준별 폰트 크기와 두께를 차등 적용하여 계층 구조를 시각적으로 표현한다. H1이 가장 크고, H6이 가장 작다. 모든 헤더는 본문 텍스트보다 크거나 같은 크기에 볼드를 적용해야 한다. MUST

헤더 크기 조정: 에이전트 응답 내 헤더는 독립 문서가 아닌 대화 컨텍스트 안에서 표시되므로, 문서 수준의 과도하게 큰 H1은 대화 흐름을 시각적으로 단절시킨다. 클라이언트는 대화 인터페이스에 적합한 크기 범위로 헤더 스케일을 조정해야 한다 (SHOULD). 예: H1을 본문 대비 1.41.6배, H2를 1.21.4배 수준으로 제한하고, H4~`H6`은 본문과 동일 크기에 볼드 또는 색상 차등만으로 구분할 수 있다.

헤더 간격: 헤더 상단에는 본문 행간보다 넓은 여백(예: 1.5~2배)을 부여하여 섹션 경계를 명확히 해야 한다 (SHOULD). 헤더 하단 여백은 본문 행간과 동일하거나 약간 넓은 수준으로 유지하여 헤더와 후속 본문의 연결감을 보존한다.

B. 블록 요소: 목록 (Lists)

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
비순서 목록 - item, * item, + item 불릿 기호(●, ○, ■ 등)와 함께 들여쓰기를 적용하여 렌더링한다. MUST
순서 목록 1. item, 2. item 숫자 번호와 함께 들여쓰기를 적용하여 렌더링한다. 번호는 마크다운 원문의 숫자가 아닌, 실제 순서를 기반으로 자동 생성해야 한다. MUST
중첩 목록 들여쓰기(2~4칸)로 하위 항목 들여쓰기 수준에 따라 불릿 기호를 차등 적용(예: 1단계 ●, 2단계 ○, 3단계 ■)하고, 각 수준의 들여쓰기가 시각적으로 명확해야 한다. 비순서↔순서 혼합 중첩도 지원해야 한다. MUST
체크리스트 - [ ] todo, - [x] done 미체크(☐)와 체크(☑) 상태를 시각적으로 구분하는 체크박스 아이콘을 표시한다. 체크박스는 읽기 전용으로, 사용자가 클릭하여 상태를 변경할 수 없다. SHOULD

B. 블록 요소: 코드 (Code Blocks)

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
펜스 코드 블록 ```language ... ``` 모노스페이스 폰트, 본문과 구분되는 배경색 컨테이너에 렌더링한다. 내용이 가로로 넘칠 경우 가로 스크롤을 지원해야 한다 (MUST). MUST
구문 하이라이팅 ```python 등 언어 식별자 해당 언어의 키워드, 문자열, 주석, 숫자 등을 색상으로 구분하는 구문 하이라이팅을 적용한다. 최소한 주요 언어(Python, JavaScript/TypeScript, Java, C/C++, Go, Rust, HTML, CSS, SQL, Bash, JSON, YAML, Markdown)를 지원해야 한다. SHOULD
코드 블록 메타 정보 코드 블록 상단에 언어명 레이블을 표시하고, 우측 상단에 복사 버튼을 제공한다. SHOULD
라인 번호 긴 코드 블록(예: 10줄 이상)에는 좌측에 라인 번호를 표시한다. MAY

B. 블록 요소: 테이블 (Tables)

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
테이블 | col | col | 행과 열이 구분된 테이블 형태로 렌더링한다. MUST

테이블 상세 명세: 헤더 행 구분(MUST), 열 정렬(MUST), 행 구분(SHOULD), 셀 패딩(MUST), 오버플로우 시 가로 스크롤(MUST), 셀 내 마크다운(MUST).

B. 블록 요소: 인용, 구분선, 이미지 (Quotes, Dividers, Images)

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
인용구 > text 좌측에 수직 보더(3~4px, 강조 색상 또는 회색)를 배치하고, 본문 대비 들여쓰기를 적용한다. 다중 수준 인용 지원. MUST
수평선 ---, ***, ___ 전체 가용 너비에 걸친 시각적 구분선을 렌더링한다. MUST
이미지 ![alt](url) 인라인 이미지로 렌더링. 최대 너비 제한(MUST), 원본 비율 유지(MUST), 로딩 중 placeholder(SHOULD), alt 텍스트 폴백(MUST). MUST
이미지 캡션 ![alt](url "title") title 속성이 제공된 경우, 이미지 하단에 캡션 텍스트로 표시한다. MAY

B. 블록 요소: 링크, 참조 (Links & References)

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
인라인 링크 [text](url) 클릭 가능한 하이퍼링크. 외부 링크는 새 탭/창에서 열어야 한다 (SHOULD). MUST
자동 링크 <https://...> 또는 URL 자동 감지 URL 형태의 텍스트를 자동으로 클릭 가능한 링크로 변환한다. SHOULD
참조 링크 [text][id] + [id]: url 참조 스타일 링크를 인라인 링크와 동일하게 렌더링한다. SHOULD
각주 [^1] + [^1]: text 본문 내 각주 참조를 위첨자 번호로 표시하고, 클릭 시 대응하는 각주 내용으로 스크롤하거나 툴팁으로 표시한다. MAY

C. 수식 (Math / LaTeX)

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
인라인 수식 $E = mc^2$ 본문 텍스트 흐름 내에서 수식을 렌더링한다. KaTeX, MathJax 등 사용. SHOULD
블록 수식 $$\n...\n$$ 독립된 블록으로 중앙 정렬하여 수식을 렌더링한다. SHOULD

D. 다이어그램 (Diagrams)

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
Mermaid 다이어그램 ```mermaid ... ``` Mermaid.js를 사용하여 다이어그램을 SVG 또는 Canvas로 렌더링한다. 렌더링 실패 시 원본 텍스트를 코드 블록으로 폴백 표시한다. MAY

E. 기타 요소 (Miscellaneous)

컴포넌트 마크다운 구문 렌더링 명세 지원 수준
이모지 :emoji_name: GitHub 스타일 이모지 숏코드를 유니코드 이모지로 변환한다. 유니코드 이모지 직접 입력도 올바르게 렌더링해야 한다 (MUST). SHOULD
줄바꿈 행 끝 공백 2칸 또는 <br> 명시적 줄바꿈을 적용한다. MUST
이스케이프 문자 \*, \#, \_ 백슬래시로 이스케이프된 마크다운 특수 문자는 리터럴 문자 그대로 표시한다. MUST
HTML 인라인 태그 <br>, <u>, <sup>, <sub>, <mark>, <kbd> 안전한(safe) HTML 태그에 한해 인라인 렌더링을 허용한다. <script>, <iframe>, <style>, <form> 등 보안 위험이 있는 태그는 반드시 무시하거나 이스케이프 처리해야 한다 (MUST). SHOULD

스트리밍 중 미완성 마크다운 방어: 렌더러는 스트리밍 중 마크다운 태그가 닫히지 않은 상태로 전달되더라도 UI가 깨지지 않도록 방어적으로 처리해야 한다 (MUST). 코드 블록은 열림 태그 수신 시 즉시 컨테이너를 생성하고 최소 높이를 할당한다 (SHOULD). 인라인 서식은 임시로 서식을 적용하되 닫는 마커 수신 시 확정한다. 테이블은 구분 행 수신 시점부터 렌더링을 시작한다 (SHOULD).

4.3. 점진적 텍스트 렌더링 (Progressive Text Rendering)

실시간 스트리밍 환경(WSS 지원 클라이언트)에서의 텍스트 렌더링 지침이다.

버퍼 병합: 클라이언트는 content_index 단위로 수신되는 텍스트 페이로드를 지연 없이 화면에 점진적으로 렌더링해야 한다 (MUST).

오토 스크롤 제어: 텍스트 생성 중에는 뷰포트 하단을 자동으로 추적하되, 사용자가 과거 이력을 보기 위해 스크롤을 위로 올린 상태(Scroll Up)에서는 읽기 방해를 막기 위해 오토 스크롤을 일시 중단해야 한다 (SHOULD).

스크롤 안정성 (Scroll Stability): 클라이언트는 사용자가 현재 읽고 있는 텍스트가 시각적으로 흔들리지 않도록 스크롤 위치를 능동적으로 제어해야 한다 (MUST). 구체적으로 다음을 준수한다:

  • 앵커 포인트 고정: 오토 스크롤이 활성화된 상태에서는, 새로운 텍스트가 삽입될 때 현재 생성 중인 마지막 라인이 뷰포트 하단의 일정 영역(예: 하단 20~30% 지점)에 고정되도록 조정해야 한다 (MUST).
  • 상방 삽입 보상 (Upward Insertion Compensation): 현재 읽고 있는 영역 위쪽에 콘텐츠가 삽입되거나 높이가 변하는 경우, 삽입된 높이만큼 scrollTop을 보상하여 현재 보고 있는 텍스트의 화면상 절대 위치가 변하지 않도록 해야 한다 (MUST).
  • 부드러운 추종: 오토 스크롤 시 scrollTobehavior: 'instant'를 사용하여 프레임 단위로 즉각 추종해야 한다 (SHOULD). behavior: 'smooth'는 빠른 텍스트 생성 속도에 뒤처져 누적 지연을 유발할 수 있으므로 스트리밍 중에는 사용하지 않아야 한다 (SHOULD NOT).
  • 높이 변동 최소화: 코드 블록, 테이블, 이미지 등 높이가 확정되지 않은 요소는 예상 높이를 미리 확보(placeholder/skeleton)하여 렌더링 완료 시 높이 변동폭을 최소화해야 한다 (SHOULD).

텍스트 출현의 시각적 연속성 (Visual Continuity of Text Appearance): 점진적으로 생성되는 텍스트는 사용자에게 매끄럽고 연속적인 흐름으로 인지되어야 한다 (MUST). 구체적으로 다음을 준수한다:

  • 마이크로 배칭 및 보간: 클라이언트는 수신된 agent.text.delta 토큰을 짧은 시간 윈도우(예: 30~60ms) 내에 모아 한 번에 렌더링하거나, requestAnimationFrame 주기에 동기화하여 프레임당 일정량의 텍스트를 출력하는 방식을 적용해야 한다 (SHOULD). 단, 배칭으로 인한 체감 지연이 100ms를 초과해서는 안 된다 (MUST NOT).
  • 출현 애니메이션: 새로 삽입되는 텍스트에 미세한 페이드인 또는 수직 슬라이드인 효과를 적용할 수 있다 (MAY). 적용 시 애니메이션 지속 시간은 50~120ms 이내로 제한해야 한다 (MUST). 애니메이션은 가장 최근에 추가된 텍스트 청크에만 적용하며, 이미 표시된 텍스트가 반복적으로 애니메이션되어서는 안 된다 (MUST NOT).
  • 하단 경계 효과 제한: 생성 중인 텍스트의 하단 경계에 블러, 그라데이션 페이드 등의 시각 효과를 적용하는 경우, 효과 영역의 높이는 텍스트 2줄 이내(약 40~48px)로 제한한다 (MUST). 블러 강도는 4px 이하로 제한한다 (SHOULD). 맥동, 깜빡임, 색상 순환 등 동적 변화를 하단 경계 효과에 적용해서는 안 된다 (MUST NOT). 생성 완료(agent.text.done) 시 즉시 제거하거나 100ms 이내에 페이드아웃해야 한다 (MUST).
  • 읽기 흐름 보호 원칙: 점진적 렌더링의 모든 시각적 처리는 다음의 상위 원칙을 따라야 한다: 사용자가 이미 생성된 텍스트를 읽는 행위를 방해해서는 안 된다 (MUST NOT).

4.4. 사고 과정 시각화 (Thinking Process)

시각적 분리: agent.thinking.delta의 내용은 일반 응답 텍스트와 명확히 구분되는 별도의 컨테이너(예: 인용구, 배경색이 다른 블록)에 렌더링해야 한다 (MUST).

진행 상태 표현 (Thinking Indicator): 사고 과정이 진행 중일 때, 사용자에게 에이전트가 능동적으로 작업 중임을 시각적으로 전달해야 한다 (MUST). 그라데이션 애니메이션(SHOULD), 1.5~3초 사이의 느린 호흡 리듬(SHOULD), "Thinking…" 레이블(MUST)을 포함한다.

실시간 텍스트 노출 정책: 사고 스트림의 텍스트 본문을 사용자에게 실시간으로 노출할지 여부는 클라이언트 설정에 따른다. 요약 모드(기본값 권장)와 실시간 모드를 지원할 것을 권장한다 (SHOULD).

상태 전이 및 제거: agent.thinking.done 수신 시, 그라데이션 애니메이션을 즉시 중단하고 (MUST), 접힌 상태로 전환하여 "Thought for Ns" 요약 한 줄만 표시한다 (SHOULD). 활성 → 접힘 전환은 150~300ms 트랜지션으로 처리한다 (SHOULD). 후속 agent.text.delta 영역으로 시선을 유도한다 (SHOULD).

마스킹 처리: redacted: true인 경우 [사고 내용 생략] 등의 플레이스홀더로 마스킹하고 (MUST), 펼침 동작 자체를 비활성화한다 (MUST).

다중 사고 블록: 각 content_index별로 독립된 사고 컨테이너를 생성하되, 동시에 두 개 이상의 Thinking Indicator가 활성 상태로 표시되어서는 안 된다 (MUST NOT).

4.5. 도구 가용 상태 및 호출 결과 렌더링 (Tool Status & Result Rendering)

4.5.1. 도구 가용 상태 표시 (Tool Availability Indicator)

tool.catalog.publish(RAWP-DPS 1.0.1 §5.4.1) 수신 시, 각 도구의 status 필드에 따라 가용 상태를 시각적으로 구분하여 표시해야 한다 (MUST). 도구 목록을 노출하는 모든 UI(도구 팔레트, 사이드바, 도구 호출 헤더 등)에 적용한다.

상태별 시각 표현:

status 시각 표현 도구명 스타일 상호작용
available 없음 (기본 상태이므로 별도 표시 불필요) 기본 텍스트 정상 사용 가능
unavailable 도구명 좌측에 금지 아이콘(🚫) 또는 빨간 점 표시 흐린 텍스트(opacity 50%), 취소선 적용 (SHOULD) 클릭/선택 비활성화
degraded 도구명 좌측에 경고 아이콘(⚠) 또는 주황 점 표시 기본 텍스트 유지 정상 사용 가능

상태 사유 표시: 도구의 status_description 필드(RAWP-DPS 1.0.1 §5.4.1)가 존재하면, 도구명 하단에 한 줄로 사유를 표시해야 한다 (MUST). unavailable이면 연한 빨간 텍스트, degraded이면 연한 주황 텍스트로 표시한다. status_description이 없으면 사유를 표시하지 않는다 (MUST NOT). 예: Bash 아래에 실행 파일을 찾을 수 없음.

진단 메시지 연동: diagnostics 배열에 해당 도구의 진단(tool_name 일치)이 포함된 경우, 도구 항목에 호버 또는 탭 시 진단 메시지를 툴팁으로 표시할 수 있다 (MAY).

도구 카탈로그 갱신: tool.catalog.publish가 세션 중 재수신되면, 도구 목록과 상태를 즉시 갱신해야 한다 (MUST). 이전에 unavailable이었던 도구가 available로 전이되면 금지 표시를 즉시 제거한다.

4.5.2. 도구 호출 결과 렌더링 (Tool Result Rendering)

진행 중 표시: tool.invoke.request 수신 시, 도구명과 함께 스피너를 인라인으로 표시해야 한다 (MUST). tool.invoke.stream 수신 시에는 실시간 출력을 점진적으로 렌더링해야 한다 (SHOULD).

병렬 도구 그룹화: 동일한 parallel_group_id를 가진 복수의 tool.invoke.request는 하나의 그룹 컨테이너로 묶어 표시해야 한다 (SHOULD).

완료 전환: tool.invoke.result 수신 시, 스피너를 즉시 중단하고 output_type에 적합한 결과 뷰어로 전환해야 한다 (MUST). 뷰어 매핑:

output_type 권장 뷰어 비고
text 모노스페이스 텍스트 블록 Bash stdout 등
diff 구문 인지 Diff 뷰어 §4.6 참조 (MUST)
file_content 라인 번호 포함 코드 뷰어 구문 하이라이팅 적용 (SHOULD)
file_list 파일 트리 또는 경로 목록 클릭 시 해당 파일 열기 지원 (MAY)
web_content 링크 포함 요약 카드 출처 URL 표시 (MUST)
structured JSON 트리 뷰어 또는 전용 위젯 TodoRead 등은 §4.8 참조
empty 성공 체크마크 한 줄 "✅ Write completed" 등
agent_result 서브에이전트 결과 접이식 블록 클릭 시 전체 결과 펼침 (SHOULD)

파일 조작 결과 헤더: tool.invoke.result에서 도구가 파일 조작 도구(category: "filesystem", tool_name ∈ {Write, Edit, MultiEdit} 또는 동등 도구)인 경우, 결과 헤더에 파일 조작 유형을 명시적으로 표시해야 한다 (MUST):

조작 유형 헤더 표시 예시 시각적 힌트
파일 생성 Created: {file_path} 녹색 계열 강조
파일 수정 Modified: {file_path} 기본 색상
파일 삭제 Deleted: {file_path} 빨간 계열 강조

조작 유형의 판단은 도구의 tool_nameinput 필드에서 유추한다. 예: tool_name: "Write"이면 파일 생성 또는 덮어쓰기, tool_name: "Edit"이면 수정.

에러 결과 표시: statuserror, timeout, cancelled인 경우, 에러 상태를 시각적으로 구분하여 표시해야 한다 (MUST).

접이식 기본 동작: 도구 결과는 기본적으로 접힌 상태로 표시하되, 결과 요약 한 줄을 노출하고 클릭 시 전체 결과를 펼칠 수 있어야 한다 (SHOULD). 단, output_type: diff인 경우에는 기본 펼침 상태를 허용한다 (MAY).

4.6. Code Diff 렌더링 (Diff Viewer)

output_type: diff 또는 output_type: text이면서 내용이 Unified Diff 형식인 도구 결과는, 구문 인지 Diff 뷰어로 렌더링해야 한다 (MUST).

Diff 형식 자동 감지: output_typetext인 경우에도, 출력 내용의 첫 10라인 이내에 --- a/, +++ b/, @@ 등 Unified Diff 시그니처가 감지되면 Diff 뷰어로 자동 전환해야 한다 (SHOULD).

라인 수준 색상 구분: 삭제=빨강 계열, 추가=녹색 계열의 대비가 즉각적으로 인지되어야 한다 (MUST).

접두 문자 의미 라이트 테마 배경 다크 테마 배경
- 삭제된 라인 #fdd #3d1114
+ 추가된 라인 #dfd #1a361a
@@ 청크 헤더 #def #1a2a3a
(공백) 컨텍스트 라인 투명 투명
diff --git 파일 경계 헤더 연한 회색 어두운 회색

인라인 단어 수준 하이라이팅: 동일 위치의 삭제/추가 라인 쌍에 대해, 라인 내 실제로 변경된 단어/문자 범위를 추가 강조할 것을 권장한다 (SHOULD).

라인 번호 표시: 원본(old)과 변경(new)의 라인 번호를 이중 컬럼으로 표시해야 한다 (SHOULD).

파일 헤더 구분: 여러 파일의 변경 사항이 포함된 경우, 각 파일 경계를 명확한 헤더로 구분해야 한다 (MUST). 파일 단위 접기/펼치기를 지원할 것을 권장한다 (SHOULD).

뷰 모드 전환: Unified View(기본값)와 Side-by-side View를 제공할 것을 권장한다 (SHOULD).

접근성 고려: 색상과 함께 접두 기호(-, +)를 항상 가시적으로 유지하고, 선택적으로 아이콘 또는 패턴을 병행 표시할 것을 권장한다 (SHOULD).

변경 통계 요약 표시: Diff 헤더 또는 푸터에 변경 통계를 한 줄로 요약 표시해야 한다 (MUST). 형식: +{추가_라인_수} -{삭제_라인_수}. 예: +12 -3.

파일 생성/삭제 배지:

  • 모든 라인이 +(추가)인 Diff는 파일 전체가 신규 생성되었음을 의미한다. Diff 상단에 New file 배지를 표시해야 한다 (MUST).
  • 모든 라인이 -(삭제)인 Diff는 파일 전체가 삭제되었음을 의미한다. Diff 상단에 File deleted 배지를 표시해야 한다 (MUST).
  • 배지는 파일 헤더 영역 내에서 파일명과 함께 표시하며, 해당 색상(생성=녹색, 삭제=빨간) 계열의 배경을 적용한다 (SHOULD).

라인 수준 추가/삭제 시각화: tool.invoke.resultoutput에 라인별 추가/삭제 정보가 포함된 경우(구조화 Diff 또는 Unified Diff), 개별 라인의 추가/삭제를 본 절의 라인 수준 색상 구분 규칙(삭제=빨강, 추가=녹색)에 따라 표시해야 한다 (MUST).

4.7. 에이전트 상태 표시 (Agent State Indicator)

agent.state.changed 이벤트는 에이전트의 내부 상태 전이를 실시간으로 통보한다. 각각 독립된 채팅 메시지로 렌더링해서는 안 된다 (MUST NOT).

단일 인라인 상태 표시줄: 클라이언트는 에이전트의 현재 상태를 대화 영역의 고정된 단일 위치에 표시하고, 수신 시마다 제자리 갱신(in-place update) 해야 한다 (MUST).

상태별 렌더링: thinking🧠 Thinking… (그라데이션 펄스), tool_calling🔧 Running tool… (스피너), awaiting_input⏸ Waiting for input (정적), error⚠ Error occurred (붉은 강조), idle → 표시줄 제거.

전환 애니메이션: 100~200ms 이내 크로스페이드 또는 슬라이드 (SHOULD). 전환 속도가 상태 변경 빈도보다 느리면 애니메이션을 생략하고 즉시 교체해야 한다 (MUST).

유휴 상태 처리: idle 전이 시 즉시 제거하거나 200~300ms 페이드아웃 (MUST). Turn 완료 후 대화 이력에 흔적이 남아서는 안 된다 (MUST NOT).

대화 이력 비오염 원칙: agent.state.changed 이벤트는 대화 이력에 영구적 항목으로 기록해서는 안 된다 (MUST NOT). 상태 표시는 순수하게 일시적(ephemeral)이다.

4.8. 태스크 목록 렌더링 (Task List Rendering)

output_type: structured 형태의 TodoRead/TodoWrite 결과(RAWP-DPS §8.2)를 수신하면, 클라이언트는 전용 태스크 관리 UI를 실시간으로 갱신해야 한다 (SHOULD).

태스크 상태 시각화:

status 시각 표현 비고
pending ○ 빈 원 또는 미체크 체크박스 회색 텍스트
in_progress ◐ 반원 또는 스피너 부착 체크박스 볼드 텍스트, 강조 배경
completed ● 채워진 원 또는 체크된 체크박스 취소선 텍스트 (SHOULD)
cancelled ✕ 취소 표시 흐린 텍스트, 불투명도 감소

계층 구조 지원: parent_id가 존재하는 태스크는 부모 태스크 하위에 들여쓰기하여 트리 구조로 렌더링해야 한다 (SHOULD).

전환 애니메이션: 태스크 상태 변경 시 부드러운 전환 애니메이션을 적용해야 한다 (SHOULD). 다수의 태스크가 동시에 갱신되는 경우 개별 애니메이션을 생략하고 전체 목록을 일괄 교체할 수 있다 (MAY).

4.9. Turn 내 콘텐츠 순서 보장 (Content Ordering within Turn)

에이전트의 단일 Turn은 텍스트 블록, 사고 과정, 도구 호출이 교차(interleave)하여 발생할 수 있다. 이 교차 콘텐츠의 렌더링 순서 규칙을 정의한다.

수신 순서 렌더링 원칙: 모든 콘텐츠 블록은 수신 순서대로 대화 영역에 아래로 추가해야 한다 (MUST). 이미 렌더링된 요소의 순서를 재배치(reorder)해서는 안 된다 (MUST NOT).

마지막 텍스트 블록 최하단 보장 (Last Text Anchoring): 에이전트가 Turn 내에서 마지막으로 생성하는 텍스트 블록(agent.text.deltaagent.text.done)은 해당 Turn의 시각적 렌더링에서 항상 최하단에 위치해야 한다 (MUST). 이는 수신 순서 렌더링 원칙에 의해 자연스럽게 보장된다 — 마지막 텍스트 블록은 마지막에 수신되므로 최하단에 추가된다.

시퀀스 예시:

수신 순서 이벤트 렌더링 위치
1 agent.text.delta (텍스트 A) 최상단
2 tool.invoke.request (도구 X) 텍스트 A 아래
3 tool.invoke.result (도구 X 결과) 도구 X 요청 아래
4 agent.text.delta (텍스트 B) 도구 X 결과 아래 (최하단)

텍스트 B가 에이전트의 마지막 텍스트 블록이므로, Turn 완료 시 최하단에 위치한다. 이후 추가 도구 호출 없이 session.turn.end가 수신되면, 텍스트 B가 사용자에게 가장 마지막으로 보이는 콘텐츠가 된다.

도구 호출로 Turn이 종료되는 경우: 에이전트가 텍스트 출력 후 도구 호출을 수행하고 추가 텍스트 없이 Turn이 종료되면, 도구 결과가 최하단이 된다. 이는 허용되는 동작이다.

4.10. 서브에이전트 메시지 렌더링 (Subagent Message Rendering)

RAWP-DPS 1.0.1 §10의 서브에이전트 위임 규격에 따라, metadata.subagent_context가 포함된 메시지의 렌더링 규칙을 정의한다.

4.10.1. 메시지 그룹핑

subagent_context가 존재하는 연속 메시지(동일 parent_invocation_id)는 시각적으로 그룹핑하여 메인 에이전트의 메시지와 구분해야 한다 (MUST).

그룹 헤더: 그룹 상단에 서브에이전트의 agent_typedescription을 표시해야 한다 (MUST). agent_type이 없으면 Subagent와 같은 일반 레이블을 사용한다. 헤더는 서브에이전트임을 즉시 인지할 수 있는 시각적 구분(아이콘, 배경색 차등, 좌측 보더 등)을 포함해야 한다 (MUST).

중첩 서브에이전트: parent_invocation_id 체인으로 식별되는 중첩 서브에이전트(서브에이전트 내에서 호출된 서브에이전트)는 들여쓰기 또는 시각적 계층으로 표현해야 한다 (SHOULD).

접기/펼치기: 서브에이전트 그룹은 접기/펼치기가 가능해야 한다 (SHOULD). 진행 중인 서브에이전트는 펼침 상태, agent.subagent.ended 수신 후 완료된 서브에이전트는 접힌 상태를 기본으로 한다 (SHOULD). 접힌 상태에서는 그룹 헤더와 결과 요약 한 줄만 표시한다.

4.10.2. 서브에이전트 도구 호출 표시

  • 서브에이전트 내의 도구 호출은 해당 서브에이전트 그룹 내에서 표시해야 한다 (MUST). 메인 에이전트의 도구 호출과 섞이면 안 된다 (MUST NOT).
  • 서브에이전트 내의 도구 호출은 §4.5.2와 동일한 UI 컴포넌트를 사용하되, 서브에이전트 그룹 컨텍스트 내에 위치해야 한다.
  • subagent 필드가 포함된 tool.invoke.request(서브에이전트를 호출하는 도구 자체)는 일반 도구 호출과 시각적으로 구분해야 한다 (SHOULD). 예: 전용 아이콘, 색상, Subagent 배지.

4.10.3. 서브에이전트 미지원 폴백

  • subagent_context가 없거나 null인 메시지는 그룹핑 없이 플랫하게 표시해야 한다 (MUST). 이것이 서브에이전트 미지원 에이전트의 기본 동작이다.
  • output_type: "agent_result"tool.invoke.resultsubagent_context 없이도 서브에이전트 결과임을 암시한다. 이 경우 해당 tool request/result 쌍을 "서브에이전트 호출"로 표시할 수 있다 (MAY). 단, 내부 메시지 그룹핑은 불가능하다.

참조