# rawp-dps 1.0.1 변경 사항 1.0.0와 비교 ## 개요 | 항목 | 값 | | --- | --- | | 원본 파일 | `rawp-dps.md` | | 추가된 섹션 | 3 | | 삭제된 섹션 | 1 | | 수정된 섹션 | 12 | | 문서 변경 여부 | 예 | ## 추가된 섹션 - 14. 하위 호환성 (Backward Compatibility) - 17. 에이전트 어댑터 프로토콜 (Agent Adapter Protocol) - 18. 단일 턴 프로세스 재생성 (Single-Turn Process Respawn) ## 삭제된 섹션 - 14. 하위 호환성 가이드라인 ## 수정된 섹션 - Document Overview - 1. 개요 (Introduction) - 2. Envelope 구조 (Frame Envelope) - 3. 이벤트 타입 시스템 (Event Type System) - 4. 에이전트 출력 이벤트 (`agent.*`) - 5. 도구 호출 이벤트 (`tool.*`) - 6. 제어 이벤트 (`control.*`) - 7. 세션 이벤트 (`session.*`) - 10. 서브에이전트 위임 규격 (Subagent Delegation) - 12. 명령어 및 능력 고지 (Command & Capability Negotiation) - 부록 A. Claude Code 출력 유형 전수 조사 및 매핑 - 부록 B. 이벤트 타입 전체 목록 (Quick Reference) ## 섹션별 변경 상세 ### Document Overview - 이전 앵커: `#document-overview` - 현재 앵커: `#document-overview` - 추가된 줄: 6 - 삭제된 줄: 7 ```diff **Remote Agent Wire Protocol — Data Plane Streaming** -| 항목 | 값 | -| ---- | ---------------------------------- | -| 상태 | Draft | -| 버전 | 1.0 | -| 날짜 | 2026-03-08 | -| 호환 | RAWP 1.0 (제어 평면) | -| 대체 | RAWP 1.0 §6 (이하 RAWP-1.0-Legacy) | +| 항목 | 값 | +| ---- | ---------------------- | +| 상태 | Draft | +| 버전 | 1.0.1 | +| 날짜 | 2026-03-16 | +| 호환 | RAWP 1.0.2 (제어 평면) | --- ``` ### 1. 개요 (Introduction) - 이전 앵커: `#1-introduction` - 현재 앵커: `#1-introduction` - 추가된 줄: 13 - 삭제된 줄: 16 ```diff ## 1. 개요 (Introduction) -RAWP-DPS 1.0은 RAWP 1.0의 데이터 평면(§6)을 대체하는 독립 스트리밍 규격이다. 기존 RAWP 1.0 §6(이하 **RAWP-1.0-Legacy**)은 단순 텍스트 스트림, 승인 상호작용, 사용량 지표, 에러 보고, 파일 전송만을 정의하였으며, 에이전트 코딩 도구(Claude Code 등)가 생성하는 도구 호출 결과, 계획 문서, 태스크 관리, 컨텍스트 압축, 서브에이전트 위임 등 다양한 출력 형태를 포괄하지 못한다. +RAWP-DPS 1.0은 RAWP 1.0의 데이터 평면(§6)을 대체하는 독립 스트리밍 규격이다. RAWP-DPS 1.0은 다음 목표를 달성하기 위해 설계되었다: ... 1. **완전성(Completeness)**: Claude Code를 포함한 에이전트 코딩 도구의 모든 출력 형태를 단일 프레임 규격으로 포맷화한다. 2. **범용성(Generality)**: 특정 에이전트에 종속되지 않으며, 임의의 에이전트 도구 체계를 수용할 수 있는 확장 가능한 타입 시스템을 제공한다. -3. **호환성(Compatibility)**: 알 수 없는 타입의 정방향 호환성(Forward Compatibility)과, RAWP-1.0-Legacy 대비 하위 호환성(Backward Compatibility)을 구조적으로 보장한다. +3. **호환성(Compatibility)**: 알 수 없는 타입의 정방향 호환성(Forward Compatibility)을 구조적으로 보장한다. ### 1.1. 요구사항 표기 규약 ... RAWP-DPS 1.0은 RAWP 1.0의 제어 평면(§1–§5, §7–§8)을 변경하지 않는다. 세션 초기화(§5.1), WebSocket 수립(§5.3), 보안 규격(§7)은 그대로 유지되며, 본 규격은 WSS 연결 수립 **이후** 교환되는 데이터 프레임의 포맷만을 재정의한다. -### 1.3. RAWP-1.0-Legacy 호환 모드 - -세션 초기화(§5.1) 시 `Sec-WebSocket-Protocol` 헤더로 프로토콜 버전을 협상한다: - -- `rawp-dps-1.0`: 본 규격 적용 -- `rawp-1.0`: RAWP-1.0-Legacy 적용 (기존 구현 호환) +### 1.3. RAWP-1.0-Legacy (지원 종료) -서버와 클라이언트 모두 `rawp-dps-1.0`을 우선 제안해야 하며 (SHOULD), 상대가 미지원 시 `rawp-1.0`으로 폴백해야 한다 (MUST). +RAWP-1.0-Legacy는 지원이 종료되었다. 모든 구현은 본 규격(`rawp-dps-1.0`)만을 사용해야 한다 (MUST). ### 1.4. 용어 정의 ... 본 문서에서 추가로 사용하는 용어: -| 용어 | 정의 | -| --------------- | ------------------------------------------------------------------------ | -| Frame | WSS를 통해 송수신되는 하나의 JSON 메시지 단위 | -| Content Block | 단일 Frame 내에서 독립적 의미를 가지는 출력 조각 | -| Turn | 에이전트의 단일 추론-행동 사이클 (프롬프트 수신 → 도구 사용 → 응답 완료) | -| Tool Invocation | 에이전트가 외부 도구를 호출하는 행위와 그 결과의 쌍 | -| Namespace | 이벤트 타입의 계층적 분류 체계 (`agent.`, `tool.`, `session.` 등) | +| 용어 | 정의 | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Agent Session | RAWP 1.0.2 §1.2에서 정의. 에이전트의 논리적 생명주기 단위. 본 규격의 모든 Frame은 `session_id` 필드를 통해 특정 Agent Session에 귀속된다. 본 문서에서 "세션"은 별도 명시가 없는 한 Agent Session을 의미한다. | +| WSS Connection | RAWP 1.0.2 §1.2에서 정의. Agent Session에 바인딩된 WebSocket 전송 채널. 본 규격의 Frame은 WSS Connection을 통해 송수신된다. 하나의 Agent Session에 복수의 WSS Connection이 동시에 존재할 수 있다. | +| Frame | WSS Connection을 통해 송수신되는 하나의 JSON 메시지 단위 | +| Content Block | 단일 Frame 내에서 독립적 의미를 가지는 출력 조각 | +| Turn | 에이전트의 단일 추론-행동 사이클 (프롬프트 수신 → 도구 사용 → 응답 완료). 하나의 Agent Session 내에서 순차적으로 발생한다. | +| Tool Invocation | 에이전트가 외부 도구를 호출하는 행위와 그 결과의 쌍 | +| Namespace | 이벤트 타입의 계층적 분류 체계 (`agent.`, `tool.`, `session.` 등) | --- ``` ### 2. Envelope 구조 (Frame Envelope) - 이전 앵커: `#2-envelope-frame-envelope` - 현재 앵커: `#2-envelope-frame-envelope` - 추가된 줄: 13 - 삭제된 줄: 1 ```diff | `message_id` | MUST | 프레임 고유 식별자. 중복 수신 시 멱등성(Idempotency) 판단 기준. | | `timestamp` | MUST | 발신 시각. ISO 8601. 밀리초 정밀도 권장 (SHOULD). | -| `session_id` | MUST | RAWP 1.0 §5.1에서 발급된 세션 식별자. | +| `session_id` | MUST | Agent Session 식별자 (UUID v4). RAWP 1.0.2 §5.1에서 발급. WSS Connection이 아닌 Agent Session을 식별한다. | | `turn_id` | SHOULD | 현재 에이전트 Turn의 식별자. 동일 Turn 내 모든 프레임은 같은 `turn_id`를 공유. | | `parent_id` | OPTIONAL | 요청-응답 상관 관계. `agent.prompt.request`에 대한 `agent.prompt.delta`는 해당 요청의 `message_id`를 `parent_id`로 참조. | ... WSS는 메시지 순서를 보장하므로, 동일 연결 내 프레임은 발신 순서대로 수신됨을 전제한다. 단, 재연결(reattach) 후 `session.history` 프레임을 통해 과거 이력이 재전송될 때는 `timestamp`와 `message_id` 기준으로 순서를 재구성해야 한다 (MUST). +### 2.4. 다중 마스터 환경 (Multi-Master Fan-out) + +클라이언트가 복수의 마스터 서버에 동시 등록된 환경(RAWP 1.0.2 §3 참조)에서의 DPS 프레임 분배 규칙을 정의한다. + +**브로드캐스트 원칙**: 클라이언트는 하나의 Agent Session에서 발생하는 모든 DPS 프레임을 해당 세션에 연결된 **모든** WSS Connection으로 브로드캐스트해야 한다 (MUST). 여기에는 세션을 생성한 마스터의 WSS뿐 아니라, 다른 마스터가 동일 세션에 연결한 WSS도 포함된다. + +- 에이전트 출력 프레임(`agent.*`, `tool.*`, `session.*`)은 해당 세션에 바인딩된 모든 WSS Connection에 전송해야 한다 (MUST). +- 마스터가 발송한 `control.*` 프레임(예: `control.prompt.request`)도 해당 세션에 바인딩된 다른 모든 WSS Connection에 중계해야 한다 (MUST). 이를 통해 마스터 A가 전송한 프롬프트를 마스터 B도 수신하여 사용자에게 표시할 수 있다. +- 로컬 UI WSS Connection(RAWP 1.0.2 §10.6)도 브로드캐스트 대상에 포함된다 (MUST). +- 로컬 세션(RAWP 1.0.2 §10, `origin: "local"`)의 DPS 프레임은 마스터에 전송하지 않는다 (MUST NOT). 로컬 UI WSS에만 전달한다. +- `control.*` 프레임의 중계 시 `message_id` 기반 멱등성 처리를 수행하여 발신자에게 자신의 프레임이 되돌아오는 것을 방지해야 한다 (MUST). 즉, 프레임을 발송한 WSS Connection에는 해당 프레임을 재전송하지 않는다. + --- ``` ### 3. 이벤트 타입 시스템 (Event Type System) - 이전 앵커: `#3-event-type-system` - 현재 앵커: `#3-event-type-system` - 추가된 줄: 3 - 삭제된 줄: 18 ```diff | `session` | 양방향 | 세션 수준 이벤트 (이력, 압축, 에러) | -### 3.1.1. 확장 네임스페이스 +#### 3.1.1. 확장 네임스페이스 본 규격에 정의되지 않은 커스텀 이벤트는 `x-{vendor}` 접두사를 사용해야 한다 (MUST). ... 수신자는 `x-` 접두 네임스페이스를 알 수 없는 타입으로 취급하여 무시할 수 있다. -### 3.2. 레거시 타입 매핑 - -RAWP-1.0-Legacy의 이벤트 타입과 본 규격 타입 간 대응 관계: +### 3.2. 레거시 타입 매핑 (지원 종료) -| RAWP-1.0-Legacy | RAWP-DPS 1.0 | 비고 | -| ---------------------------------------------- | -------------------------------------- | ------------------- | -| `agent_session_history` | `session.history` | | -| `agent_stdin_write` / `agent_prompt_req` | `control.prompt.request` | | -| `agent_text_stream` / `agent_prompt_res` | `agent.text.delta` + `agent.text.done` | 분리 | -| `agent_approval_req` / `agent_interaction_ask` | `agent.interaction.request` | | -| `agent_approval_res` / `agent_interaction_ans` | `control.interaction.response` | | -| `agent_interaction_timeout` | `control.interaction.timeout` | | -| `agent_usage_metrics` | `session.usage` | | -| `agent_error` | `agent.error` | | -| `agent_file_transfer` | `agent.file.transfer` | | -| (해당 없음) | `control.file.search` | 신규, Legacy 미지원 | -| (해당 없음) | `session.file.candidates` | 신규, Legacy 미지원 | -| (해당 없음) | `control.file.search.cancel` | 신규, Legacy 미지원 | +RAWP-1.0-Legacy 이벤트 타입과의 매핑은 지원이 종료되었다. 본 규격의 이벤트 타입만을 사용해야 한다 (MUST). --- ``` ### 4. 에이전트 출력 이벤트 (`agent.*`) - 이전 앵커: `#4-agent` - 현재 앵커: `#4-agent` - 추가된 줄: 10 - 삭제된 줄: 10 ```diff 에이전트의 자연어 응답을 실시간으로 전달한다. -### 4.1.1. `agent.text.delta` (Client → Master) +#### 4.1.1. `agent.text.delta` (Client → Master) ```json ... ``` -### 4.1.2. `agent.text.done` (Client → Master) +#### 4.1.2. `agent.text.done` (Client → Master) 텍스트 스트리밍이 완료되었음을 알린다. 하나의 Content Block이 종료될 때마다 발송한다. ... 에이전트의 내부 추론 과정을 전달한다. Extended Thinking, Chain-of-Thought 등에 사용. -### 4.2.1. `agent.thinking.delta` (Client → Master) +#### 4.2.1. `agent.thinking.delta` (Client → Master) ```json ... ``` -### 4.2.2. `agent.thinking.done` (Client → Master) +#### 4.2.2. `agent.thinking.done` (Client → Master) ```json ... ### 4.3. 상호작용 요청 (Interaction Request) -에이전트가 사용자의 승인 또는 선택을 요구할 때 발송한다. RAWP-1.0-Legacy의 `agent_approval_req`/`agent_interaction_ask`를 통합 확장한다. +에이전트가 사용자의 승인 또는 선택을 요구할 때 발송한다. -### 4.3.1. `agent.interaction.request` (Client → Master) +#### 4.3.1. `agent.interaction.request` (Client → Master) ```json ... ### 4.4. 에러 보고 -### 4.4.1. `agent.error` (Client → Master) +#### 4.4.1. `agent.error` (Client → Master) ```json ... ### 4.5. 파일 전송 -### 4.5.1. `agent.file.transfer` (양방향) +#### 4.5.1. `agent.file.transfer` (양방향) -RAWP-1.0-Legacy와 동일하게, 바이너리는 WSS를 태우지 않고 HTTP 스토리지 URL로 교환한다. +바이너리는 WSS를 태우지 않고 HTTP 스토리지 URL로 교환한다. ```json ... ### 4.6. 에이전트 상태 변경 -### 4.6.1. `agent.state.changed` (Client → Master) +#### 4.6.1. `agent.state.changed` (Client → Master) 에이전트의 내부 상태 전이를 마스터에 통보한다. ``` ### 5. 도구 호출 이벤트 (`tool.*`) - 이전 앵커: `#5-tool` - 현재 앵커: `#5-tool` - 추가된 줄: 57 - 삭제된 줄: 5 ```diff ### 5.2. 도구 호출 요청 -### 5.2.1. `tool.invoke.request` (Client → Master) +#### 5.2.1. `tool.invoke.request` (Client → Master) 에이전트가 도구를 호출하려 함을 마스터에 통보한다. 승인이 필요한 도구의 경우 `agent.interaction.request`가 선행한다. ... ### 5.3. 도구 실행 결과 -### 5.3.1. `tool.invoke.result` (Client → Master) +#### 5.3.1. `tool.invoke.result` (Client → Master) 도구 실행이 완료된 후 결과를 보고한다. ... | `agent_result` | 서브에이전트 실행 결과 | Task(Subagent) | -### 5.3.2. `tool.invoke.stream` (Client → Master) +#### 5.3.2. `tool.invoke.stream` (Client → Master) 장시간 실행 도구의 중간 출력을 스트리밍한다 (예: Bash 명령의 실시간 stdout). ... ``` +#### 5.3.3. `output_type` 결정 규칙 + +`tool.invoke.result`의 `output_type` 값은 다음 우선순위에 따라 결정해야 한다 (MUST): + +1. **도구 카탈로그 사전 선언**: `tool.catalog.publish`(§5.4.1)에서 해당 도구의 `output_type`이 사전 선언된 경우, 해당 값을 사용한다. 이것이 최우선이다. +2. **도구 카테고리 기반 기본값**: 사전 선언이 없으면, `tool.catalog.publish`의 `category` 필드에 따른 기본값을 적용한다: + +| `category` | 도구 동작 | 기본 `output_type` | +| ----------------- | --------------------------------------- | ---------------------------------- | +| `filesystem` | 파일 쓰기/수정 (Write, Edit, MultiEdit) | `diff` (변경 발생 시) 또는 `empty` | +| `filesystem` | 파일 읽기 (Read, NotebookRead) | `file_content` | +| `filesystem` | 파일 탐색 (Glob, LS) | `file_list` | +| `shell` | 셸 명령 실행 (Bash) | `text` | +| `search` | 검색 (Grep, WebSearch) | `text` 또는 `file_list` | +| `web` | 웹 콘텐츠 접근 (WebFetch) | `web_content` | +| `task_management` | 태스크 관리 (TodoRead, TodoWrite) | `structured` | +| `agent` | 서브에이전트 위임 (Task) | `agent_result` | + +3. **폴백**: 위 규칙으로 결정할 수 없으면 `text`로 설정한다 (MUST). + +`output_type`은 수신 측(마스터, 엣지 노드)이 결과를 적절한 뷰어로 렌더링하기 위한 힌트이다. 각 `output_type`의 렌더링 규칙은 RAWP-CRS 1.0.1 §4.5를 참조한다. + ### 5.4. 도구 사용 가능 목록 고지 (Tool Catalog) -### 5.4.1. `tool.catalog.publish` (Client → Master) +#### 5.4.1. `tool.catalog.publish` (Client → Master) 에이전트가 현재 세션에서 사용 가능한 도구 목록을 마스터에 고지한다. 세션 시작 직후 또는 도구 구성 변경 시 발송한다. ... "output_type": "String (선택, 기본 output_type)", "requires_approval": "Boolean (선택, 실행 전 승인 필요 여부)", - "category": "String (선택, 도구 분류. 아래 열거 값)" + "category": "String (선택, 도구 분류. 아래 열거 값)", + "status": "String (선택, 기본값 'available'. 아래 열거 값)", + "status_description": "String (선택, 현재 상태에 대한 사유 설명. 없으면 UI에 상태 사유를 표시하지 않는다)" } + ], + "diagnostics": [ + { + "severity": "String (필수, 'info' | 'warning' | 'error' | 'fatal')", + "tool_name": "String (선택, 특정 도구에 관한 진단이면 해당 도구명)", + "code": "String (필수, 진단 코드. 예: 'TOOL_UNAVAILABLE', 'VERSION_MISMATCH', 'DEPENDENCY_MISSING')", + "message": "String (필수, 휴먼 리더블 진단 메시지)" + } ] } ... | `custom` | 사용자 정의 도구 | 커스텀 도구 | +**`status` 열거 값:** + +| 값 | 설명 | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| `available` | 도구가 정상 동작 가능. 기본값. `status` 필드가 생략되면 `available`로 간주한다. | +| `unavailable` | 도구를 사용할 수 없음. 의존성 누락, 권한 부족, 실행 파일 미설치 등. 마스터는 이 도구에 대한 `tool.invoke.request` 발송을 차단해야 한다 (MUST). | +| `degraded` | 도구가 동작하지만 일부 기능이 제한됨. 사용은 허용되나 사용자에게 제한 사항을 고지해야 한다 (SHOULD). | + ... diff truncated ... ``` ### 6. 제어 이벤트 (`control.*`) - 이전 앵커: `#6-control` - 현재 앵커: `#6-control` - 추가된 줄: 46 - 삭제된 줄: 8 ```diff ### 6.1. 프롬프트/입력 전달 -### 6.1.1. `control.prompt.request` (Master → Client) +#### 6.1.1. `control.prompt.request` (Master → Client) ```json ... ``` -> **변경 사항**: `file_references` 필드가 추가되었다. 이 필드는 `prompt_text` 내에 삽입된 인라인 파일 참조 토큰(§16.2)의 메타데이터를 제공한다. `file_references`와 기존 `context_files`의 관계: `context_files`는 프롬프트와 함께 첨부되는 참조 파일이고, `file_references`는 프롬프트 텍스트 내에서 인라인으로 언급된 파일의 메타데이터이다. 양자는 독립적이며, 동일 파일이 양쪽에 모두 존재할 수 있다. - **`input_type` 열거 값:** ... | `piped_stdin` | 파이프된 표준 입력 (headless 모드) | -### 6.1.2. `control.prompt.cancel` (Master → Client) +#### 6.1.2. `control.prompt.cancel` (Master → Client) 진행 중인 에이전트 Turn을 취소한다. 수신 시 클라이언트는 현재 실행 중인 도구를 가능한 한 빨리 중단하고, `agent.text.done`(is_cancelled: true)을 발송해야 한다 (MUST). ... ### 6.2. 상호작용 응답 -### 6.2.1. `control.interaction.response` (Master → Client) +#### 6.2.1. `control.interaction.response` (Master → Client) ```json ... ``` -### 6.2.2. `control.interaction.timeout` (Master → Client) +#### 6.2.2. `control.interaction.timeout` (Master → Client) ```json ... ### 6.3. 세션 제어 명령 -### 6.3.1. `control.session.compact` (Master → Client) +#### 6.3.1. `control.session.compact` (Master → Client) 마스터가 컨텍스트 압축을 요청한다 (사용자의 `/compact` 명령 등). ... ``` -### 6.3.2. `control.mode.switch` (Master → Client) +**자동 압축 트리거 조건:** +에이전트는 `session.capabilities`에서 `context_compaction: true`를 고지한 경우에 한하여 자동 압축을 수행할 수 있다 (MAY). 자동 압축의 트리거 조건은 다음을 따른다: + +- `context_window.utilization` ≥ 0.80이면 압축을 고려해야 한다 (SHOULD). +- `context_window.utilization` ≥ 0.95이면 압축을 수행해야 한다 (MUST). +- 자동 압축 시 `session.compacted`(§7.2.1)의 `trigger` 필드는 `"auto"`로 설정한다. +- 마스터의 `control.session.compact` 없이 에이전트가 자체적으로 수행한다. + +**`target_token_ratio` 필드 의미:** + +- `target_token_ratio`는 압축 후 목표 컨텍스트 윈도우 사용률을 의미한다. 값 범위: `0.0`(최대 압축) ~ `1.0`(압축하지 않음). +- 예: `target_token_ratio: 0.5`이면 컨텍스트 윈도우의 50% 이하로 압축을 목표로 한다. +- 이 값은 best-effort이다. 에이전트가 정확한 비율 달성을 보장하지 않는다. +- 필드가 생략되면 에이전트의 기본 압축 전략을 따른다. + +**압축 미지원 시 동작:** + +`session.capabilities`에서 `context_compaction: false`이거나 미고지인 클라이언트가 `control.session.compact`를 수신하면, `session.error` (error_code: `"COMPACTION_NOT_SUPPORTED"`, fatal: `false`)를 반환해야 한다 (MUST). + +#### 6.3.2. `control.mode.switch` (Master → Client) + 에이전트 동작 모드를 전환한다. ... | `review` | 코드 리뷰 모드 | +**모드별 도구 사용 제한:** + +| 모드 | 허용 도구 카테고리 | 금지 도구 카테고리 | +| --------- | -------------------------------------------------------------- | --------------------------------------------------- | +| `default` | 모든 카테고리 | 없음 | +| `plan` | `search`, `filesystem`(읽기 전용: Read, Glob, LS, Grep), `web` | `filesystem`(쓰기: Write, Edit, MultiEdit), `shell` | +| `review` | `search`, `filesystem`(읽기 전용), `web` | `filesystem`(쓰기), `shell` | + ... diff truncated ... ``` ### 7. 세션 이벤트 (`session.*`) - 이전 앵커: `#7-session` - 현재 앵커: `#7-session` - 추가된 줄: 112 - 삭제된 줄: 8 ```diff ### 7.1. 이력 복구 -### 7.1.1. `session.history` (Client → Master) +#### 7.1.1. `session.history` (Client → Master) -재연결(reattach) 성공 직후 선제적으로 발송한다. RAWP-1.0-Legacy의 `agent_session_history`를 대체한다. +재연결(reattach) 성공 직후 선제적으로 발송한다. ```json ... ### 7.2. 컨텍스트 압축 보고 -### 7.2.1. `session.compacted` (Client → Master) +#### 7.2.1. `session.compacted` (Client → Master) 에이전트가 자동 또는 수동 컨텍스트 압축을 수행한 후 결과를 보고한다. ... ### 7.3. 사용량 지표 -### 7.3.1. `session.usage` (양방향, 주로 Client → Master) +#### 7.3.1. `session.usage` (양방향, 주로 Client → Master) -텍스트 생성 완료 시점(`agent.text.done`) 또는 Turn 종료 시 반드시 동반 발송해야 한다 (MUST). RAWP-1.0-Legacy의 `agent_usage_metrics`를 대체한다. +텍스트 생성 완료 시점(`agent.text.done`) 또는 Turn 종료 시 반드시 동반 발송해야 한다 (MUST). ```json ... ### 7.4. 세션 에러 -### 7.4.1. `session.error` (양방향) +#### 7.4.1. `session.error` (양방향) 세션 수준의 프로토콜 에러를 보고한다. 에이전트 수준 에러(`agent.error`)와 구분된다. ... ### 7.5. Turn 라이프사이클 -### 7.5.1. `session.turn.start` (Client → Master) +#### 7.5.1. `session.turn.start` (Client → Master) 에이전트가 새 Turn을 시작함을 알린다. ... ``` -### 7.5.2. `session.turn.end` (Client → Master) +#### 7.5.2. `session.turn.end` (Client → Master) Turn이 완료되었음을 알린다. 이 이벤트 직후 `session.usage`가 동반되어야 한다 (MUST). ... | `awaiting_input` | 사용자 입력 대기 | +#### 7.5.3. 세션 종료 시 진행 중 항목 처리 + +세션이 종료(RAWP 1.0.2 §5.2 `DELETE /v1/session/{session_id}` 또는 `session.error` (fatal: `true`))될 때, 진행 중인 Turn이 존재하면 다음 순서로 정리 프레임을 발송해야 한다 (MUST): + +1. 모든 미완료 도구 호출에 대해 `tool.invoke.result` (status: `"cancelled"`)를 발송한다. +2. `session.turn.end` (stop_reason: `"error"`)를 발송한다. +3. WSS 연결을 종료한다. + +위 프레임들은 WSS 연결 종료 전에 모두 발송 완료되어야 한다 (MUST). 진행 중인 Turn이 없으면 즉시 WSS를 종료한다. + +### 7.6. 세션 이름 변경 + +#### 7.6.1. `session.renamed` (양방향) + +```json +{ + "type": "session.renamed", + "payload": { + "session_id": "String (필수, 대상 세션 식별자)", + "name": "String (필수, 변경된 세션 이름)", + "previous_name": "String (선택, 변경 전 세션 이름)", + "renamed_by": "String (필수, 'edge' | 'client' | 'master')" + } +} +``` + +`renamed_by`는 이름 변경을 요청한 주체를 식별한다. 마스터는 이 이벤트를 해당 세션에 연결된 모든 엣지 WSS로 브로드캐스트해야 한다 (MUST). + +### 7.7. 세션 삭제 + ... diff truncated ... ``` ### 10. 서브에이전트 위임 규격 (Subagent Delegation) - 이전 앵커: `#10-subagent-delegation` - 현재 앵커: `#10-subagent-delegation` - 추가된 줄: 96 - 삭제된 줄: 14 ```diff ## 10. 서브에이전트 위임 규격 (Subagent Delegation) -에이전트가 하위 에이전트(Task/Agent)를 생성하여 작업을 위임하는 구조를 정의한다. +에이전트가 하위 에이전트(서브에이전트)를 생성하여 작업을 위임하는 구조를 정의한다. 서브에이전트는 부모 에이전트와 동일한 Agent Session 내에서 실행되며, 서브에이전트 내부에서 발생하는 모든 DPS 프레임은 부모와 동일한 `session_id`를 공유한다. -### 10.1. 서브에이전트 시작 +### 10.1. 서브에이전트 호출 -`tool.invoke.request`에서 `tool_name: "Task"` 또는 `tool_name: "Agent"`를 사용하며, `input`에 서브에이전트 설정을 포함한다: +`tool.invoke.request`에서 서브에이전트를 생성하는 도구를 호출한다. `payload`에 `subagent` 필드가 존재하면 이 도구 호출이 서브에이전트를 생성함을 의미한다. ```json ... "type": "tool.invoke.request", "payload": { - "invocation_id": "subagent-uuid-here", - "tool_name": "Task", + "invocation_id": "String (필수, UUID v4. 이 값이 서브에이전트의 parent_invocation_id가 된다)", + "tool_name": "String (필수, 예: 'Task', 'Agent')", "input": { "description": "String (필수, 서브에이전트 임무 설명)", ... "allowed_tools": ["String (선택, 서브에이전트 허용 도구 목록)"], "model": "String (선택, 사용할 모델)" + }, + "subagent": { + "agent_type": "String (선택, 서브에이전트 유형. 예: 'Explore', 'Plan', 'general-purpose')", + "description": "String (선택, 서브에이전트 임무 요약)" } } ... ``` -### 10.2. 서브에이전트 출력 +`subagent` 필드가 없으면 일반 도구 호출이다. -서브에이전트의 모든 출력은 부모 에이전트의 세션 내에서 `tool.invoke.stream`으로 중계되거나, 완료 시 `tool.invoke.result`(output_type: `agent_result`)로 최종 결과가 보고된다. +### 10.2. 서브에이전트 컨텍스트 (`metadata.subagent_context`) -서브에이전트의 중간 이벤트를 마스터에 직접 노출하려면, 각 프레임의 `metadata`에 위임 체인을 기록한다: +서브에이전트 내부에서 발생하는 모든 DPS 프레임은 `metadata.subagent_context` 필드를 포함해야 한다 (MUST). 이를 통해 수신 측은 각 메시지의 출처 에이전트를 식별할 수 있다. ```json { "metadata": { - "delegation_chain": [ - { - "agent_id": "String (부모 에이전트 식별자)", - "invocation_id": "String (위임 호출 ID)" - } - ] + "subagent_context": { + "parent_invocation_id": "String (필수, 이 서브에이전트를 호출한 tool.invoke.request의 invocation_id)", + "agent_type": "String (선택, 서브에이전트 유형)", + "depth": "Number (필수, 중첩 깊이. 0 = 메인 에이전트, 1 = 서브에이전트, 2 = 서브의 서브에이전트)" + } } } ``` +**규칙:** + +- `subagent_context`가 없거나 `null`인 프레임은 메인 에이전트(`depth: 0`)의 메시지로 취급해야 한다 (MUST). +- 서브에이전트 내부의 `agent.*`, `tool.*`, `session.*` 모든 프레임에 포함해야 한다 (MUST). +- `depth`는 발신 측(클라이언트)이 서브에이전트 생성 시점에 이미 알고 있는 값이다. 수신 측이 전체 프레임 히스토리 없이 단일 프레임만으로 중첩 깊이를 결정할 수 있도록 명시적으로 포함한다. +- 중첩 서브에이전트의 경우 `parent_invocation_id`는 직계 부모의 `invocation_id`만 가리킨다. 전체 위임 체인이 필요한 경우 `parent_invocation_id`를 재귀 추적하여 복원한다. + +### 10.3. 서브에이전트 생명주기 이벤트 + +#### 10.3.1. `agent.subagent.started` (Client → Master) + +서브에이전트가 시작되었음을 통보한다. `tool.invoke.request`(`subagent` 포함) 발송 직후에 발송해야 한다 (MUST). + +```json +{ + "type": "agent.subagent.started", + "payload": { + "parent_invocation_id": "String (필수, 대응하는 tool.invoke.request의 invocation_id)", + "agent_type": "String (선택, 서브에이전트 유형)", + "description": "String (선택, 서브에이전트 임무 설명)", ... diff truncated ... ``` ### 12. 명령어 및 능력 고지 (Command & Capability Negotiation) - 이전 앵커: `#12-command-capability-negotiation` - 현재 앵커: `#12-command-capability-negotiation` - 추가된 줄: 2 - 삭제된 줄: 4 ```diff 에이전트가 지원하는 슬래시 명령어 목록을 마스터에 고지한다. -### 12.1.1. `agent.commands.publish` (Client → Master) +#### 12.1.1. `agent.commands.publish` (Client → Master) ```json ... 세션 시작 직후, 양측은 `session.capabilities` 이벤트를 교환하여 지원하는 기능 목록을 협상한다. -### 12.2.1. `session.capabilities` (양방향) +#### 12.2.1. `session.capabilities` (양방향) ```json ... ``` -> **변경 사항**: `features`에 `file_reference`와 `file_search_fuzzy`가 추가되었다 (§16.5 참조). - 수신 측은 상대방이 고지하지 않은 `features`의 이벤트를 발송해서는 안 된다 (MUST NOT). 예를 들어 마스터가 `thinking_stream: false`이면, 클라이언트는 `agent.thinking.delta`를 발송하지 않아야 한다. ``` ### 부록 A. Claude Code 출력 유형 전수 조사 및 매핑 - 이전 앵커: `#-a-claude-code-` - 현재 앵커: `#-a-claude-code-` - 추가된 줄: 2 - 삭제된 줄: 20 ```diff | 세션 종료 | `session.turn.end` + RAWP 1.0 §5.2 | -### A.4. RAWP-1.0-Legacy 미지원 항목 - -기존 RAWP-1.0-Legacy에서 지원하지 못했으나 본 규격에서 해결된 항목: +### A.4. RAWP-1.0-Legacy (지원 종료) -| 항목 | RAWP-1.0-Legacy | RAWP-DPS 1.0 | -| ------------------------- | --------------- | -------------------------------------------------------- | -| 도구 호출/결과 프레이밍 | ❌ 미지원 | ✅ `tool.invoke.*` | -| 계획 문서 전달 | ❌ 미지원 | ✅ `metadata.content_role: plan` | -| TODO/태스크 관리 | ❌ 미지원 | ✅ §8 + `tool.invoke.result` | -| 컨텍스트 압축 보고 | ❌ 미지원 | ✅ `session.compacted` | -| 명령어 목록 조회 | ❌ 미지원 | ✅ `agent.commands.publish` | -| 사고 스트리밍 | ❌ 미지원 | ✅ `agent.thinking.*` | -| 서브에이전트 위임 | ❌ 미지원 | ✅ §10 | -| 구조화 출력 | ❌ 미지원 | ✅ §11 | -| 도구 출력 실시간 스트리밍 | ❌ 미지원 | ✅ `tool.invoke.stream` | -| 능력 협상 | ❌ 미지원 | ✅ `session.capabilities` | -| 병렬 도구 호출 그룹화 | ❌ 미지원 | ✅ `parallel_group_id` | -| Turn 라이프사이클 | ❌ 미지원 | ✅ `session.turn.*` | -| 프롬프트 취소 | ❌ 미지원 | ✅ `control.prompt.cancel` | -| 동작 모드 전환 | ❌ 미지원 | ✅ `control.mode.switch` | -| 파일 참조 검색 | ❌ 미지원 | ✅ §16 `control.file.search` / `session.file.candidates` | +RAWP-1.0-Legacy와의 비교 항목은 지원 종료로 더 이상 유지하지 않는다. --- ``` ### 부록 B. 이벤트 타입 전체 목록 (Quick Reference) - 이전 앵커: `#-b-quick-reference` - 현재 앵커: `#-b-quick-reference` - 추가된 줄: 4 - 삭제된 줄: 0 ```diff | `agent.state.changed` | C→M | 4.6.1 | | `agent.commands.publish` | C→M | 12.1.1 | +| `agent.subagent.started` | C→M | 10.3.1 | +| `agent.subagent.ended` | C→M | 10.3.2 | | `tool.invoke.request` | C→M | 5.2.1 | | `tool.invoke.result` | C→M | 5.3.1 | ... | `session.capabilities` | 양방향 | 12.2.1 | | `session.file.candidates` | C→M | 16.1.2 | +| `session.renamed` | 양방향 | 7.6.1 | +| `session.deleted` | 양방향 | 7.7.1 | ```